From 437bbf0c9da3a79c65b7c84e387bea65ab870805 Mon Sep 17 00:00:00 2001 From: kapitche <142559040+kapitche@users.noreply.github.com> Date: Fri, 4 Jul 2025 00:12:59 -0400 Subject: [PATCH] local file mnemonics info instead of fetching them --- .gitignore | 4 +- package.json | 6 +- scrapper/requirements.txt | 3 + scrapper/scraper.py | 363 ++ src/extension.js | 127 +- src/mnemonics.js | 55 - syntaxes/x86_instructions.json | 9666 ++++++++++++++++++++++++++++++++ 7 files changed, 10108 insertions(+), 116 deletions(-) create mode 100644 scrapper/requirements.txt create mode 100644 scrapper/scraper.py delete mode 100644 src/mnemonics.js create mode 100644 syntaxes/x86_instructions.json diff --git a/.gitignore b/.gitignore index 67dfeb3..8dc600d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules -*.vsix \ No newline at end of file +*.vsix +/scrapper/discovered_mnemonics.txt +/scrapper/mnemonic_url_mappings.txt \ No newline at end of file diff --git a/package.json b/package.json index b87963c..ec8f337 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "x86-assembly-syntax", "displayName": "Universal Assembly Syntax Highlighting", "description": "Syntax highlighting extension for x86, x64 and ARM assembly both for Intel and AT&T syntax", - "version": "1.2.2", + "version": "1.2.3", "engines": { "vscode": "^1.75.0" }, @@ -93,10 +93,6 @@ "highlighting" ], "homepage": "https://github.com/haxo-games/x86-x64-syntax-highlighting#readme", - "dependencies": { - "axios": "^1.7.7", - "cheerio": "^1.0.0" - }, "devDependencies": { "vscode": "^1.1.34" } diff --git a/scrapper/requirements.txt b/scrapper/requirements.txt new file mode 100644 index 0000000..a7c175d --- /dev/null +++ b/scrapper/requirements.txt @@ -0,0 +1,3 @@ +requests>=2.25.1 +beautifulsoup4>=4.9.3 +lxml>=4.6.3 \ No newline at end of file diff --git a/scrapper/scraper.py b/scrapper/scraper.py new file mode 100644 index 0000000..bcd5237 --- /dev/null +++ b/scrapper/scraper.py @@ -0,0 +1,363 @@ +#!/usr/bin/env python3 +""" +X86 Instruction Scraper +Combines mnemonic discovery from scraper.py with batch processing from populate_json.py +Scrapes x86 instruction information from https://www.felixcloutier.com/x86/ +and saves it to a local JSON file for offline use. +""" + +import requests +from bs4 import BeautifulSoup +import json +import time +import re +import os +from typing import Dict, Optional, List, Tuple + +def fetch_all_mnemonics() -> Tuple[List[str], Dict[str, str]]: + """ + Fetch all mnemonics from the main x86 reference page tables + + Returns: + Tuple of (mnemonics_list, mnemonic_to_url_mapping) + """ + print("Fetching all mnemonics from https://www.felixcloutier.com/x86/") + + try: + response = requests.get("https://www.felixcloutier.com/x86/", timeout=15) + response.raise_for_status() + + soup = BeautifulSoup(response.content, 'html.parser') + + # Find all tables containing instructions + tables = soup.find_all('table') + print(f"Found {len(tables)} tables on the page") + + all_mnemonics = set() + mnemonic_to_url = {} # Maps mnemonic to its actual URL path + + for i, table in enumerate(tables): + print(f"Processing table {i+1}/{len(tables)}") + + # Find all rows in the table + rows = table.find_all('tr') + + # Skip header row and process data rows + for row in rows[1:]: # Skip first row (header) + cells = row.find_all(['td', 'th']) + if cells: + # First cell should contain the mnemonic + mnemonic_cell = cells[0] + + # Extract mnemonic from the cell (could be a link) + mnemonic_link = mnemonic_cell.find('a') + if mnemonic_link: + # Extract mnemonic from the link text + mnemonic_text = mnemonic_link.get_text().strip() + # Extract the href for the URL + href = mnemonic_link.get('href', '') + if href.startswith('/x86/'): + url_path = href[5:] # Remove '/x86/' prefix + else: + url_path = href + else: + # Extract mnemonic from cell text + mnemonic_text = mnemonic_cell.get_text().strip() + url_path = mnemonic_text.lower() + + if mnemonic_text: + # Clean up the mnemonic text + # Remove any extra whitespace or special characters + mnemonic_text = mnemonic_text.split()[0] if mnemonic_text.split() else "" + + # Handle special cases like "GETSEC[CAPABILITIES]" -> "CAPABILITIES" + if '[' in mnemonic_text and ']' in mnemonic_text: + # Extract the part inside brackets + match = re.search(r'\[([^\]]+)\]', mnemonic_text) + if match: + extracted_mnemonic = match.group(1) + all_mnemonics.add(extracted_mnemonic.upper()) + mnemonic_to_url[extracted_mnemonic.upper()] = url_path + + # Handle cases like "VMLAUNCH/VMRESUME" -> both instructions + elif '/' in mnemonic_text: + for part in mnemonic_text.split('/'): + clean_part = part.strip() + if clean_part and clean_part.replace('_', '').isalnum(): + all_mnemonics.add(clean_part.upper()) + mnemonic_to_url[clean_part.upper()] = url_path + elif ':' in mnemonic_text: + # Handle cases like "VMLAUNCH:VMRESUME" -> both instructions + for part in mnemonic_text.split(':'): + clean_part = part.strip() + if clean_part and clean_part.replace('_', '').isalnum(): + all_mnemonics.add(clean_part.upper()) + mnemonic_to_url[clean_part.upper()] = url_path + else: + # Regular single mnemonic + if mnemonic_text and mnemonic_text.replace('_', '').isalnum(): + all_mnemonics.add(mnemonic_text.upper()) + mnemonic_to_url[mnemonic_text.upper()] = url_path + + # Convert to sorted list + mnemonics_list = sorted(list(all_mnemonics)) + + print(f"Successfully extracted {len(mnemonics_list)} unique mnemonics") + print(f"Sample mnemonics: {mnemonics_list[:10]}") + print(f"Sample URL mappings:") + for mnemonic in mnemonics_list[:5]: + print(f" {mnemonic} -> {mnemonic_to_url.get(mnemonic, 'N/A')}") + + return mnemonics_list, mnemonic_to_url + + except requests.RequestException as e: + print(f"Error fetching main page: {e}") + print("Falling back to hardcoded list...") + fallback_mnemonics = get_fallback_mnemonics() + fallback_mapping = {m: m.lower() for m in fallback_mnemonics} + return fallback_mnemonics, fallback_mapping + except Exception as e: + print(f"Error parsing main page: {e}") + print("Falling back to hardcoded list...") + fallback_mnemonics = get_fallback_mnemonics() + fallback_mapping = {m: m.lower() for m in fallback_mnemonics} + return fallback_mnemonics, fallback_mapping + +def get_fallback_mnemonics() -> List[str]: + """ + Fallback list of mnemonics in case web scraping fails + """ + return [ + # Core common instructions + "MOV", "LEA", "PUSH", "POP", "XCHG", "MOVSX", "MOVZX", "CVTSI2SD", "CVTSD2SI", + "ADD", "SUB", "MUL", "DIV", "INC", "DEC", "AND", "OR", "XOR", "NOT", "SHL", "SHR", + "JMP", "CALL", "RET", "LOOP", "JNZ", "JZ", "JE", "JNE", "JL", "JLE", "JG", "JGE", + "CMP", "TEST", "NEG", "CLD", "STD", "NOP", "HLT", "INT", "IRET", "LEAVE", + # Add more common ones + "FADD", "FSUB", "FMUL", "FDIV", "FLD", "FST", "FSTP" + ] + +def scrape_instruction_info(instruction: str, url_path: str) -> Optional[Dict]: + """ + Scrape instruction information from felixcloutier.com + """ + try: + url = f"https://www.felixcloutier.com/x86/{url_path}" + print(f"Scraping: {instruction} from {url}") + + response = requests.get(url, timeout=10) + response.raise_for_status() + + soup = BeautifulSoup(response.content, 'html.parser') + + # Extract the title (instruction name) + title_elem = soup.find('h1') + instruction_title = title_elem.get_text().strip() if title_elem else "" + + # Extract Opcode table and relevant details + opcode = "" + instruction_description = "" + + table = soup.find('table') + if table: + rows = table.find_all('tr') + # Look for rows that mention our specific instruction + instruction_row = None + for row in rows[1:]: # Skip header row + cells = row.find_all(['td', 'th']) + if len(cells) > 1: + # Check if this row contains our instruction + instruction_cell = cells[1].get_text().strip() + if instruction.upper() in instruction_cell.upper(): + instruction_row = row + break + + # If we found a specific row for this instruction, use it + if instruction_row: + cells = instruction_row.find_all(['td', 'th']) + if len(cells) > 0: + opcode = cells[0].get_text().strip() + if len(cells) > 6: + instruction_description = cells[6].get_text().strip() + elif len(cells) > 5: + instruction_description = cells[5].get_text().strip() + elif len(cells) > 4: + instruction_description = cells[4].get_text().strip() + else: + # Fall back to first data row + if len(rows) > 1: + cells = rows[1].find_all(['td', 'th']) + if len(cells) > 0: + opcode = cells[0].get_text().strip() + if len(cells) > 6: + instruction_description = cells[6].get_text().strip() + elif len(cells) > 5: + instruction_description = cells[5].get_text().strip() + + # Extract the operation section + operation_section = "" + operation_header = soup.find('h2', id='operation') + if operation_header: + # Get all pre tags until the next h2 + operation_parts = [] + for sibling in operation_header.find_next_siblings(): + if sibling.name == 'h2': + break + if sibling.name == 'pre': + # Preserve original formatting and indentation + operation_parts.append(sibling.get_text()) + operation_section = '\n\n'.join(operation_parts) + + # Extract the description section + description_section = "" + description_header = soup.find('h2', id='description') + if description_header: + # Get all paragraphs until the next h2 + description_parts = [] + for sibling in description_header.find_next_siblings(): + if sibling.name == 'h2': + break + if sibling.name == 'p': + description_parts.append(sibling.get_text().strip()) + description_section = '\n'.join(description_parts) + + return { + 'instruction': instruction.upper(), + 'title': instruction_title, + 'opcode': opcode, + 'description': description_section, + 'operation': operation_section, + 'url': url + } + + except requests.RequestException as e: + print(f"Error fetching {instruction}: {e}") + return None + except Exception as e: + print(f"Error parsing {instruction}: {e}") + return None + +def load_existing_data(filename: str) -> Dict: + """Load existing JSON data if it exists""" + if os.path.exists(filename): + try: + with open(filename, 'r', encoding='utf-8') as f: + return json.load(f) + except: + return {} + return {} + +def save_data(data: Dict, filename: str): + """Save data to JSON file""" + with open(filename, 'w', encoding='utf-8') as f: + json.dump(data, f, indent=2, ensure_ascii=False) + +def main(): + """Main function to scrape all instructions and save to JSON file""" + print("=== Merged X86 Instruction Scraper ===") + + # Load existing data + output_file = "../syntaxes/x86_instructions.json" + existing_data = load_existing_data(output_file) + print(f"Loaded {len(existing_data)} existing instructions") + + # Fetch all mnemonics from the website + print("\n" + "=" * 60) + print("PHASE 1: Fetching all mnemonics from the website") + print("=" * 60) + + all_mnemonics, mnemonic_to_url = fetch_all_mnemonics() + print(f"Total mnemonics discovered: {len(all_mnemonics)}") + + if not all_mnemonics: + print("No mnemonics found! Exiting.") + return + + # Save the discovered mnemonics to a file for reference + with open("discovered_mnemonics.txt", "w") as f: + for mnemonic in all_mnemonics: + f.write(f"{mnemonic}\n") + print(f"Saved discovered mnemonics to: discovered_mnemonics.txt") + + # Save the URL mappings for reference + with open("mnemonic_url_mappings.txt", "w") as f: + for mnemonic in all_mnemonics: + url_path = mnemonic_to_url.get(mnemonic, mnemonic.lower()) + f.write(f"{mnemonic} -> {url_path}\n") + print(f"Saved URL mappings to: mnemonic_url_mappings.txt") + + # Filter out already processed mnemonics + remaining_mnemonics = [m for m in all_mnemonics if m.lower() not in existing_data] + print(f"Remaining mnemonics to process: {len(remaining_mnemonics)}") + + if not remaining_mnemonics: + print("All mnemonics already processed!") + return + + print("\n" + "=" * 60) + print("PHASE 2: Scraping detailed information for each instruction") + print("=" * 60) + + # Process in batches + batch_size = 50 + successful_scrapes = 0 + failed_scrapes = 0 + + for i in range(0, len(remaining_mnemonics), batch_size): + batch = remaining_mnemonics[i:i+batch_size] + print(f"\n=== Processing batch {i//batch_size + 1} ({len(batch)} instructions) ===") + + for j, instruction in enumerate(batch): + print(f"[{i+j+1}/{len(remaining_mnemonics)}] Processing: {instruction}") + + # Get URL path + url_path = mnemonic_to_url.get(instruction, instruction.lower()) + + # Scrape instruction info + info = scrape_instruction_info(instruction, url_path) + if info: + existing_data[instruction.lower()] = info + successful_scrapes += 1 + print(f" ✓ Successfully scraped: {instruction}") + else: + failed_scrapes += 1 + print(f" ✗ Failed to scrape: {instruction}") + + # No current rate limit but uncomment if needed + # time.sleep(0.3) + + # Save after each batch + save_data(existing_data, output_file) + print(f"Saved batch to {output_file}") + + # Pause between batches + if i + batch_size < len(remaining_mnemonics): + print(f"Pausing 3 seconds before next batch...") + time.sleep(3) + + print(f"\n" + "=" * 60) + print("SCRAPING COMPLETE") + print("=" * 60) + print(f"Successfully scraped: {successful_scrapes}") + print(f"Failed to scrape: {failed_scrapes}") + print(f"Total instructions in database: {len(existing_data)}") + if remaining_mnemonics: + print(f"Success rate: {successful_scrapes / len(remaining_mnemonics) * 100:.1f}%") + + # Show file size + if os.path.exists(output_file): + file_size = os.path.getsize(output_file) + print(f"Final file size: {file_size / (1024*1024):.1f} MB") + + # Show statistics + if existing_data: + print(f"\nSample instruction data (first entry):") + first_key = next(iter(existing_data)) + sample = existing_data[first_key] + print(f" Instruction: {sample['instruction']}") + print(f" Title: {sample['title']}") + print(f" Opcode: {sample['opcode']}") + print(f" Description: {sample['description'][:100]}...") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/extension.js b/src/extension.js index 1a6efdf..df71fdf 100644 --- a/src/extension.js +++ b/src/extension.js @@ -1,11 +1,14 @@ const vscode = require("vscode"); -const axios = require("axios"); -const cheerio = require("cheerio"); -const list = require("./mnemonics.js"); +const fs = require("fs"); +const path = require("path"); let languageConfigDisposable = null; +let instructionData = null; function activate(context) { + // Load instruction data from local JSON file + loadInstructionData(); + // Set up initial language configuration updateLanguageConfiguration(); @@ -20,24 +23,18 @@ function activate(context) { // Hover provider for mnemonics const hoverProvider = vscode.languages.registerHoverProvider("x86asm", { - async provideHover(document, position, token) { + provideHover(document, position, token) { const range = document.getWordRangeAtPosition( position, /\b[a-zA-Z0-9_]+\b/ ); const word = document.getText(range); - if (word) { - // Check if the word is a valid mnemonic - if (list.x86x64Mnemonics.includes(word.toUpperCase())) { - const instructionInfo = await fetchInstructionInfo( - word.toLowerCase() - ); - if (instructionInfo) { - return new vscode.Hover(instructionInfo); - } - } else { - return undefined; + if (word && instructionData) { + // Check if the word is a valid mnemonic by looking it up in the instruction data + const instructionInfo = getInstructionInfo(word.toLowerCase()); + if (instructionInfo) { + return new vscode.Hover(instructionInfo); } } @@ -68,6 +65,38 @@ function activate(context) { ); } +function loadInstructionData() { + try { + const dataPath = path.join( + __dirname, + "..", + "syntaxes", + "x86_instructions.json" + ); + if (fs.existsSync(dataPath)) { + const rawData = fs.readFileSync(dataPath, "utf8"); + instructionData = JSON.parse(rawData); + console.log( + `Loaded ${ + Object.keys(instructionData).length + } instructions from syntaxes database` + ); + } else { + console.warn( + "syntaxes/x86_instructions.json not found. Please run the scraper.py script first." + ); + vscode.window.showWarningMessage( + "syntaxes/x86_instructions.json not found. Please run the scraper.py script to generate the instruction database." + ); + } + } catch (error) { + console.error("Error loading instruction data:", error); + vscode.window.showErrorMessage( + "Error loading instruction database: " + error.message + ); + } +} + function updateLanguageConfiguration() { // Dispose previous language configuration if it exists if (languageConfigDisposable) { @@ -116,47 +145,35 @@ function updateLanguageConfiguration() { ); } -async function fetchInstructionInfo(instruction) { - try { - const url = `https://www.felixcloutier.com/x86/${instruction}`; - const response = await axios.get(url); - const $ = cheerio.load(response.data); - - // Extract the title (instruction name) - const instructionTitle = $("h1").text(); - - // Extract Opcode table and relevant details - const opcodeTable = $("table").first(); - const opcode = opcodeTable.find("tr").eq(1).find("td").eq(0).text(); - const instructionDescription = opcodeTable - .find("tr") - .eq(1) - .find("td") - .eq(5) - .text(); - - // Extract the operation section - const operationSection = $("#operation").next("pre").text(); - - // Extract the description section - const descriptionSection = $("#description").nextUntil("h2", "p").text(); - - // Combine the extracted information into a formatted output - let hoverContent = `**${instructionTitle}**\n\n`; - hoverContent += `**Opcode:** ${opcode}\n`; - hoverContent += `**Description:** ${instructionDescription}\n\n`; - hoverContent += `**Details:**\n${descriptionSection}\n\n`; - hoverContent += `**Operation:**\n${operationSection}`; - - return hoverContent; - } catch (error) { - if (error.response && error.response.status === 404) { - console.warn(`Instruction info not found for: ${instruction}`); - } else { - console.error(`Failed to fetch instruction info: ${error.message}`); - } - return null; // Return null if fetching fails +function getInstructionInfo(instruction) { + if (!instructionData) { + return null; } + + const info = instructionData[instruction.toLowerCase()]; + if (!info) { + return null; + } + + // Format the hover content using the syntaxes/x86_instructions.json format + // Keep title as is since it usually doesn't need paragraph breaks + let hoverContent = `**${info.title}**\n\n`; + + if (info.opcode) { + hoverContent += `**Opcode:** ${info.opcode}\n\n`; + } + + if (info.description) { + // Replace single \n with double \n for proper markdown paragraph breaks + const formattedDescription = info.description.replace(/\n/g, "\n\n"); + hoverContent += `**Description:** ${formattedDescription}\n\n`; + } + + if (info.url) { + hoverContent += `[View Documentation](${info.url})`; + } + + return hoverContent; } async function findDefinition(word) { diff --git a/src/mnemonics.js b/src/mnemonics.js deleted file mode 100644 index 052bb97..0000000 --- a/src/mnemonics.js +++ /dev/null @@ -1,55 +0,0 @@ -const x86x64Mnemonics = [ - // Data Transfer - "MOV", "LEA", "PUSH", "POP", "XCHG", "MOVSX", "MOVZX", "CVTSI2SD", "CVTSD2SI", - "MOVD", "MOVQ", "MOVSS", "MOVSD", "MOVAPD", "MOVDQA", "MOVDQU", - "MOVNTI", "MOVNTQ", "MOVNTDQ", "MOVNTDQA", "MOVNTQ", "MOVNTDQ", - // Arithmetic and Logical - "ADD", "SUB", "MUL", "DIV", "INC", "DEC", "AND", "OR", "XOR", "NOT", "SHL", "SHR", - "SAL", "SAR", "SHRD", "SHLD", "IMUL", "IDIV", "IDIVQ", "MULSD", "DIVSD", - "ADDPD", "SUBPD", "MULPD", "DIVPD", "ANDPD", "ORPD", "XORPD", - "ADDPS", "SUBPS", "MULPS", "DIVPS", "ANDPS", "ORPS", "XORPS", - // Control Flow - "JMP", "Jcc", "CALL", "RET", "LOOP", "JNZ", "JZ", "JE", "JNE", "JL", "JLE", - "JG", "JGE", "JB", "JBE", "JA", "JAE", "LOOPNE", "LOOPE", - "LOOPNZ", "LOOPZ", "CMOVcc", "SETcc", - // Other - "CMP", "TEST", "NEG", "NOT", "CLD", "STD", "CWD", "CDQ", "CQO", - "LEA", "LES", "LDS", "LSS", "LFS", "LGS", - "LES", "LDS", "LSS", "LFS", "LGS", - "REP", "REPE", "REPNE", "REPZ", "REPNZ", - "BSF", "BSR", "BT", "BTC", "BTR", "BTS", "LEAVE", - // Floating-Point - "FADD", "FSUB", "FMUL", "FDIV", "FCHS", "FABS", "FCOM", "FCOMP", "FCOMPP", - "FADD", "FSUB", "FMUL", "FDIV", "FCHS", "FABS", "FCOM", "FCOMP", "FCOMPP", - "FST", "FSTPN", "FSTP", "FLD", "FLD1", "FLDPI", "FLDL2T", "FLDL2E", - "FLDCW", "FSTCW", - "FCOMI", "FCOMIP", "FUCOMI", "FUCOMIP", - // SIMD - "MOVDQA", "MOVDQU", "PSHUFD", "PSHUFLW", "PSHUFLH", "PSLLD", "PSLLQ", "PSLLW", - "PSRAD", "PSRAQ", "PSRAW", "PADDW", "PADDQ", "PADDUSB", "PADDUSW", - "PSUBW", "PSUBQ", "PSUBUSB", "PSUBUSW", - "PMADDWD", "PMULHW", "PMULLW", - "PMAXSW", "PMAXUW", "PMINSW", "PMINUW", - // AVX Instructions - "VMOVD", "VMOVQ", "VMOVSS", "VMOVSD", "VMOVAPD", "VMOVDQA", "VMOVDQU", - "VADDPD", "VADDPS", "VADDL", "VADDL2", "VADDL3", "VADDL4", - "VSUBPD", "VSUBPS", "VSUBL", "VSUBL2", "VSUBL3", "VSUBL4", - "VMULPD", "VMULPS", "VMULL", "VMULL2", "VMULL3", "VMULL4", - "VDIVPD", "VDIVPS", "VDIVL", "VDIVL2", "VDIVL3", "VDIVL4", - "VANDPD", "VANDPS", "VANDL", "VANDL2", "VANDL3", "VANDL4", - "VORPD", "VORPS", "VORL", "VORL2", "VORL3", "VORL4", - "VXORPD", "VXORPS", "VXORL", "VXORL2", "VXORL3", "VXORL4", - // AVX-512 Instructions - "VPMOVD", "VPMOVQ", "VPMOVSS", "VPMOVSD", "VPMOVAPD", "VPMOVDQA", "VPMOVDQU", - "VPADDPD", "VPADDPS", "VPADDL", "VPADDL2", "VPADDL3", "VPADDL4", - "VPSUBPD", "VPSUBPS", "VPSUBL", "VPSUBL2", "VPSUBL3", "VPSUBL4", - "VPMULPD", "VPMULPS", "VPMULL", "VPMULL2", "VPMULL3", "VPMULL4", - "VPDIVPD", "VPDIVPS", "VPDIVL", "VPDIVL2", "VPDIVL3", "VPDIVL4", - "VPANDPD", "VPANDPS", "VPANDL", "VPANDL2", "VPANDL3", "VPANDL4", - "VPORPD", "VPORPS", "VPORL", "VPORL2", "VPORL3", "VPORL4", - "VPXORPD", "VPXORPS", "VPXORL", "VPXORL2", "VPXORL3", "VPXORL4", - ]; - - module.exports = { - x86x64Mnemonics - }; \ No newline at end of file diff --git a/syntaxes/x86_instructions.json b/syntaxes/x86_instructions.json new file mode 100644 index 0000000..778c6d2 --- /dev/null +++ b/syntaxes/x86_instructions.json @@ -0,0 +1,9666 @@ +{ + "aaa": { + "instruction": "AAA", + "title": "AAA\n\t\t— ASCII Adjust After Addition", + "opcode": "37", + "description": "Adjusts the sum of two unpacked BCD values to create an unpacked BCD result. The AL register is the implied source and destination operand for this instruction. The AAA instruction is only useful when it follows an ADD instruction that adds (binary addition) two unpacked BCD values and stores a byte result in the AL register. The AAA instruction then adjusts the contents of the AL register to contain the correct 1-digit unpacked BCD result.\nIf the addition produces a decimal carry, the AH register increments by 1, and the CF and AF flags are set. If there was no decimal carry, the CF and AF flags are cleared and the AH register is unchanged. In either case, bits 4 through 7 of the AL register are set to 0.\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\n ELSE\n IF ((AL AND 0FH) > 9) or (AF = 1)\n THEN\n AX := AX + 106H;\n AF := 1;\n CF := 1;\n ELSE\n AF := 0;\n CF := 0;\n FI;\n AL := AL AND 0FH;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/aaa" + }, + "aad": { + "instruction": "AAD", + "title": "AAD\n\t\t— ASCII Adjust AX Before Division", + "opcode": "D5 0A", + "description": "Adjusts two unpacked BCD digits (the least-significant digit in the AL register and the most-significant digit in the AH register) so that a division operation performed on the result will yield a correct unpacked BCD value. The AAD instruction is only useful when it precedes a DIV instruction that divides (binary division) the adjusted value in the AX register by an unpacked BCD value.\nThe AAD instruction sets the value in the AL register to (AL + (10 * AH)), and then clears the AH register to 00H. The value in the AX register is then equal to the binary equivalent of the original unpacked two-digit (base 10) number in registers AH and AL.\nThe generalized version of this instruction allows adjustment of two unpacked digits of any number base (see the “Operation” section below), by setting the imm8 byte to the selected number base (for example, 08H for octal, 0AH for decimal, or 0CH for base 12 numbers). The AAD mnemonic is interpreted by all assemblers to mean adjust ASCII (base 10) values. To adjust values in another number base, the instruction must be hand coded in machine code (D5 imm8).\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\n ELSE\n tempAL := AL;\n tempAH := AH;\n AL := (tempAL + (tempAH ∗ imm8)) AND FFH;\n (* imm8 is set to 0AH for the AAD mnemonic.*)\n AH := 0;\nFI;\nThe immediate value (imm8) is taken from the second byte of the instruction.\n", + "url": "https://www.felixcloutier.com/x86/aad" + }, + "aam": { + "instruction": "AAM", + "title": "AAM\n\t\t— ASCII Adjust AX After Multiply", + "opcode": "D4 0A", + "description": "Adjusts the result of the multiplication of two unpacked BCD values to create a pair of unpacked (base 10) BCD values. The AX register is the implied source and destination operand for this instruction. The AAM instruction is only useful when it follows an MUL instruction that multiplies (binary multiplication) two unpacked BCD values and stores a word result in the AX register. The AAM instruction then adjusts the contents of the AX register to contain the correct 2-digit unpacked (base 10) BCD result.\nThe generalized version of this instruction allows adjustment of the contents of the AX to create two unpacked digits of any number base (see the “Operation” section below). Here, the imm8 byte is set to the selected number base (for example, 08H for octal, 0AH for decimal, or 0CH for base 12 numbers). The AAM mnemonic is interpreted by all assemblers to mean adjust to ASCII (base 10) values. To adjust to values in another number base, the instruction must be hand coded in machine code (D4 imm8).\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\n ELSE\n tempAL := AL;\n AH := tempAL / imm8; (* imm8 is set to 0AH for the AAM mnemonic *)\n AL := tempAL MOD imm8;\nFI;\nThe immediate value (imm8) is taken from the second byte of the instruction.\n", + "url": "https://www.felixcloutier.com/x86/aam" + }, + "aas": { + "instruction": "AAS", + "title": "AAS\n\t\t— ASCII Adjust AL After Subtraction", + "opcode": "3F", + "description": "Adjusts the result of the subtraction of two unpacked BCD values to create a unpacked BCD result. The AL register is the implied source and destination operand for this instruction. The AAS instruction is only useful when it follows a SUB instruction that subtracts (binary subtraction) one unpacked BCD value from another and stores a byte result in the AL register. The AAA instruction then adjusts the contents of the AL register to contain the correct 1-digit unpacked BCD result.\nIf the subtraction produced a decimal carry, the AH register decrements by 1, and the CF and AF flags are set. If no decimal carry occurred, the CF and AF flags are cleared, and the AH register is unchanged. In either case, the AL register is left with its top four bits set to 0.\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-bit mode\n THEN\n #UD;\n ELSE\n IF ((AL AND 0FH) > 9) or (AF = 1)\n THEN\n AX := AX – 6;\n AH := AH – 1;\n AF := 1;\n CF := 1;\n AL := AL AND 0FH;\n ELSE\n CF := 0;\n AF := 0;\n AL := AL AND 0FH;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/aas" + }, + "adc": { + "instruction": "ADC", + "title": "ADC\n\t\t— Add With Carry", + "opcode": "14 ib", + "description": "Adds the destination operand (first operand), the source operand (second operand), and the carry (CF) flag and stores the result in the destination operand. The destination operand can be a register or a memory location; the source operand can be an immediate, a register, or a memory location. (However, two memory operands cannot be used in one instruction.) The state of the CF flag represents a carry from a previous addition. When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.\nThe ADC instruction does not distinguish between signed or unsigned operands. Instead, the processor evaluates the result for both data types and sets the OF and CF flags to indicate a carry in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.\nThe ADC instruction is usually executed as part of a multibyte or multiword addition in which an ADD instruction is followed by an ADC instruction.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := DEST + SRC + CF;\n", + "url": "https://www.felixcloutier.com/x86/adc" + }, + "adcx": { + "instruction": "ADCX", + "title": "ADCX\n\t\t— Unsigned Integer Addition of Two Operands With Carry Flag", + "opcode": "66 0F 38 F6 /r ADCX r32, r/m32", + "description": "Performs an unsigned addition of the destination operand (first operand), the source operand (second operand) and the carry-flag (CF) and stores the result in the destination operand. The destination operand is a general-purpose register, whereas the source operand can be a general-purpose register or memory location. The state of CF can represent a carry from a previous addition. The instruction sets the CF flag with the carry generated by the unsigned addition of the operands.\nThe ADCX instruction is executed in the context of multi-precision addition, where we add a series of operands with a carry-chain. At the beginning of a chain of additions, we need to make sure the CF is in a desired initial state. Often, this initial state needs to be 0, which can be achieved with an instruction to zero the CF (e.g. XOR).\nThis instruction is supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode.\nIn 64-bit mode, the default operation size is 32 bits. Using a REX Prefix in the form of REX.R permits access to additional registers (R8-15). Using REX Prefix in the form of REX.W promotes operation to 64 bits.\nADCX executes normally either inside or outside a transaction region.\nNote: ADCX defines the OF flag differently than the ADD/ADC instructions as defined in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A.", + "operation": "IF OperandSize is 64-bit\n THEN CF:DEST[63:0] := DEST[63:0] + SRC[63:0] + CF;\n ELSE CF:DEST[31:0] := DEST[31:0] + SRC[31:0] + CF;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/adcx" + }, + "add": { + "instruction": "ADD", + "title": "ADD\n\t\t— Add", + "opcode": "04 ib", + "description": "Adds the destination operand (first operand) and the source operand (second operand) and then stores the result in the destination operand. The destination operand can be a register or a memory location; the source operand can be an immediate, a register, or a memory location. (However, two memory operands cannot be used in one instruction.) When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.\nThe ADD instruction performs integer addition. It evaluates the result for both signed and unsigned integer operands and sets the OF and CF flags to indicate a carry (overflow) in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := DEST + SRC;\n", + "url": "https://www.felixcloutier.com/x86/add" + }, + "addpd": { + "instruction": "ADDPD", + "title": "ADDPD\n\t\t— Add Packed Double Precision Floating-Point Values", + "opcode": "66 0F 58 /r ADDPD xmm1, xmm2/m128", + "description": "Adds two, four or eight packed double precision floating-point values from the first source operand to the second source operand, and stores the packed double precision floating-point result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: the first source operand is a XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC1[i+63:i] + SRC2[i+63:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+63:i] := SRC1[i+63:i] + SRC2[63:0]\n ELSE\n DEST[i+63:i] := SRC1[i+63:i] + SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[127:64] := SRC1[127:64] + SRC2[127:64]\nDEST[191:128] := SRC1[191:128] + SRC2[191:128]\nDEST[255:192] := SRC1[255:192] + SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n.\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[127:64] := SRC1[127:64] + SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0]\nDEST[127:64] := DEST[127:64] + SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/addpd" + }, + "addps": { + "instruction": "ADDPS", + "title": "ADDPS\n\t\t— Add Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 58 /r ADDPS xmm1, xmm2/m128", + "description": "Adds four, eight or sixteen packed single precision floating-point values from the first source operand with the second source operand, and stores the packed single precision floating-point result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: the first source operand is a XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC1[i+31:i] + SRC2[i+31:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=\n SRC1[i+31:i] + SRC2[31:0]\n ELSE\n DEST[i+31:i] :=\n SRC1[i+31:i] + SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i]\n remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] :=\n 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[63:32] := SRC1[63:32] + SRC2[63:32]\nDEST[95:64] := SRC1[95:64] + SRC2[95:64]\nDEST[127:96] := SRC1[127:96] + SRC2[127:96]\nDEST[159:128] := SRC1[159:128] + SRC2[159:128]\nDEST[191:160]:= SRC1[191:160] + SRC2[191:160]\nDEST[223:192] := SRC1[223:192] + SRC2[223:192]\nDEST[255:224] := SRC1[255:224] + SRC2[255:224].\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[63:32] := SRC1[63:32] + SRC2[63:32]\nDEST[95:64] := SRC1[95:64] + SRC2[95:64]\nDEST[127:96] := SRC1[127:96] + SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[63:32] := SRC1[63:32] + SRC2[63:32]\nDEST[95:64] := SRC1[95:64] + SRC2[95:64]\nDEST[127:96] := SRC1[127:96] + SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/addps" + }, + "addsd": { + "instruction": "ADDSD", + "title": "ADDSD\n\t\t— Add Scalar Double Precision Floating-Point Values", + "opcode": "F2 0F 58 /r ADDSD xmm1, xmm2/m64", + "description": "Adds the low double precision floating-point values from the second source operand and the first source operand and stores the double precision floating-point result in the destination operand.\nThe second source operand can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The first source and destination operands are the same. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nEVEX and VEX.128 encoded version: The first source operand is encoded by EVEX.vvvv/VEX.vvvv. Bits (127:64) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX version: The low quadword element of the destination is updated according to the writemask.\nSoftware should ensure VADDSD is encoded with VEX.L=0. Encoding VADDSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC1[63:0] + SRC2[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/addsd" + }, + "addss": { + "instruction": "ADDSS", + "title": "ADDSS\n\t\t— Add Scalar Single Precision Floating-Point Values", + "opcode": "F3 0F 58 /r ADDSS xmm1, xmm2/m32", + "description": "Adds the low single precision floating-point values from the second source operand and the first source operand, and stores the double precision floating-point result in the destination operand.\nThe second source operand can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The first source and destination operands are the same. Bits (MAXVL-1:32) of the corresponding the destination register remain unchanged.\nEVEX and VEX.128 encoded version: The first source operand is encoded by EVEX.vvvv/VEX.vvvv. Bits (127:32) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX version: The low doubleword element of the destination is updated according to the writemask.\nSoftware should ensure VADDSS is encoded with VEX.L=0. Encoding VADDSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC1[31:0] + SRC2[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0]\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/addss" + }, + "addsubpd": { + "instruction": "ADDSUBPD", + "title": "ADDSUBPD\n\t\t— Packed Double Precision Floating-Point Add/Subtract", + "opcode": "66 0F D0 /r ADDSUBPD xmm1, xmm2/m128", + "description": "Adds odd-numbered double precision floating-point values of the first source operand (second operand) with the corresponding double precision floating-point values from the second source operand (third operand); stores the result in the odd-numbered values of the destination operand (first operand). Subtracts the even-numbered double precision floating-point values from the second source operand from the corresponding double precision floating values in the first source operand; stores the result into the even-numbered values of the destination operand.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified. See Figure 3-3.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "DEST[63:0] := DEST[63:0] - SRC[63:0]\nDEST[127:64] := DEST[127:64] + SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[63:0] - SRC2[63:0]\nDEST[127:64] := SRC1[127:64] + SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0] - SRC2[63:0]\nDEST[127:64] := SRC1[127:64] + SRC2[127:64]\nDEST[191:128] := SRC1[191:128] - SRC2[191:128]\nDEST[255:192] := SRC1[255:192] + SRC2[255:192]\n", + "url": "https://www.felixcloutier.com/x86/addsubpd" + }, + "addsubps": { + "instruction": "ADDSUBPS", + "title": "ADDSUBPS\n\t\t— Packed Single Precision Floating-Point Add/Subtract", + "opcode": "F2 0F D0 /r ADDSUBPS xmm1, xmm2/m128", + "description": "Adds odd-numbered single precision floating-point values of the first source operand (second operand) with the corresponding single precision floating-point values from the second source operand (third operand); stores the result in the odd-numbered values of the destination operand (first operand). Subtracts the even-numbered single precision floating-point values from the second source operand from the corresponding single precision floating values in the first source operand; stores the result into the even-numbered values of the destination operand.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified. See Figure 3-4.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "DEST[31:0] := DEST[31:0] - SRC[31:0]\nDEST[63:32] := DEST[63:32] + SRC[63:32]\nDEST[95:64] := DEST[95:64] - SRC[95:64]\nDEST[127:96] := DEST[127:96] + SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := SRC1[31:0] - SRC2[31:0]\nDEST[63:32] := SRC1[63:32] + SRC2[63:32]\nDEST[95:64] := SRC1[95:64] - SRC2[95:64]\nDEST[127:96] := SRC1[127:96] + SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC2[31:0]\nDEST[63:32] := SRC1[63:32] + SRC2[63:32]\nDEST[95:64] := SRC1[95:64] - SRC2[95:64]\nDEST[127:96] := SRC1[127:96] + SRC2[127:96]\nDEST[159:128] := SRC1[159:128] - SRC2[159:128]\nDEST[191:160] := SRC1[191:160] + SRC2[191:160]\nDEST[223:192] := SRC1[223:192] - SRC2[223:192]\nDEST[255:224] := SRC1[255:224] + SRC2[255:224]\n", + "url": "https://www.felixcloutier.com/x86/addsubps" + }, + "adox": { + "instruction": "ADOX", + "title": "ADOX\n\t\t— Unsigned Integer Addition of Two Operands With Overflow Flag", + "opcode": "F3 0F 38 F6 /r ADOX r32, r/m32", + "description": "Performs an unsigned addition of the destination operand (first operand), the source operand (second operand) and the overflow-flag (OF) and stores the result in the destination operand. The destination operand is a general-purpose register, whereas the source operand can be a general-purpose register or memory location. The state of OF represents a carry from a previous addition. The instruction sets the OF flag with the carry generated by the unsigned addition of the operands.\nThe ADOX instruction is executed in the context of multi-precision addition, where we add a series of operands with a carry-chain. At the beginning of a chain of additions, we execute an instruction to zero the OF (e.g. XOR).\nThis instruction is supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode.\nIn 64-bit mode, the default operation size is 32 bits. Using a REX Prefix in the form of REX.R permits access to additional registers (R8-15). Using REX Prefix in the form of REX.W promotes operation to 64-bits.\nADOX executes normally either inside or outside a transaction region.\nNote: ADOX defines the CF and OF flags differently than the ADD/ADC instructions as defined in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A.", + "operation": "IF OperandSize is 64-bit\n THEN OF:DEST[63:0] := DEST[63:0] + SRC[63:0] + OF;\n ELSE OF:DEST[31:0] := DEST[31:0] + SRC[31:0] + OF;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/adox" + }, + "aesdec": { + "instruction": "AESDEC", + "title": "AESDEC\n\t\t— Perform One Round of an AES Decryption Flow", + "opcode": "66 0F 38 DE /r AESDEC xmm1, xmm2/m128", + "description": "This instruction performs a single round of the AES decryption flow using the Equivalent Inverse Cipher, using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.\nUse the AESDEC instruction for all but the last decryption round. For the last decryption round, use the AESDECLAST instruction.\nVEX and EVEX encoded versions of the instruction allow 3-operand (non-destructive) operation. The legacy encoded versions of the instruction require that the first source operand and the destination operand are the same and must be an XMM register.\nThe EVEX encoded form of this instruction does not support memory fault suppression.", + "operation": "STATE := SRC1;\nRoundKey := SRC2;\nSTATE := InvShiftRows( STATE );\nSTATE := InvSubBytes( STATE );\nSTATE := InvMixColumns( STATE );\nDEST[127:0] := STATE XOR RoundKey;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL,VL) = (1,128), (2,256)\nFOR i = 0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := InvShiftRows( STATE )\n STATE := InvSubBytes( STATE )\n STATE := InvMixColumns( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n\n\n(KL,VL) = (1,128), (2,256), (4,512)\nFOR i = 0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := InvShiftRows( STATE )\n STATE := InvSubBytes( STATE )\n STATE := InvMixColumns( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] :=0\n", + "url": "https://www.felixcloutier.com/x86/aesdec" + }, + "aesdec128kl": { + "instruction": "AESDEC128KL", + "title": "AESDEC128KL\n\t\t— Perform Ten Rounds of AES Decryption Flow With Key Locker Using 128-BitKey", + "opcode": "F3 0F 38 DD !(11):rrr:bbb AESDEC128KL xmm, m384", + "description": "The AESDEC128KL1 instruction performs 10 rounds of AES to decrypt the first operand using the 128-bit key indicated by the handle from the second operand. It stores the result in the first operand if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 384 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [2] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128);\nIF (Illegal Handle) {\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey);\n IF (Authentic == 0)\n THEN RFLAGS.ZF := 1;\n ELSE\n DEST := AES128Decrypt (DEST, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesdec128kl" + }, + "aesdec256kl": { + "instruction": "AESDEC256KL", + "title": "AESDEC256KL\n\t\t— Perform 14 Rounds of AES Decryption Flow With Key Locker Using 256-Bit Key", + "opcode": "F3 0F 38 DF !(11):rrr:bbb AESDEC256KL xmm, m512", + "description": "The AESDEC256KL1 instruction performs 14 rounds of AES to decrypt the first operand using the 256-bit key indicated by the handle from the second operand. It stores the result in the first operand if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 512 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [2] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES256);\nIF (Illegal Handle)\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey);\n IF (Authentic == 0)\n THEN RFLAGS.ZF := 1;\n ELSE\n DEST := AES256Decrypt (DEST, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesdec256kl" + }, + "aesdeclast": { + "instruction": "AESDECLAST", + "title": "AESDECLAST\n\t\t— Perform Last Round of an AES Decryption Flow", + "opcode": "66 0F 38 DF /r AESDECLAST xmm1, xmm2/m128", + "description": "This instruction performs the last round of the AES decryption flow using the Equivalent Inverse Cipher, using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.\nVEX and EVEX encoded versions of the instruction allow 3-operand (non-destructive) operation. The legacy encoded versions of the instruction require that the first source operand and the destination operand are the same and must be an XMM register.\nThe EVEX encoded form of this instruction does not support memory fault suppression.", + "operation": "STATE := SRC1;\nRoundKey := SRC2;\nSTATE := InvShiftRows( STATE );\nSTATE := InvSubBytes( STATE );\nDEST[127:0] := STATE XOR RoundKey;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL,VL) = (1,128), (2,256)\nFOR i = 0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := InvShiftRows( STATE )\n STATE := InvSubBytes( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n\n\n(KL,VL) = (1,128), (2,256), (4,512)\nFOR i = 0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := InvShiftRows( STATE )\n STATE := InvSubBytes( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/aesdeclast" + }, + "aesdecwide128kl": { + "instruction": "AESDECWIDE128KL", + "title": "AESDECWIDE128KL\n\t\t— Perform Ten Rounds of AES Decryption Flow With Key Locker on 8 BlocksUsing 128-Bit Key", + "opcode": "F3 0F 38 D8 !(11):001:bbb AESDECWIDE128KL m384, ", + "description": "The AESDECWIDE128KL1 instruction performs ten rounds of AES to decrypt each of the eight blocks in XMM0-7 using the 128-bit key indicated by the handle from the second operand. It replaces each input block in XMM0-7 with its corresponding decrypted block if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 384 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [2] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128);\nIF (Illegal Handle)\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey);\n IF Authentic == 0 {\n THEN RFLAGS.ZF := 1;\n ELSE\n XMM0 := AES128Decrypt (XMM0, UnwrappedKey) ;\n XMM1 := AES128Decrypt (XMM1, UnwrappedKey) ;\n XMM2 := AES128Decrypt (XMM2, UnwrappedKey) ;\n XMM3 := AES128Decrypt (XMM3, UnwrappedKey) ;\n XMM4 := AES128Decrypt (XMM4, UnwrappedKey) ;\n XMM5 := AES128Decrypt (XMM5, UnwrappedKey) ;\n XMM6 := AES128Decrypt (XMM6, UnwrappedKey) ;\n XMM7 := AES128Decrypt (XMM7, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesdecwide128kl" + }, + "aesdecwide256kl": { + "instruction": "AESDECWIDE256KL", + "title": "AESDECWIDE256KL\n\t\t— Perform 14 Rounds of AES Decryption Flow With Key Locker on 8 BlocksUsing 256-Bit Key", + "opcode": "F3 0F 38 D8 !(11):011:bbb AESDECWIDE256KL m512, ", + "description": "The AESDECWIDE256KL1 instruction performs 14 rounds of AES to decrypt each of the eight blocks in XMM0-7 using the 256-bit key indicated by the handle from the second operand. It replaces each input block in XMM0-7 with its corresponding decrypted block if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 512 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [2] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES256);\nIF (Illegal Handle) {\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey);\n IF (Authentic == 0)\n THEN RFLAGS.ZF := 1;\n ELSE\n XMM0 := AES256Decrypt (XMM0, UnwrappedKey) ;\n XMM1 := AES256Decrypt (XMM1, UnwrappedKey) ;\n XMM2 := AES256Decrypt (XMM2, UnwrappedKey) ;\n XMM3 := AES256Decrypt (XMM3, UnwrappedKey) ;\n XMM4 := AES256Decrypt (XMM4, UnwrappedKey) ;\n XMM5 := AES256Decrypt (XMM5, UnwrappedKey) ;\n XMM6 := AES256Decrypt (XMM6, UnwrappedKey) ;\n XMM7 := AES256Decrypt (XMM7, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesdecwide256kl" + }, + "aesenc": { + "instruction": "AESENC", + "title": "AESENC\n\t\t— Perform One Round of an AES Encryption Flow", + "opcode": "66 0F 38 DC /r AESENC xmm1, xmm2/m128", + "description": "This instruction performs a single round of an AES encryption flow using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.\nUse the AESENC instruction for all but the last encryption rounds. For the last encryption round, use the AESENCCLAST instruction.\nVEX and EVEX encoded versions of the instruction allow 3-operand (non-destructive) operation. The legacy encoded versions of the instruction require that the first source operand and the destination operand are the same and must be an XMM register.\nThe EVEX encoded form of this instruction does not support memory fault suppression.", + "operation": "STATE := SRC1;\nRoundKey := SRC2;\nSTATE := ShiftRows( STATE );\nSTATE := SubBytes( STATE );\nSTATE := MixColumns( STATE );\nDEST[127:0] := STATE XOR RoundKey;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL,VL) = (1,128), (2,256)\nFOR I := 0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := ShiftRows( STATE )\n STATE := SubBytes( STATE )\n STATE := MixColumns( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n\n\n(KL,VL) = (1,128), (2,256), (4,512)\nFOR i := 0 to KL-1:\n STATE := SRC1.xmm[i] // xmm[i] is the i’th xmm word in the SIMD register\n RoundKey := SRC2.xmm[i]\n STATE := ShiftRows( STATE )\n STATE := SubBytes( STATE )\n STATE := MixColumns( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/aesenc" + }, + "aesenc128kl": { + "instruction": "AESENC128KL", + "title": "AESENC128KL\n\t\t— Perform Ten Rounds of AES Encryption Flow With Key Locker Using 128-Bit Key", + "opcode": "F3 0F 38 DC !(11):rrr:bbb AESENC128KL xmm, m384", + "description": "The AESENC128KL1 instruction performs ten rounds of AES to encrypt the first operand using the 128-bit key indicated by the handle from the second operand. It stores the result in the first operand if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 384 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (\n HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [1] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128\n );\nIF (Illegal Handle) {\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey);\n IF (Authentic == 0)\n THEN RFLAGS.ZF := 1;\n ELSE\n DEST := AES128Encrypt (DEST, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesenc128kl" + }, + "aesenc256kl": { + "instruction": "AESENC256KL", + "title": "AESENC256KL\n\t\t— Perform 14 Rounds of AES Encryption Flow With Key Locker Using 256-Bit Key", + "opcode": "F3 0F 38 DE !(11):rrr:bbb AESENC256KL xmm, m512", + "description": "The AESENC256KL1 instruction performs 14 rounds of AES to encrypt the first operand using the 256-bit key indicated by the handle from the second operand. It stores the result in the first operand if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 512 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (\n HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [1] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES256\n );\nIF (Illegal Handle)\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey);\n IF (Authentic == 0)\n THEN RFLAGS.ZF := 1;\n ELSE\n DEST := AES256Encrypt (DEST, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesenc256kl" + }, + "aesenclast": { + "instruction": "AESENCLAST", + "title": "AESENCLAST\n\t\t— Perform Last Round of an AES Encryption Flow", + "opcode": "66 0F 38 DD /r AESENCLAST xmm1, xmm2/m128", + "description": "This instruction performs the last round of an AES encryption flow using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.\nVEX and EVEX encoded versions of the instruction allows 3-operand (non-destructive) operation. The legacy encoded versions of the instruction require that the first source operand and the destination operand are the same and must be an XMM register.\nThe EVEX encoded form of this instruction does not support memory fault suppression.", + "operation": "STATE := SRC1;\nRoundKey := SRC2;\nSTATE := ShiftRows( STATE );\nSTATE := SubBytes( STATE );\nDEST[127:0] := STATE XOR RoundKey;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (1,128), (2,256)\nFOR I=0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := ShiftRows( STATE )\n STATE := SubBytes( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n\n\n(KL,VL) = (1,128), (2,256), (4,512)\nFOR i = 0 to KL-1:\n STATE := SRC1.xmm[i]\n RoundKey := SRC2.xmm[i]\n STATE := ShiftRows( STATE )\n STATE := SubBytes( STATE )\n DEST.xmm[i] := STATE XOR RoundKey\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/aesenclast" + }, + "aesencwide128kl": { + "instruction": "AESENCWIDE128KL", + "title": "AESENCWIDE128KL\n\t\t— Perform Ten Rounds of AES Encryption Flow With Key Locker on 8 BlocksUsing 128-Bit Key", + "opcode": "F3 0F 38 D8 !(11):000:bbb AESENCWIDE128KL m384, ", + "description": "The AESENCWIDE128KL1 instruction performs ten rounds of AES to encrypt each of the eight blocks in XMM0-7 using the 128-bit key indicated by the handle from the second operand. It replaces each input block in XMM0-7 with its corresponding encrypted block if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 384 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (\n HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [1] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128\n );\nIF (Illegal Handle)\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey);\n IF Authentic == 0\n THEN RFLAGS.ZF := 1;\n ELSE\n XMM0 := AES128Encrypt (XMM0, UnwrappedKey) ;\n XMM1 := AES128Encrypt (XMM1, UnwrappedKey) ;\n XMM2 := AES128Encrypt (XMM2, UnwrappedKey) ;\n XMM3 := AES128Encrypt (XMM3, UnwrappedKey) ;\n XMM4 := AES128Encrypt (XMM4, UnwrappedKey) ;\n XMM5 := AES128Encrypt (XMM5, UnwrappedKey) ;\n XMM6 := AES128Encrypt (XMM6, UnwrappedKey) ;\n XMM7 := AES128Encrypt (XMM7, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n1. Further details on Key Locker and usage of this instruction can be found here:\n", + "url": "https://www.felixcloutier.com/x86/aesencwide128kl" + }, + "aesencwide256kl": { + "instruction": "AESENCWIDE256KL", + "title": "AESENCWIDE256KL\n\t\t— Perform 14 Rounds of AES Encryption Flow With Key Locker on 8 BlocksUsing 256-Bit Key", + "opcode": "F3 0F 38 D8 !(11):010:bbb AESENCWIDE256KL m512, ", + "description": "The AESENCWIDE256KL1 instruction performs 14 rounds of AES to encrypt each of the eight blocks in XMM0-7 using the 256-bit key indicated by the handle from the second operand. It replaces each input block in XMM0-7 with its corresponding encrypted block if the operation succeeds (e.g., does not run into a handle violation failure).", + "operation": "Handle := UnalignedLoad of 512 bit (SRC); // Load is not guaranteed to be atomic.\nIllegal Handle = (\n HandleReservedBitSet (Handle) ||\n (Handle[0] AND (CPL > 0)) ||\n Handle [1] ||\n HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES256\n );\nIF (Illegal Handle)\n THEN RFLAGS.ZF := 1;\n ELSE\n (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey);\n IF (Authentic == 0)\n THEN RFLAGS.ZF := 1;\n ELSE\n XMM0 := AES256Encrypt (XMM0, UnwrappedKey) ;\n XMM1 := AES256Encrypt (XMM1, UnwrappedKey) ;\n XMM2 := AES256Encrypt (XMM2, UnwrappedKey) ;\n XMM3 := AES256Encrypt (XMM3, UnwrappedKey) ;\n XMM4 := AES256Encrypt (XMM4, UnwrappedKey) ;\n XMM5 := AES256Encrypt (XMM5, UnwrappedKey) ;\n XMM6 := AES256Encrypt (XMM6, UnwrappedKey) ;\n XMM7 := AES256Encrypt (XMM7, UnwrappedKey) ;\n RFLAGS.ZF := 0;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n1. Further details on Key Locker and usage of this instruction can be found here:\n", + "url": "https://www.felixcloutier.com/x86/aesencwide256kl" + }, + "aesimc": { + "instruction": "AESIMC", + "title": "AESIMC\n\t\t— Perform the AES InvMixColumn Transformation", + "opcode": "66 0F 38 DB /r AESIMC xmm1, xmm2/m128", + "description": "Perform the InvMixColumns transformation on the source operand and store the result in the destination operand. The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location.\nNote: the AESIMC instruction should be applied to the expanded AES round keys (except for the first and last round key) in order to prepare them for decryption using the “Equivalent Inverse Cipher” (defined in FIPS 197).\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "DEST[127:0] := InvMixColumns( SRC );\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := InvMixColumns( SRC );\nDEST[MAXVL-1:128] := 0;\n", + "url": "https://www.felixcloutier.com/x86/aesimc" + }, + "aeskeygenassist": { + "instruction": "AESKEYGENASSIST", + "title": "AESKEYGENASSIST\n\t\t— AES Round Key Generation Assist", + "opcode": "66 0F 3A DF /r ib AESKEYGENASSIST xmm1, xmm2/m128, imm8", + "description": "Assist in expanding the AES cipher key, by computing steps towards generating a round key for encryption, using 128-bit data specified in the source operand and an 8-bit round constant specified as an immediate, store the result in the destination operand.\nThe destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "X3[31:0] := SRC [127: 96];\nX2[31:0] := SRC [95: 64];\nX1[31:0] := SRC [63: 32];\nX0[31:0] := SRC [31: 0];\nRCON[31:0] := ZeroExtend(imm8[7:0]);\nDEST[31:0] := SubWord(X1);\nDEST[63:32 ] := RotWord( SubWord(X1) ) XOR RCON;\nDEST[95:64] := SubWord(X3);\nDEST[127:96] := RotWord( SubWord(X3) ) XOR RCON;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nX3[31:0] := SRC [127: 96];\nX2[31:0] := SRC [95: 64];\nX1[31:0] := SRC [63: 32];\nX0[31:0] := SRC [31: 0];\nRCON[31:0] := ZeroExtend(imm8[7:0]);\nDEST[31:0] := SubWord(X1);\nDEST[63:32 ] := RotWord( SubWord(X1) ) XOR RCON;\nDEST[95:64] := SubWord(X3);\nDEST[127:96] := RotWord( SubWord(X3) ) XOR RCON;\nDEST[MAXVL-1:128] := 0;\n", + "url": "https://www.felixcloutier.com/x86/aeskeygenassist" + }, + "and": { + "instruction": "AND", + "title": "AND\n\t\t— Logical AND", + "opcode": "24 ib", + "description": "Performs a bitwise AND operation on the destination (first) and source (second) operands and stores the result in the destination operand location. The source operand can be an immediate, a register, or a memory location; the destination operand can be a register or a memory location. (However, two memory operands cannot be used in one instruction.) Each bit of the result is set to 1 if both corresponding bits of the first and second operands are 1; otherwise, it is set to 0.\nThis instruction can be used with a LOCK prefix to allow the it to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := DEST AND SRC;\n", + "url": "https://www.felixcloutier.com/x86/and" + }, + "andn": { + "instruction": "ANDN", + "title": "ANDN\n\t\t— Logical AND NOT", + "opcode": "VEX.LZ.0F38.W0 F2 /r ANDN r32a, r32b, r/m32", + "description": "Performs a bitwise logical AND of inverted second operand (the first source operand) with the third operand (the\nsecond source operand). The result is stored in the first operand (destination operand).\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "DEST := (NOT SRC1) bitwiseAND SRC2;\nSF := DEST[OperandSize -1];\nZF := (DEST = 0);\n", + "url": "https://www.felixcloutier.com/x86/andn" + }, + "andnpd": { + "instruction": "ANDNPD", + "title": "ANDNPD\n\t\t— Bitwise Logical AND NOT of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 55 /r ANDNPD xmm1, xmm2/m128", + "description": "Performs a bitwise logical AND NOT of the two, four or eight packed double precision floating-point values from the first source operand and the second source operand, and stores the result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := (NOT(SRC1[i+63:i])) BITWISE AND SRC2[63:0]\n ELSE\n DEST[i+63:i] := (NOT(SRC1[i+63:i])) BITWISE AND SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] = 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := (NOT(SRC1[63:0])) BITWISE AND SRC2[63:0]\nDEST[127:64] := (NOT(SRC1[127:64])) BITWISE AND SRC2[127:64]\nDEST[191:128] := (NOT(SRC1[191:128])) BITWISE AND SRC2[191:128]\nDEST[255:192] := (NOT(SRC1[255:192])) BITWISE AND SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := (NOT(SRC1[63:0])) BITWISE AND SRC2[63:0]\nDEST[127:64] := (NOT(SRC1[127:64])) BITWISE AND SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := (NOT(DEST[63:0])) BITWISE AND SRC[63:0]\nDEST[127:64] := (NOT(DEST[127:64])) BITWISE AND SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/andnpd" + }, + "andnps": { + "instruction": "ANDNPS", + "title": "ANDNPS\n\t\t— Bitwise Logical AND NOT of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 55 /r ANDNPS xmm1, xmm2/m128", + "description": "Performs a bitwise logical AND NOT of the four, eight or sixteen packed single precision floating-point values from the first source operand and the second source operand, and stores the result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+31:i] := (NOT(SRC1[i+31:i])) BITWISE AND SRC2[31:0]\n ELSE\n DEST[i+31:i] := (NOT(SRC1[i+31:i])) BITWISE AND SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] = 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := (NOT(SRC1[31:0])) BITWISE AND SRC2[31:0]\nDEST[63:32] := (NOT(SRC1[63:32])) BITWISE AND SRC2[63:32]\nDEST[95:64] := (NOT(SRC1[95:64])) BITWISE AND SRC2[95:64]\nDEST[127:96] := (NOT(SRC1[127:96])) BITWISE AND SRC2[127:96]\nDEST[159:128] := (NOT(SRC1[159:128])) BITWISE AND SRC2[159:128]\nDEST[191:160] := (NOT(SRC1[191:160])) BITWISE AND SRC2[191:160]\nDEST[223:192] := (NOT(SRC1[223:192])) BITWISE AND SRC2[223:192]\nDEST[255:224] := (NOT(SRC1[255:224])) BITWISE AND SRC2[255:224].\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := (NOT(SRC1[31:0])) BITWISE AND SRC2[31:0]\nDEST[63:32] := (NOT(SRC1[63:32])) BITWISE AND SRC2[63:32]\nDEST[95:64] := (NOT(SRC1[95:64])) BITWISE AND SRC2[95:64]\nDEST[127:96] := (NOT(SRC1[127:96])) BITWISE AND SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := (NOT(DEST[31:0])) BITWISE AND SRC[31:0]\nDEST[63:32] := (NOT(DEST[63:32])) BITWISE AND SRC[63:32]\nDEST[95:64] := (NOT(DEST[95:64])) BITWISE AND SRC[95:64]\nDEST[127:96] := (NOT(DEST[127:96])) BITWISE AND SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/andnps" + }, + "andpd": { + "instruction": "ANDPD", + "title": "ANDPD\n\t\t— Bitwise Logical AND of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 54 /r ANDPD xmm1, xmm2/m128", + "description": "Performs a bitwise logical AND of the two, four or eight packed double precision floating-point values from the first source operand and the second source operand, and stores the result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := SRC1[i+63:i] BITWISE AND SRC2[63:0]\n ELSE\n DEST[i+63:i] := SRC1[i+63:i] BITWISE AND SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] = 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]\nDEST[127:64] := SRC1[127:64] BITWISE AND SRC2[127:64]\nDEST[191:128] := SRC1[191:128] BITWISE AND SRC2[191:128]\nDEST[255:192] := SRC1[255:192] BITWISE AND SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]\nDEST[127:64] := SRC1[127:64] BITWISE AND SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] BITWISE AND SRC[63:0]\nDEST[127:64] := DEST[127:64] BITWISE AND SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/andpd" + }, + "andps": { + "instruction": "ANDPS", + "title": "ANDPS\n\t\t— Bitwise Logical AND of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 54 /r ANDPS xmm1, xmm2/m128", + "description": "Performs a bitwise logical AND of the four, eight or sixteen packed single precision floating-point values from the first source operand and the second source operand, and stores the result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := SRC1[i+31:i] BITWISE AND SRC2[31:0]\n ELSE\n DEST[i+31:i] := SRC1[i+31:i] BITWISE AND SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0;\n\n\nDEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]\nDEST[63:32] := SRC1[63:32] BITWISE AND SRC2[63:32]\nDEST[95:64] := SRC1[95:64] BITWISE AND SRC2[95:64]\nDEST[127:96] := SRC1[127:96] BITWISE AND SRC2[127:96]\nDEST[159:128] := SRC1[159:128] BITWISE AND SRC2[159:128]\nDEST[191:160] := SRC1[191:160] BITWISE AND SRC2[191:160]\nDEST[223:192] := SRC1[223:192] BITWISE AND SRC2[223:192]\nDEST[255:224] := SRC1[255:224] BITWISE AND SRC2[255:224].\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]\nDEST[63:32] := SRC1[63:32] BITWISE AND SRC2[63:32]\nDEST[95:64] := SRC1[95:64] BITWISE AND SRC2[95:64]\nDEST[127:96] := SRC1[127:96] BITWISE AND SRC2[127:96]\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[31:0] := DEST[31:0] BITWISE AND SRC[31:0]\nDEST[63:32] := DEST[63:32] BITWISE AND SRC[63:32]\nDEST[95:64] := DEST[95:64] BITWISE AND SRC[95:64]\nDEST[127:96] := DEST[127:96] BITWISE AND SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/andps" + }, + "arpl": { + "instruction": "ARPL", + "title": "ARPL\n\t\t— Adjust RPL Field of Segment Selector", + "opcode": "63 /r", + "description": "Compares the RPL fields of two segment selectors. The first operand (the destination operand) contains one segment selector and the second operand (source operand) contains the other. (The RPL field is located in bits 0 and 1 of each operand.) If the RPL field of the destination operand is less than the RPL field of the source operand, the ZF flag is set and the RPL field of the destination operand is increased to match that of the source operand. Otherwise, the ZF flag is cleared and no change is made to the destination operand. (The destination operand can be a word register or a memory location; the source operand must be a word register.)\nThe ARPL instruction is provided for use by operating-system procedures (however, it can also be used by applications). It is generally used to adjust the RPL of a segment selector that has been passed to the operating system by an application program to match the privilege level of the application program. Here the segment selector passed to the operating system is placed in the destination operand and segment selector for the application program’s code segment is placed in the source operand. (The RPL field in the source operand represents the privilege level of the application program.) Execution of the ARPL instruction then ensures that the RPL of the segment selector received by the operating system is no lower (does not have a higher privilege) than the privilege level of the application program (the segment selector for the application program’s code segment can be read from the stack following a procedure call).\nThis instruction executes as described in compatibility mode and legacy mode. It is not encodable in 64-bit mode.\nSee “Checking Caller Access Privileges” in Chapter 3, “Protected-Mode Memory Management,” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for more information about the use of this instruction.", + "operation": "IF 64-BIT MODE\n THEN\n See MOVSXD;\n ELSE\n IF DEST[RPL] < SRC[RPL]\n THEN\n ZF := 1;\n DEST[RPL] := SRC[RPL];\n ELSE\n ZF := 0;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/arpl" + }, + "bextr": { + "instruction": "BEXTR", + "title": "BEXTR\n\t\t— Bit Field Extract", + "opcode": "VEX.LZ.0F38.W0 F7 /r BEXTR r32a, r/m32, r32b", + "description": "Extracts contiguous bits from the first source operand (the second operand) using an index value and length value specified in the second source operand (the third operand). Bit 7:0 of the second source operand specifies the starting bit position of bit extraction. A START value exceeding the operand size will not extract any bits from the second source operand. Bit 15:8 of the second source operand specifies the maximum number of bits (LENGTH) beginning at the START position to extract. Only bit positions up to (OperandSize -1) of the first source operand are extracted. The extracted bits are written to the destination register, starting from the least significant bit. All higher order bits in the destination operand (starting at bit position LENGTH) are zeroed. The destination register is cleared if no bits are extracted.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "START := SRC2[7:0];\nLEN := SRC2[15:8];\nTEMP := ZERO_EXTEND_TO_512 (SRC1 );\nDEST := ZERO_EXTEND(TEMP[START+LEN -1: START]);\nZF := (DEST = 0);\n", + "url": "https://www.felixcloutier.com/x86/bextr" + }, + "blendpd": { + "instruction": "BLENDPD", + "title": "BLENDPD\n\t\t— Blend Packed Double Precision Floating-Point Values", + "opcode": "66 0F 3A 0D /r ib BLENDPD xmm1, xmm2/m128, imm8", + "description": "Double-precision floating-point values from the second source operand (third operand) are conditionally merged with values from the first source operand (second operand) and written to the destination operand (first operand). The immediate bits [3:0] determine whether the corresponding double precision floating-point value in the destination is copied from the second source or first source. If a bit in the mask, corresponding to a word, is ”1”, then the double precision floating-point value in the second source operand is copied, else the value in the first source operand is copied.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "IF (IMM8[0] = 0)THEN DEST[63:0] := DEST[63:0]\n ELSE DEST [63:0] := SRC[63:0] FI\nIF (IMM8[1] = 0) THEN DEST[127:64] := DEST[127:64]\n ELSE DEST [127:64] := SRC[127:64] FI\nDEST[MAXVL-1:128] (Unmodified)\n\n\nIF (IMM8[0] = 0)THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST [63:0] := SRC2[63:0] FI\nIF (IMM8[1] = 0) THEN DEST[127:64] := SRC1[127:64]\n ELSE DEST [127:64] := SRC2[127:64] FI\nDEST[MAXVL-1:128] := 0\n\n\nIF (IMM8[0] = 0)THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST [63:0] := SRC2[63:0] FI\nIF (IMM8[1] = 0) THEN DEST[127:64] := SRC1[127:64]\n ELSE DEST [127:64] := SRC2[127:64] FI\nIF (IMM8[2] = 0) THEN DEST[191:128] := SRC1[191:128]\n ELSE DEST [191:128] := SRC2[191:128] FI\nIF (IMM8[3] = 0) THEN DEST[255:192] := SRC1[255:192]\n ELSE DEST [255:192] := SRC2[255:192] FI\n", + "url": "https://www.felixcloutier.com/x86/blendpd" + }, + "blendps": { + "instruction": "BLENDPS", + "title": "BLENDPS\n\t\t— Blend Packed Single Precision Floating-Point Values", + "opcode": "66 0F 3A 0C /r ib BLENDPS xmm1, xmm2/m128, imm8", + "description": "Packed single precision floating-point values from the second source operand (third operand) are conditionally merged with values from the first source operand (second operand) and written to the destination operand (first operand). The immediate bits [7:0] determine whether the corresponding single precision floating-point value in the destination is copied from the second source or first source. If a bit in the mask, corresponding to a word, is “1”, then the single precision floating-point value in the second source operand is copied, else the value in the first source operand is copied.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: The first source operand an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "IF (IMM8[0] = 0) THEN DEST[31:0] :=DEST[31:0]\n ELSE DEST [31:0] := SRC[31:0] FI\nIF (IMM8[1] = 0) THEN DEST[63:32] := DEST[63:32]\n ELSE DEST [63:32] := SRC[63:32] FI\nIF (IMM8[2] = 0) THEN DEST[95:64] := DEST[95:64]\n ELSE DEST [95:64] := SRC[95:64] FI\nIF (IMM8[3] = 0) THEN DEST[127:96] := DEST[127:96]\n ELSE DEST [127:96] := SRC[127:96] FI\nDEST[MAXVL-1:128] (Unmodified)\n\n\nIF (IMM8[0] = 0) THEN DEST[31:0] :=SRC1[31:0]\n ELSE DEST [31:0] := SRC2[31:0] FI\nIF (IMM8[1] = 0) THEN DEST[63:32] := SRC1[63:32]\n ELSE DEST [63:32] := SRC2[63:32] FI\nIF (IMM8[2] = 0) THEN DEST[95:64] := SRC1[95:64]\n ELSE DEST [95:64] := SRC2[95:64] FI\nIF (IMM8[3] = 0) THEN DEST[127:96] := SRC1[127:96]\n ELSE DEST [127:96] := SRC2[127:96] FI\nDEST[MAXVL-1:128] := 0\n\n\nIF (IMM8[0] = 0) THEN DEST[31:0] :=SRC1[31:0]\n ELSE DEST [31:0] := SRC2[31:0] FI\nIF (IMM8[1] = 0) THEN DEST[63:32] := SRC1[63:32]\n ELSE DEST [63:32] := SRC2[63:32] FI\nIF (IMM8[2] = 0) THEN DEST[95:64] := SRC1[95:64]\n ELSE DEST [95:64] := SRC2[95:64] FI\nIF (IMM8[3] = 0) THEN DEST[127:96] := SRC1[127:96]\n ELSE DEST [127:96] := SRC2[127:96] FI\nIF (IMM8[4] = 0) THEN DEST[159:128] := SRC1[159:128]\n ELSE DEST [159:128] := SRC2[159:128] FI\nIF (IMM8[5] = 0) THEN DEST[191:160] := SRC1[191:160]\n ELSE DEST [191:160] := SRC2[191:160] FI\nIF (IMM8[6] = 0) THEN DEST[223:192] := SRC1[223:192]\n ELSE DEST [223:192] := SRC2[223:192] FI\nIF (IMM8[7] = 0) THEN DEST[255:224] := SRC1[255:224]\n ELSE DEST [255:224] := SRC2[255:224] FI.\n", + "url": "https://www.felixcloutier.com/x86/blendps" + }, + "blendvpd": { + "instruction": "BLENDVPD", + "title": "BLENDVPD\n\t\t— Variable Blend Packed Double Precision Floating-Point Values", + "opcode": "66 0F 38 15 /r BLENDVPD xmm1, xmm2/m128 , ", + "description": "Conditionally copy each quadword data element of double precision floating-point value from the second source operand and the first source operand depending on mask bits defined in the mask register operand. The mask bits are the most significant bit in each quadword element of the mask register.\nEach quadword element of the destination operand is copied from:\nThe register assignment of the implicit mask operand for BLENDVPD is defined to be the architectural register XMM0.\n128-bit Legacy SSE version: The first source operand and the destination operand is the same. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The mask register operand is implicitly defined to be the architectural register XMM0. An attempt to execute BLENDVPD with a VEX prefix will cause #UD.\nVEX.128 encoded version: The first source operand and the destination operand are XMM registers. The second source operand is an XMM register or 128-bit memory location. The mask operand is the third source register, and encoded in bits[7:4] of the immediate byte(imm8). The bits[3:0] of imm8 are ignored. In 32-bit mode, imm8[7] is ignored. The upper bits (MAXVL-1:128) of the corresponding YMM register (destination register) are zeroed. VEX.W must be 0, otherwise, the instruction will #UD.\nVEX.256 encoded version: The first source operand and destination operand are YMM registers. The second source operand can be a YMM register or a 256-bit memory location. The mask operand is the third source register, and encoded in bits[7:4] of the immediate byte(imm8). The bits[3:0] of imm8 are ignored. In 32-bit mode, imm8[7] is ignored. VEX.W must be 0, otherwise, the instruction will #UD.\nVBLENDVPD permits the mask to be any XMM or YMM register. In contrast, BLENDVPD treats XMM0 implicitly as the mask and do not support non-destructive destination operation.", + "operation": "MASK := XMM0\nIF (MASK[63] = 0) THEN DEST[63:0] := DEST[63:0]\n ELSE DEST [63:0] := SRC[63:0] FI\nIF (MASK[127] = 0) THEN DEST[127:64] := DEST[127:64]\n ELSE DEST [127:64] := SRC[127:64] FI\nDEST[MAXVL-1:128] (Unmodified)\n\n\nMASK := SRC3\nIF (MASK[63] = 0) THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST [63:0] := SRC2[63:0] FI\nIF (MASK[127] = 0) THEN DEST[127:64] := SRC1[127:64]\n ELSE DEST [127:64] := SRC2[127:64] FI\nDEST[MAXVL-1:128] := 0\n\n\nMASK := SRC3\nIF (MASK[63] = 0) THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST [63:0] := SRC2[63:0] FI\nIF (MASK[127] = 0) THEN DEST[127:64] := SRC1[127:64]\n ELSE DEST [127:64] := SRC2[127:64] FI\nIF (MASK[191] = 0) THEN DEST[191:128] := SRC1[191:128]\n ELSE DEST [191:128] := SRC2[191:128] FI\nIF (MASK[255] = 0) THEN DEST[255:192] := SRC1[255:192]\n ELSE DEST [255:192] := SRC2[255:192] FI\n", + "url": "https://www.felixcloutier.com/x86/blendvpd" + }, + "blendvps": { + "instruction": "BLENDVPS", + "title": "BLENDVPS\n\t\t— Variable Blend Packed Single Precision Floating-Point Values", + "opcode": "66 0F 38 14 /r BLENDVPS xmm1, xmm2/m128, ", + "description": "Conditionally copy each dword data element of single precision floating-point value from the second source operand and the first source operand depending on mask bits defined in the mask register operand. The mask bits are the most significant bit in each dword element of the mask register.\nEach quadword element of the destination operand is copied from:\nThe register assignment of the implicit mask operand for BLENDVPS is defined to be the architectural register XMM0.\n128-bit Legacy SSE version: The first source operand and the destination operand is the same. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The mask register operand is implicitly defined to be the architectural register XMM0. An attempt to execute BLENDVPS with a VEX prefix will cause #UD.\nVEX.128 encoded version: The first source operand and the destination operand are XMM registers. The second source operand is an XMM register or 128-bit memory location. The mask operand is the third source register, and encoded in bits[7:4] of the immediate byte(imm8). The bits[3:0] of imm8 are ignored. In 32-bit mode, imm8[7] is ignored. The upper bits (MAXVL-1:128) of the corresponding YMM register (destination register) are zeroed. VEX.W must be 0, otherwise, the instruction will #UD.\nVEX.256 encoded version: The first source operand and destination operand are YMM registers. The second source operand can be a YMM register or a 256-bit memory location. The mask operand is the third source register, and encoded in bits[7:4] of the immediate byte(imm8). The bits[3:0] of imm8 are ignored. In 32-bit mode, imm8[7] is ignored. VEX.W must be 0, otherwise, the instruction will #UD.\nVBLENDVPS permits the mask to be any XMM or YMM register. In contrast, BLENDVPS treats XMM0 implicitly as the mask and do not support non-destructive destination operation.", + "operation": "MASK := XMM0\nIF (MASK[31] = 0) THEN DEST[31:0] := DEST[31:0]\n ELSE DEST [31:0] := SRC[31:0] FI\nIF (MASK[63] = 0) THEN DEST[63:32] := DEST[63:32]\n ELSE DEST [63:32] := SRC[63:32] FI\nIF (MASK[95] = 0) THEN DEST[95:64] := DEST[95:64]\n ELSE DEST [95:64] := SRC[95:64] FI\nIF (MASK[127] = 0) THEN DEST[127:96] := DEST[127:96]\n ELSE DEST [127:96] := SRC[127:96] FI\nDEST[MAXVL-1:128] (Unmodified)\n\n\nMASK := SRC3\nIF (MASK[31] = 0) THEN DEST[31:0] := SRC1[31:0]\n ELSE DEST [31:0] := SRC2[31:0] FI\nIF (MASK[63] = 0) THEN DEST[63:32] := SRC1[63:32]\n ELSE DEST [63:32] := SRC2[63:32] FI\nIF (MASK[95] = 0) THEN DEST[95:64] := SRC1[95:64]\n ELSE DEST [95:64] := SRC2[95:64] FI\nIF (MASK[127] = 0) THEN DEST[127:96] := SRC1[127:96]\n ELSE DEST [127:96] := SRC2[127:96] FI\nDEST[MAXVL-1:128] := 0\n\n\nMASK := SRC3\nIF (MASK[31] = 0) THEN DEST[31:0] := SRC1[31:0]\n ELSE DEST [31:0] := SRC2[31:0] FI\nIF (MASK[63] = 0) THEN DEST[63:32] := SRC1[63:32]\n ELSE DEST [63:32] := SRC2[63:32] FI\nIF (MASK[95] = 0) THEN DEST[95:64] := SRC1[95:64]\n ELSE DEST [95:64] := SRC2[95:64] FI\nIF (MASK[127] = 0) THEN DEST[127:96] := SRC1[127:96]\n ELSE DEST [127:96] := SRC2[127:96] FI\nIF (MASK[159] = 0) THEN DEST[159:128] := SRC1[159:128]\n ELSE DEST [159:128] := SRC2[159:128] FI\nIF (MASK[191] = 0) THEN DEST[191:160] := SRC1[191:160]\n ELSE DEST [191:160] := SRC2[191:160] FI\nIF (MASK[223] = 0) THEN DEST[223:192] := SRC1[223:192]\n ELSE DEST [223:192] := SRC2[223:192] FI\nIF (MASK[255] = 0) THEN DEST[255:224] := SRC1[255:224]\n ELSE DEST [255:224] := SRC2[255:224] FI\n", + "url": "https://www.felixcloutier.com/x86/blendvps" + }, + "blsi": { + "instruction": "BLSI", + "title": "BLSI\n\t\t— Extract Lowest Set Isolated Bit", + "opcode": "VEX.LZ.0F38.W0 F3 /3 BLSI r32, r/m32", + "description": "Extracts the lowest set bit from the source operand and set the corresponding bit in the destination register. All other bits in the destination operand are zeroed. If no bits are set in the source operand, BLSI sets all the bits in the destination to 0 and sets ZF and CF.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "temp := (-SRC) bitwiseAND (SRC);\nSF := temp[OperandSize -1];\nZF := (temp = 0);\nIF SRC = 0\n CF := 0;\nELSE\n CF := 1;\nFI\nDEST := temp;\n", + "url": "https://www.felixcloutier.com/x86/blsi" + }, + "blsmsk": { + "instruction": "BLSMSK", + "title": "BLSMSK\n\t\t— Get Mask Up to Lowest Set Bit", + "opcode": "VEX.LZ.0F38.W0 F3 /2 BLSMSK r32, r/m32", + "description": "Sets all the lower bits of the destination operand to “1” up to and including lowest set bit (=1) in the source operand. If source operand is zero, BLSMSK sets all bits of the destination operand to 1 and also sets CF to 1.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "temp := (SRC-1) XOR (SRC) ;\nSF := temp[OperandSize -1];\nZF := 0;\nIF SRC = 0\n CF := 1;\nELSE\n CF := 0;\nFI\nDEST := temp;\n", + "url": "https://www.felixcloutier.com/x86/blsmsk" + }, + "blsr": { + "instruction": "BLSR", + "title": "BLSR\n\t\t— Reset Lowest Set Bit", + "opcode": "VEX.LZ.0F38.W0 F3 /1 BLSR r32, r/m32", + "description": "Copies all bits from the source operand to the destination operand and resets (=0) the bit position in the destination operand that corresponds to the lowest set bit of the source operand. If the source operand is zero BLSR sets CF.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "temp := (SRC-1) bitwiseAND ( SRC );\nSF := temp[OperandSize -1];\nZF := (temp = 0);\nIF SRC = 0\n CF := 1;\nELSE\n CF := 0;\nFI\nDEST := temp;\n", + "url": "https://www.felixcloutier.com/x86/blsr" + }, + "bndcl": { + "instruction": "BNDCL", + "title": "BNDCL\n\t\t— Check Lower Bound", + "opcode": "F3 0F 1A /r BNDCL bnd, r/m32", + "description": "Compare the address in the second operand with the lower bound in bnd. The second operand can be either a register or memory operand. If the address is lower than the lower bound in bnd.LB, it will set BNDSTATUS to 01H and signal a #BR exception.\nThis instruction does not cause any memory access, and does not read or write any flags.", + "operation": "IF reg < BND.LB Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nTEMP := LEA(mem);\nIF TEMP < BND.LB Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bndcl" + }, + "bndcn": { + "instruction": "BNDCN", + "title": "BNDCU/BNDCN\n\t\t— Check Upper Bound", + "opcode": "F2 0F 1A /r BNDCU bnd, r/m32", + "description": "Compare the address in the second operand with the upper bound in bnd. The second operand can be either a register or a memory operand. If the address is higher than the upper bound in bnd.UB, it will set BNDSTATUS to 01H and signal a #BR exception.\nBNDCU perform 1’s complement operation on the upper bound of bnd first before proceeding with address comparison. BNDCN perform address comparison directly using the upper bound in bnd that is already reverted out of 1’s complement form.\nThis instruction does not cause any memory access, and does not read or write any flags.\nEffective address computation of m32/64 has identical behavior to LEA", + "operation": "IF reg > NOT(BND.UB) Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nTEMP := LEA(mem);\nIF TEMP > NOT(BND.UB) Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nIF reg > BND.UB Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nTEMP := LEA(mem);\nIF TEMP > BND.UB Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bndcu:bndcn" + }, + "bndcu": { + "instruction": "BNDCU", + "title": "BNDCU/BNDCN\n\t\t— Check Upper Bound", + "opcode": "F2 0F 1A /r BNDCU bnd, r/m32", + "description": "Compare the address in the second operand with the upper bound in bnd. The second operand can be either a register or a memory operand. If the address is higher than the upper bound in bnd.UB, it will set BNDSTATUS to 01H and signal a #BR exception.\nBNDCU perform 1’s complement operation on the upper bound of bnd first before proceeding with address comparison. BNDCN perform address comparison directly using the upper bound in bnd that is already reverted out of 1’s complement form.\nThis instruction does not cause any memory access, and does not read or write any flags.\nEffective address computation of m32/64 has identical behavior to LEA", + "operation": "IF reg > NOT(BND.UB) Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nTEMP := LEA(mem);\nIF TEMP > NOT(BND.UB) Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nIF reg > BND.UB Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n\n\nTEMP := LEA(mem);\nIF TEMP > BND.UB Then\n BNDSTATUS := 01H;\n #BR;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bndcu:bndcn" + }, + "bndldx": { + "instruction": "BNDLDX", + "title": "BNDLDX\n\t\t— Load Extended Bounds Using Address Translation", + "opcode": "NP 0F 1A /r BNDLDX bnd, mib", + "description": "BNDLDX uses the linear address constructed from the base register and displacement of the SIB-addressing form of the memory operand (mib) to perform address translation to access a bound table entry and conditionally load the bounds in the BTE to the destination. The destination register is updated with the bounds in the BTE, if the content of the index register of mib matches the pointer value stored in the BTE.\nIf the pointer value comparison fails, the destination is updated with INIT bounds (lb = 0x0, ub = 0x0) (note: as articulated earlier, the upper bound is represented using 1's complement, therefore, the 0x0 value of upper bound allows for access to full memory).\nThis instruction does not cause memory access to the linear address of mib nor the effective address referenced by the base, and does not read or write any flags.\nSegment overrides apply to the linear address computation with the base of mib, and are used during address translation to generate the address of the bound table entry. By default, the address of the BTE is assumed to be linear address. There are no segmentation checks performed on the base of mib.\nThe base of mib will not be checked for canonical address violation as it does not access memory.\nAny encoding of this instruction that does not specify base or index register will treat those registers as zero (constant). The reg-reg form of this instruction will remain a NOP.\nThe scale field of the SIB byte has no effect on these instructions and is ignored.\nThe bound register may be partially updated on memory faults. The order in which memory operands are loaded is implementation specific.", + "operation": "base := mib.SIB.base ? mib.SIB.base + Disp: 0;\nptr_value := mib.SIB.index ? mib.SIB.index : 0;\n\n\nA_BDE[31:0] := (Zero_extend32(base[31:12] « 2) + (BNDCFG[31:12] «12 );\nA_BT[31:0] := LoadFrom(A_BDE );\nIF A_BT[0] equal 0 Then\n BNDSTATUS := A_BDE | 02H;\n #BR;\nFI;\nA_BTE[31:0] := (Zero_extend32(base[11:2] « 4) + (A_BT[31:2] « 2 );\nTemp_lb[31:0] := LoadFrom(A_BTE);\nTemp_ub[31:0] := LoadFrom(A_BTE + 4);\nTemp_ptr[31:0] := LoadFrom(A_BTE + 8);\nIF Temp_ptr equal ptr_value Then\n BND.LB := Temp_lb;\n BND.UB := Temp_ub;\nELSE\n BND.LB := 0;\n BND.UB := 0;\nFI;\n\n\nA_BDE[63:0] := (Zero_extend64(base[47+MAWA:20] « 3) + (BNDCFG[63:12] «12 );1\nA_BT[63:0] := LoadFrom(A_BDE);\nIF A_BT[0] equal 0 Then\n BNDSTATUS := A_BDE | 02H;\n #BR;\nFI;\nA_BTE[63:0] := (Zero_extend64(base[19:3] « 5) + (A_BT[63:3] « 3 );\nTemp_lb[63:0] := LoadFrom(A_BTE);\nTemp_ub[63:0] := LoadFrom(A_BTE + 8);\nTemp_ptr[63:0] := LoadFrom(A_BTE + 16);\nIF Temp_ptr equal ptr_value Then\n BND.LB := Temp_lb;\n BND.UB := Temp_ub;\nELSE\n BND.LB := 0;\n BND.UB := 0;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bndldx" + }, + "bndmk": { + "instruction": "BNDMK", + "title": "BNDMK\n\t\t— Make Bounds", + "opcode": "F3 0F 1B /r BNDMK bnd, m32", + "description": "Makes bounds from the second operand and stores the lower and upper bounds in the bound register bnd. The second operand must be a memory operand. The content of the base register from the memory operand is stored in the lower bound bnd.LB. The 1's complement of the effective address of m32/m64 is stored in the upper bound b.UB. Computation of m32/m64 has identical behavior to LEA.\nThis instruction does not cause any memory access, and does not read or write any flags.\nIf the instruction did not specify base register, the lower bound will be zero. The reg-reg form of this instruction retains legacy behavior (NOP).\nThe instruction causes an invalid-opcode exception (#UD) if executed in 64-bit mode with RIP-relative addressing.", + "operation": "BND.LB := SRCMEM.base;\nIF 64-bit mode Then\n BND.UB := NOT(LEA.64_bits(SRCMEM));\nELSE\n BND.UB := Zero_Extend.64_bits(NOT(LEA.32_bits(SRCMEM)));\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bndmk" + }, + "bndmov": { + "instruction": "BNDMOV", + "title": "BNDMOV\n\t\t— Move Bounds", + "opcode": "66 0F 1A /r BNDMOV bnd1, bnd2/m64", + "description": "BNDMOV moves a pair of lower and upper bound values from the source operand (the second operand) to the destination (the first operand). Each operation is 128-bit move. The exceptions are same as the MOV instruction. The memory format for loading/store bounds in 64-bit mode is shown in Figure 3-5.\nThis instruction does not change flags.", + "operation": "DEST.LB := SRC.LB;\nDEST.UB := SRC.UB;\n\n\nIF 64-bit mode THEN\n DEST.LB := LOAD_QWORD(SRC);\n DEST.UB := LOAD_QWORD(SRC+8);\n ELSE\n DEST.LB := LOAD_DWORD_ZERO_EXT(SRC);\n DEST.UB := LOAD_DWORD_ZERO_EXT(SRC+4);\nFI;\n\n\nIF 64-bit mode THEN\n DEST[63:0] := SRC.LB;\n DEST[127:64] := SRC.UB;\n ELSE\n DEST[31:0] := SRC.LB;\n DEST[63:32] := SRC.UB;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bndmov" + }, + "bndstx": { + "instruction": "BNDSTX", + "title": "BNDSTX\n\t\t— Store Extended Bounds Using Address Translation", + "opcode": "NP 0F 1B /r BNDSTX mib, bnd", + "description": "BNDSTX uses the linear address constructed from the displacement and base register of the SIB-addressing form of the memory operand (mib) to perform address translation to store to a bound table entry. The bounds in the source operand bnd are written to the lower and upper bounds in the BTE. The content of the index register of mib is written to the pointer value field in the BTE.\nThis instruction does not cause memory access to the linear address of mib nor the effective address referenced by the base, and does not read or write any flags.\nSegment overrides apply to the linear address computation with the base of mib, and are used during address translation to generate the address of the bound table entry. By default, the address of the BTE is assumed to be linear address. There are no segmentation checks performed on the base of mib.\nThe base of mib will not be checked for canonical address violation as it does not access memory.\nAny encoding of this instruction that does not specify base or index register will treat those registers as zero (constant). The reg-reg form of this instruction will remain a NOP.\nThe scale field of the SIB byte has no effect on these instructions and is ignored.\nThe bound register may be partially updated on memory faults. The order in which memory operands are loaded is implementation specific.", + "operation": "base := mib.SIB.base ? mib.SIB.base + Disp: 0;\nptr_value := mib.SIB.index ? mib.SIB.index : 0;\n\n\nA_BDE[31:0] := (Zero_extend32(base[31:12] « 2) + (BNDCFG[31:12] «12 );\nA_BT[31:0] := LoadFrom(A_BDE);\nIF A_BT[0] equal 0 Then\n BNDSTATUS := A_BDE | 02H;\n #BR;\nFI;\nA_DEST[31:0] := (Zero_extend32(base[11:2] « 4) + (A_BT[31:2] « 2 ); // address of Bound table entry\nA_DEST[8][31:0] := ptr_value;\nA_DEST[0][31:0] := BND.LB;\nA_DEST[4][31:0] := BND.UB;\n\n\nA_BDE[63:0] := (Zero_extend64(base[47+MAWA:20] « 3) + (BNDCFG[63:12] «12 );1\nA_BT[63:0] := LoadFrom(A_BDE);\nIF A_BT[0] equal 0 Then\n BNDSTATUS := A_BDE | 02H;\n #BR;\nFI;\nA_DEST[63:0] := (Zero_extend64(base[19:3] « 5) + (A_BT[63:3] « 3 ); // address of Bound table entry\nA_DEST[16][63:0] := ptr_value;\nA_DEST[0][63:0] := BND.LB;\nA_DEST[8][63:0] := BND.UB;\n", + "url": "https://www.felixcloutier.com/x86/bndstx" + }, + "bound": { + "instruction": "BOUND", + "title": "BOUND\n\t\t— Check Array Index Against Bounds", + "opcode": "62 /r", + "description": "BOUND determines if the first operand (array index) is within the bounds of an array specified the second operand (bounds operand). The array index is a signed integer located in a register. The bounds operand is a memory location that contains a pair of signed doubleword-integers (when the operand-size attribute is 32) or a pair of signed word-integers (when the operand-size attribute is 16). The first doubleword (or word) is the lower bound of the array and the second doubleword (or word) is the upper bound of the array. The array index must be greater than or equal to the lower bound and less than or equal to the upper bound plus the operand size in bytes. If the index is not within bounds, a BOUND range exceeded exception (#BR) is signaled. When this exception is generated, the saved return instruction pointer points to the BOUND instruction.\nThe bounds limit data structure (two words or doublewords containing the lower and upper limits of the array) is usually placed just before the array itself, making the limits addressable via a constant offset from the beginning of the array. Because the address of the array already will be present in a register, this practice avoids extra bus cycles to obtain the effective address of the array bounds.\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64bit Mode\n THEN\n #UD;\n ELSE\n IF (ArrayIndex < LowerBound OR ArrayIndex > UpperBound) THEN\n (* Below lower bound or above upper bound *)\n IF THEN BNDSTATUS := 0\n #BR;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bound" + }, + "bsf": { + "instruction": "BSF", + "title": "BSF\n\t\t— Bit Scan Forward", + "opcode": "0F BC /r", + "description": "Searches the source operand (second operand) for the least significant set bit (1 bit). If a least significant 1 bit is found, its bit index is stored in the destination operand (first operand). The source operand can be a register or a memory location; the destination operand is a register. The bit index is an unsigned offset from bit 0 of the source operand. If the content of the source operand is 0, the content of the destination operand is undefined.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF SRC = 0\n THEN\n ZF := 1;\n DEST is undefined;\n ELSE\n ZF := 0;\n temp := 0;\n WHILE Bit(SRC, temp) = 0\n DO\n temp := temp + 1;\n OD;\n DEST := temp;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bsf" + }, + "bsr": { + "instruction": "BSR", + "title": "BSR\n\t\t— Bit Scan Reverse", + "opcode": "0F BD /r", + "description": "Searches the source operand (second operand) for the most significant set bit (1 bit). If a most significant 1 bit is found, its bit index is stored in the destination operand (first operand). The source operand can be a register or a memory location; the destination operand is a register. The bit index is an unsigned offset from bit 0 of the source operand. If the content source operand is 0, the content of the destination operand is undefined.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF SRC = 0\n THEN\n ZF := 1;\n DEST is undefined;\n ELSE\n ZF := 0;\n temp := OperandSize – 1;\n WHILE Bit(SRC, temp) = 0\n DO\n temp := temp - 1;\n OD;\n DEST := temp;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bsr" + }, + "bswap": { + "instruction": "BSWAP", + "title": "BSWAP\n\t\t— Byte Swap", + "opcode": "0F C8+rd", + "description": "Reverses the byte order of a 32-bit or 64-bit (destination) register. This instruction is provided for converting little-endian values to big-endian format and vice versa. To swap bytes in a word value (16-bit register), use the XCHG instruction. When the BSWAP instruction references a 16-bit register, the result is undefined.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "TEMP := DEST\nIF 64-bit mode AND OperandSize = 64\n THEN\n DEST[7:0] := TEMP[63:56];\n DEST[15:8] := TEMP[55:48];\n DEST[23:16] := TEMP[47:40];\n DEST[31:24] := TEMP[39:32];\n DEST[39:32] := TEMP[31:24];\n DEST[47:40] := TEMP[23:16];\n DEST[55:48] := TEMP[15:8];\n DEST[63:56] := TEMP[7:0];\n ELSE\n DEST[7:0] := TEMP[31:24];\n DEST[15:8] := TEMP[23:16];\n DEST[23:16] := TEMP[15:8];\n DEST[31:24] := TEMP[7:0];\nFI;\n", + "url": "https://www.felixcloutier.com/x86/bswap" + }, + "bt": { + "instruction": "BT", + "title": "BT\n\t\t— Bit Test", + "opcode": "0F A3 /r", + "description": "Selects the bit in a bit string (specified with the first operand, called the bit base) at the bit-position designated by the bit offset (specified by the second operand) and stores the value of the bit in the CF flag. The bit base operand can be a register or a memory location; the bit offset operand can be a register or an immediate value:\nSee also: Bit(BitBase, BitOffset) on page 3-11.\nSome assemblers support immediate bit offsets larger than 31 by using the immediate bit offset field in combination with the displacement field of the memory operand. In this case, the low-order 3 or 5 bits (3 for 16-bit operands, 5 for 32-bit operands) of the immediate bit offset are stored in the immediate bit offset field, and the high-order bits are shifted and combined with the byte displacement in the addressing mode by the assembler. The processor will ignore the high order bits if they are not zero.\nWhen accessing a bit in memory, the processor may access 4 bytes starting from the memory address for a 32-bit operand size, using by the following relationship:\nEffective Address + (4 ∗ (BitOffset DIV 32))\nOr, it may access 2 bytes starting from the memory address for a 16-bit operand, using this relationship:\nEffective Address + (2 ∗ (BitOffset DIV 16))\nIt may do so even when only a single byte needs to be accessed to reach the given bit. When using this bit addressing mechanism, software should avoid referencing areas of memory close to address space holes. In particular, it should avoid references to memory-mapped I/O registers. Instead, software should use the MOV instructions to load from or store to these addresses, and use the register form of these instructions to manipulate the data.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit operands. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "CF := Bit(BitBase, BitOffset);\n", + "url": "https://www.felixcloutier.com/x86/bt" + }, + "btc": { + "instruction": "BTC", + "title": "BTC\n\t\t— Bit Test and Complement", + "opcode": "0F BB /r", + "description": "Selects the bit in a bit string (specified with the first operand, called the bit base) at the bit-position designated by the bit offset operand (second operand), stores the value of the bit in the CF flag, and complements the selected bit in the bit string. The bit base operand can be a register or a memory location; the bit offset operand can be a register or an immediate value:\nSee also: Bit(BitBase, BitOffset) on page 3-11.\nSome assemblers support immediate bit offsets larger than 31 by using the immediate bit offset field in combination with the displacement field of the memory operand. See “BT—Bit Test” in this chapter for more information on this addressing mechanism.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "CF := Bit(BitBase, BitOffset);\nBit(BitBase, BitOffset) := NOT Bit(BitBase, BitOffset);\n", + "url": "https://www.felixcloutier.com/x86/btc" + }, + "btr": { + "instruction": "BTR", + "title": "BTR\n\t\t— Bit Test and Reset", + "opcode": "0F B3 /r", + "description": "Selects the bit in a bit string (specified with the first operand, called the bit base) at the bit-position designated by the bit offset operand (second operand), stores the value of the bit in the CF flag, and clears the selected bit in the bit string to 0. The bit base operand can be a register or a memory location; the bit offset operand can be a register or an immediate value:\nSee also: Bit(BitBase, BitOffset) on page 3-11.\nSome assemblers support immediate bit offsets larger than 31 by using the immediate bit offset field in combination with the displacement field of the memory operand. See “BT—Bit Test” in this chapter for more information on this addressing mechanism.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "CF := Bit(BitBase, BitOffset);\nBit(BitBase, BitOffset) := 0;\n", + "url": "https://www.felixcloutier.com/x86/btr" + }, + "bts": { + "instruction": "BTS", + "title": "BTS\n\t\t— Bit Test and Set", + "opcode": "0F AB /r", + "description": "Selects the bit in a bit string (specified with the first operand, called the bit base) at the bit-position designated by the bit offset operand (second operand), stores the value of the bit in the CF flag, and sets the selected bit in the bit string to 1. The bit base operand can be a register or a memory location; the bit offset operand can be a register or an immediate value:\nSee also: Bit(BitBase, BitOffset) on page 3-11.\nSome assemblers support immediate bit offsets larger than 31 by using the immediate bit offset field in combination with the displacement field of the memory operand. See “BT—Bit Test” in this chapter for more information on this addressing mechanism.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "CF := Bit(BitBase, BitOffset);\nBit(BitBase, BitOffset) := 1;\n", + "url": "https://www.felixcloutier.com/x86/bts" + }, + "bzhi": { + "instruction": "BZHI", + "title": "BZHI\n\t\t— Zero High Bits Starting with Specified Bit Position", + "opcode": "VEX.LZ.0F38.W0 F5 /r BZHI r32a, r/m32, r32b", + "description": "BZHI copies the bits of the first source operand (the second operand) into the destination operand (the first operand) and clears the higher bits in the destination according to the INDEX value specified by the second source operand (the third operand). The INDEX is specified by bits 7:0 of the second source operand. The INDEX value is saturated at the value of OperandSize -1. CF is set, if the number contained in the 8 low bits of the third operand is greater than OperandSize -1.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "N := SRC2[7:0]\nDEST := SRC1\nIF (N < OperandSize)\n DEST[OperandSize-1:N] := 0\nFI\nIF (N > OperandSize - 1)\n CF := 1\nELSE\n CF := 0\nFI\n", + "url": "https://www.felixcloutier.com/x86/bzhi" + }, + "call": { + "instruction": "CALL", + "title": "CALL\n\t\t— Call Procedure", + "opcode": "E8 cw", + "description": "Saves procedure linking information on the stack and branches to the called procedure specified using the target operand. The target operand specifies the address of the first instruction in the called procedure. The operand can be an immediate value, a general-purpose register, or a memory location.\nThis instruction can be used to execute four types of calls:\nThe latter two call types (inter-privilege-level call and task switch) can only be executed in protected mode. See “Calling Procedures Using Call and RET” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for additional information on near, far, and inter-privilege-level calls. See Chapter 8, “Task Management,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for information on performing task switches with the CALL instruction.\nNear Call. When executing a near call, the processor pushes the value of the EIP register (which contains the offset of the instruction following the CALL instruction) on the stack (for use later as a return-instruction pointer). The processor then branches to the address in the current code segment specified by the target operand. The target operand specifies either an absolute offset in the code segment (an offset from the base of the code segment) or a relative offset (a signed displacement relative to the current value of the instruction pointer in the EIP register; this value points to the instruction following the CALL instruction). The CS register is not changed on near calls.\nFor a near call absolute, an absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16, r/m32, or r/m64). The operand-size attribute determines the size of the target operand (16, 32 or 64 bits). When in 64-bit mode, the operand size for near call (and all near branches) is forced to 64-bits. Absolute offsets are loaded directly into the EIP(RIP) register. If the operand size attribute is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits. When accessing an absolute offset indirectly using the stack pointer [ESP] as the base register, the base value used is the value of the ESP before the instruction executes.\nA relative offset (rel16 or rel32) is generally specified as a label in assembly code. But at the machine code level, it is encoded as a signed, 16- or 32-bit immediate value. This value is added to the value in the EIP(RIP) register. In 64-bit mode the relative offset is always a 32-bit immediate value which is sign extended to 64-bits before it is added to the value in the RIP register for the target calculation. As with absolute offsets, the operand-size attribute determines the size of the target operand (16, 32, or 64 bits). In 64-bit mode the target operand will always be 64-bits because the operand size is forced to 64-bits for near branches.\nFar Calls in Real-Address or Virtual-8086 Mode. When executing a far call in real- address or virtual-8086 mode, the processor pushes the current value of both the CS and EIP registers on the stack for use as a return-instruction pointer. The processor then performs a “far branch” to the code segment and offset specified with the target operand for the called procedure. The target operand specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). With the pointer method, the segment and offset of the called procedure is encoded in the instruction using a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address immediate. With the indirect method, the target operand specifies a memory location that contains a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address. The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The far address is loaded directly into the CS and EIP registers. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.\nFar Calls in Protected Mode. When the processor is operating in protected mode, the CALL instruction can be used to perform the following types of far calls:\nIn protected mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access rights determine the type of call operation to be performed.\nIf the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far call to the same privilege level in protected mode is very similar to one carried out in real-address or virtual-8086 mode. The target operand specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The operand- size attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment selector and its descriptor are loaded into CS register; the offset from the instruction is loaded into the EIP register.\nA call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same privilege level. Using this mechanism provides an extra level of indirection and is the preferred method of making calls between 16-bit and 32-bit code segments.\nWhen executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed through a call gate. The segment selector specified by the target operand identifies the call gate. The target operand can specify the call gate segment selector either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The processor obtains the segment selector for the new code segment and the new instruction pointer (offset) from the call gate descriptor. (The offset from the target operand is ignored when a call gate is used.)\nOn inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The segment selector for the new stack segment is specified in the TSS for the currently running task. The branch to the new code segment occurs after the stack switch. (Note that when using a call gate to perform a far call to a segment at the same privilege level, no stack switch occurs.) On the new stack, the processor pushes the segment selector and stack pointer for the calling procedure’s stack, an optional set of parameters from the calling procedures stack, and the segment selector and instruction pointer for the calling procedure’s code segment. (A value in the call gate descriptor determines how many parameters to copy to the new stack.) Finally, the processor branches to the address of the procedure being called within the new code segment.\nExecuting a task switch with the CALL instruction is similar to executing a call through a call gate. The target operand specifies the segment selector of the task gate for the new task activated by the switch (the offset in the target operand is ignored). The task gate in turn points to the TSS for the new task, which contains the segment selectors for the task’s code and stack segments. Note that the TSS also contains the EIP value for the next instruction that was to be executed before the calling task was suspended. This instruction pointer value is loaded into the EIP register to re-start the calling task.\nThe CALL instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of the task gate. See Chapter 8, “Task Management,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for information on the mechanics of a task switch.\nWhen you execute at task switch with a CALL instruction, the nested task flag (NT) is set in the EFLAGS register and the new TSS’s previous task link field is loaded with the old task’s TSS selector. Code is expected to suspend this nested task by executing an IRET instruction which, because the NT flag is set, automatically uses the previous task link to return to the calling task. (See “Task Linking” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for information on nested tasks.) Switching tasks with the CALL instruction differs in this regard from JMP instruction. JMP does not set the NT flag and therefore does not expect an IRET instruction to suspend the task.\nMixing 16-Bit and 32-Bit Calls. When making far calls between 16-bit and 32-bit code segments, use a call gate. If the far call is from a 32-bit code segment to a 16-bit code segment, the call should be made from the first 64 KBytes of the 32-bit code segment. This is because the operand-size attribute of the instruction is set to 16, so only a 16-bit return address offset can be saved. Also, the call should be made using a 16-bit call gate so that 16-bit values can be pushed on the stack. See Chapter 22, “Mixing 16-Bit and 32-Bit Code,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B, for more information.\nFar Calls in Compatibility Mode. When the processor is operating in compatibility mode, the CALL instruction can be used to perform the following types of far calls:\nNote that a CALL instruction can not be used to cause a task switch in compatibility mode since task switches are not supported in IA-32e mode.\nIn compatibility mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate) and access rights determine the type of call operation to be performed.\nIf the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far call to the same privilege level in compatibility mode is very similar to one carried out in protected mode. The target operand specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment selector and its descriptor are loaded into CS register and the offset from the instruction is loaded into the EIP register. The difference is that 64-bit mode may be entered. This specified by the L bit in the new code segment descriptor.\nNote that a 64-bit call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same privilege level. However, using this mechanism requires that the target code segment descriptor have the L bit set, causing an entry to 64-bit mode.\nWhen executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed through a 64-bit call gate. The segment selector specified by the target operand identifies the call gate. The target\noperand can specify the call gate segment selector either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The processor obtains the segment selector for the new code segment and the new instruction pointer (offset) from the 16-byte call gate descriptor. (The offset from the target operand is ignored when a call gate is used.)\nOn inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The segment selector for the new stack segment is set to NULL. The new stack pointer is specified in the TSS for the currently running task. The branch to the new code segment occurs after the stack switch. (Note that when using a call gate to perform a far call to a segment at the same privilege level, an implicit stack switch occurs as a result of entering 64-bit mode. The SS selector is unchanged, but stack segment accesses use a segment base of 0x0, the limit is ignored, and the default stack size is 64-bits. The full value of RSP is used for the offset, of which the upper 32-bits are undefined.) On the new stack, the processor pushes the segment selector and stack pointer for the calling procedure’s stack and the segment selector and instruction pointer for the calling procedure’s code segment. (Parameter copy is not supported in IA-32e mode.) Finally, the processor branches to the address of the procedure being called within the new code segment.\nNear/(Far) Calls in 64-bit Mode. When the processor is operating in 64-bit mode, the CALL instruction can be used to perform the following types of far calls:\nNote that in this mode the CALL instruction can not be used to cause a task switch in 64-bit mode since task switches are not supported in IA-32e mode.\nIn 64-bit mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate) and access rights determine the type of call operation to be performed.\nIf the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far call to the same privilege level in 64-bit mode is very similar to one carried out in compatibility mode. The target operand specifies an absolute far address indirectly with a memory location (m16:16, m16:32 or m16:64). The form of CALL with a direct specification of absolute far address is not defined in 64-bit mode. The operand-size attribute determines the size of the offset (16, 32, or 64 bits) in the far address. The new code segment selector and its descriptor are loaded into the CS register; the offset from the instruction is loaded into the EIP register. The new code segment may specify entry either into compatibility or 64-bit mode, based on the L bit value.\nA 64-bit call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same privilege level. However, using this mechanism requires that the target code segment descriptor have the L bit set.\nWhen executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed through a 64-bit call gate. The segment selector specified by the target operand identifies the call gate. The target operand can only specify the call gate segment selector indirectly with a memory location (m16:16, m16:32 or m16:64). The processor obtains the segment selector for the new code segment and the new instruction pointer (offset) from the 16-byte call gate descriptor. (The offset from the target operand is ignored when a call gate is used.)\nOn inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The segment selector for the new stack segment is set to NULL. The new stack pointer is specified in the TSS for the currently running task. The branch to the new code segment occurs after the stack switch.\nNote that when using a call gate to perform a far call to a segment at the same privilege level, an implicit stack switch occurs as a result of entering 64-bit mode. The SS selector is unchanged, but stack segment accesses use a segment base of 0x0, the limit is ignored, and the default stack size is 64-bits. (The full value of RSP is used for the offset.) On the new stack, the processor pushes the segment selector and stack pointer for the calling procedure’s stack and the segment selector and instruction pointer for the calling procedure’s code segment. (Parameter copy is not supported in IA-32e mode.) Finally, the processor branches to the address of the procedure being called within the new code segment.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions‚” and Chapter 17, “Control-flow Enforcement Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. Instructions following a far call may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the far call have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).\nInstructions sequentially following a near indirect CALL instruction (i.e., those not at the target) may be executed speculatively. If software needs to prevent this (e.g., in order to prevent a speculative execution side channel), then an LFENCE instruction opcode can be placed after the near indirect CALL in order to block speculative execution.", + "operation": "IF near call\n THEN IF near relative call\n THEN\n IF OperandSize = 64\n THEN\n tempDEST := SignExtend(DEST); (* DEST is rel32 *)\n tempRIP := RIP + tempDEST;\n IF stack not large enough for a 8-byte return address\n THEN #SS(0); FI;\n Push(RIP);\n IF ShadowStackEnabled(CPL) AND DEST != 0\n ShadowStackPush8B(RIP);\n FI;\n RIP := tempRIP;\n FI;\n IF OperandSize = 32\n THEN\n tempEIP := EIP + DEST; (* DEST is rel32 *)\n IF tempEIP is not within code segment limit THEN #GP(0); FI;\n IF stack not large enough for a 4-byte return address\n THEN #SS(0); FI;\n Push(EIP);\n IF ShadowStackEnabled(CPL) AND DEST != 0\n ShadowStackPush4B(EIP);\n FI;\n EIP := tempEIP;\n FI;\n IF OperandSize = 16\n THEN\n tempEIP := (EIP + DEST) AND 0000FFFFH; (* DEST is rel16 *)\n IF tempEIP is not within code segment limit THEN #GP(0); FI;\n IF stack not large enough for a 2-byte return address\n THEN #SS(0); FI;\n Push(IP);\n IF ShadowStackEnabled(CPL) AND DEST != 0\n (* IP is zero extended and pushed as a 32 bit value on shadow stack *)\n ShadowStackPush4B(IP);\n FI;\n EIP := tempEIP;\n FI;\n ELSE (* Near absolute call *)\n IF OperandSize = 64\n THEN\n tempRIP := DEST; (* DEST is r/m64 *)\n IF stack not large enough for a 8-byte return address\n THEN #SS(0); FI;\n Push(RIP);\n IF ShadowStackEnabled(CPL)\n ShadowStackPush8B(RIP);\n FI;\n RIP := tempRIP;\n FI;\n IF OperandSize = 32\n THEN\n tempEIP := DEST; (* DEST is r/m32 *)\n IF tempEIP is not within code segment limit THEN #GP(0); FI;\n IF stack not large enough for a 4-byte return address\n THEN #SS(0); FI;\n Push(EIP);\n IF ShadowStackEnabled(CPL)\n ShadowStackPush4B(EIP);\n FI;\n EIP := tempEIP;\n FI;\n IF OperandSize = 16\n THEN\n tempEIP := DEST AND 0000FFFFH; (* DEST is r/m16 *)\n IF tempEIP is not within code segment limit THEN #GP(0); FI;\n IF stack not large enough for a 2-byte return address\n THEN #SS(0); FI;\n Push(IP);\n IF ShadowStackEnabled(CPL)\n (* IP is zero extended and pushed as a 32 bit value on shadow stack *)\n ShadowStackPush4B(IP);\n FI;\n EIP := tempEIP;\n FI;\n FI;rel/abs\n IF (Call near indirect, absolute indirect)\n IF EndbranchEnabledAndNotSuppressed(CPL)\n IF CPL = 3\n THEN\n IF ( no 3EH prefix OR IA32_U_CET.NO_TRACK_EN == 0 )\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n FI;\n ELSE\n IF ( no 3EH prefix OR IA32_S_CET.NO_TRACK_EN == 0 )\n THEN\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n FI;\n FI;\n FI;\n FI;\nFI; near\nIF far call and (PE = 0 or (PE = 1 and VM = 1)) (* Real-address or virtual-8086 mode *)\n THEN\n IF OperandSize = 32\n THEN\n IF stack not large enough for a 6-byte return address\n THEN #SS(0); FI;\n IF DEST[31:16] is not zero THEN #GP(0); FI;\n Push(CS); (* Padded with 16 high-order bits *)\n Push(EIP);\n CS := DEST[47:32]; (* DEST is ptr16:32 or [m16:32] *)\n EIP := DEST[31:0]; (* DEST is ptr16:32 or [m16:32] *)\n ELSE (* OperandSize = 16 *)\n IF stack not large enough for a 4-byte return address\n THEN #SS(0); FI;\n Push(CS);\n Push(IP);\n CS := DEST[31:16]; (* DEST is ptr16:16 or [m16:16] *)\n EIP := DEST[15:0]; (* DEST is ptr16:16 or [m16:16]; clear upper 16 bits *)\n FI;\nFI;\nIF far call and (PE = 1 and VM = 0) (* Protected mode or IA-32e Mode, not virtual-8086 mode*)\n THEN\n IF segment selector in target operand NULL\n THEN #GP(0); FI;\n IF segment selector index not within descriptor table limits\n THEN #GP(new code segment selector); FI;\n Read type and access rights of selected segment descriptor;\n IF IA32_EFER.LMA = 0\n THEN\n IF segment type is not a conforming or nonconforming code segment, call\n gate, task gate, or TSS\n THEN #GP(segment selector); FI;\n ELSE\n IF segment type is not a conforming or nonconforming code segment or\n 64-bit call gate,\n THEN #GP(segment selector); FI;\n FI;\n Depending on type and access rights:\n GO TO CONFORMING-CODE-SEGMENT;\n GO TO NONCONFORMING-CODE-SEGMENT;\n GO TO CALL-GATE;\n GO TO TASK-GATE;\n GO TO TASK-STATE-SEGMENT;\nFI;\nCONFORMING-CODE-SEGMENT:\n IF L bit = 1 and D bit = 1 and IA32_EFER.LMA = 1\n THEN GP(new code segment selector); FI;\n IF DPL > CPL\n THEN #GP(new code segment selector); FI;\n IF segment not present\n THEN #NP(new code segment selector); FI;\n IF stack not large enough for return address\n THEN #SS(0); FI;\n tempEIP := DEST(Offset);\n IF target mode = Compatibility mode\n THEN tempEIP := tempEIP AND 00000000_FFFFFFFFH; FI;\n IF OperandSize = 16\n THEN\n tempEIP := tempEIP AND 0000FFFFH; FI; (* Clear upper 16 bits *)\n IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and (tempEIP outside new code segment limit)\n THEN #GP(0); FI;\n IF tempEIP is non-canonical\n THEN #GP(0); FI;\n IF ShadowStackEnabled(CPL)\n IF OperandSize = 32\n THEN\n tempPushLIP = CSBASE + EIP;\n ELSE\n IF OperandSize = 16\n THEN\n tempPushLIP = CSBASE + IP;\n ELSE (* OperandSize = 64 *)\n tempPushLIP = RIP;\n FI;\n FI;\n tempPushCS = CS;\n FI;\n IF OperandSize = 32\n THEN\n Push(CS); (* Padded with 16 high-order bits *)\n Push(EIP);\n CS := DEST(CodeSegmentSelector);\n (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n EIP := tempEIP;\n ELSE\n IF OperandSize = 16\n THEN\n Push(CS);\n Push(IP);\n CS := DEST(CodeSegmentSelector);\n (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n EIP := tempEIP;\n ELSE (* OperandSize = 64 *)\n Push(CS); (* Padded with 48 high-order bits *)\n Push(RIP);\n CS := DEST(CodeSegmentSelector);\n (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n RIP := tempEIP;\n FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF (IA32_EFER.LMA and DEST(CodeSegmentSelector).L) = 0\n (* If target is legacy or compatibility mode then the SSP must be in low 4GB *)\n IF (SSP & 0xFFFFFFFF00000000 != 0)\n THEN #GP(0); FI;\n FI;\n (* align to 8 byte boundary if not already aligned *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (SSP – 4)\n SSP = SSP & 0xFFFFFFFFFFFFFFF8H\n ShadowStackPush8B(tempPushCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(tempPushLIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled(CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\nEND;\nNONCONFORMING-CODE-SEGMENT:\n IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1\n THEN GP(new code segment selector); FI;\n IF (RPL > CPL) or (DPL ≠ CPL)\n THEN #GP(new code segment selector); FI;\n IF segment not present\n THEN #NP(new code segment selector); FI;\n IF stack not large enough for return address\n THEN #SS(0); FI;\n tempEIP := DEST(Offset);\n IF target mode = Compatibility mode\n THEN tempEIP := tempEIP AND 00000000_FFFFFFFFH; FI;\n IF OperandSize = 16\n THEN tempEIP := tempEIP AND 0000FFFFH; FI; (* Clear upper 16 bits *)\n IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and (tempEIP outside new code segment limit)\n THEN #GP(0); FI;\n IF tempEIP is non-canonical\n THEN #GP(0); FI;\n IF ShadowStackEnabled(CPL)\n IF IA32_EFER.LMA & CS.L\n tempPushLIP = RIP\n ELSE\n tempPushLIP = CSBASE + EIP;\n FI;\n tempPushCS = CS;\n FI;\n IF OperandSize = 32\n THEN\n Push(CS); (* Padded with 16 high-order bits *)\n Push(EIP);\n CS := DEST(CodeSegmentSelector);\n (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n EIP := tempEIP;\n ELSE\n IF OperandSize = 16\n THEN\n Push(CS);\n Push(IP);\n CS := DEST(CodeSegmentSelector);\n (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n EIP := tempEIP;\n ELSE (* OperandSize = 64 *)\n Push(CS); (* Padded with 48 high-order bits *)\n Push(RIP);\n CS := DEST(CodeSegmentSelector);\n (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n RIP := tempEIP;\n FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF (IA32_EFER.LMA and DEST(CodeSegmentSelector).L) = 0\n (* If target is legacy or compatibility mode then the SSP must be in low 4GB *)\n IF (SSP & 0xFFFFFFFF00000000 != 0)\n THEN #GP(0); FI;\n FI;\n (* align to 8 byte boundary if not already aligned *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (SSP – 4)\n SSP = SSP & 0xFFFFFFFFFFFFFFF8H\n ShadowStackPush8B(tempPushCS); (* Padded with 48 high-order 0 bits *)\n ShadowStackPush8B(tempPushLIP); (* Padded 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled(CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\nEND;\nCALL-GATE:\n IF call gate (DPL < CPL) or (RPL > DPL)\n THEN #GP(call-gate selector); FI;\n IF call gate not present\n THEN #NP(call-gate selector); FI;\n IF call-gate code-segment selector is NULL\n THEN #GP(0); FI;\n IF call-gate code-segment selector index is outside descriptor table limits\n THEN #GP(call-gate code-segment selector); FI;\n Read call-gate code-segment descriptor;\n IF call-gate code-segment descriptor does not indicate a code segment\n or call-gate code-segment descriptor DPL > CPL\n THEN #GP(call-gate code-segment selector); FI;\n IF IA32_EFER.LMA = 1 AND (call-gate code-segment descriptor is\n not a 64-bit code segment or call-gate code-segment descriptor has both L-bit and D-bit set)\n THEN #GP(call-gate code-segment selector); FI;\n IF call-gate code segment not present\n THEN #NP(call-gate code-segment selector); FI;\n IF call-gate code segment is non-conforming and DPL < CPL\n THEN go to MORE-PRIVILEGE;\n ELSE go to SAME-PRIVILEGE;\n FI;\nEND;\nMORE-PRIVILEGE:\n IF current TSS is 32-bit\n THEN\n TSSstackAddress := (new code-segment DPL ∗ 8) + 4;\n IF (TSSstackAddress + 5) > current TSS limit\n THEN #TS(current TSS selector); FI;\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);\n NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);\n ELSE\n IF current TSS is 16-bit\n THEN\n TSSstackAddress := (new code-segment DPL ∗ 4) + 2\n IF (TSSstackAddress + 3) > current TSS limit\n THEN #TS(current TSS selector); FI;\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);\n NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);\n ELSE (* current TSS is 64-bit *)\n TSSstackAddress := (new code-segment DPL ∗ 8) + 4;\n IF (TSSstackAddress + 7) > current TSS limit\n THEN #TS(current TSS selector); FI;\n NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n FI;\n FI;\n IF IA32_EFER.LMA = 0 and NewSS is NULL\n THEN #TS(NewSS); FI;\n Read new stack-segment descriptor;\n IF IA32_EFER.LMA = 0 and (NewSS RPL ≠ new code-segment DPL\n or new stack-segment DPL ≠ new code-segment DPL or new stack segment is not a\n writable data segment)\n THEN #TS(NewSS); FI\n IF IA32_EFER.LMA = 0 and new stack segment not present\n THEN #SS(NewSS); FI;\n IF CallGateSize = 32\n THEN\n IF new stack does not have room for parameters plus 16 bytes\n THEN #SS(NewSS); FI;\n IF CallGate(InstructionPointer) not within new code-segment limit\n THEN #GP(0); FI;\n SS:=newSS; (*Segmentdescriptorinformationalsoloaded*)\n ESP := newESP;\n CS:EIP := CallGate(CS:InstructionPointer);\n (* Segment descriptor information also loaded *)\n Push(oldSS:oldESP); (* From calling procedure *)\n temp := parameter count from call gate, masked to 5 bits;\n Push(parameters from calling procedure’s stack, temp)\n Push(oldCS:oldEIP); (* Return address to calling procedure *)\n ELSE\n IF CallGateSize = 16\n THEN\n IF new stack does not have room for parameters plus 8 bytes\n THEN #SS(NewSS); FI;\n IF (CallGate(InstructionPointer) AND FFFFH) not in new code-segment limit\n THEN #GP(0); FI;\n SS:=newSS; (*Segmentdescriptorinformationalsoloaded*)\n ESP := newESP;\n CS:IP := CallGate(CS:InstructionPointer);\n (* Segment descriptor information also loaded *)\n Push(oldSS:oldESP); (* From calling procedure *)\n temp := parameter count from call gate, masked to 5 bits;\n Push(parameters from calling procedure’s stack, temp)\n Push(oldCS:oldEIP); (* Return address to calling procedure *)\n ELSE (* CallGateSize = 64 *)\n IF pushing 32 bytes on the stack would use a non-canonical address\n THEN #SS(NewSS); FI;\n IF (CallGate(InstructionPointer) is non-canonical)\n THEN #GP(0); FI;\n SS := NewSS; (* NewSS is NULL)\n RSP := NewESP;\n CS:IP := CallGate(CS:InstructionPointer);\n (* Segment descriptor information also loaded *)\n Push(oldSS:oldESP); (* From calling procedure *)\n Push(oldCS:oldEIP); (* Return address to calling procedure *)\n FI;\n FI;\n IF ShadowStackEnabled(CPL) AND CPL = 3\n THEN\n IF IA32_EFER.LMA = 0\n THEN IA32_PL3_SSP := SSP;\n ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n FI;\n FI;\n CPL := CodeSegment(DPL)\n CS(RPL) := CPL\n IF ShadowStackEnabled(CPL)\n oldSSP := SSP\n SSP := IA32_PLi_SSP; (* where i is the CPL *)\n IF SSP & 0x07 != 0 (* if SSP not aligned to 8 bytes then #GP *)\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region*)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n IF oldSS.DPL != 3\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE+oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(oldSSP);\n FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\nEND;\nSAME-PRIVILEGE:\n IF CallGateSize = 32\n THEN\n IF stack does not have room for 8 bytes\n THEN #SS(0); FI;\n IF CallGate(InstructionPointer) not within code segment limit\n THEN #GP(0); FI;\n CS:EIP := CallGate(CS:EIP) (* Segment descriptor information also loaded *)\n Push(oldCS:oldEIP); (* Return address to calling procedure *)\n ELSE\n If CallGateSize = 16\n THEN\n IF stack does not have room for 4 bytes\n THEN #SS(0); FI;\n IF CallGate(InstructionPointer) not within code segment limit\n THEN #GP(0); FI;\n CS:IP := CallGate(CS:instruction pointer);\n (* Segment descriptor information also loaded *)\n Push(oldCS:oldIP); (* Return address to calling procedure *)\n ELSE (* CallGateSize = 64)\n IF pushing 16 bytes on the stack touches non-canonical addresses\n THEN #SS(0); FI;\n IF RIP non-canonical\n THEN #GP(0); FI;\n CS:IP := CallGate(CS:instruction pointer);\n (* Segment descriptor information also loaded *)\n Push(oldCS:oldIP); (* Return address to calling procedure *)\n FI;\n FI;\n CS(RPL) := CPL\n IF ShadowStackEnabled(CPL)\n (* Align to next 8 byte boundary *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (SSP – 4)\n SSP = SSP & 0xFFFFFFFFFFFFFFF8H;\n (* push cs:lip:ssp on shadow stack *)\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled (CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\nEND;\nTASK-GATE:\n IF task gate DPL < CPL or RPL\n THEN #GP(task gate selector); FI;\n IF task gate not present\n THEN #NP(task gate selector); FI;\n Read the TSS segment selector in the task-gate descriptor;\n IF TSS segment selector local/global bit is set to local\n or index not within GDT limits\n THEN #GP(TSS selector); FI;\n Access TSS descriptor in GDT;\n IF descriptor is not a TSS segment\n THEN #GP(TSS selector); FI;\n IF TSS descriptor specifies that the TSS is busy\n THEN #GP(TSS selector); FI;\n IF TSS not present\n THEN #NP(TSS selector); FI;\n SWITCH-TASKS (with nesting) to TSS;\n IF EIP not within code segment limit\n THEN #GP(0); FI;\nEND;\nTASK-STATE-SEGMENT:\n IF TSS DPL < CPL or RPL\n or TSS descriptor indicates TSS not available\n THEN #GP(TSS selector); FI;\n IF TSS is not present\n THEN #NP(TSS selector); FI;\n SWITCH-TASKS (with nesting) to TSS;\n IF EIP not within code segment limit\n THEN #GP(0); FI;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/call" + }, + "capabilities": { + "instruction": "CAPABILITIES", + "title": "GETSEC[CAPABILITIES]\n\t\t— Report the SMX Capabilities", + "opcode": "NP 0F 37 (EAX = 0)", + "description": "The GETSEC[CAPABILITIES] function returns a bit vector of supported GETSEC leaf functions. The CAPABILITIES leaf of GETSEC is selected with EAX set to 0 at entry. EBX is used as the selector for returning the bit vector field in EAX. GETSEC[CAPABILITIES] may be executed at all privilege levels, but the CR4.SMXE bit must be set or an undefined opcode exception (#UD) is returned.\nWith EBX = 0 upon execution of GETSEC[CAPABILITIES], EAX returns the a bit vector representing status on the presence of a Intel® TXT-capable chipset and the first 30 available GETSEC leaf functions. The format of the returned bit vector is provided in Table 7-3.\nIf bit 0 is set to 1, then an Intel® TXT-capable chipset has been sampled present by the processor. If bits in the range of 1-30 are set, then the corresponding GETSEC leaf function is available. If the bit value at a given bit index is 0, then the GETSEC leaf function corresponding to that index is unsupported and attempted execution results in a #UD.\nBit 31 of EAX indicates if further leaf indexes are supported. If the Extended Leafs bit 31 is set, then additional leaf functions are accessed by repeating GETSEC[CAPABILITIES] with EBX incremented by one. When the most significant bit of EAX is not set, then additional GETSEC leaf functions are not supported; indexing EBX to a higher value results in EAX returning zero.", + "operation": "IF (CR4.SMXE=0)\n THEN #UD;\nELSIF (in VMX non-root operation)\n THEN VM Exit (reason=”GETSEC instruction”);\nIF (EBX=0) THEN\n BitVector := 0;\n IF (TXT chipset present)\n BitVector[Chipset present] := 1;\n IF (ENTERACCS Available)\n THEN BitVector[ENTERACCS] := 1;\n IF (EXITAC Available)\n THEN BitVector[EXITAC] := 1;\n IF (SENTER Available)\n THEN BitVector[SENTER] := 1;\n IF (SEXIT Available)\n THEN BitVector[SEXIT] := 1;\n IF (PARAMETERS Available)\n THEN BitVector[PARAMETERS] := 1;\n IF (SMCTRL Available)\n THEN BitVector[SMCTRL] := 1;\n IF (WAKEUP Available)\n THEN BitVector[WAKEUP] := 1;\n EAX := BitVector;\nELSE\n EAX := 0;\nEND;;\n", + "url": "https://www.felixcloutier.com/x86/capabilities" + }, + "cbw": { + "instruction": "CBW", + "title": "CBW/CWDE/CDQE\n\t\t— Convert Byte to Word/Convert Word to Doubleword/Convert Doubleword toQuadword", + "opcode": "98", + "description": "Double the size of the source operand by means of sign extension. The CBW (convert byte to word) instruction copies the sign (bit 7) in the source operand into every bit in the AH register. The CWDE (convert word to double-word) instruction copies the sign (bit 15) of the word in the AX register into the high 16 bits of the EAX register.\nCBW and CWDE reference the same opcode. The CBW instruction is intended for use when the operand-size attribute is 16; CWDE is intended for use when the operand-size attribute is 32. Some assemblers may force the operand size. Others may treat these two mnemonics as synonyms (CBW/CWDE) and use the setting of the operand-size attribute to determine the size of values to be converted.\nIn 64-bit mode, the default operation size is the size of the destination register. Use of the REX.W prefix promotes this instruction (CDQE when promoted) to operate on 64-bit operands. In which case, CDQE copies the sign (bit 31) of the doubleword in the EAX register into the high 32 bits of RAX.", + "operation": "IF OperandSize = 16 (* Instruction = CBW *)\n THEN\n AX := SignExtend(AL);\n ELSE IF (OperandSize = 32, Instruction = CWDE)\n EAX := SignExtend(AX); FI;\n ELSE (* 64-Bit Mode, OperandSize = 64, Instruction = CDQE*)\n RAX := SignExtend(EAX);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cbw:cwde:cdqe" + }, + "cdq": { + "instruction": "CDQ", + "title": "CWD/CDQ/CQO\n\t\t— Convert Word to Doubleword/Convert Doubleword to Quadword", + "opcode": "99", + "description": "Doubles the size of the operand in register AX, EAX, or RAX (depending on the operand size) by means of sign extension and stores the result in registers DX:AX, EDX:EAX, or RDX:RAX, respectively. The CWD instruction copies the sign (bit 15) of the value in the AX register into every bit position in the DX register. The CDQ instruction copies the sign (bit 31) of the value in the EAX register into every bit position in the EDX register. The CQO instruction (available in 64-bit mode only) copies the sign (bit 63) of the value in the RAX register into every bit position in the RDX register.\nThe CWD instruction can be used to produce a doubleword dividend from a word before word division. The CDQ instruction can be used to produce a quadword dividend from a doubleword before doubleword division. The CQO instruction can be used to produce a double quadword dividend from a quadword before a quadword division.\nThe CWD and CDQ mnemonics reference the same opcode. The CWD instruction is intended for use when the operand-size attribute is 16 and the CDQ instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when CWD is used and to 32 when CDQ is used. Others may treat these mnemonics as synonyms (CWD/CDQ) and use the current setting of the operand-size attribute to determine the size of values to be converted, regardless of the mnemonic used.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. The CQO mnemonics reference the same opcode as CWD/CDQ. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 16 (* CWD instruction *)\n THEN\n DX := SignExtend(AX);\n ELSE IF OperandSize = 32 (* CDQ instruction *)\n EDX := SignExtend(EAX); FI;\n ELSE IF 64-Bit Mode and OperandSize = 64 (* CQO instruction*)\n RDX := SignExtend(RAX); FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cwd:cdq:cqo" + }, + "cdqe": { + "instruction": "CDQE", + "title": "CBW/CWDE/CDQE\n\t\t— Convert Byte to Word/Convert Word to Doubleword/Convert Doubleword toQuadword", + "opcode": "REX.W + 98", + "description": "Double the size of the source operand by means of sign extension. The CBW (convert byte to word) instruction copies the sign (bit 7) in the source operand into every bit in the AH register. The CWDE (convert word to double-word) instruction copies the sign (bit 15) of the word in the AX register into the high 16 bits of the EAX register.\nCBW and CWDE reference the same opcode. The CBW instruction is intended for use when the operand-size attribute is 16; CWDE is intended for use when the operand-size attribute is 32. Some assemblers may force the operand size. Others may treat these two mnemonics as synonyms (CBW/CWDE) and use the setting of the operand-size attribute to determine the size of values to be converted.\nIn 64-bit mode, the default operation size is the size of the destination register. Use of the REX.W prefix promotes this instruction (CDQE when promoted) to operate on 64-bit operands. In which case, CDQE copies the sign (bit 31) of the doubleword in the EAX register into the high 32 bits of RAX.", + "operation": "IF OperandSize = 16 (* Instruction = CBW *)\n THEN\n AX := SignExtend(AL);\n ELSE IF (OperandSize = 32, Instruction = CWDE)\n EAX := SignExtend(AX); FI;\n ELSE (* 64-Bit Mode, OperandSize = 64, Instruction = CDQE*)\n RAX := SignExtend(EAX);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cbw:cwde:cdqe" + }, + "clac": { + "instruction": "CLAC", + "title": "CLAC\n\t\t— Clear AC Flag in EFLAGS Register", + "opcode": "NP 0F 01 CA CLAC", + "description": "Clears the AC flag bit in EFLAGS register. This disables any alignment checking of user-mode data accesses. Ifthe SMAP bit is set in the CR4 register, this disallows explicit supervisor-mode data accesses to user-mode pages.\nThis instruction's operation is the same in non-64-bit modes and 64-bit mode. Attempts to execute CLAC when CPL > 0 cause #UD.", + "operation": "EFLAGS.AC := 0;\n", + "url": "https://www.felixcloutier.com/x86/clac" + }, + "clc": { + "instruction": "CLC", + "title": "CLC\n\t\t— Clear Carry Flag", + "opcode": "F8", + "description": "Clears the CF flag in the EFLAGS register. Operation is the same in all modes.", + "operation": "CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/clc" + }, + "cld": { + "instruction": "CLD", + "title": "CLD\n\t\t— Clear Direction Flag", + "opcode": "FC", + "description": "Clears the DF flag in the EFLAGS register. When the DF flag is set to 0, string operations increment the index registers (ESI and/or EDI). Operation is the same in all modes.", + "operation": "DF := 0;\n", + "url": "https://www.felixcloutier.com/x86/cld" + }, + "cldemote": { + "instruction": "CLDEMOTE", + "title": "CLDEMOTE\n\t\t— Cache Line Demote", + "opcode": "NP 0F 1C /0 CLDEMOTE m8", + "description": "Hints to hardware that the cache line that contains the linear address specified with the memory operand should be moved (“demoted”) from the cache(s) closest to the processor core to a level more distant from the processor core. This may accelerate subsequent accesses to the line by other cores in the same coherence domain, especially if the line was written by the core that demotes the line. Moving the line in such a manner is a performance optimization, i.e., it is a hint which does not modify architectural state. Hardware may choose which level in the cache hierarchy to retain the line (e.g., L3 in typical server designs). The source operand is a byte memory location.\nThe availability of the CLDEMOTE instruction is indicated by the presence of the CPUID feature flag CLDEMOTE (bit 25 of the ECX register in sub-leaf 07H, see “CPUID—CPU Identification”). On processors which do not support the CLDEMOTE instruction (including legacy hardware) the instruction will be treated as a NOP.\nA CLDEMOTE instruction is ordered with respect to stores to the same cache line, but unordered with respect to other instructions including memory fences, CLDEMOTE, CLWB or CLFLUSHOPT instructions to a different cache line. Since CLDEMOTE will retire in order with respect to stores to the same cache line, software should ensure that after issuing CLDEMOTE the line is not accessed again immediately by the same core to avoid cache data movement penalties.\nThe effective memory type of the page containing the affected line determines the effect; cacheable types are likely to generate a data movement operation, while uncacheable types may cause the instruction to be ignored.\nSpeculative fetching can occur at any time and is not tied to instruction execution. The CLDEMOTE instruction is not ordered with respect to PREFETCHh instructions or any of the speculative fetching mechanisms. That is, data can be speculatively loaded into a cache line just before, during, or after the execution of a CLDEMOTE instruction that references the cache line.\nUnlike CLFLUSH, CLFLUSHOPT, and CLWB instructions, CLDEMOTE is not guaranteed to write back modified data to memory.\nThe CLDEMOTE instruction may be ignored by hardware in certain cases and is not a guarantee.\nThe CLDEMOTE instruction can be used at all privilege levels. In certain processor implementations the CLDEMOTE instruction may set the A bit but not the D bit in the page tables.\nIf the line is not found in the cache, the instruction will be treated as a NOP.\nIn some implementations, the CLDEMOTE instruction may always cause a transactional abort with Transactional Synchronization Extensions (TSX). However, programmers must not rely on CLDEMOTE instruction to force a transactional abort.", + "operation": "Cache_Line_Demote(m8);\n", + "url": "https://www.felixcloutier.com/x86/cldemote" + }, + "clflush": { + "instruction": "CLFLUSH", + "title": "CLFLUSH\n\t\t— Flush Cache Line", + "opcode": "NP 0F AE /7 CLFLUSH m8", + "description": "Invalidates from every level of the cache hierarchy in the cache coherence domain the cache line that contains the linear address specified with the memory operand. If that cache line contains modified data at any level of the cache hierarchy, that data is written back to memory. The source operand is a byte memory location.\nThe availability of CLFLUSH is indicated by the presence of the CPUID feature flag CLFSH (CPUID.01H:EDX[bit 19]). The aligned cache line size affected is also indicated with the CPUID instruction (bits 8 through 15 of the EBX register when the initial value in the EAX register is 1).\nThe memory attribute of the page containing the affected line has no effect on the behavior of this instruction. It should be noted that processors are free to speculatively fetch and cache data from system memory regions assigned a memory-type allowing for speculative reads (such as, the WB, WC, and WT memory types). PREFETCHh instructions can be used to provide the processor with hints for this speculative behavior. Because this speculative fetching can occur at any time and is not tied to instruction execution, the CLFLUSH instruction is not ordered with respect to PREFETCHh instructions or any of the speculative fetching mechanisms (that is, data can be speculatively loaded into a cache line just before, during, or after the execution of a CLFLUSH instruction that references the cache line).\nExecutions of the CLFLUSH instruction are ordered with respect to each other and with respect to writes, locked read-modify-write instructions, and fence instructions.1 They are not ordered with respect to executions of CLFLUSHOPT and CLWB. Software can use the SFENCE instruction to order an execution of CLFLUSH relative to one of those operations.\nThe CLFLUSH instruction can be used at all privilege levels and is subject to all permission checking and faults associated with a byte load (and in addition, a CLFLUSH instruction is allowed to flush a linear address in an execute-only segment). Like a load, the CLFLUSH instruction sets the A bit but not the D bit in the page tables.\nIn some implementations, the CLFLUSH instruction may always cause transactional abort with Transactional Synchronization Extensions (TSX). The CLFLUSH instruction is not expected to be commonly used inside typical transactional regions. However, programmers must not rely on CLFLUSH instruction to force a transactional abort, since whether they cause transactional abort is implementation dependent.\nThe CLFLUSH instruction was introduced with the SSE2 extensions; however, because it has its own CPUID feature flag, it can be implemented in IA-32 processors that do not include the SSE2 extensions. Also, detecting the presence of the SSE2 extensions with the CPUID instruction does not guarantee that the CLFLUSH instruction is implemented in the processor.\nCLFLUSH operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "Flush_Cache_Line(SRC);\n", + "url": "https://www.felixcloutier.com/x86/clflush" + }, + "clflushopt": { + "instruction": "CLFLUSHOPT", + "title": "CLFLUSHOPT\n\t\t— Flush Cache Line Optimized", + "opcode": "NFx 66 0F AE /7 CLFLUSHOPT m8", + "description": "Invalidates from every level of the cache hierarchy in the cache coherence domain the cache line that contains the linear address specified with the memory operand. If that cache line contains modified data at any level of the cache hierarchy, that data is written back to memory. The source operand is a byte memory location.\nThe availability of CLFLUSHOPT is indicated by the presence of the CPUID feature flag CLFLUSHOPT (CPUID.(EAX=07H,ECX=0H):EBX[bit 23]). The aligned cache line size affected is also indicated with the CPUID instruction (bits 8 through 15 of the EBX register when the initial value in the EAX register is 1).\nThe memory attribute of the page containing the affected line has no effect on the behavior of this instruction. It should be noted that processors are free to speculatively fetch and cache data from system memory regions assigned a memory-type allowing for speculative reads (such as, the WB, WC, and WT memory types). PREFETCHh instructions can be used to provide the processor with hints for this speculative behavior. Because this speculative fetching can occur at any time and is not tied to instruction execution, the CLFLUSH instruction is not ordered with respect to PREFETCHh instructions or any of the speculative fetching mechanisms (that is, data can be speculatively loaded into a cache line just before, during, or after the execution of a CLFLUSH instruction that references the cache line).\nExecutions of the CLFLUSHOPT instruction are ordered with respect to fence instructions and to locked read-modify-write instructions; they are also ordered with respect to older writes to the cache line being invalidated. They are not ordered with respect to other executions of CLFLUSHOPT, to executions of CLFLUSH and CLWB, or to younger writes to the cache line being invalidated. Software can use the SFENCE instruction to order an execution of CLFLUSHOPT relative to one of those operations.\nThe CLFLUSHOPT instruction can be used at all privilege levels and is subject to all permission checking and faults associated with a byte load (and in addition, a CLFLUSHOPT instruction is allowed to flush a linear address in an execute-only segment). Like a load, the CLFLUSHOPT instruction sets the A bit but not the D bit in the page tables.\nIn some implementations, the CLFLUSHOPT instruction may always cause transactional abort with Transactional Synchronization Extensions (TSX). The CLFLUSHOPT instruction is not expected to be commonly used inside typical transactional regions. However, programmers must not rely on CLFLUSHOPT instruction to force a transactional abort, since whether they cause transactional abort is implementation dependent.\nCLFLUSHOPT operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "Flush_Cache_Line_Optimized(SRC);\n", + "url": "https://www.felixcloutier.com/x86/clflushopt" + }, + "cli": { + "instruction": "CLI", + "title": "CLI\n\t\t— Clear Interrupt Flag", + "opcode": "FA", + "description": "In most cases, CLI clears the IF flag in the EFLAGS register and no other flags are affected. Clearing the IF flag causes the processor to ignore maskable external interrupts. The IF flag and the CLI and STI instruction have no effect on the generation of exceptions and NMI interrupts.\nOperation is different in two modes defined as follows:\nIf IOPL < 3 and either VME mode or PVI mode is active, CLI clears the VIF flag in the EFLAGS register, leaving IF unaffected.\nTable 3-7 indicates the action of the CLI instruction depending on the processor operating mode, IOPL, and CPL.", + "operation": "IF CR0.PE = 0\n THEN IF := 0; (* Reset Interrupt Flag *)\n ELSE\n IF IOPL ≥ CPL (* CPL = 3 if EFLAGS.VM = 1 *)\n THEN IF := 0; (* Reset Interrupt Flag *)\n ELSE\n IF VME mode OR PVI mode\n THEN VIF := 0; (* Reset Virtual Interrupt Flag *)\n ELSE #GP(0);\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cli" + }, + "clrssbsy": { + "instruction": "CLRSSBSY", + "title": "CLRSSBSY\n\t\t— Clear Busy Flag in a Supervisor Shadow Stack Token", + "opcode": "F3 0F AE /6 CLRSSBSY m64", + "description": "Clear busy flag in supervisor shadow stack token reference by m64. Subsequent to marking the shadow stack as not busy the SSP is loaded with value 0.", + "operation": "IF (CR4.CET = 0)\n THEN #UD; FI;\nIF (IA32_S_CET.SH_STK_EN = 0)\n THEN #UD; FI;\nIF CPL > 0\n THEN GP(0); FI;\nSSP_LA = Linear_Address(mem operand)\nIF SSP_LA not aligned to 8 bytes\n THEN #GP(0); FI;\nexpected_token_value=SSP_LA|BUSY_BIT (*busybit-bitposition0-mustbeset*)\nnew_token_value = SSP_LA (* Clear the busy bit *)\nIF shadow_stack_lock_cmpxchg8b(SSP_LA, new_token_value, expected_token_value) != expected_token_value\n invalid_token := 1; FI\n(* Set the CF if invalid token was detected *)\nRFLAGS.CF = (invalid_token == 1) ? 1 : 0;\nRFLAGS.ZF,PF,AF,OF,SF := 0;\nSSP := 0\n", + "url": "https://www.felixcloutier.com/x86/clrssbsy" + }, + "clts": { + "instruction": "CLTS", + "title": "CLTS\n\t\t— Clear Task-Switched Flag in CR0", + "opcode": "0F 06", + "description": "Clears the task-switched (TS) flag in the CR0 register. This instruction is intended for use in operating-system procedures. It is a privileged instruction that can only be executed at a CPL of 0. It is allowed to be executed in real-address mode to allow initialization for protected mode.\nThe processor sets the TS flag every time a task switch occurs. The flag is used to synchronize the saving of FPU context in multitasking applications. See the description of the TS flag in the section titled “Control Registers” in Chapter 2 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for more information about this flag.\nCLTS operation is the same in non-64-bit modes and 64-bit mode.\nSee Chapter 26, “VMX Non-Root Operation,” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "CR0.TS[bit 3] := 0;\n", + "url": "https://www.felixcloutier.com/x86/clts" + }, + "clui": { + "instruction": "CLUI", + "title": "CLUI\n\t\t— Clear User Interrupt Flag", + "opcode": "F3 0F 01 EE CLUI", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/clui" + }, + "clwb": { + "instruction": "CLWB", + "title": "CLWB\n\t\t— Cache Line Write Back", + "opcode": "66 0F AE /6 CLWB m8", + "description": "Writes back to memory the cache line (if modified) that contains the linear address specified with the memory operand from any level of the cache hierarchy in the cache coherence domain. The line may be retained in the cache hierarchy in non-modified state. Retaining the line in the cache hierarchy is a performance optimization (treated as a hint by hardware) to reduce the possibility of cache miss on a subsequent access. Hardware may choose to retain the line at any of the levels in the cache hierarchy, and in some cases, may invalidate the line from the cache hierarchy. The source operand is a byte memory location.\nThe availability of CLWB instruction is indicated by the presence of the CPUID feature flag CLWB (bit 24 of the EBX register, see “CPUID — CPU Identification” in this chapter). The aligned cache line size affected is also indicated with the CPUID instruction (bits 8 through 15 of the EBX register when the initial value in the EAX register is 1).\nThe memory attribute of the page containing the affected line has no effect on the behavior of this instruction. It should be noted that processors are free to speculatively fetch and cache data from system memory regions that are assigned a memory-type allowing for speculative reads (such as, the WB, WC, and WT memory types). PREFETCHh instructions can be used to provide the processor with hints for this speculative behavior. Because this speculative fetching can occur at any time and is not tied to instruction execution, the CLWB instruction is not ordered with respect to PREFETCHh instructions or any of the speculative fetching mechanisms (that is, data can be speculatively loaded into a cache line just before, during, or after the execution of a CLWB instruction that references the cache line).\nExecutions of the CLWB instruction are ordered with respect to fence instructions and to locked read-modify-write instructions; they are also ordered with respect to older writes to the cache line being written back. They are not ordered with respect to other executions of CLWB, to executions of CLFLUSH and CLFLUSHOPT, or to younger writes to the cache line being written back. Software can use the SFENCE instruction to order an execution of CLWB relative to one of those operations.\nFor usages that require only writing back modified data from cache lines to memory (do not require the line to be invalidated), and expect to subsequently access the data, software is recommended to use CLWB (with appropriate fencing) instead of CLFLUSH or CLFLUSHOPT for improved performance.\nThe CLWB instruction can be used at all privilege levels and is subject to all permission checking and faults associated with a byte load. Like a load, the CLWB instruction sets the accessed flag but not the dirty flag in the page tables.\nIn some implementations, the CLWB instruction may always cause transactional abort with Transactional Synchronization Extensions (TSX). CLWB instruction is not expected to be commonly used inside typical transactional regions. However, programmers must not rely on CLWB instruction to force a transactional abort, since whether they cause transactional abort is implementation dependent.", + "operation": "Cache_Line_Write_Back(m8);\n", + "url": "https://www.felixcloutier.com/x86/clwb" + }, + "cmc": { + "instruction": "CMC", + "title": "CMC\n\t\t— Complement Carry Flag", + "opcode": "F5", + "description": "Complements the CF flag in the EFLAGS register. CMC operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "EFLAGS.CF[bit 0] := NOT EFLAGS.CF[bit 0];\n", + "url": "https://www.felixcloutier.com/x86/cmc" + }, + "cmovcc": { + "instruction": "CMOVCC", + "title": "CMOVcc\n\t\t— Conditional Move", + "opcode": "0F 47 /r", + "description": "Each of the CMOVcc instructions performs a move operation if the status flags in the EFLAGS register (CF, OF, PF, SF, and ZF) are in a specified state (or condition). A condition code (cc) is associated with each instruction to indicate the condition being tested for. If the condition is not satisfied, a move is not performed and execution continues with the instruction following the CMOVcc instruction.\nSpecifically, CMOVcc loads data from its source operand into a temporary register unconditionally (regardless of the condition code and the status flags in the EFLAGS register). If the condition code associated with the instruction (cc) is satisfied, the data in the temporary register is then copied into the instruction's destination operand.\nThese instructions can move 16-bit, 32-bit or 64-bit values from memory to a general-purpose register or from one general-purpose register to another. Conditional moves of 8-bit register operands are not supported.\nThe condition for each CMOVcc mnemonic is given in the description column of the above table. The terms “less” and “greater” are used for comparisons of signed integers and the terms “above” and “below” are used for unsigned integers.\nBecause a particular state of the status flags can sometimes be interpreted in two ways, two mnemonics are defined for some opcodes. For example, the CMOVA (conditional move if above) instruction and the CMOVNBE (conditional move if not below or equal) instruction are alternate mnemonics for the opcode 0F 47H.\nThe CMOVcc instructions were introduced in P6 family processors; however, these instructions may not be supported by all IA-32 processors. Software can determine if the CMOVcc instructions are supported by checking the processor’s feature information with the CPUID instruction (see “CPUID—CPU Identification” in this chapter).\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "temp := SRC\nIF condition TRUE\n THEN DEST := temp;\nELSE IF (OperandSize = 32 and IA-32e mode active)\n THEN DEST[63:32] := 0;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmovcc" + }, + "cmp": { + "instruction": "CMP", + "title": "CMP\n\t\t— Compare Two Operands", + "opcode": "3C ib", + "description": "Compares the first source operand with the second source operand and sets the status flags in the EFLAGS register according to the results. The comparison is performed by subtracting the second operand from the first operand and then setting the status flags in the same manner as the SUB instruction. When an immediate value is used as an operand, it is sign-extended to the length of the first operand.\nThe condition codes used by the Jcc, CMOVcc, and SETcc instructions are based on the results of a CMP instruction. Appendix B, “EFLAGS Condition Codes,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, shows the relationship of the status flags and the condition codes.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "temp := SRC1 − SignExtend(SRC2);\nModifyStatusFlags; (* Modify status flags in the same manner as the SUB instruction*)\n", + "url": "https://www.felixcloutier.com/x86/cmp" + }, + "cmppd": { + "instruction": "CMPPD", + "title": "CMPPD\n\t\t— Compare Packed Double Precision Floating-Point Values", + "opcode": "66 0F C2 /r ib CMPPD xmm1, xmm2/m128, imm8", + "description": "Performs a SIMD compare of the packed double precision floating-point values in the second source operand and the first source operand and returns the result of the comparison to the destination operand. The comparison predicate operand (immediate byte) specifies the type of comparison performed on each pair of packed values in the two source operands.\nEVEX encoded versions: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand (first operand) is an opmask register. Comparison results are written to the destination operand under the writemask k2. Each comparison result is a single mask bit of 1 (comparison true) or 0 (comparison false).\nVEX.256 encoded version: The first source operand (second operand) is a YMM register. The second source operand (third operand) can be a YMM register or a 256-bit memory location. The destination operand (first operand) is a YMM register. Four comparisons are performed with results written to the destination operand. The result of each comparison is a quadword mask of all 1s (comparison true) or all 0s (comparison false).\n128-bit Legacy SSE version: The first source and destination operand (first operand) is an XMM register. The second source operand (second operand) can be an XMM register or 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged. Two comparisons are performed with results written to bits 127:0 of the destination operand. The result of each comparison is a quadword mask of all 1s (comparison true) or all 0s (comparison false).\nVEX.128 encoded version: The first source operand (second operand) is an XMM register. The second source operand (third operand) can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination ZMM register are zeroed. Two comparisons are performed with results written to bits 127:0 of the destination operand.\nThe comparison predicate operand is an 8-bit immediate:\nThe unordered relationship is true when at least one of the two source operands being compared is a NaN; the ordered relationship is true when neither source operand is a NaN.\nA subsequent computational instruction that uses the mask result in the destination operand as an input operand will not generate an exception, because a mask of all 0s corresponds to a floating-point value of +0.0 and a mask of all 1s corresponds to a QNaN.\nNote that processors with “CPUID.1H:ECX.AVX =0” do not implement the “greater-than”, “greater-than-or-equal”, “not-greater than”, and “not-greater-than-or-equal relations” predicates. These comparisons can be made either by using the inverse relationship (that is, use the “not-less-than-or-equal” to make a “greater-than” comparison) or by using software emulation. When using software emulation, the program must swap the operands (copying registers when necessary to protect the data that will now be in the destination), and then perform the compare using a different predicate. The predicate to be used for these emulations is listed in the first 8 rows of Table 3-7 (Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A) under the heading Emulation.\nCompilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand CMPPD instruction, for processors with “CPUID.1H:ECX.AVX =0”. See Table 3-2. The compiler should treat reserved imm8 values as illegal syntax.\nThe greater-than relations that the processor does not implement require more than one instruction to emulate in software and therefore should not be implemented as pseudo-ops. (For these, the programmer should reverse the operands of the corresponding less than relations and use move instructions to ensure that the mask is moved to the correct destination register and that the source operand is left intact.)\nProcessors with “CPUID.1H:ECX.AVX =1” implement the full complement of 32 predicates shown in Table 3-3, software emulation is no longer needed. Compilers and assemblers may implement the following three-operand pseudo-ops in addition to the four-operand VCMPPD instruction. See Table 3-3, where the notations of reg1 reg2, and reg3 represent either XMM registers or YMM registers. The compiler should treat reserved imm8 values as\nillegal syntax. Alternately, intrinsics can map the pseudo-ops to pre-defined constants to support a simpler intrinsic interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded VCMPPD instructions in a similar fashion by extending the syntax listed in Table 3-3.", + "operation": "CASE (COMPARISON PREDICATE) OF\n0: OP3 := EQ_OQ; OP5 := EQ_OQ;\n 1: OP3 := LT_OS; OP5 := LT_OS;\n 2: OP3 := LE_OS; OP5 := LE_OS;\n 3: OP3 := UNORD_Q; OP5 := UNORD_Q;\n 4: OP3 := NEQ_UQ; OP5 := NEQ_UQ;\n 5: OP3 := NLT_US; OP5 := NLT_US;\n 6: OP3 := NLE_US; OP5 := NLE_US;\n 7: OP3 := ORD_Q; OP5 := ORD_Q;\n 8: OP5 := EQ_UQ;\n 9: OP5 := NGE_US;\n 10: OP5 := NGT_US;\n 11: OP5 := FALSE_OQ;\n 12: OP5 := NEQ_OQ;\n 13: OP5 := GE_OS;\n 14: OP5 := GT_OS;\n 15: OP5 := TRUE_UQ;\n 16: OP5 := EQ_OS;\n 17: OP5 := LT_OQ;\n 18: OP5 := LE_OQ;\n 19: OP5 := UNORD_S;\n 20: OP5 := NEQ_US;\n 21: OP5 := NLT_UQ;\n 22: OP5 := NLE_UQ;\n 23: OP5 := ORD_S;\n 24: OP5 := EQ_US;\n 25: OP5 := NGE_UQ;\n 26: OP5 := NGT_UQ;\n 27: OP5 := FALSE_OS;\n 28: OP5 := NEQ_OS;\n 29: OP5 := GE_OQ;\n 30: OP5 := GT_OQ;\n 31: OP5 := TRUE_US;\n DEFAULT: Reserved;\nESAC;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k2[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n CMP := SRC1[i+63:i] OP5 SRC2[63:0]\n ELSE\n CMP := SRC1[i+63:i] OP5 SRC2[i+63:i]\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking only\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nCMP0 := SRC1[63:0] OP5 SRC2[63:0];\nCMP1 := SRC1[127:64] OP5 SRC2[127:64];\nCMP2 := SRC1[191:128] OP5 SRC2[191:128];\nCMP3 := SRC1[255:192] OP5 SRC2[255:192];\nIF CMP0 = TRUE\n THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[63:0] := 0000000000000000H; FI;\nIF CMP1 = TRUE\n THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[127:64] := 0000000000000000H; FI;\nIF CMP2 = TRUE\n THEN DEST[191:128] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[191:128] := 0000000000000000H; FI;\nIF CMP3 = TRUE\n THEN DEST[255:192] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[255:192] := 0000000000000000H; FI;\nDEST[MAXVL-1:256] := 0\n\n\nCMP0 := SRC1[63:0] OP5 SRC2[63:0];\nCMP1 := SRC1[127:64] OP5 SRC2[127:64];\nIF CMP0 = TRUE\n THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[63:0] := 0000000000000000H; FI;\nIF CMP1 = TRUE\n THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[127:64] := 0000000000000000H; FI;\nDEST[MAXVL-1:128] := 0\n\n\nCMP0 := SRC1[63:0] OP3 SRC2[63:0];\nCMP1 := SRC1[127:64] OP3 SRC2[127:64];\nIF CMP0 = TRUE\n THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[63:0] := 0000000000000000H; FI;\nIF CMP1 = TRUE\n THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[127:64] := 0000000000000000H; FI;\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cmppd" + }, + "cmpps": { + "instruction": "CMPPS", + "title": "CMPPS\n\t\t— Compare Packed Single Precision Floating-Point Values", + "opcode": "NP 0F C2 /r ib CMPPS xmm1, xmm2/m128, imm8", + "description": "Performs a SIMD compare of the packed single precision floating-point values in the second source operand and the first source operand and returns the result of the comparison to the destination operand. The comparison predicate operand (immediate byte) specifies the type of comparison performed on each of the pairs of packed values.\nEVEX encoded versions: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is an opmask register. Comparison results are written to the destination operand under the writemask k2. Each comparison result is a single mask bit of 1 (comparison true) or 0 (comparison false).\nVEX.256 encoded version: The first source operand (second operand) is a YMM register. The second source operand (third operand) can be a YMM register or a 256-bit memory location. The destination operand (first operand) is a YMM register. Eight comparisons are performed with results written to the destination operand. The result of each comparison is a doubleword mask of all 1s (comparison true) or all 0s (comparison false).\n128-bit Legacy SSE version: The first source and destination operand (first operand) is an XMM register. The second source operand (second operand) can be an XMM register or 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged. Four comparisons are performed with results written to bits 127:0 of the destination operand. The result of each comparison is a doubleword mask of all 1s (comparison true) or all 0s (comparison false).\nVEX.128 encoded version: The first source operand (second operand) is an XMM register. The second source operand (third operand) can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination ZMM register are zeroed. Four comparisons are performed with results written to bits 127:0 of the destination operand.\nThe comparison predicate operand is an 8-bit immediate:\nThe unordered relationship is true when at least one of the two source operands being compared is a NaN; the ordered relationship is true when neither source operand is a NaN.\nA subsequent computational instruction that uses the mask result in the destination operand as an input operand will not generate an exception, because a mask of all 0s corresponds to a floating-point value of +0.0 and a mask of all 1s corresponds to a QNaN.\nNote that processors with “CPUID.1H:ECX.AVX =0” do not implement the “greater-than”, “greater-than-or-equal”, “not-greater than”, and “not-greater-than-or-equal relations” predicates. These comparisons can be made either by using the inverse relationship (that is, use the “not-less-than-or-equal” to make a “greater-than” comparison) or by using software emulation. When using software emulation, the program must swap the operands (copying registers when necessary to protect the data that will now be in the destination), and then perform the compare using a different predicate. The predicate to be used for these emulations is listed in the first 8 rows of Table 3-7 (Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A) under the heading Emulation.\nCompilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand CMPPS instruction, for processors with “CPUID.1H:ECX.AVX =0”. See Table 3-4. The compiler should treat reserved imm8 values as illegal syntax.\nThe greater-than relations that the processor does not implement require more than one instruction to emulate in software and therefore should not be implemented as pseudo-ops. (For these, the programmer should reverse the operands of the corresponding less than relations and use move instructions to ensure that the mask is moved to the correct destination register and that the source operand is left intact.)\nProcessors with “CPUID.1H:ECX.AVX =1” implement the full complement of 32 predicates shown in Table 3-5, software emulation is no longer needed. Compilers and assemblers may implement the following three-operand pseudo-ops in addition to the four-operand VCMPPS instruction. See Table 3-5, where the notation of reg1 and reg2 represent either XMM registers or YMM registers. The compiler should treat reserved imm8 values as illegal syntax. Alternately, intrinsics can map the pseudo-ops to pre-defined constants to support a simpler intrinsic interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded VCMPPS instructions in a similar fashion by extending the syntax listed in Table 3-5.\n:", + "operation": "CASE (COMPARISON PREDICATE) OF\n 0: OP3 := EQ_OQ; OP5 := EQ_OQ;\n 1: OP3 := LT_OS; OP5 := LT_OS;\n 2: OP3 := LE_OS; OP5 := LE_OS;\n 3: OP3 := UNORD_Q; OP5 := UNORD_Q;\n 4: OP3 := NEQ_UQ; OP5 := NEQ_UQ;\n 5: OP3 := NLT_US; OP5 := NLT_US;\n 6: OP3 := NLE_US; OP5 := NLE_US;\n 7: OP3 := ORD_Q; OP5 := ORD_Q;\n 8: OP5 := EQ_UQ;\n 9: OP5 := NGE_US;\n 10: OP5 := NGT_US;\n 11: OP5 := FALSE_OQ;\n 12: OP5 := NEQ_OQ;\n 13: OP5 := GE_OS;\n 14: OP5 := GT_OS;\n 15: OP5 := TRUE_UQ;\n 16: OP5 := EQ_OS;\n 17: OP5 := LT_OQ;\n 18: OP5 := LE_OQ;\n 19: OP5 := UNORD_S;\n 20: OP5 := NEQ_US;\n 21: OP5 := NLT_UQ;\n 22: OP5 := NLE_UQ;\n 23: OP5 := ORD_S;\n 24: OP5 := EQ_US;\n 25: OP5 := NGE_UQ;\n 26: OP5 := NGT_UQ;\n 27: OP5 := FALSE_OS;\n 28: OP5 := NEQ_OS;\n 29: OP5 := GE_OQ;\n 30: OP5 := GT_OQ;\n 31: OP5 := TRUE_US;\n DEFAULT: Reserved\nESAC;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n CMP := SRC1[i+31:i] OP5 SRC2[31:0]\n ELSE\n CMP := SRC1[i+31:i] OP5 SRC2[i+31:i]\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nCMP0 := SRC1[31:0] OP5 SRC2[31:0];\nCMP1 := SRC1[63:32] OP5 SRC2[63:32];\nCMP2 := SRC1[95:64] OP5 SRC2[95:64];\nCMP3 := SRC1[127:96] OP5 SRC2[127:96];\nCMP4 := SRC1[159:128] OP5 SRC2[159:128];\nCMP5 := SRC1[191:160] OP5 SRC2[191:160];\nCMP6 := SRC1[223:192] OP5 SRC2[223:192];\nCMP7 := SRC1[255:224] OP5 SRC2[255:224];\nIF CMP0 = TRUE\n THEN DEST[31:0] :=FFFFFFFFH;\n ELSE DEST[31:0] := 000000000H; FI;\nIF CMP1 = TRUE\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] :=000000000H; FI;\nIF CMP2 = TRUE\n THEN DEST[95:64] := FFFFFFFFH;\n ELSE DEST[95:64] := 000000000H; FI;\nIF CMP3 = TRUE\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 000000000H; FI;\nIF CMP4 = TRUE\n THEN DEST[159:128] := FFFFFFFFH;\n ELSE DEST[159:128] := 000000000H; FI;\nIF CMP5 = TRUE\n THEN DEST[191:160] := FFFFFFFFH;\n ELSE DEST[191:160] := 000000000H; FI;\nIF CMP6 = TRUE\n THEN DEST[223:192] := FFFFFFFFH;\n ELSE DEST[223:192] :=000000000H; FI;\nIF CMP7 = TRUE\n THEN DEST[255:224] := FFFFFFFFH;\n ELSE DEST[255:224] := 000000000H; FI;\nDEST[MAXVL-1:256] := 0\n\n\nCMP0 := SRC1[31:0] OP5 SRC2[31:0];\nCMP1 := SRC1[63:32] OP5 SRC2[63:32];\nCMP2 := SRC1[95:64] OP5 SRC2[95:64];\nCMP3 := SRC1[127:96] OP5 SRC2[127:96];\nIF CMP0 = TRUE\n THEN DEST[31:0] :=FFFFFFFFH;\n ELSE DEST[31:0] := 000000000H; FI;\nIF CMP1 = TRUE\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 000000000H; FI;\nIF CMP2 = TRUE\n THEN DEST[95:64] := FFFFFFFFH;\n ELSE DEST[95:64] := 000000000H; FI;\nIF CMP3 = TRUE\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] :=000000000H; FI;\nDEST[MAXVL-1:128] := 0\n\n\nCMP0 := SRC1[31:0] OP3 SRC2[31:0];\nCMP1 := SRC1[63:32] OP3 SRC2[63:32];\nCMP2 := SRC1[95:64] OP3 SRC2[95:64];\nCMP3 := SRC1[127:96] OP3 SRC2[127:96];\nIF CMP0 = TRUE\n THEN DEST[31:0] :=FFFFFFFFH;\n ELSE DEST[31:0] := 000000000H; FI;\nIF CMP1 = TRUE\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 000000000H; FI;\nIF CMP2 = TRUE\n THEN DEST[95:64] := FFFFFFFFH;\n ELSE DEST[95:64] := 000000000H; FI;\nIF CMP3 = TRUE\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] :=000000000H; FI;\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cmpps" + }, + "cmps": { + "instruction": "CMPS", + "title": "CMPS/CMPSB/CMPSW/CMPSD/CMPSQ\n\t\t— Compare String Operands", + "opcode": "A6", + "description": "Compares the byte, word, doubleword, or quadword specified with the first source operand with the byte, word, doubleword, or quadword specified with the second source operand and sets the status flags in the EFLAGS register according to the results.\nBoth source operands are located in memory. The address of the first source operand is read from DS:SI, DS:ESI or RSI (depending on the address-size attribute of the instruction is 16, 32, or 64, respectively). The address of the second source operand is read from ES:DI, ES:EDI or RDI (again depending on the address-size attribute of the instruction is 16, 32, or 64). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the CMPS mnemonic) allows the two source operands to be specified explicitly. Here, the source operands should be symbols that indicate the size and location of the source values. This explicit-operand form is provided to allow documentation. However, note that the documentation provided by this form can be misleading. That is, the source operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords, quadwords), but they do not have to specify the correct loca-\ntion. Locations of the source operands are always specified by the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers, which must be loaded correctly before the compare string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the CMPS instructions. Here also the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers are assumed by the processor to specify the location of the source operands. The size of the source operands is selected with the mnemonic: CMPSB (byte comparison), CMPSW (word comparison), CMPSD (doubleword comparison), or CMPSQ (quadword comparison using REX.W).\nAfter the comparison, the (E/R)SI and (E/R)DI registers increment or decrement automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E/R)SI and (E/R)DI register increment; if the DF flag is 1, the registers decrement.) The registers increment or decrement by 1 for byte operations, by 2 for word operations, 4 for doubleword operations. If operand size is 64, RSI and RDI registers increment by 8 for quadword operations.\nThe CMPS, CMPSB, CMPSW, CMPSD, and CMPSQ instructions can be preceded by the REP prefix for block comparisons. More often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of the status flags before the next comparison is made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64 bits, 32 bit address size is supported using the prefix 67H. Use of the REX.W prefix promotes doubleword operation to 64 bits (see CMPSQ). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "temp := SRC1 - SRC2;\nSetStatusFlags(temp);\nIF (64-Bit Mode)\n THEN\n IF (Byte comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 2;\n (R|E)DI\n := (R|E)DI + 2;\n ELSE\n (R|E)SI\n := (R|E)SI – 2;\n (R|E)DI\n := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword\n comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 4;\n (R|E)DI\n := (R|E)DI + 4;\n ELSE\n (R|E)SI\n := (R|E)SI – 4;\n (R|E)DI\n := (R|E)DI – 4;\n FI;\n ELSE (* Quadword comparison *)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\n ELSE (* Non-64-bit Mode *)\n IF (byte comparison)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THENIFDF =0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE (* Doubleword comparison *)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmps:cmpsb:cmpsw:cmpsd:cmpsq" + }, + "cmpsb": { + "instruction": "CMPSB", + "title": "CMPS/CMPSB/CMPSW/CMPSD/CMPSQ\n\t\t— Compare String Operands", + "opcode": "A6", + "description": "Compares the byte, word, doubleword, or quadword specified with the first source operand with the byte, word, doubleword, or quadword specified with the second source operand and sets the status flags in the EFLAGS register according to the results.\nBoth source operands are located in memory. The address of the first source operand is read from DS:SI, DS:ESI or RSI (depending on the address-size attribute of the instruction is 16, 32, or 64, respectively). The address of the second source operand is read from ES:DI, ES:EDI or RDI (again depending on the address-size attribute of the instruction is 16, 32, or 64). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the CMPS mnemonic) allows the two source operands to be specified explicitly. Here, the source operands should be symbols that indicate the size and location of the source values. This explicit-operand form is provided to allow documentation. However, note that the documentation provided by this form can be misleading. That is, the source operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords, quadwords), but they do not have to specify the correct loca-\ntion. Locations of the source operands are always specified by the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers, which must be loaded correctly before the compare string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the CMPS instructions. Here also the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers are assumed by the processor to specify the location of the source operands. The size of the source operands is selected with the mnemonic: CMPSB (byte comparison), CMPSW (word comparison), CMPSD (doubleword comparison), or CMPSQ (quadword comparison using REX.W).\nAfter the comparison, the (E/R)SI and (E/R)DI registers increment or decrement automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E/R)SI and (E/R)DI register increment; if the DF flag is 1, the registers decrement.) The registers increment or decrement by 1 for byte operations, by 2 for word operations, 4 for doubleword operations. If operand size is 64, RSI and RDI registers increment by 8 for quadword operations.\nThe CMPS, CMPSB, CMPSW, CMPSD, and CMPSQ instructions can be preceded by the REP prefix for block comparisons. More often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of the status flags before the next comparison is made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64 bits, 32 bit address size is supported using the prefix 67H. Use of the REX.W prefix promotes doubleword operation to 64 bits (see CMPSQ). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "temp := SRC1 - SRC2;\nSetStatusFlags(temp);\nIF (64-Bit Mode)\n THEN\n IF (Byte comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 2;\n (R|E)DI\n := (R|E)DI + 2;\n ELSE\n (R|E)SI\n := (R|E)SI – 2;\n (R|E)DI\n := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword\n comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 4;\n (R|E)DI\n := (R|E)DI + 4;\n ELSE\n (R|E)SI\n := (R|E)SI – 4;\n (R|E)DI\n := (R|E)DI – 4;\n FI;\n ELSE (* Quadword comparison *)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\n ELSE (* Non-64-bit Mode *)\n IF (byte comparison)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THENIFDF =0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE (* Doubleword comparison *)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmps:cmpsb:cmpsw:cmpsd:cmpsq" + }, + "cmpsd": { + "instruction": "CMPSD", + "title": "CMPSD\n\t\t— Compare Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F C2 /r ib CMPSD xmm1, xmm2/m64, imm8", + "description": "Compares the low double precision floating-point values in the second source operand and the first source operand and returns the result of the comparison to the destination operand. The comparison predicate operand (immediate operand) specifies the type of comparison performed.\n128-bit Legacy SSE version: The first source and destination operand (first operand) is an XMM register. The second source operand (second operand) can be an XMM register or 64-bit memory location. Bits (MAXVL-1:64) of the corresponding YMM destination register remain unchanged. The comparison result is a quadword mask of all 1s (comparison true) or all 0s (comparison false).\nVEX.128 encoded version: The first source operand (second operand) is an XMM register. The second source operand (third operand) can be an XMM register or a 64-bit memory location. The result is stored in the low quadword of the destination operand; the high quadword is filled with the contents of the high quadword of the first source operand. Bits (MAXVL-1:128) of the destination ZMM register are zeroed. The comparison result is a quadword mask of all 1s (comparison true) or all 0s (comparison false).\nEVEX encoded version: The first source operand (second operand) is an XMM register. The second source operand can be a XMM register or a 64-bit memory location. The destination operand (first operand) is an opmask register. The comparison result is a single mask bit of 1 (comparison true) or 0 (comparison false), written to the destination starting from the LSB according to the writemask k2. Bits (MAX_KL-1:128) of the destination register are cleared.\nThe comparison predicate operand is an 8-bit immediate:\nThe unordered relationship is true when at least one of the two source operands being compared is a NaN; the ordered relationship is true when neither source operand is a NaN.\nA subsequent computational instruction that uses the mask result in the destination operand as an input operand will not generate an exception, because a mask of all 0s corresponds to a floating-point value of +0.0 and a mask of all 1s corresponds to a QNaN.\nNote that processors with “CPUID.1H:ECX.AVX =0” do not implement the “greater-than”, “greater-than-or-equal”, “not-greater than”, and “not-greater-than-or-equal relations” predicates. These comparisons can be made either\nby using the inverse relationship (that is, use the “not-less-than-or-equal” to make a “greater-than” comparison) or by using software emulation. When using software emulation, the program must swap the operands (copying registers when necessary to protect the data that will now be in the destination), and then perform the compare using a different predicate. The predicate to be used for these emulations is listed in the first 8 rows of Table 3-7 (Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A) under the heading Emulation.\nCompilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand CMPSD instruction, for processors with “CPUID.1H:ECX.AVX =0”. See Table 3-6. The compiler should treat reserved imm8 values as illegal syntax.\nThe greater-than relations that the processor does not implement require more than one instruction to emulate in software and therefore should not be implemented as pseudo-ops. (For these, the programmer should reverse the operands of the corresponding less than relations and use move instructions to ensure that the mask is moved to the correct destination register and that the source operand is left intact.)\nProcessors with “CPUID.1H:ECX.AVX =1” implement the full complement of 32 predicates shown in Table 3-7, software emulation is no longer needed. Compilers and assemblers may implement the following three-operand pseudo-ops in addition to the four-operand VCMPSD instruction. See Table 3-7, where the notations of reg1 reg2, and reg3 represent either XMM registers or YMM registers. The compiler should treat reserved imm8 values as illegal syntax. Alternately, intrinsics can map the pseudo-ops to pre-defined constants to support a simpler intrinsic interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded VCMPSD instructions in a similar fashion by extending the syntax listed in Table 3-7.\nSoftware should ensure VCMPSD is encoded with VEX.L=0. Encoding VCMPSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "CASE (COMPARISON PREDICATE) OF\n 0: OP3 := EQ_OQ; OP5 := EQ_OQ;\n 1: OP3 := LT_OS; OP5 := LT_OS;\n 2: OP3 := LE_OS; OP5 := LE_OS;\n 3: OP3 := UNORD_Q; OP5 := UNORD_Q;\n 4: OP3 := NEQ_UQ; OP5 := NEQ_UQ;\n 5: OP3 := NLT_US; OP5 := NLT_US;\n 6: OP3 := NLE_US; OP5 := NLE_US;\n 7: OP3 := ORD_Q; OP5 := ORD_Q;\n 8: OP5 := EQ_UQ;\n 9: OP5 := NGE_US;\n 10: OP5 := NGT_US;\n 11: OP5 := FALSE_OQ;\n 12: OP5 := NEQ_OQ;\n 13: OP5 := GE_OS;\n 14: OP5 := GT_OS;\n 15: OP5 := TRUE_UQ;\n 16: OP5 := EQ_OS;\n 17: OP5 := LT_OQ;\n 18: OP5 := LE_OQ;\n 19: OP5 := UNORD_S;\n 20: OP5 := NEQ_US;\n 21: OP5 := NLT_UQ;\n 22: OP5 := NLE_UQ;\n 23: OP5 := ORD_S;\n 24: OP5 := EQ_US;\n 25: OP5 := NGE_UQ;\n 26: OP5 := NGT_UQ;\n 27: OP5 := FALSE_OS;\n 28: OP5 := NEQ_OS;\n 29: OP5 := GE_OQ;\n 30: OP5 := GT_OQ;\n 31: OP5 := TRUE_US;\n DEFAULT: Reserved\nESAC;\n\n\nCMP0 := SRC1[63:0] OP5 SRC2[63:0];\nIF k2[0] or *no writemask*\n THEN IF CMP0 = TRUE\n THEN DEST[0] := 1;\n ELSE DEST[0] := 0; FI;\n ELSE DEST[0] := 0\n ; zeroing-masking only\nFI;\nDEST[MAX_KL-1:1] := 0\n\n\nCMP0 := DEST[63:0] OP3 SRC[63:0];\nIF CMP0 = TRUE\nTHEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\nELSE DEST[63:0] := 0000000000000000H; FI;\nDEST[MAXVL-1:64] (Unmodified)\n\n\nCMP0 := SRC1[63:0] OP5 SRC2[63:0];\nIF CMP0 = TRUE\nTHEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\nELSE DEST[63:0] := 0000000000000000H; FI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/cmpsd" + }, + "cmpsq": { + "instruction": "CMPSQ", + "title": "CMPS/CMPSB/CMPSW/CMPSD/CMPSQ\n\t\t— Compare String Operands", + "opcode": "REX.W + A7", + "description": "Compares the byte, word, doubleword, or quadword specified with the first source operand with the byte, word, doubleword, or quadword specified with the second source operand and sets the status flags in the EFLAGS register according to the results.\nBoth source operands are located in memory. The address of the first source operand is read from DS:SI, DS:ESI or RSI (depending on the address-size attribute of the instruction is 16, 32, or 64, respectively). The address of the second source operand is read from ES:DI, ES:EDI or RDI (again depending on the address-size attribute of the instruction is 16, 32, or 64). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the CMPS mnemonic) allows the two source operands to be specified explicitly. Here, the source operands should be symbols that indicate the size and location of the source values. This explicit-operand form is provided to allow documentation. However, note that the documentation provided by this form can be misleading. That is, the source operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords, quadwords), but they do not have to specify the correct loca-\ntion. Locations of the source operands are always specified by the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers, which must be loaded correctly before the compare string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the CMPS instructions. Here also the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers are assumed by the processor to specify the location of the source operands. The size of the source operands is selected with the mnemonic: CMPSB (byte comparison), CMPSW (word comparison), CMPSD (doubleword comparison), or CMPSQ (quadword comparison using REX.W).\nAfter the comparison, the (E/R)SI and (E/R)DI registers increment or decrement automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E/R)SI and (E/R)DI register increment; if the DF flag is 1, the registers decrement.) The registers increment or decrement by 1 for byte operations, by 2 for word operations, 4 for doubleword operations. If operand size is 64, RSI and RDI registers increment by 8 for quadword operations.\nThe CMPS, CMPSB, CMPSW, CMPSD, and CMPSQ instructions can be preceded by the REP prefix for block comparisons. More often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of the status flags before the next comparison is made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64 bits, 32 bit address size is supported using the prefix 67H. Use of the REX.W prefix promotes doubleword operation to 64 bits (see CMPSQ). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "temp := SRC1 - SRC2;\nSetStatusFlags(temp);\nIF (64-Bit Mode)\n THEN\n IF (Byte comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 2;\n (R|E)DI\n := (R|E)DI + 2;\n ELSE\n (R|E)SI\n := (R|E)SI – 2;\n (R|E)DI\n := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword\n comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 4;\n (R|E)DI\n := (R|E)DI + 4;\n ELSE\n (R|E)SI\n := (R|E)SI – 4;\n (R|E)DI\n := (R|E)DI – 4;\n FI;\n ELSE (* Quadword comparison *)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\n ELSE (* Non-64-bit Mode *)\n IF (byte comparison)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THENIFDF =0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE (* Doubleword comparison *)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmps:cmpsb:cmpsw:cmpsd:cmpsq" + }, + "cmpss": { + "instruction": "CMPSS", + "title": "CMPSS\n\t\t— Compare Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F C2 /r ib CMPSS xmm1, xmm2/m32, imm8", + "description": "Compares the low single precision floating-point values in the second source operand and the first source operand and returns the result of the comparison to the destination operand. The comparison predicate operand (immediate operand) specifies the type of comparison performed.\n128-bit Legacy SSE version: The first source and destination operand (first operand) is an XMM register. The second source operand (second operand) can be an XMM register or 32-bit memory location. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged. The comparison result is a doubleword mask of all 1s (comparison true) or all 0s (comparison false).\nVEX.128 encoded version: The first source operand (second operand) is an XMM register. The second source operand (third operand) can be an XMM register or a 32-bit memory location. The result is stored in the low 32 bits of the destination operand; bits 127:32 of the destination operand are copied from the first source operand. Bits (MAXVL-1:128) of the destination ZMM register are zeroed. The comparison result is a doubleword mask of all 1s (comparison true) or all 0s (comparison false).\nEVEX encoded version: The first source operand (second operand) is an XMM register. The second source operand can be a XMM register or a 32-bit memory location. The destination operand (first operand) is an opmask register. The comparison result is a single mask bit of 1 (comparison true) or 0 (comparison false), written to the destination starting from the LSB according to the writemask k2. Bits (MAX_KL-1:128) of the destination register are cleared.\nThe comparison predicate operand is an 8-bit immediate:\nThe unordered relationship is true when at least one of the two source operands being compared is a NaN; the ordered relationship is true when neither source operand is a NaN.\nA subsequent computational instruction that uses the mask result in the destination operand as an input operand will not generate an exception, because a mask of all 0s corresponds to a floating-point value of +0.0 and a mask of all 1s corresponds to a QNaN.\nNote that processors with “CPUID.1H:ECX.AVX =0” do not implement the “greater-than”, “greater-than-or-equal”, “not-greater than”, and “not-greater-than-or-equal relations” predicates. These comparisons can be made either by using the inverse relationship (that is, use the “not-less-than-or-equal” to make a “greater-than” comparison) or by using software emulation. When using software emulation, the program must swap the operands (copying registers when necessary to protect the data that will now be in the destination), and then perform the compare using a different predicate. The predicate to be used for these emulations is listed in the first 8 rows of Table 3-7 (Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A) under the heading Emulation.\nCompilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand CMPSS instruction, for processors with “CPUID.1H:ECX.AVX =0”. See Table 3-8. The compiler should treat reserved imm8 values as illegal syntax.\nThe greater-than relations that the processor does not implement require more than one instruction to emulate in software and therefore should not be implemented as pseudo-ops. (For these, the programmer should reverse the operands of the corresponding less than relations and use move instructions to ensure that the mask is moved to the correct destination register and that the source operand is left intact.)\nProcessors with “CPUID.1H:ECX.AVX =1” implement the full complement of 32 predicates shown in Table 3-7, software emulation is no longer needed. Compilers and assemblers may implement the following three-operand pseudo-ops in addition to the four-operand VCMPSS instruction. See Table 3-9, where the notations of reg1 reg2, and reg3 represent either XMM registers or YMM registers. The compiler should treat reserved imm8 values as illegal syntax. Alternately, intrinsics can map the pseudo-ops to pre-defined constants to support a simpler intrinsic interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded VCMPSS instructions in a similar fashion by extending the syntax listed in Table 3-9.\nSoftware should ensure VCMPSS is encoded with VEX.L=0. Encoding VCMPSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "CASE (COMPARISON PREDICATE) OF\n 0: OP3 := EQ_OQ; OP5 := EQ_OQ;\n 1: OP3 := LT_OS; OP5 := LT_OS;\n 2: OP3 := LE_OS; OP5 := LE_OS;\n 3: OP3 := UNORD_Q; OP5 := UNORD_Q;\n 4: OP3 := NEQ_UQ; OP5 := NEQ_UQ;\n 5: OP3 := NLT_US; OP5 := NLT_US;\n 6: OP3 := NLE_US; OP5 := NLE_US;\n 7: OP3 := ORD_Q; OP5 := ORD_Q;\n 8: OP5 := EQ_UQ;\n 9: OP5 := NGE_US;\n 10: OP5 := NGT_US;\n 11: OP5 := FALSE_OQ;\n 12: OP5 := NEQ_OQ;\n 13: OP5 := GE_OS;\n 14: OP5 := GT_OS;\n 15: OP5 := TRUE_UQ;\n 16: OP5 := EQ_OS;\n 17: OP5 := LT_OQ;\n 18: OP5 := LE_OQ;\n 19: OP5 := UNORD_S;\n 20: OP5 := NEQ_US;\n 21: OP5 := NLT_UQ;\n 22: OP5 := NLE_UQ;\n 23: OP5 := ORD_S;\n 24: OP5 := EQ_US;\n 25: OP5 := NGE_UQ;\n 26: OP5 := NGT_UQ;\n 27: OP5 := FALSE_OS;\n 28: OP5 := NEQ_OS;\n 29: OP5 := GE_OQ;\n 30: OP5 := GT_OQ;\n 31: OP5 := TRUE_US;\n DEFAULT: Reserved\nESAC;\n\n\nCMP0 := SRC1[31:0] OP5 SRC2[31:0];\nIF k2[0] or *no writemask*\n THEN IF CMP0 = TRUE\n THEN DEST[0] := 1;\n ELSE DEST[0] := 0; FI;\n ELSE DEST[0] := 0\n ; zeroing-masking only\nFI;\nDEST[MAX_KL-1:1] := 0\n\n\nCMP0 := DEST[31:0] OP3 SRC[31:0];\nIF CMP0 = TRUE\nTHEN DEST[31:0] := FFFFFFFFH;\nELSE DEST[31:0] := 00000000H; FI;\nDEST[MAXVL-1:32] (Unmodified)\n\n\nCMP0 := SRC1[31:0] OP5 SRC2[31:0];\nIF CMP0 = TRUE\nTHEN DEST[31:0] := FFFFFFFFH;\nELSE DEST[31:0] := 00000000H; FI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/cmpss" + }, + "cmpsw": { + "instruction": "CMPSW", + "title": "CMPS/CMPSB/CMPSW/CMPSD/CMPSQ\n\t\t— Compare String Operands", + "opcode": "A7", + "description": "Compares the byte, word, doubleword, or quadword specified with the first source operand with the byte, word, doubleword, or quadword specified with the second source operand and sets the status flags in the EFLAGS register according to the results.\nBoth source operands are located in memory. The address of the first source operand is read from DS:SI, DS:ESI or RSI (depending on the address-size attribute of the instruction is 16, 32, or 64, respectively). The address of the second source operand is read from ES:DI, ES:EDI or RDI (again depending on the address-size attribute of the instruction is 16, 32, or 64). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the CMPS mnemonic) allows the two source operands to be specified explicitly. Here, the source operands should be symbols that indicate the size and location of the source values. This explicit-operand form is provided to allow documentation. However, note that the documentation provided by this form can be misleading. That is, the source operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords, quadwords), but they do not have to specify the correct loca-\ntion. Locations of the source operands are always specified by the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers, which must be loaded correctly before the compare string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the CMPS instructions. Here also the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers are assumed by the processor to specify the location of the source operands. The size of the source operands is selected with the mnemonic: CMPSB (byte comparison), CMPSW (word comparison), CMPSD (doubleword comparison), or CMPSQ (quadword comparison using REX.W).\nAfter the comparison, the (E/R)SI and (E/R)DI registers increment or decrement automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E/R)SI and (E/R)DI register increment; if the DF flag is 1, the registers decrement.) The registers increment or decrement by 1 for byte operations, by 2 for word operations, 4 for doubleword operations. If operand size is 64, RSI and RDI registers increment by 8 for quadword operations.\nThe CMPS, CMPSB, CMPSW, CMPSD, and CMPSQ instructions can be preceded by the REP prefix for block comparisons. More often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of the status flags before the next comparison is made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64 bits, 32 bit address size is supported using the prefix 67H. Use of the REX.W prefix promotes doubleword operation to 64 bits (see CMPSQ). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "temp := SRC1 - SRC2;\nSetStatusFlags(temp);\nIF (64-Bit Mode)\n THEN\n IF (Byte comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 2;\n (R|E)DI\n := (R|E)DI + 2;\n ELSE\n (R|E)SI\n := (R|E)SI – 2;\n (R|E)DI\n := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword\n comparison)\n THEN IF DF = 0\n THEN\n (R|E)SI\n := (R|E)SI + 4;\n (R|E)DI\n := (R|E)DI + 4;\n ELSE\n (R|E)SI\n := (R|E)SI – 4;\n (R|E)DI\n := (R|E)DI – 4;\n FI;\n ELSE (* Quadword comparison *)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\n ELSE (* Non-64-bit Mode *)\n IF (byte comparison)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word comparison)\n THENIFDF =0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE (* Doubleword comparison *)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmps:cmpsb:cmpsw:cmpsd:cmpsq" + }, + "cmpxchg": { + "instruction": "CMPXCHG", + "title": "CMPXCHG\n\t\t— Compare and Exchange", + "opcode": "0F B0/r CMPXCHG r/m8, r8", + "description": "Compares the value in the AL, AX, EAX, or RAX register with the first operand (destination operand). If the two values are equal, the second operand (source operand) is loaded into the destination operand. Otherwise, the destination operand is loaded into the AL, AX, EAX or RAX register. RAX register is available only in 64-bit mode.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is written into the destination. (The processor never produces a locked read without also producing a locked write.)\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "(* Accumulator = AL, AX, EAX, or RAX depending on whether a byte, word, doubleword, or quadword comparison is being performed *)\nTEMP := DEST\nIF accumulator = TEMP\n THEN\n ZF := 1;\n DEST := SRC;\n ELSE\n ZF := 0;\n accumulator := TEMP;\n DEST := TEMP;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmpxchg" + }, + "cmpxchg16b": { + "instruction": "CMPXCHG16B", + "title": "CMPXCHG8B/CMPXCHG16B\n\t\t— Compare and Exchange Bytes", + "opcode": "0F C7 /1 CMPXCHG8B m64", + "description": "Compares the 64-bit value in EDX:EAX (or 128-bit value in RDX:RAX if operand size is 128 bits) with the operand (destination operand). If the values are equal, the 64-bit value in ECX:EBX (or 128-bit value in RCX:RBX) is stored in the destination operand. Otherwise, the value in the destination operand is loaded into EDX:EAX (or RDX:RAX). The destination operand is an 8-byte memory location (or 16-byte memory location if operand size is 128 bits). For the EDX:EAX and ECX:EBX register pairs, EDX and ECX contain the high-order 32 bits and EAX and EBX contain the low-order 32 bits of a 64-bit value. For the RDX:RAX and RCX:RBX register pairs, RDX and RCX contain the high-order 64 bits and RAX and RBX contain the low-order 64bits of a 128-bit value.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is written into the destination. (The processor never produces a locked read without also producing a locked write.)\nIn 64-bit mode, default operation size is 64 bits. Use of the REX.W prefix promotes operation to 128 bits. Note that CMPXCHG16B requires that the destination (memory) operand be 16-byte aligned. See the summary chart at the beginning of this section for encoding data and limits. For information on the CPUID flag that indicates CMPX-CHG16B, see page 3-243.", + "operation": "IF (64-Bit Mode and OperandSize = 64)\n THEN\n TEMP128 := DEST\n IF (RDX:RAX = TEMP128)\n THEN\n ZF := 1;\n DEST := RCX:RBX;\n ELSE\n ZF := 0;\n RDX:RAX := TEMP128;\n DEST := TEMP128;\n FI;\n FI\n ELSE\n TEMP64 := DEST;\n IF (EDX:EAX = TEMP64)\n THEN\n ZF := 1;\n DEST := ECX:EBX;\n ELSE\n ZF := 0;\n EDX:EAX := TEMP64;\n DEST := TEMP64;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b" + }, + "cmpxchg8b": { + "instruction": "CMPXCHG8B", + "title": "CMPXCHG8B/CMPXCHG16B\n\t\t— Compare and Exchange Bytes", + "opcode": "0F C7 /1 CMPXCHG8B m64", + "description": "Compares the 64-bit value in EDX:EAX (or 128-bit value in RDX:RAX if operand size is 128 bits) with the operand (destination operand). If the values are equal, the 64-bit value in ECX:EBX (or 128-bit value in RCX:RBX) is stored in the destination operand. Otherwise, the value in the destination operand is loaded into EDX:EAX (or RDX:RAX). The destination operand is an 8-byte memory location (or 16-byte memory location if operand size is 128 bits). For the EDX:EAX and ECX:EBX register pairs, EDX and ECX contain the high-order 32 bits and EAX and EBX contain the low-order 32 bits of a 64-bit value. For the RDX:RAX and RCX:RBX register pairs, RDX and RCX contain the high-order 64 bits and RAX and RBX contain the low-order 64bits of a 128-bit value.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is written into the destination. (The processor never produces a locked read without also producing a locked write.)\nIn 64-bit mode, default operation size is 64 bits. Use of the REX.W prefix promotes operation to 128 bits. Note that CMPXCHG16B requires that the destination (memory) operand be 16-byte aligned. See the summary chart at the beginning of this section for encoding data and limits. For information on the CPUID flag that indicates CMPX-CHG16B, see page 3-243.", + "operation": "IF (64-Bit Mode and OperandSize = 64)\n THEN\n TEMP128 := DEST\n IF (RDX:RAX = TEMP128)\n THEN\n ZF := 1;\n DEST := RCX:RBX;\n ELSE\n ZF := 0;\n RDX:RAX := TEMP128;\n DEST := TEMP128;\n FI;\n FI\n ELSE\n TEMP64 := DEST;\n IF (EDX:EAX = TEMP64)\n THEN\n ZF := 1;\n DEST := ECX:EBX;\n ELSE\n ZF := 0;\n EDX:EAX := TEMP64;\n DEST := TEMP64;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b" + }, + "comisd": { + "instruction": "COMISD", + "title": "COMISD\n\t\t— Compare Scalar Ordered Double Precision Floating-Point Values and Set EFLAGS", + "opcode": "66 0F 2F /r COMISD xmm1, xmm2/m64", + "description": "Compares the double precision floating-point values in the low quadwords of operand 1 (first operand) and operand 2 (second operand), and sets the ZF, PF, and CF flags in the EFLAGS register according to the result (unordered, greater than, less than, or equal). The OF, SF, and AF flags in the EFLAGS register are set to 0. The unordered result is returned if either source operand is a NaN (QNaN or SNaN).\nOperand 1 is an XMM register; operand 2 can be an XMM register or a 64 bit memory location. The COMISD instruction differs from the UCOMISD instruction in that it signals a SIMD floating-point invalid operation exception (#I) when a source operand is either a QNaN or SNaN. The UCOMISD instruction signals an invalid operation exception only if a source operand is an SNaN.\nThe EFLAGS register is not updated if an unmasked SIMD floating-point exception is generated.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCOMISD is encoded with VEX.L=0. Encoding VCOMISD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "RESULT := OrderedCompare(DEST[63:0] <> SRC[63:0]) {\n(* Set EFLAGS *) CASE (RESULT) OF\n UNORDERED: ZF,PF,CF := 111;\n GREATER_THAN: ZF,PF,CF := 000;\n LESS_THAN: ZF,PF,CF := 001;\n EQUAL: ZF,PF,CF := 100;\nESAC;\nOF, AF, SF := 0; }\n", + "url": "https://www.felixcloutier.com/x86/comisd" + }, + "comiss": { + "instruction": "COMISS", + "title": "COMISS\n\t\t— Compare Scalar Ordered Single Precision Floating-Point Values and Set EFLAGS", + "opcode": "NP 0F 2F /r COMISS xmm1, xmm2/m32", + "description": "Compares the single precision floating-point values in the low quadwords of operand 1 (first operand) and operand 2 (second operand), and sets the ZF, PF, and CF flags in the EFLAGS register according to the result (unordered, greater than, less than, or equal). The OF, SF, and AF flags in the EFLAGS register are set to 0. The unordered result is returned if either source operand is a NaN (QNaN or SNaN).\nOperand 1 is an XMM register; operand 2 can be an XMM register or a 32 bit memory location.\nThe COMISS instruction differs from the UCOMISS instruction in that it signals a SIMD floating-point invalid operation exception (#I) when a source operand is either a QNaN or SNaN. The UCOMISS instruction signals an invalid operation exception only if a source operand is an SNaN.\nThe EFLAGS register is not updated if an unmasked SIMD floating-point exception is generated.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCOMISS is encoded with VEX.L=0. Encoding VCOMISS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "RESULT := OrderedCompare(DEST[31:0] <> SRC[31:0]) {\n(* Set EFLAGS *) CASE (RESULT) OF\n UNORDERED: ZF,PF,CF := 111;\n GREATER_THAN: ZF,PF,CF := 000;\n LESS_THAN: ZF,PF,CF := 001;\n EQUAL: ZF,PF,CF := 100;\nESAC;\nOF, AF, SF := 0; }\n", + "url": "https://www.felixcloutier.com/x86/comiss" + }, + "cpuid": { + "instruction": "CPUID", + "title": "CPUID\n\t\t— CPU Identification", + "opcode": "0F A2", + "description": "The ID flag (bit 21) in the EFLAGS register indicates support for the CPUID instruction. If a software procedure can set and clear this flag, the processor executing the procedure supports the CPUID instruction. This instruction operates the same in non-64-bit modes and 64-bit mode.\nCPUID returns processor identification and feature information in the EAX, EBX, ECX, and EDX registers.1 The instruction’s output is dependent on the contents of the EAX register upon execution (in some cases, ECX as well). For example, the following pseudocode loads EAX with 00H and causes CPUID to return a Maximum Return Value and the Vendor Identification String in the appropriate registers:\nMOV EAX, 00H\nCPUID\nTable 3-8 shows information returned, depending on the initial value loaded into the EAX register.\nTwo types of information are returned: basic and extended function information. If a value entered for CPUID.EAX is higher than the maximum input value for basic or extended function for that processor then the data for the highest basic information leaf is returned. For example, using some Intel processors, the following is true:\nCPUID.EAX = 05H (* Returns MONITOR/MWAIT leaf. *)\nCPUID.EAX = 0AH (* Returns Architectural Performance Monitoring leaf. *) CPUID.EAX = 0BH (* Returns Extended Topology Enumeration leaf. *)2 CPUID.EAX =1FH (* Returns V2 Extended Topology Enumeration leaf. *)2\nCPUID.EAX = 80000008H (* Returns linear/physical address size data. *)\nCPUID.EAX = 8000000AH (* INVALID: Returns same information as CPUID.EAX = 0BH. *)\nIf a value entered for CPUID.EAX is less than or equal to the maximum input value and the leaf is not supported on that processor then 0 is returned in all the registers.\nWhen CPUID returns the highest basic leaf information as a result of an invalid input EAX value, any dependence on input ECX value in the basic leaf is honored.\nCPUID can be executed at any privilege level to serialize instruction execution. Serializing instruction execution guarantees that any modifications to flags, registers, and memory for previous instructions are completed before the next instruction is fetched and executed.\nSee also:\n“Serializing Instructions” in Chapter 9, “Multiple-Processor Management,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\n“Caching Translation Information” in Chapter 4, “Paging,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.", + "operation": "IA32_BIOS_SIGN_ID MSR := Update with installed microcode revision number;\nCASE (EAX) OF\n EAX = 0:\n EAX := Highest basic function input value understood by CPUID;\n EBX := Vendor identification string;\n EDX := Vendor identification string;\n ECX := Vendor identification string;\n BREAK;\n EAX = 1H:\n EAX[3:0] := Stepping ID;\n EAX[7:4] := Model;\n EAX[11:8] := Family;\n EAX[13:12] := Processor type;\n EAX[15:14] := Reserved;\n EAX[19:16] := Extended Model;\n EAX[27:20] := Extended Family;\n EAX[31:28] := Reserved;\n EBX[7:0] := Brand Index; (* Reserved if the value is zero. *)\n EBX[15:8] := CLFLUSH Line Size;\n EBX[16:23] := Reserved; (* Number of threads enabled = 2 if MT enable fuse set. *)\n EBX[24:31] := Initial APIC ID;\n ECX := Feature flags; (* See Figure 3-7. *)\n EDX := Feature flags; (* See Figure 3-8. *)\n BREAK;\n EAX = 2H:\n EAX := Cache and TLB information;\n EBX := Cache and TLB information;\n ECX := Cache and TLB information;\n EDX := Cache and TLB information;\n BREAK;\n EAX = 3H:\n EAX := Reserved;\n EBX := Reserved;\n ECX := ProcessorSerialNumber[31:0];\n (* Pentium III processors only, otherwise reserved. *)\n EDX := ProcessorSerialNumber[63:32];\n (* Pentium III processors only, otherwise reserved. *\n BREAK\n EAX = 4H:\n EAX := Deterministic Cache Parameters Leaf; (* See Table 3-8. *)\n EBX := Deterministic Cache Parameters Leaf;\n ECX := Deterministic Cache Parameters Leaf;\n EDX := Deterministic Cache Parameters Leaf;\n BREAK;\n EAX = 5H:\n EAX := MONITOR/MWAIT Leaf; (* See Table 3-8. *)\n EBX := MONITOR/MWAIT Leaf;\n ECX := MONITOR/MWAIT Leaf;\n EDX := MONITOR/MWAIT Leaf;\n BREAK;\n EAX = 6H:\n EAX := Thermal and Power Management Leaf; (* See Table 3-8. *)\n EBX := Thermal and Power Management Leaf;\n ECX := Thermal and Power Management Leaf;\n EDX := Thermal and Power Management Leaf;\n BREAK;\n EAX = 7H:\n EAX := Structured Extended Feature Flags Enumeration Leaf; (* See Table 3-8. *)\n EBX := Structured Extended Feature Flags Enumeration Leaf;\n ECX := Structured Extended Feature Flags Enumeration Leaf;\n EDX := Structured Extended Feature Flags Enumeration Leaf;\n BREAK;\n EAX = 8H:\n EAX := Reserved = 0;\n EBX := Reserved = 0;\n ECX := Reserved = 0;\n EDX := Reserved = 0;\n BREAK;\n EAX = 9H:\n EAX := Direct Cache Access Information Leaf; (* See Table 3-8. *)\n EBX := Direct Cache Access Information Leaf;\n ECX := Direct Cache Access Information Leaf;\n EDX := Direct Cache Access Information Leaf;\n BREAK;\n EAX = AH:\n EAX := Architectural Performance Monitoring Leaf; (* See Table 3-8. *)\n EBX := Architectural Performance Monitoring Leaf;\n ECX := Architectural Performance Monitoring Leaf;\n EDX := Architectural Performance Monitoring Leaf;\n BREAK\n EAX = BH:\n EAX := Extended Topology Enumeration Leaf; (* See Table 3-8. *)\n EBX := Extended Topology Enumeration Leaf;\n ECX := Extended Topology Enumeration Leaf;\n EDX := Extended Topology Enumeration Leaf;\n BREAK;\n EAX = CH:\n EAX := Reserved = 0;\n EBX := Reserved = 0;\n ECX := Reserved = 0;\n EDX := Reserved = 0;\n BREAK;\n EAX = DH:\n EAX := Processor Extended State Enumeration Leaf; (* See Table 3-8. *)\n EBX := Processor Extended State Enumeration Leaf;\n ECX := Processor Extended State Enumeration Leaf;\n EDX := Processor Extended State Enumeration Leaf;\n BREAK;\n EAX = EH:\n EAX := Reserved = 0;\n EBX := Reserved = 0;\n ECX := Reserved = 0;\n EDX := Reserved = 0;\n BREAK;\n EAX = FH:\n EAX := Intel Resource Director Technology Monitoring Enumeration Leaf; (* See Table 3-8. *)\n EBX := Intel Resource Director Technology Monitoring Enumeration Leaf;\n ECX := Intel Resource Director Technology Monitoring Enumeration Leaf;\n EDX := Intel Resource Director Technology Monitoring Enumeration Leaf;\n BREAK;\n EAX = 10H:\n EAX := Intel Resource Director Technology Allocation Enumeration Leaf; (* See Table 3-8. *)\n EBX := Intel Resource Director Technology Allocation Enumeration Leaf;\n ECX := Intel Resource Director Technology Allocation Enumeration Leaf;\n EDX := Intel Resource Director Technology Allocation Enumeration Leaf;\n BREAK;\n EAX = 12H:\n EAX := Intel SGX Enumeration Leaf; (* See Table 3-8. *)\n EBX := Intel SGX Enumeration Leaf;\n ECX := Intel SGX Enumeration Leaf;\n EDX := Intel SGX Enumeration Leaf;\n BREAK;\n EAX = 14H:\n EAX := Intel Processor Trace Enumeration Leaf; (* See Table 3-8. *)\n EBX := Intel Processor Trace Enumeration Leaf;\n ECX := Intel Processor Trace Enumeration Leaf;\n EDX := Intel Processor Trace Enumeration Leaf;\n BREAK;\n EAX = 15H:\n EAX := Time Stamp Counter and Nominal Core Crystal Clock Information Leaf; (* See Table 3-8. *)\n EBX := Time Stamp Counter and Nominal Core Crystal Clock Information Leaf;\n ECX := Time Stamp Counter and Nominal Core Crystal Clock Information Leaf;\n EDX := Time Stamp Counter and Nominal Core Crystal Clock Information Leaf;\n BREAK;\n EAX = 16H:\n EAX := Processor Frequency Information Enumeration Leaf; (* See Table 3-8. *)\n EBX := Processor Frequency Information Enumeration Leaf;\n ECX := Processor Frequency Information Enumeration Leaf;\n EDX := Processor Frequency Information Enumeration Leaf;\n BREAK;\n EAX = 17H:\n EAX := System-On-Chip Vendor Attribute Enumeration Leaf; (* See Table 3-8. *)\n EBX := System-On-Chip Vendor Attribute Enumeration Leaf;\n ECX := System-On-Chip Vendor Attribute Enumeration Leaf;\n EDX := System-On-Chip Vendor Attribute Enumeration Leaf;\n BREAK;\n EAX = 18H:\n EAX := Deterministic Address Translation Parameters Enumeration Leaf; (* See Table 3-8. *)\n EBX := Deterministic Address Translation Parameters Enumeration Leaf;\n ECX := Deterministic Address Translation Parameters Enumeration Leaf;\n EDX := Deterministic Address Translation Parameters Enumeration Leaf;\n BREAK;\n EAX = 19H:\n EAX := Key Locker Enumeration Leaf; (* See Table 3-8. *)\n EBX := Key Locker Enumeration Leaf;\n ECX := Key Locker Enumeration Leaf;\n EDX := Key Locker Enumeration Leaf;\n BREAK;\n EAX = 1AH:\n EAX := Native Model ID Enumeration Leaf; (* See Table 3-8. *)\n EBX := Native Model ID Enumeration Leaf;\n ECX := Native Model ID Enumeration Leaf;\n EDX := Native Model ID Enumeration Leaf;\n BREAK;\n EAX = 1BH:\n EAX := PCONFIG Information Enumeration Leaf; (* See “INPUT EAX = 1BH: Returns PCONFIG Information” on page 3-253. *)\n EBX := PCONFIG Information Enumeration Leaf;\n ECX := PCONFIG Information Enumeration Leaf;\n EDX := PCONFIG Information Enumeration Leaf;\n BREAK;\n EAX = 1CH:\n EAX := Last Branch Record Information Enumeration Leaf; (* See Table 3-8. *)\n EBX := Last Branch Record Information Enumeration Leaf;\n ECX := Last Branch Record Information Enumeration Leaf;\n EDX := Last Branch Record Information Enumeration Leaf;\n BREAK;\n EAX = 1DH:\n EAX := Tile Information Enumeration Leaf; (* See Table 3-8. *)\n EBX := Tile Information Enumeration Leaf;\n ECX := Tile Information Enumeration Leaf;\n EDX := Tile Information Enumeration Leaf;\n BREAK;\n EAX = 1EH:\n EAX := TMUL Information Enumeration Leaf; (* See Table 3-8. *)\n EBX := TMUL Information Enumeration Leaf;\n ECX := TMUL Information Enumeration Leaf;\n EDX := TMUL Information Enumeration Leaf;\n BREAK;\n EAX = 1FH:\n EAX := V2 Extended Topology Enumeration Leaf; (* See Table 3-8. *)\n EBX := V2 Extended Topology Enumeration Leaf;\n ECX := V2 Extended Topology Enumeration Leaf;\n EDX := V2 Extended Topology Enumeration Leaf;\n BREAK;\n EAX = 20H:\n EAX := Processor History Reset Sub-leaf; (* See Table 3-8. *)\n EBX := Processor History Reset Sub-leaf;\n ECX := Processor History Reset Sub-leaf;\n EDX := Processor History Reset Sub-leaf;\n BREAK;\n EAX = 80000000H:\n EAX := Highest extended function input value understood by CPUID;\n EBX := Reserved;\n ECX := Reserved;\n EDX := Reserved;\n BREAK;\n EAX = 80000001H:\n EAX := Reserved;\n EBX := Reserved;\n ECX := Extended Feature Bits (* See Table 3-8.*);\n EDX := Extended Feature Bits (* See Table 3-8. *);\n BREAK;\n EAX = 80000002H:\n EAX := Processor Brand String;\n EBX := Processor Brand String,\n continued;\n ECX := Processor Brand String,\n continued;\n EDX := Processor Brand String,\n continued;\n BREAK;\n EAX = 80000003H:\n EAX := Processor Brand String,\n continued;\n EBX := Processor Brand String,\n continued;\n ECX := Processor Brand String,\n continued;\n EDX := Processor Brand String,\n continued;\n BREAK;\n EAX = 80000004H:\n EAX := Processor Brand String,\n continued;\n EBX := Processor Brand String,\n continued;\n ECX := Processor Brand String,\n continued;\n EDX := Processor Brand String, continued;\n BREAK;\n EAX = 80000005H:\n EAX := Reserved = 0;\n EBX := Reserved = 0;\n ECX := Reserved = 0;\n EDX := Reserved = 0;\n BREAK;\n EAX = 80000006H:\n EAX := Reserved = 0;\n EBX := Reserved = 0;\n ECX := Cache information;\n EDX := Reserved = 0;\n BREAK;\n EAX = 80000007H:\n EAX := Reserved = 0;\n EBX := Reserved = 0;\n ECX := Reserved = 0;\n EDX := Reserved = Misc Feature Flags;\n BREAK;\n EAX = 80000008H:\n EAX := Address Size Information;\n EBX := Misc Feature Flags;\n ECX := Reserved = 0;\n EDX := Reserved = 0;\n BREAK;\n EAX >= 40000000H and EAX <= 4FFFFFFFH:\n DEFAULT: (* EAX = Value outside of recognized range for CPUID. *)\n (* If the highest basic information leaf data depend on ECX input value, ECX is honored.*)\n EAX := Reserved; (* Information returned for highest basic information leaf. *)\n EBX := Reserved; (* Information returned for highest basic information leaf. *)\n ECX := Reserved; (* Information returned for highest basic information leaf. *)\n EDX := Reserved; (* Information returned for highest basic information leaf. *)\n BREAK;\nESAC;\n", + "url": "https://www.felixcloutier.com/x86/cpuid" + }, + "cqo": { + "instruction": "CQO", + "title": "CWD/CDQ/CQO\n\t\t— Convert Word to Doubleword/Convert Doubleword to Quadword", + "opcode": "REX.W + 99", + "description": "Doubles the size of the operand in register AX, EAX, or RAX (depending on the operand size) by means of sign extension and stores the result in registers DX:AX, EDX:EAX, or RDX:RAX, respectively. The CWD instruction copies the sign (bit 15) of the value in the AX register into every bit position in the DX register. The CDQ instruction copies the sign (bit 31) of the value in the EAX register into every bit position in the EDX register. The CQO instruction (available in 64-bit mode only) copies the sign (bit 63) of the value in the RAX register into every bit position in the RDX register.\nThe CWD instruction can be used to produce a doubleword dividend from a word before word division. The CDQ instruction can be used to produce a quadword dividend from a doubleword before doubleword division. The CQO instruction can be used to produce a double quadword dividend from a quadword before a quadword division.\nThe CWD and CDQ mnemonics reference the same opcode. The CWD instruction is intended for use when the operand-size attribute is 16 and the CDQ instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when CWD is used and to 32 when CDQ is used. Others may treat these mnemonics as synonyms (CWD/CDQ) and use the current setting of the operand-size attribute to determine the size of values to be converted, regardless of the mnemonic used.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. The CQO mnemonics reference the same opcode as CWD/CDQ. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 16 (* CWD instruction *)\n THEN\n DX := SignExtend(AX);\n ELSE IF OperandSize = 32 (* CDQ instruction *)\n EDX := SignExtend(EAX); FI;\n ELSE IF 64-Bit Mode and OperandSize = 64 (* CQO instruction*)\n RDX := SignExtend(RAX); FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cwd:cdq:cqo" + }, + "crc32": { + "instruction": "CRC32", + "title": "CRC32\n\t\t— Accumulate CRC32 Value", + "opcode": "F2 0F 38 F0 /r CRC32 r32, r/m8", + "description": "Starting with an initial value in the first operand (destination operand), accumulates a CRC32 (polynomial 11EDC6F41H) value for the second operand (source operand) and stores the result in the destination operand. The source operand can be a register or a memory location. The destination operand must be an r32 or r64 register. If the destination is an r64 register, then the 32-bit result is stored in the least significant double word and 00000000H is stored in the most significant double word of the r64 register.\nThe initial value supplied in the destination operand is a double word integer stored in the r32 register or the least significant double word of the r64 register. To incrementally accumulate a CRC32 value, software retains the result of the previous CRC32 operation in the destination operand, then executes the CRC32 instruction again with new input data in the source operand. Data contained in the source operand is processed in reflected bit order. This means that the most significant bit of the source operand is treated as the least significant bit of the quotient, and so on, for all the bits of the source operand. Likewise, the result of the CRC operation is stored in the destination operand in reflected bit order. This means that the most significant bit of the resulting CRC (bit 31) is stored in the least significant bit of the destination operand (bit 0), and so on, for all the bits of the CRC.", + "operation": "CRC32 instruction for 64-bit source operand and 64-bit destination operand:\n TEMP1[63-0] := BIT_REFLECT64 (SRC[63-0])\n TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])\n TEMP3[95-0] := TEMP1[63-0] « 32\n TEMP4[95-0] := TEMP2[31-0] « 64\n TEMP5[95-0] := TEMP3[95-0] XOR TEMP4[95-0]\n TEMP6[31-0] := TEMP5[95-0] MOD2 11EDC6F41H\n DEST[31-0] := BIT_REFLECT (TEMP6[31-0])\n DEST[63-32] := 00000000H\nCRC32 instruction for 32-bit source operand and 32-bit destination operand:\n TEMP1[31-0] := BIT_REFLECT32 (SRC[31-0])\n TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])\n TEMP3[63-0] := TEMP1[31-0] « 32\n TEMP4[63-0] := TEMP2[31-0] « 32\n TEMP5[63-0] := TEMP3[63-0] XOR TEMP4[63-0]\n TEMP6[31-0] := TEMP5[63-0] MOD2 11EDC6F41H\n DEST[31-0] := BIT_REFLECT (TEMP6[31-0])\nCRC32 instruction for 16-bit source operand and 32-bit destination operand:\n TEMP1[15-0] := BIT_REFLECT16 (SRC[15-0])\n TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])\n TEMP3[47-0] := TEMP1[15-0] « 32\n TEMP4[47-0] := TEMP2[31-0] « 16\n TEMP5[47-0] := TEMP3[47-0] XOR TEMP4[47-0]\n TEMP6[31-0] := TEMP5[47-0] MOD2 11EDC6F41H\n DEST[31-0] := BIT_REFLECT (TEMP6[31-0])\nCRC32 instruction for 8-bit source operand and 64-bit destination operand:\n TEMP1[7-0] := BIT_REFLECT8(SRC[7-0])\n TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])\n TEMP3[39-0] := TEMP1[7-0] « 32\n TEMP4[39-0] := TEMP2[31-0] « 8\n TEMP5[39-0] := TEMP3[39-0] XOR TEMP4[39-0]\n TEMP6[31-0] := TEMP5[39-0] MOD2 11EDC6F41H\n DEST[31-0] := BIT_REFLECT (TEMP6[31-0])\n DEST[63-32] := 00000000H\nCRC32 instruction for 8-bit source operand and 32-bit destination operand:\n TEMP1[7-0] := BIT_REFLECT8(SRC[7-0])\n TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])\n TEMP3[39-0] := TEMP1[7-0] « 32\n TEMP4[39-0] := TEMP2[31-0] « 8\n TEMP5[39-0] := TEMP3[39-0] XOR TEMP4[39-0]\n TEMP6[31-0] := TEMP5[39-0] MOD2 11EDC6F41H\n DEST[31-0] := BIT_REFLECT (TEMP6[31-0])\n", + "url": "https://www.felixcloutier.com/x86/crc32" + }, + "cvtdq2pd": { + "instruction": "CVTDQ2PD", + "title": "CVTDQ2PD\n\t\t— Convert Packed Doubleword Integers to Packed Double Precision Floating-PointValues", + "opcode": "F3 0F E6 /r CVTDQ2PD xmm1, xmm2/m64", + "description": "Converts two, four or eight packed signed doubleword integers in the source operand (the second operand) to two, four or eight packed double precision floating-point values in the destination operand (the first operand).\nEVEX encoded versions: The source operand can be a YMM/XMM/XMM (low 64 bits) register, a 256/128/64-bit memory location or a 256/128/64-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1. Attempt to encode this instruction with EVEX embedded rounding is ignored.\nVEX.256 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a YMM register.\nVEX.128 encoded version: The source operand is an XMM register or 64- bit memory location. The destination operand is a XMM register. The upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 64- bit memory location. The destination operand is an XMM register. The upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n k := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] :=\n Convert_Integer_To_Double_Precision_Floating_Point(SRC[k+31:k])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n k := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+63:i] :=\n Convert_Integer_To_Double_Precision_Floating_Point(SRC[31:0])\n ELSE\n DEST[i+63:i] :=\n Convert_Integer_To_Double_Precision_Floating_Point(SRC[k+31:k])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[31:0])\nDEST[127:64] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[63:32])\nDEST[191:128] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[95:64])\nDEST[255:192] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[127:96)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[31:0])\nDEST[127:64] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[63:32])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[31:0])\nDEST[127:64] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[63:32])\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtdq2pd" + }, + "cvtdq2ps": { + "instruction": "CVTDQ2PS", + "title": "CVTDQ2PS\n\t\t— Convert Packed Doubleword Integers to Packed Single Precision Floating-PointValues", + "opcode": "NP 0F 5B /r CVTDQ2PS xmm1, xmm2/m128", + "description": "Converts four, eight or sixteen packed signed doubleword integers in the source operand to four, eight or sixteen packed single precision floating-point values in the destination operand.\nEVEX encoded versions: The source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The source operand is a YMM register or 256- bit memory location. The destination operand is a YMM register. Bits (MAXVL-1:256) of the corresponding register destination are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 128- bit memory location. The destination operand is an XMM register. The upper Bits (MAXVL-1:128) of the corresponding register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC); ; refer to Table 15-4 in the Intel® 64 and IA-32 Architectures\nSoftware Developer’s Manual, Volume 1\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC); ; refer to Table 15-4 in the Intel® 64 and IA-32 Architectures\nSoftware Developer’s Manual, Volume 1\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n Convert_Integer_To_Single_Precision_Floating_Point(SRC[i+31:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=\n Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0])\n ELSE\n DEST[i+31:i] :=\n Convert_Integer_To_Single_Precision_Floating_Point(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0])\nDEST[63:32] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:32])\nDEST[95:64] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[95:64])\nDEST[127:96] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[127:96)\nDEST[159:128] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[159:128])\nDEST[191:160] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[191:160])\nDEST[223:192] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[223:192])\nDEST[255:224] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[255:224)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0])\nDEST[63:32] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:32])\nDEST[95:64] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[95:64])\nDEST[127:96] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[127z:96)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0])\nDEST[63:32] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:32])\nDEST[95:64] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[95:64])\nDEST[127:96] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[127z:96)\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtdq2ps" + }, + "cvtpd2dq": { + "instruction": "CVTPD2DQ", + "title": "CVTPD2DQ\n\t\t— Convert Packed Double Precision Floating-Point Values to Packed DoublewordIntegers", + "opcode": "F2 0F E6 /r CVTPD2DQ xmm1, xmm2/m128", + "description": "Converts packed double precision floating-point values in the source operand (second operand) to packed signed doubleword integers in the destination operand (first operand).\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register or the embedded rounding control bits. If a converted result cannot be represented in the destination format, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (2w-1, where w represents the number of bits in the destination format) is returned.\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1. The upper bits (MAXVL-1:256/128/64) of the corresponding destination are zeroed.\nVEX.256 encoded version: The source operand is a YMM register or 256- bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:64) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 128- bit memory location. The destination operand is an XMM register. Bits[127:64] of the destination XMM register are zeroed. However, the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n k := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n Convert_Double_Precision_Floating_Point_To_Integer(SRC[k+63:k])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL/2] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n k := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=\n Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0])\n ELSE\n DEST[i+31:i] :=\n Convert_Double_Precision_Floating_Point_To_Integer(SRC[k+63:k])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL/2] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[127:64])\nDEST[95:64] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[191:128])\nDEST[127:96] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[255:192)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[127:64])\nDEST[MAXVL-1:64] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[127:64])\nDEST[127:64] := 0\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtpd2dq" + }, + "cvtpd2pi": { + "instruction": "CVTPD2PI", + "title": "CVTPD2PI\n\t\t— Convert Packed Double Precision Floating-Point Values to Packed Dword Integers", + "opcode": "66 0F 2D /r CVTPD2PI mm, xmm/m128", + "description": "Converts two packed double precision floating-point values in the source operand (second operand) to two packed signed doubleword integers in the destination operand (first operand).\nThe source operand can be an XMM register or a 128-bit memory location. The destination operand is an MMX technology register.\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nThis instruction causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the CVTPD2PI instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer32(SRC[63:0]);\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer32(SRC[127:64]);\n", + "url": "https://www.felixcloutier.com/x86/cvtpd2pi" + }, + "cvtpd2ps": { + "instruction": "CVTPD2PS", + "title": "CVTPD2PS\n\t\t— Convert Packed Double Precision Floating-Point Values to Packed Single PrecisionFloating-Point Values", + "opcode": "66 0F 5A /r CVTPD2PS xmm1, xmm2/m128", + "description": "Converts two, four or eight packed double precision floating-point values in the source operand (second operand) to two, four or eight packed single precision floating-point values in the destination operand (first operand).\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register or the embedded rounding control bits.\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a YMM/XMM/XMM (low 64-bits) register conditionally updated with writemask k1. The upper bits (MAXVL-1:256/128/64) of the corresponding destination are zeroed.\nVEX.256 encoded version: The source operand is a YMM register or 256- bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:64) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 128- bit memory location. The destination operand is an XMM register. Bits[127:64] of the destination XMM register are zeroed. However, the upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n k := j * 64\n IF k1[j] OR *no writemask*\n THEN\n DEST[i+31:i] := Convert_Double_Precision_Floating_Point_To_Single_Precision_Floating_Point(SRC[k+63:k])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL/2] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n k := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=Convert_Double_Precision_Floating_Point_To_Single_Precision_Floating_Point(SRC[63:0])\n ELSE\n DEST[i+31:i] := Convert_Double_Precision_Floating_Point_To_Single_Precision_Floating_Point(SRC[k+63:k])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL/2] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[127:64])\nDEST[95:64] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[191:128])\nDEST[127:96] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[255:192)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[127:64])\nDEST[MAXVL-1:64] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[127:64])\nDEST[127:64] := 0\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtpd2ps" + }, + "cvtpi2pd": { + "instruction": "CVTPI2PD", + "title": "CVTPI2PD\n\t\t— Convert Packed Dword Integers to Packed Double Precision Floating-Point Values", + "opcode": "66 0F 2A /r CVTPI2PD xmm, mm/m641", + "description": "Converts two packed signed doubleword integers in the source operand (second operand) to two packed double precision floating-point values in the destination operand (first operand).\nThe source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an XMM register. In addition, depending on the operand configuration:\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[31:0]);\nDEST[127:64] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[63:32]);\n", + "url": "https://www.felixcloutier.com/x86/cvtpi2pd" + }, + "cvtpi2ps": { + "instruction": "CVTPI2PS", + "title": "CVTPI2PS\n\t\t— Convert Packed Dword Integers to Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 2A /r CVTPI2PS xmm, mm/m64", + "description": "Converts two packed signed doubleword integers in the source operand (second operand) to two packed single precision floating-point values in the destination operand (first operand).\nThe source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an XMM register. The results are stored in the low quadword of the destination operand, and the high quadword remains unchanged. When a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register.\nThis instruction causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the CVTPI2PS instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0]);\nDEST[63:32] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:32]);\n(* High quadword of destination unchanged *)\n", + "url": "https://www.felixcloutier.com/x86/cvtpi2ps" + }, + "cvtps2dq": { + "instruction": "CVTPS2DQ", + "title": "CVTPS2DQ\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed SignedDoubleword Integer Values", + "opcode": "66 0F 5B /r CVTPS2DQ xmm1, xmm2/m128", + "description": "Converts four, eight or sixteen packed single precision floating-point values in the source operand to four, eight or sixteen signed doubleword integers in the destination operand.\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register or the embedded rounding control bits. If a converted result cannot be represented in the destination format, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (2w-1, where w represents the number of bits in the destination format) is returned.\nEVEX encoded versions: The source operand is a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The source operand is a YMM register or 256- bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 128- bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n Convert_Single_Precision_Floating_Point_To_Integer(SRC[i+31:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO 15\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=\n Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0])\n ELSE\n DEST[i+31:i] :=\n Convert_Single_Precision_Floating_Point_To_Integer(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0])\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[63:32])\nDEST[95:64] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[95:64])\nDEST[127:96] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[127:96)\nDEST[159:128] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[159:128])\nDEST[191:160] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[191:160])\nDEST[223:192] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[223:192])\nDEST[255:224] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[255:224])\n\n\nDEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0])\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[63:32])\nDEST[95:64] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[95:64])\nDEST[127:96] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[127:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0])\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[63:32])\nDEST[95:64] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[95:64])\nDEST[127:96] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[127:96])\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtps2dq" + }, + "cvtps2pd": { + "instruction": "CVTPS2PD", + "title": "CVTPS2PD\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed Double PrecisionFloating-Point Values", + "opcode": "NP 0F 5A /r CVTPS2PD xmm1, xmm2/m64", + "description": "Converts two, four or eight packed single precision floating-point values in the source operand (second operand) to two, four or eight packed double precision floating-point values in the destination operand (first operand).\nEVEX encoded versions: The source operand is a YMM/XMM/XMM (low 64-bits) register, a 256/128/64-bit memory location or a 256/128/64-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a YMM register. Bits (MAXVL-1:256) of the corresponding destination ZMM register are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 64- bit memory location. The destination operand is a XMM register. The upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 64- bit memory location. The destination operand is an XMM register. The upper Bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n k := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] :=\n Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[k+31:k])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n k := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+63:i] :=\n Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[31:0])\n ELSE\n DEST[i+63:i] :=\n Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[k+31:k])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[31:0])\nDEST[127:64] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[63:32])\nDEST[191:128] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[95:64])\nDEST[255:192] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[127:96)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[31:0])\nDEST[127:64] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[63:32])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[31:0])\nDEST[127:64] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[63:32])\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtps2pd" + }, + "cvtps2pi": { + "instruction": "CVTPS2PI", + "title": "CVTPS2PI\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed Dword Integers", + "opcode": "NP 0F 2D /r CVTPS2PI mm, xmm/m64", + "description": "Converts two packed single precision floating-point values in the source operand (second operand) to two packed signed doubleword integers in the destination operand (first operand).\nThe source operand can be an XMM register or a 128-bit memory location. The destination operand is an MMX technology register. When the source operand is an XMM register, the two single precision floating-point values are contained in the low quadword of the register. When a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nCVTPS2PI causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the CVTPS2PI instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0]);\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[63:32]);\n", + "url": "https://www.felixcloutier.com/x86/cvtps2pi" + }, + "cvtsd2si": { + "instruction": "CVTSD2SI", + "title": "CVTSD2SI\n\t\t— Convert Scalar Double Precision Floating-Point Value to Doubleword Integer", + "opcode": "F2 0F 2D /r CVTSD2SI r32, xmm1/m64", + "description": "Converts a double precision floating-point value in the source operand (the second operand) to a signed double-word integer in the destination operand (first operand). The source operand can be an XMM register or a 64-bit memory location. The destination operand is a general-purpose register. When the source operand is an XMM register, the double precision floating-point value is contained in the low quadword of the register.\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register.\nIf a converted result exceeds the range limits of signed doubleword integer (in non-64-bit modes or 64-bit mode with REX.W/VEX.W/EVEX.W=0), the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nIf a converted result exceeds the range limits of signed quadword integer (in 64-bit mode and REX.W/VEX.W/EVEX.W = 1), the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000_00000000H) is returned.\nLegacy SSE instruction: Use of the REX.W prefix promotes the instruction to produce 64-bit data in 64-bit mode. See the summary chart at the beginning of this section for encoding data and limits.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCVTSD2SI is encoded with VEX.L=0. Encoding VCVTSD2SI with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF SRC *is register* AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF 64-Bit Mode and OperandSize = 64\n THEN DEST[63:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0]);\n ELSE DEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0]);\nFI\n\n\nIF 64-Bit Mode and OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0]);\nELSE\n DEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer(SRC[63:0]);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cvtsd2si" + }, + "cvtsd2ss": { + "instruction": "CVTSD2SS", + "title": "CVTSD2SS\n\t\t— Convert Scalar Double Precision Floating-Point Value to Scalar Single PrecisionFloating-Point Value", + "opcode": "F2 0F 5A /r CVTSD2SS xmm1, xmm2/m64", + "description": "Converts a double precision floating-point value in the “convert-from” source operand (the second operand in SSE2 version, otherwise the third operand) to a single precision floating-point value in the destination operand.\nWhen the “convert-from” operand is an XMM register, the double precision floating-point value is contained in the low quadword of the register. The result is stored in the low doubleword of the destination operand. When the conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register.\n128-bit Legacy SSE version: The “convert-from” source operand (the second operand) is an XMM register or memory location. Bits (MAXVL-1:32) of the corresponding destination register remain unchanged. The destination operand is an XMM register.\nVEX.128 and EVEX encoded versions: The “convert-from” source operand (the third operand) can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers. Bits (127:32) of the XMM register destination are copied from the corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: the converted result in written to the low doubleword element of the destination under the writemask.\nSoftware should ensure VCVTSD2SS is encoded with VEX.L=0. Encoding VCVTSD2SS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (SRC2 *is register*) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC2[63:0]);\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC2[63:0]);\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_To_Single_Precision_Floating_Point(SRC[63:0]);\n(* DEST[MAXVL-1:32] Unmodified *)\n", + "url": "https://www.felixcloutier.com/x86/cvtsd2ss" + }, + "cvtsi2sd": { + "instruction": "CVTSI2SD", + "title": "CVTSI2SD\n\t\t— Convert Doubleword Integer to Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 2A /r CVTSI2SD xmm1, r32/m32", + "description": "Converts a signed doubleword integer (or signed quadword integer if operand size is 64 bits) in the “convert-from” source operand to a double precision floating-point value in the destination operand. The result is stored in the low quadword of the destination operand, and the high quadword left unchanged. When conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register.\nThe second source operand can be a general-purpose register or a 32/64-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: Use of the REX.W prefix promotes the instruction to 64-bit operands. The “convert-from” source operand (the second operand) is a general-purpose register or memory location. The destination is an XMM register Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded versions: The “convert-from” source operand (the third operand) can be a general-purpose register or a memory location. The first source and destination operands are XMM registers. Bits (127:64) of the XMM register destination are copied from the corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX.W0 version: attempt to encode this instruction with EVEX embedded rounding is ignored.\nVEX.W1 and EVEX.W1 versions: promotes the instruction to use 64-bit input value in 64-bit mode.\nSoftware should ensure VCVTSI2SD is encoded with VEX.L=0. Encoding VCVTSI2SD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (SRC2 *is register*) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF 64-Bit Mode And OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC2[63:0]);\nELSE\n DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC2[31:0]);\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nIF 64-Bit Mode And OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC2[63:0]);\nELSE\n DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC2[31:0]);\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nIF 64-Bit Mode And OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[63:0]);\nELSE\n DEST[63:0] := Convert_Integer_To_Double_Precision_Floating_Point(SRC[31:0]);\nFI;\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtsi2sd" + }, + "cvtsi2ss": { + "instruction": "CVTSI2SS", + "title": "CVTSI2SS\n\t\t— Convert Doubleword Integer to Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F 2A /r CVTSI2SS xmm1, r/m32", + "description": "Converts a signed doubleword integer (or signed quadword integer if operand size is 64 bits) in the “convert-from” source operand to a single precision floating-point value in the destination operand (first operand). The “convert-from” source operand can be a general-purpose register or a memory location. The destination operand is an XMM register. The result is stored in the low doubleword of the destination operand, and the upper three doublewords are left unchanged. When a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register or the embedded rounding control bits.\n128-bit Legacy SSE version: In 64-bit mode, Use of the REX.W prefix promotes the instruction to use 64-bit input value. The “convert-from” source operand (the second operand) is a general-purpose register or memory location. Bits (MAXVL-1:32) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded versions: The “convert-from” source operand (the third operand) can be a general-purpose register or a memory location. The first source and destination operands are XMM registers. Bits (127:32) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: the converted result in written to the low doubleword element of the destination under the writemask.\nSoftware should ensure VCVTSI2SS is encoded with VEX.L=0. Encoding VCVTSI2SS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (SRC2 *is register*) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF 64-Bit Mode And OperandSize = 64\nTHEN\n DEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:0]);\nELSE\n DEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0]);\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nIF 64-Bit Mode And OperandSize = 64\nTHEN\n DEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:0]);\nELSE\n DEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0]);\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nIF 64-Bit Mode And OperandSize = 64\nTHEN\n DEST[31:0] := Convert_Integer_To_Single_Precision_Floating_Point(SRC[63:0]);\nELSE\n DEST[31:0] :=Convert_Integer_To_Single_Precision_Floating_Point(SRC[31:0]);\nFI;\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtsi2ss" + }, + "cvtss2sd": { + "instruction": "CVTSS2SD", + "title": "CVTSS2SD\n\t\t— Convert Scalar Single Precision Floating-Point Value to Scalar Double PrecisionFloating-Point Value", + "opcode": "F3 0F 5A /r CVTSS2SD xmm1, xmm2/m32", + "description": "Converts a single precision floating-point value in the “convert-from” source operand to a double precision floating-point value in the destination operand. When the “convert-from” source operand is an XMM register, the single precision floating-point value is contained in the low doubleword of the register. The result is stored in the low quadword of the destination operand.\n128-bit Legacy SSE version: The “convert-from” source operand (the second operand) is an XMM register or memory location. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged. The destination operand is an XMM register.\nVEX.128 and EVEX encoded versions: The “convert-from” source operand (the third operand) can be an XMM register or a 32-bit memory location. The first source and destination operands are XMM registers. Bits (127:64) of the XMM register destination are copied from the corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nSoftware should ensure VCVTSS2SD is encoded with VEX.L=0. Encoding VCVTSS2SD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF k1[0] or *no writemask*\n THEN DEST[63:0] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC2[31:0]);\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] = 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC2[31:0])\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := Convert_Single_Precision_To_Double_Precision_Floating_Point(SRC[31:0]);\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvtss2sd" + }, + "cvtss2si": { + "instruction": "CVTSS2SI", + "title": "CVTSS2SI\n\t\t— Convert Scalar Single Precision Floating-Point Value to Doubleword Integer", + "opcode": "F3 0F 2D /r CVTSS2SI r32, xmm1/m32", + "description": "Converts a single precision floating-point value in the source operand (the second operand) to a signed doubleword integer (or signed quadword integer if operand size is 64 bits) in the destination operand (the first operand). The source operand can be an XMM register or a memory location. The destination operand is a general-purpose register. When the source operand is an XMM register, the single precision floating-point value is contained in the low doubleword of the register.\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register or the embedded rounding control bits. If a converted result cannot be represented in the destination format, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (2w-1, where w represents the number of bits in the destination format) is returned.\nLegacy SSE instructions: In 64-bit mode, Use of the REX.W prefix promotes the instruction to produce 64-bit data. See the summary chart at the beginning of this section for encoding data and limits.\nVEX.W1 and EVEX.W1 versions: promotes the instruction to produce 64-bit data in 64-bit mode.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCVTSS2SI is encoded with VEX.L=0. Encoding VCVTSS2SI with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (SRC *is register*) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF 64-bit Mode and OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0]);\nELSE\n DEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0]);\nFI;\n\n\nIF 64-bit Mode and OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0]);\nELSE\n DEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer(SRC[31:0]);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cvtss2si" + }, + "cvttpd2dq": { + "instruction": "CVTTPD2DQ", + "title": "CVTTPD2DQ\n\t\t— Convert with Truncation Packed Double Precision Floating-Point Values toPacked Doubleword Integers", + "opcode": "66 0F E6 /r CVTTPD2DQ xmm1, xmm2/m128", + "description": "Converts two, four or eight packed double precision floating-point values in the source operand (second operand) to two, four or eight packed signed doubleword integers in the destination operand (first operand).\nWhen a conversion is inexact, a truncated (round toward zero) value is returned. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a YMM/XMM/XMM (low 64 bits) register conditionally updated with writemask k1. The upper bits (MAXVL-1:256) of the corresponding destination are zeroed.\nVEX.256 encoded version: The source operand is a YMM register or 256- bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:64) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 128- bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n k := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[k+63:k])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL/2] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n k := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=\n Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[63:0])\n ELSE\n DEST[i+31:i] :=\n Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[k+63:k])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL/2] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[127:64])\nDEST[95:64] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[191:128])\nDEST[127:96] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[255:192)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[127:64])\nDEST[MAXVL-1:64] := 0\n\n\nDEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[63:0])\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[127:64])\nDEST[127:64] := 0\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvttpd2dq" + }, + "cvttpd2pi": { + "instruction": "CVTTPD2PI", + "title": "CVTTPD2PI\n\t\t— Convert With Truncation Packed Double Precision Floating-Point Values to PackedDword Integers", + "opcode": "66 0F 2C /r CVTTPD2PI mm, xmm/m128", + "description": "Converts two packed double precision floating-point values in the source operand (second operand) to two packed signed doubleword integers in the destination operand (first operand). The source operand can be an XMM register or a 128-bit memory location. The destination operand is an MMX technology register.\nWhen a conversion is inexact, a truncated (round toward zero) result is returned. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nThis instruction causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the CVTTPD2PI instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer32_Truncate(SRC[63:0]);\nDEST[63:32] := Convert_Double_Precision_Floating_Point_To_Integer32_Truncate(SRC[127:64]);\n", + "url": "https://www.felixcloutier.com/x86/cvttpd2pi" + }, + "cvttps2dq": { + "instruction": "CVTTPS2DQ", + "title": "CVTTPS2DQ\n\t\t— Convert With Truncation Packed Single Precision Floating-Point Values to PackedSigned Doubleword Integer Values", + "opcode": "F3 0F 5B /r CVTTPS2DQ xmm1, xmm2/m128", + "description": "Converts four, eight or sixteen packed single precision floating-point values in the source operand to four, eight or sixteen signed doubleword integers in the destination operand.\nWhen a conversion is inexact, a truncated (round toward zero) value is returned. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The source operand is a YMM register or 256- bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The source operand is an XMM register or 128- bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The source operand is an XMM register or 128- bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[i+31:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO 15\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1)\n THEN\n DEST[i+31:i] :=\n Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0])\n ELSE\n DEST[i+31:i] :=\n Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0])\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[63:32])\nDEST[95:64] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[95:64])\nDEST[127:96] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[127:96)\nDEST[159:128] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[159:128])\nDEST[191:160] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[191:160])\nDEST[223:192] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[223:192])\nDEST[255:224] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[255:224])\n\n\nDEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0])\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[63:32])\nDEST[95:64] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[95:64])\nDEST[127:96] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[127:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0])\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[63:32])\nDEST[95:64] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[95:64])\nDEST[127:96] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[127:96])\nDEST[MAXVL-1:128] (unmodified)\n", + "url": "https://www.felixcloutier.com/x86/cvttps2dq" + }, + "cvttps2pi": { + "instruction": "CVTTPS2PI", + "title": "CVTTPS2PI\n\t\t— Convert With Truncation Packed Single Precision Floating-Point Values to PackedDword Integers", + "opcode": "NP 0F 2C /r CVTTPS2PI mm, xmm/m64", + "description": "Converts two packed single precision floating-point values in the source operand (second operand) to two packed signed doubleword integers in the destination operand (first operand). The source operand can be an XMM register or a 64-bit memory location. The destination operand is an MMX technology register. When the source operand is an XMM register, the two single precision floating-point values are contained in the low quadword of the register.\nWhen a conversion is inexact, a truncated (round toward zero) result is returned. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nThis instruction causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the CVTTPS2PI instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0]);\nDEST[63:32] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[63:32]);\n", + "url": "https://www.felixcloutier.com/x86/cvttps2pi" + }, + "cvttsd2si": { + "instruction": "CVTTSD2SI", + "title": "CVTTSD2SI\n\t\t— Convert With Truncation Scalar Double Precision Floating-Point Value to SignedInteger", + "opcode": "F2 0F 2C /r CVTTSD2SI r32, xmm1/m64", + "description": "Converts a double precision floating-point value in the source operand (the second operand) to a signed double-word integer (or signed quadword integer if operand size is 64 bits) in the destination operand (the first operand). The source operand can be an XMM register or a 64-bit memory location. The destination operand is a general purpose register. When the source operand is an XMM register, the double precision floating-point value is contained in the low quadword of the register.\nWhen a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register.\nIf a converted result exceeds the range limits of signed doubleword integer (in non-64-bit modes or 64-bit mode with REX.W/VEX.W/EVEX.W=0), the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000H) is returned.\nIf a converted result exceeds the range limits of signed quadword integer (in 64-bit mode and REX.W/VEX.W/EVEX.W = 1), the floating-point invalid exception is raised, and if this exception is masked, the indefinite integer value (80000000_00000000H) is returned.\nLegacy SSE instructions: In 64-bit mode, Use of the REX.W prefix promotes the instruction to 64-bit operation. See the summary chart at the beginning of this section for encoding data and limits.\nVEX.W1 and EVEX.W1 versions: promotes the instruction to produce 64-bit data in 64-bit mode.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCVTTSD2SI is encoded with VEX.L=0. Encoding VCVTTSD2SI with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF 64-Bit Mode and OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[63:0]);\nELSE\n DEST[31:0] := Convert_Double_Precision_Floating_Point_To_Integer_Truncate(SRC[63:0]);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cvttsd2si" + }, + "cvttss2si": { + "instruction": "CVTTSS2SI", + "title": "CVTTSS2SI\n\t\t— Convert With Truncation Scalar Single Precision Floating-Point Value to Integer", + "opcode": "F3 0F 2C /r CVTTSS2SI r32, xmm1/m32", + "description": "Converts a single precision floating-point value in the source operand (the second operand) to a signed doubleword integer (or signed quadword integer if operand size is 64 bits) in the destination operand (the first operand). The source operand can be an XMM register or a 32-bit memory location. The destination operand is a general purpose register. When the source operand is an XMM register, the single precision floating-point value is contained in the low doubleword of the register.\nWhen a conversion is inexact, a truncated (round toward zero) result is returned. If a converted result is larger than the maximum signed doubleword integer, the floating-point invalid exception is raised. If this exception is masked, the indefinite integer value (80000000H or 80000000_00000000H if operand size is 64 bits) is returned.\nLegacy SSE instructions: In 64-bit mode, Use of the REX.W prefix promotes the instruction to 64-bit operation. See the summary chart at the beginning of this section for encoding data and limits.\nVEX.W1 and EVEX.W1 versions: promotes the instruction to produce 64-bit data in 64-bit mode.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCVTTSS2SI is encoded with VEX.L=0. Encoding VCVTTSS2SI with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF 64-Bit Mode and OperandSize = 64\nTHEN\n DEST[63:0] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0]);\nELSE\n DEST[31:0] := Convert_Single_Precision_Floating_Point_To_Integer_Truncate(SRC[31:0]);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cvttss2si" + }, + "cwd": { + "instruction": "CWD", + "title": "CWD/CDQ/CQO\n\t\t— Convert Word to Doubleword/Convert Doubleword to Quadword", + "opcode": "99", + "description": "Doubles the size of the operand in register AX, EAX, or RAX (depending on the operand size) by means of sign extension and stores the result in registers DX:AX, EDX:EAX, or RDX:RAX, respectively. The CWD instruction copies the sign (bit 15) of the value in the AX register into every bit position in the DX register. The CDQ instruction copies the sign (bit 31) of the value in the EAX register into every bit position in the EDX register. The CQO instruction (available in 64-bit mode only) copies the sign (bit 63) of the value in the RAX register into every bit position in the RDX register.\nThe CWD instruction can be used to produce a doubleword dividend from a word before word division. The CDQ instruction can be used to produce a quadword dividend from a doubleword before doubleword division. The CQO instruction can be used to produce a double quadword dividend from a quadword before a quadword division.\nThe CWD and CDQ mnemonics reference the same opcode. The CWD instruction is intended for use when the operand-size attribute is 16 and the CDQ instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when CWD is used and to 32 when CDQ is used. Others may treat these mnemonics as synonyms (CWD/CDQ) and use the current setting of the operand-size attribute to determine the size of values to be converted, regardless of the mnemonic used.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. The CQO mnemonics reference the same opcode as CWD/CDQ. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 16 (* CWD instruction *)\n THEN\n DX := SignExtend(AX);\n ELSE IF OperandSize = 32 (* CDQ instruction *)\n EDX := SignExtend(EAX); FI;\n ELSE IF 64-Bit Mode and OperandSize = 64 (* CQO instruction*)\n RDX := SignExtend(RAX); FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cwd:cdq:cqo" + }, + "cwde": { + "instruction": "CWDE", + "title": "CBW/CWDE/CDQE\n\t\t— Convert Byte to Word/Convert Word to Doubleword/Convert Doubleword toQuadword", + "opcode": "98", + "description": "Double the size of the source operand by means of sign extension. The CBW (convert byte to word) instruction copies the sign (bit 7) in the source operand into every bit in the AH register. The CWDE (convert word to double-word) instruction copies the sign (bit 15) of the word in the AX register into the high 16 bits of the EAX register.\nCBW and CWDE reference the same opcode. The CBW instruction is intended for use when the operand-size attribute is 16; CWDE is intended for use when the operand-size attribute is 32. Some assemblers may force the operand size. Others may treat these two mnemonics as synonyms (CBW/CWDE) and use the setting of the operand-size attribute to determine the size of values to be converted.\nIn 64-bit mode, the default operation size is the size of the destination register. Use of the REX.W prefix promotes this instruction (CDQE when promoted) to operate on 64-bit operands. In which case, CDQE copies the sign (bit 31) of the doubleword in the EAX register into the high 32 bits of RAX.", + "operation": "IF OperandSize = 16 (* Instruction = CBW *)\n THEN\n AX := SignExtend(AL);\n ELSE IF (OperandSize = 32, Instruction = CWDE)\n EAX := SignExtend(AX); FI;\n ELSE (* 64-Bit Mode, OperandSize = 64, Instruction = CDQE*)\n RAX := SignExtend(EAX);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/cbw:cwde:cdqe" + }, + "daa": { + "instruction": "DAA", + "title": "DAA\n\t\t— Decimal Adjust AL After Addition", + "opcode": "27", + "description": "Adjusts the sum of two packed BCD values to create a packed BCD result. The AL register is the implied source and destination operand. The DAA instruction is only useful when it follows an ADD instruction that adds (binary addition) two 2-digit, packed BCD values and stores a byte result in the AL register. The DAA instruction then adjusts the contents of the AL register to contain the correct 2-digit, packed BCD result. If a decimal carry is detected, the CF and AF flags are set accordingly.\nThis instruction executes as described above in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\n ELSE\n old_AL := AL;\n old_CF := CF;\n CF := 0;\n IF (((AL AND 0FH) > 9) or AF = 1)\n THEN\n AL := AL + 6;\n CF := old_CF or (Carry from AL := AL + 6);\n AF := 1;\n ELSE\n AF := 0;\n FI;\n IF ((old_AL > 99H) or (old_CF = 1))\n THEN\n AL := AL + 60H;\n CF := 1;\n ELSE\n CF := 0;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/daa" + }, + "das": { + "instruction": "DAS", + "title": "DAS\n\t\t— Decimal Adjust AL After Subtraction", + "opcode": "2F", + "description": "Adjusts the result of the subtraction of two packed BCD values to create a packed BCD result. The AL register is the implied source and destination operand. The DAS instruction is only useful when it follows a SUB instruction that subtracts (binary subtraction) one 2-digit, packed BCD value from another and stores a byte result in the AL register. The DAS instruction then adjusts the contents of the AL register to contain the correct 2-digit, packed BCD result. If a decimal borrow is detected, the CF and AF flags are set accordingly.\nThis instruction executes as described above in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\n ELSE\n old_AL := AL;\n old_CF := CF;\n CF := 0;\n IF (((AL AND 0FH) > 9) or AF = 1)\n THEN\n AL:=AL -6;\n CF := old_CF or (Borrow from AL := AL − 6);\n AF := 1;\n ELSE\n AF := 0;\n FI;\n IF ((old_AL > 99H) or (old_CF = 1))\n THEN\n AL := AL − 60H;\n CF := 1;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/das" + }, + "dec": { + "instruction": "DEC", + "title": "DEC\n\t\t— Decrement by 1", + "opcode": "FE /1", + "description": "Subtracts 1 from the destination operand, while preserving the state of the CF flag. The destination operand can be a register or a memory location. This instruction allows a loop counter to be updated without disturbing the CF flag. (To perform a decrement operation that updates the CF flag, use a SUB instruction with an immediate operand of 1.)\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, DEC r16 and DEC r32 are not encodable (because opcodes 48H through 4FH are REX prefixes). Otherwise, the instruction’s 64-bit mode default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits.\nSee the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := DEST – 1;\n", + "url": "https://www.felixcloutier.com/x86/dec" + }, + "div": { + "instruction": "DIV", + "title": "DIV\n\t\t— Unsigned Divide", + "opcode": "F6 /6", + "description": "Divides unsigned the value in the AX, DX:AX, EDX:EAX, or RDX:RAX registers (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL), DX:AX, EDX:EAX, or RDX:RAX registers. The source operand can be a general-purpose register or a memory location. The action of this instruction depends on the operand size (dividend/divisor). Division using 64-bit operand is available only in 64-bit mode.\nNon-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magnitude. Overflow is indicated with the #DE (divide error) exception rather than with the CF flag.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is applied, the instruction divides the unsigned value in RDX:RAX by the source operand and stores the quotient in RAX, the remainder in RDX.\nSee the summary chart at the beginning of this section for encoding data and limits. See Table 3-15.", + "operation": "IF SRC = 0\n THEN #DE; FI; (* Divide Error *)\nIF OperandSize = 8 (* Word/Byte Operation *)\n THEN\n temp := AX / SRC;\n IF temp > FFH\n THEN #DE; (* Divide error *)\n ELSE\n AL := temp;\n AH := AX MOD SRC;\n FI;\n ELSE IF OperandSize = 16 (* Doubleword/word operation *)\n THEN\n temp := DX:AX / SRC;\n IF temp > FFFFH\n THEN #DE; (* Divide error *)\n ELSE\n AX := temp;\n DX := DX:AX MOD SRC;\n FI;\n FI;\n ELSE IF Operandsize = 32 (* Quadword/doubleword operation *)\n THEN\n temp := EDX:EAX / SRC;\n IF temp > FFFFFFFFH\n THEN #DE; (* Divide error *)\n ELSE\n EAX := temp;\n EDX := EDX:EAX MOD SRC;\n FI;\n FI;\n ELSE IF 64-Bit Mode and Operandsize = 64 (* Doublequadword/quadword operation *)\n THEN\n temp := RDX:RAX / SRC;\n IF temp > FFFFFFFFFFFFFFFFH\n THEN #DE; (* Divide error *)\n ELSE\n RAX := temp;\n RDX := RDX:RAX MOD SRC;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/div" + }, + "divpd": { + "instruction": "DIVPD", + "title": "DIVPD\n\t\t— Divide Packed Double Precision Floating-Point Values", + "opcode": "66 0F 5E /r DIVPD xmm1, xmm2/m128", + "description": "Performs a SIMD divide of the double precision floating-point values in the first source operand by the floating-point values in the second source operand (the third operand). Results are written to the destination operand (the first operand).\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand (the second operand) is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding destination are zeroed.\nVEX.128 encoded version: The first source operand (the second operand) is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding destination are zeroed.\n128-bit Legacy SSE version: The second source operand (the second operand) can be an XMM register or an 128-bit memory location. The destination is the same as the first source operand. The upper bits (MAXVL-1:128) of the corresponding destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC); ; refer to Table 15-4 in the Intel® 64 and IA-32 Architectures\nSoftware Developer’s Manual, Volume 1\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := SRC1[i+63:i] / SRC2[63:0]\n ELSE\n DEST[i+63:i] := SRC1[i+63:i] / SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0] / SRC2[63:0]\nDEST[127:64] := SRC1[127:64] / SRC2[127:64]\nDEST[191:128] := SRC1[191:128] / SRC2[191:128]\nDEST[255:192] := SRC1[255:192] / SRC2[255:192]\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[63:0] := SRC1[63:0] / SRC2[63:0]\nDEST[127:64] := SRC1[127:64] / SRC2[127:64]\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[63:0] := SRC1[63:0] / SRC2[63:0]\nDEST[127:64] := SRC1[127:64] / SRC2[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/divpd" + }, + "divps": { + "instruction": "DIVPS", + "title": "DIVPS\n\t\t— Divide Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 5E /r DIVPS xmm1, xmm2/m128", + "description": "Performs a SIMD divide of the four, eight or sixteen packed single precision floating-point values in the first source operand (the second operand) by the four, eight or sixteen packed single precision floating-point values in the second source operand (the third operand). Results are written to the destination operand (the first operand).\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+31:i] := SRC1[i+31:i] / SRC2[31:0]\n ELSE\n DEST[i+31:i] := SRC1[i+31:i] / SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[31:0] / SRC2[31:0]\nDEST[63:32] := SRC1[63:32] / SRC2[63:32]\nDEST[95:64] := SRC1[95:64] / SRC2[95:64]\nDEST[127:96] := SRC1[127:96] / SRC2[127:96]\nDEST[159:128] := SRC1[159:128] / SRC2[159:128]\nDEST[191:160] := SRC1[191:160] / SRC2[191:160]\nDEST[223:192] := SRC1[223:192] / SRC2[223:192]\nDEST[255:224] := SRC1[255:224] / SRC2[255:224].\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[31:0] := SRC1[31:0] / SRC2[31:0]\nDEST[63:32] := SRC1[63:32] / SRC2[63:32]\nDEST[95:64] := SRC1[95:64] / SRC2[95:64]\nDEST[127:96] := SRC1[127:96] / SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] / SRC2[31:0]\nDEST[63:32] := SRC1[63:32] / SRC2[63:32]\nDEST[95:64] := SRC1[95:64] / SRC2[95:64]\nDEST[127:96] := SRC1[127:96] / SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/divps" + }, + "divsd": { + "instruction": "DIVSD", + "title": "DIVSD\n\t\t— Divide Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 5E /r DIVSD xmm1, xmm2/m64", + "description": "Divides the low double precision floating-point value in the first source operand by the low double precision floating-point value in the second source operand, and stores the double precision floating-point result in the destination operand. The second source operand can be an XMM register or a 64-bit memory location. The first source and destination are XMM registers.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:64) of the corresponding ZMM destination register remain unchanged.\nVEX.128 encoded version: The first source operand is an xmm register encoded by VEX.vvvv. The quadword at bits 127:64 of the destination operand is copied from the corresponding quadword of the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX.128 encoded version: The first source operand is an xmm register encoded by EVEX.vvvv. The quadword element of the destination operand at bits 127:64 are copied from the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX version: The low quadword element of the destination is updated according to the writemask.\nSoftware should ensure VDIVSD is encoded with VEX.L=0. Encoding VDIVSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC1[63:0] / SRC2[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0] / SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] / SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/divsd" + }, + "divss": { + "instruction": "DIVSS", + "title": "DIVSS\n\t\t— Divide Scalar Single Precision Floating-Point Values", + "opcode": "F3 0F 5E /r DIVSS xmm1, xmm2/m32", + "description": "Divides the low single precision floating-point value in the first source operand by the low single precision floating-point value in the second source operand, and stores the single precision floating-point result in the destination operand. The second source operand can be an XMM register or a 32-bit memory location.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source operand is an xmm register encoded by VEX.vvvv. The three high-order doublewords of the destination operand are copied from the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX.128 encoded version: The first source operand is an xmm register encoded by EVEX.vvvv. The doubleword elements of the destination operand at bits 127:32 are copied from the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX version: The low doubleword element of the destination is updated according to the writemask.\nSoftware should ensure VDIVSS is encoded with VEX.L=0. Encoding VDIVSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC1[31:0] / SRC2[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] / SRC2[31:0]\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0] / SRC[31:0]\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/divss" + }, + "dppd": { + "instruction": "DPPD", + "title": "DPPD\n\t\t— Dot Product of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 3A 41 /r ib DPPD xmm1, xmm2/m128, imm8", + "description": "Conditionally multiplies the packed double precision floating-point values in the destination operand (first operand) with the packed double precision floating-point values in the source (second operand) depending on a mask extracted from bits [5:4] of the immediate operand (third operand). If a condition mask bit is zero, the corresponding multiplication is replaced by a value of 0.0 in the manner described by Section 12.8.4 of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nThe two resulting double precision values are summed into an intermediate result. The intermediate result is conditionally broadcasted to the destination using a broadcast mask specified by bits [1:0] of the immediate byte.\nIf a broadcast mask bit is “1”, the intermediate result is copied to the corresponding qword element in the destination operand. If a broadcast mask bit is zero, the corresponding element in the destination is set to zero.\nDPPD follows the NaN forwarding rules stated in the Software Developer’s Manual, vol. 1, table 4-7. These rules do not cover horizontal prioritization of NaNs. Horizontal propagation of NaNs to the destination and the positioning of those NaNs in the destination is implementation dependent. NaNs on the input sources or computationally generated NaNs will have at least one NaN propagated to the destination.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nIf VDPPD is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "IF (imm8[4] = 1)\n THEN Temp1[63:0] := DEST[63:0] * SRC[63:0]; // update SIMD exception flags\n ELSE Temp1[63:0] := +0.0; FI;\nIF (imm8[5] = 1)\n THEN Temp1[127:64] := DEST[127:64] * SRC[127:64]; // update SIMD exception flags\n ELSE Temp1[127:64] := +0.0; FI;\n/* if unmasked exception reported, execute exception handler*/\nTemp2[63:0] := Temp1[63:0] + Temp1[127:64]; // update SIMD exception flags\n/* if unmasked exception reported, execute exception handler*/\nIF (imm8[0] = 1)\n THEN DEST[63:0] := Temp2[63:0];\n ELSE DEST[63:0] := +0.0; FI;\nIF (imm8[1] = 1)\n THEN DEST[127:64] := Temp2[63:0];\n ELSE DEST[127:64] := +0.0; FI;\n\n\nDEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/dppd" + }, + "dpps": { + "instruction": "DPPS", + "title": "DPPS\n\t\t— Dot Product of Packed Single Precision Floating-Point Values", + "opcode": "66 0F 3A 40 /r ib DPPS xmm1, xmm2/m128, imm8", + "description": "Conditionally multiplies the packed single precision floating-point values in the destination operand (first operand) with the packed single precision floats in the source (second operand) depending on a mask extracted from the high 4 bits of the immediate byte (third operand). If a condition mask bit in imm8[7:4] is zero, the corresponding multiplication is replaced by a value of 0.0 in the manner described by Section 12.8.4 of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nThe four resulting single precision values are summed into an intermediate result. The intermediate result is conditionally broadcasted to the destination using a broadcast mask specified by bits [3:0] of the immediate byte.\nIf a broadcast mask bit is “1”, the intermediate result is copied to the corresponding dword element in the destination operand. If a broadcast mask bit is zero, the corresponding element in the destination is set to zero.\nDPPS follows the NaN forwarding rules stated in the Software Developer’s Manual, vol. 1, table 4-7. These rules do not cover horizontal prioritization of NaNs. Horizontal propagation of NaNs to the destination and the positioning of those NaNs in the destination is implementation dependent. NaNs on the input sources or computationally generated NaNs will have at least one NaN propagated to the destination.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "IF (imm8[4] = 1)\n THEN Temp1[31:0] := DEST[31:0] * SRC[31:0]; // update SIMD exception flags\n ELSE Temp1[31:0] := +0.0; FI;\nIF (imm8[5] = 1)\n THEN Temp1[63:32] := DEST[63:32] * SRC[63:32]; // update SIMD exception flags\n ELSE Temp1[63:32] := +0.0; FI;\nIF (imm8[6] = 1)\n THEN Temp1[95:64] := DEST[95:64] * SRC[95:64]; // update SIMD exception flags\n ELSE Temp1[95:64] := +0.0; FI;\nIF (imm8[7] = 1)\n THEN Temp1[127:96] := DEST[127:96] * SRC[127:96]; // update SIMD exception flags\n ELSE Temp1[127:96] := +0.0; FI;\nTemp2[31:0] := Temp1[31:0] + Temp1[63:32]; // update SIMD exception flags\n/* if unmasked exception reported, execute exception handler*/\nTemp3[31:0] := Temp1[95:64] + Temp1[127:96]; // update SIMD exception flags\n/* if unmasked exception reported, execute exception handler*/\nTemp4[31:0] := Temp2[31:0] + Temp3[31:0]; // update SIMD exception flags\n/* if unmasked exception reported, execute exception handler*/\nIF (imm8[0] = 1)\n THEN DEST[31:0] := Temp4[31:0];\n ELSE DEST[31:0] := +0.0; FI;\nIF (imm8[1] = 1)\n THEN DEST[63:32] := Temp4[31:0];\n ELSE DEST[63:32] := +0.0; FI;\nIF (imm8[2] = 1)\n THEN DEST[95:64] := Temp4[31:0];\n ELSE DEST[95:64] := +0.0; FI;\nIF (imm8[3] = 1)\n THEN DEST[127:96] := Temp4[31:0];\n ELSE DEST[127:96] := +0.0; FI;\n\n\nDEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);\nDEST[255:128] := DP_Primitive(SRC1[255:128], SRC2[255:128]);\n", + "url": "https://www.felixcloutier.com/x86/dpps" + }, + "eaccept": { + "instruction": "EACCEPT", + "title": "EACCEPT\n\t\t— Accept Changes to an EPC Page", + "opcode": "EAX = 05H ENCLU[EACCEPT]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eaccept" + }, + "eacceptcopy": { + "instruction": "EACCEPTCOPY", + "title": "EACCEPTCOPY\n\t\t— Initialize a Pending Page", + "opcode": "EAX = 07H ENCLU[EACCEPTCOPY]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eacceptcopy" + }, + "eadd": { + "instruction": "EADD", + "title": "EADD\n\t\t— Add a Page to an Uninitialized Enclave", + "opcode": "EAX = 01H ENCLS[EADD]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eadd" + }, + "eaug": { + "instruction": "EAUG", + "title": "EAUG\n\t\t— Add a Page to an Initialized Enclave", + "opcode": "EAX = 0DH ENCLS[EAUG]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eaug" + }, + "eblock": { + "instruction": "EBLOCK", + "title": "EBLOCK\n\t\t— Mark a page in EPC as Blocked", + "opcode": "EAX = 09H ENCLS[EBLOCK]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eblock" + }, + "ecreate": { + "instruction": "ECREATE", + "title": "ECREATE\n\t\t— Create an SECS page in the Enclave Page Cache", + "opcode": "EAX = 00H ENCLS[ECREATE]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/ecreate" + }, + "edbgrd": { + "instruction": "EDBGRD", + "title": "EDBGRD\n\t\t— Read From a Debug Enclave", + "opcode": "EAX = 04H ENCLS[EDBGRD]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/edbgrd" + }, + "edbgwr": { + "instruction": "EDBGWR", + "title": "EDBGWR\n\t\t— Write to a Debug Enclave", + "opcode": "EAX = 05H ENCLS[EDBGWR]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/edbgwr" + }, + "edeccssa": { + "instruction": "EDECCSSA", + "title": "EDECCSSA\n\t\t— Decrements TCS.CSSA", + "opcode": "EAX = 09H ENCLU[EDECCSSA]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/edeccssa" + }, + "edecvirtchild": { + "instruction": "EDECVIRTCHILD", + "title": "EDECVIRTCHILD\n\t\t— Decrement VIRTCHILDCNT in SECS", + "opcode": "EAX = 00H ENCLV[EDECVIRTCHILD]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/edecvirtchild" + }, + "eenter": { + "instruction": "EENTER", + "title": "EENTER\n\t\t— Enters an Enclave", + "opcode": "EAX = 02H ENCLU[EENTER]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eenter" + }, + "eexit": { + "instruction": "EEXIT", + "title": "EEXIT\n\t\t— Exits an Enclave", + "opcode": "", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eexit" + }, + "eextend": { + "instruction": "EEXTEND", + "title": "EEXTEND\n\t\t— Extend Uninitialized Enclave Measurement by 256 Bytes", + "opcode": "EAX = 06H ENCLS[EEXTEND]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eextend" + }, + "egetkey": { + "instruction": "EGETKEY", + "title": "EGETKEY\n\t\t— Retrieves a Cryptographic Key", + "opcode": "EAX = 01H ENCLU[EGETKEY]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/egetkey" + }, + "eincvirtchild": { + "instruction": "EINCVIRTCHILD", + "title": "EINCVIRTCHILD\n\t\t— Increment VIRTCHILDCNT in SECS", + "opcode": "EAX = 01H ENCLV[EINCVIRTCHILD]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eincvirtchild" + }, + "einit": { + "instruction": "EINIT", + "title": "EINIT\n\t\t— Initialize an Enclave for Execution", + "opcode": "EAX = 02H ENCLS[EINIT]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/einit" + }, + "eldb": { + "instruction": "ELDB", + "title": "ELDB/ELDU/ELDBC/ELDUC\n\t\t— Load an EPC Page and Mark its State", + "opcode": "EAX = 07H ENCLS[ELDB]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eldb:eldu:eldbc:elduc" + }, + "eldbc": { + "instruction": "ELDBC", + "title": "ELDB/ELDU/ELDBC/ELDUC\n\t\t— Load an EPC Page and Mark its State", + "opcode": "EAX = 07H ENCLS[ELDB]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eldb:eldu:eldbc:elduc" + }, + "eldu": { + "instruction": "ELDU", + "title": "ELDB/ELDU/ELDBC/ELDUC\n\t\t— Load an EPC Page and Mark its State", + "opcode": "EAX = 07H ENCLS[ELDB]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eldb:eldu:eldbc:elduc" + }, + "elduc": { + "instruction": "ELDUC", + "title": "ELDB/ELDU/ELDBC/ELDUC\n\t\t— Load an EPC Page and Mark its State", + "opcode": "EAX = 07H ENCLS[ELDB]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eldb:eldu:eldbc:elduc" + }, + "emms": { + "instruction": "EMMS", + "title": "EMMS\n\t\t— Empty MMX Technology State", + "opcode": "NP 0F 77", + "description": "Sets the values of all the tags in the x87 FPU tag word to empty (all 1s). This operation marks the x87 FPU data registers (which are aliased to the MMX technology registers) as available for use by x87 FPU floating-point instructions. (See Figure 8-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for the format of the x87 FPU tag word.) All other MMX instructions (other than the EMMS instruction) set all the tags in x87 FPU tag word to valid (all 0s).\nThe EMMS instruction must be used to clear the MMX technology state at the end of all MMX technology procedures or subroutines and before calling other procedures or subroutines that may execute x87 floating-point instructions. If a floating-point instruction loads one of the registers in the x87 FPU data register stack before the x87 FPU tag word has been reset by the EMMS instruction, an x87 floating-point register stack overflow can occur that will result in an x87 floating-point exception or incorrect result.\nEMMS operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "x87FPUTagWord := FFFFH;\n", + "url": "https://www.felixcloutier.com/x86/emms" + }, + "emodpe": { + "instruction": "EMODPE", + "title": "EMODPE\n\t\t— Extend an EPC Page Permissions", + "opcode": "EAX = 06H ENCLU[EMODPE]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/emodpe" + }, + "emodpr": { + "instruction": "EMODPR", + "title": "EMODPR\n\t\t— Restrict the Permissions of an EPC Page", + "opcode": "EAX = 0EH ENCLS[EMODPR]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/emodpr" + }, + "emodt": { + "instruction": "EMODT", + "title": "EMODT\n\t\t— Change the Type of an EPC Page", + "opcode": "EAX = 0FH ENCLS[EMODT]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/emodt" + }, + "encls": { + "instruction": "ENCLS", + "title": "ENCLS\n\t\t— Execute an Enclave System Function of Specified Leaf Number", + "opcode": "NP 0F 01 CF ENCLS", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/encls" + }, + "enclu": { + "instruction": "ENCLU", + "title": "ENCLU\n\t\t— Execute an Enclave User Function of Specified Leaf Number", + "opcode": "NP 0F 01 D7 ENCLU", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/enclu" + }, + "enclv": { + "instruction": "ENCLV", + "title": "ENCLV\n\t\t— Execute an Enclave VMM Function of Specified Leaf Number", + "opcode": "NP 0F 01 C0 ENCLV", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/enclv" + }, + "encodekey128": { + "instruction": "ENCODEKEY128", + "title": "ENCODEKEY128\n\t\t— Encode 128-Bit Key With Key Locker", + "opcode": "F3 0F 38 FA 11:rrr:bbb ENCODEKEY128 r32, r32, , ", + "description": "The ENCODEKEY1281 instruction wraps a 128-bit AES key from the implicit operand XMM0 into a key handle that is then stored in the implicit destination operands XMM0-2.\nThe explicit source operand specifies handle restrictions, if any.\nThe explicit destination operand is populated with information on the source of the key and its attributes. XMM4 through XMM6 are reserved for future usages and software should not rely upon them being zeroed.", + "operation": "#GP (0) if a reserved bit2 in SRC[31:0] is set\nInputKey[127:0] := XMM0;\nKeyMetadata[2:0] = SRC[2:0];\nKeyMetadata[23:3] = 0;\n // Reserved for future usage\nKeyMetadata[27:24] = 0;\n // KeyType is AES-128 (value of 0)\nKeyMetadata[127:28] = 0;\n // Reserved for future usage\n// KeyMetadata is the AAD input and InputKey is the Plaintext input for WrapKey128\nHandle[383:0] := WrapKey128(InputKey[127:0], KeyMetadata[127:0], IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0]);\nDEST[0] := IWKey.NoBackup;\nDEST[4:1] := IWKey.KeySource[3:0];\nDEST[31:5] = 0;\nXMM0 := Handle[127:0]; // AAD\nXMM1 := Handle[255:128]; // Integrity Tag\nXMM2 := Handle[383:256]; // CipherText\n/\nXMM4 := 0;\n/\nXMM4 := 0;\nR\nXMM4 := 0;\ne\nXMM4 := 0;\ns\nXMM4 := 0;\ne\nXMM4 := 0;\nr\nXMM4 := 0;\nv\nXMM4 := 0;\ne\nXMM4 := 0;\nd\nXMM4 := 0;\nf\nXMM4 := 0;\no\nXMM4 := 0;\nr\nXMM4 := 0;\nf\nXMM4 := 0;\nu\nXMM4 := 0;\nt\nXMM4 := 0;\nu\nXMM4 := 0;\nr\nXMM4 := 0;\ne\nXMM4 := 0;\nXMM4 := 0;\n/\nXMM5 := 0;\n/\nXMM5 := 0;\nR\nXMM5 := 0;\ne\nXMM5 := 0;\ns\nXMM5 := 0;\ne\nXMM5 := 0;\nr\nXMM5 := 0;\nv\nXMM5 := 0;\ne\nXMM5 := 0;\nd\nXMM5 := 0;\nf\nXMM5 := 0;\no\nXMM5 := 0;\nr\nXMM5 := 0;\nf\nXMM5 := 0;\nu\nXMM5 := 0;\nt\nXMM5 := 0;\nu\nXMM5 := 0;\nr\nXMM5 := 0;\ne\nXMM5 := 0;\nXMM5 := 0;\n/\nXMM6 := 0;\n/\nXMM6 := 0;\nR\nXMM6 := 0;\ne\nXMM6 := 0;\ns\nXMM6 := 0;\ne\nXMM6 := 0;\nr\nXMM6 := 0;\nv\nXMM6 := 0;\ne\nXMM6 := 0;\nd\nXMM6 := 0;\nf\nXMM6 := 0;\no\nXMM6 := 0;\nr\nXMM6 := 0;\nf\nXMM6 := 0;\nu\nXMM6 := 0;\nt\nXMM6 := 0;\nu\nXMM6 := 0;\nr\nXMM6 := 0;\ne\nXMM6 := 0;\nXMM6 := 0;\nRFLAGS.OF, SF, ZF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/encodekey128" + }, + "encodekey256": { + "instruction": "ENCODEKEY256", + "title": "ENCODEKEY256\n\t\t— Encode 256-Bit Key With Key Locker", + "opcode": "F3 0F 38 FB 11:rrr:bbb ENCODEKEY256 r32, r32 ", + "description": "The ENCODEKEY2561 instruction wraps a 256-bit AES key from the implicit operand XMM1:XMM0 into a key handle that is then stored in the implicit destination operands XMM0-3.\nThe explicit source operand is a general-purpose register and specifies what handle restrictions should be built into the handle.\nThe explicit destination operand is populated with information on the source of the key and its attributes. XMM4 through XMM6 are reserved for future usages and software should not rely upon them being zeroed.", + "operation": "#GP (0) if a reserved bit2 in SRC[31:0] is set\nInputKey[255:0] := XMM1:XMM0;\nKeyMetadata[2:0] = SRC[2:0];\nKeyMetadata[23:3] = 0; // Reserved for future usage\nKeyMetadata[27:24] = 1; // KeyType is AES-256 (value of 1)\nKeyMetadata[127:28] = 0; // Reserved for future usage\n// KeyMetadata is the AAD input and InputKey is the Plaintext input for WrapKey256\nHandle[511:0] := WrapKey256(InputKey[255:0], KeyMetadata[127:0], IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0]);\nDEST[0] := IWKey.NoBackup;\nDEST[4:1] := IWKey.KeySource[3:0];\nDEST[31:5] = 0;\nXMM0 := Handle[127:0]; // AAD\nXMM1 := Handle[255:128]; // Integrity Tag\nXMM2 := Handle[383:256]; // CipherText[127:0]\nXMM3 := Handle[511:384]; // CipherText[255:128]\nXMM4 := 0;\n // Reserved for future usage\nXMM5 := 0;\n // Reserved for future usage\nXMM6 := 0;\n // Reserved for future usage\nRFLAGS.OF, SF, ZF, AF, PF, CF := 0;\n1. Further details on Key Locker and usage of this instruction can be found here:\n", + "url": "https://www.felixcloutier.com/x86/encodekey256" + }, + "endbr32": { + "instruction": "ENDBR32", + "title": "ENDBR32\n\t\t— Terminate an Indirect Branch in 32-bit and Compatibility Mode", + "opcode": "F3 0F 1E FB ENDBR32", + "description": "Terminate an indirect branch in 32 bit and compatibility mode.", + "operation": "IF EndbranchEnabled(CPL) & (IA32_EFER.LMA = 0 | (IA32_EFER.LMA=1 & CS.L = 0)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = IDLE\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = IDLE\n IA32_S_CET.SUPPRESS = 0\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/endbr32" + }, + "endbr64": { + "instruction": "ENDBR64", + "title": "ENDBR64\n\t\t— Terminate an Indirect Branch in 64-bit Mode", + "opcode": "F3 0F 1E FA ENDBR64", + "description": "Terminate an indirect branch in 64 bit mode.", + "operation": "IF EndbranchEnabled(CPL) & IA32_EFER.LMA = 1 & CS.L = 1\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = IDLE\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = IDLE\n IA32_S_CET.SUPPRESS = 0\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/endbr64" + }, + "enqcmd": { + "instruction": "ENQCMD", + "title": "ENQCMD\n\t\t— Enqueue Command", + "opcode": "F2 0F 38 F8 !(11):rrr:bbb ENQCMD r32/r64, m512", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/enqcmd" + }, + "enqcmds": { + "instruction": "ENQCMDS", + "title": "ENQCMDS\n\t\t— Enqueue Command Supervisor", + "opcode": "F3 0F 38 F8 !(11):rrr:bbb ENQCMDS r32/r64, m512", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/enqcmds" + }, + "enter": { + "instruction": "ENTER", + "title": "ENTER\n\t\t— Make Stack Frame for Procedure Parameters", + "opcode": "C8 iw 00", + "description": "Creates a stack frame (comprising of space for dynamic storage and 1-32 frame pointer storage) for a procedure. The first operand (imm16) specifies the size of the dynamic storage in the stack frame (that is, the number of bytes of dynamically allocated on the stack for the procedure). The second operand (imm8) gives the lexical nesting level (0 to 31) of the procedure. The nesting level (imm8 mod 32) and the OperandSize attribute determine the size in bytes of the storage space for frame pointers.\nThe nesting level determines the number of frame pointers that are copied into the “display area” of the new stack frame from the preceding frame. The default size of the frame pointer is the StackAddrSize attribute, but can be overridden using the 66H prefix. Thus, the OperandSize attribute determines the size of each frame pointer that will be copied into the stack frame and the data being transferred from SP/ESP/RSP register into the BP/EBP/RBP register.\nThe ENTER and companion LEAVE instructions are provided to support block structured languages. The ENTER instruction (when used) is typically the first instruction in a procedure and is used to set up a new stack frame for a procedure. The LEAVE instruction is then used at the end of the procedure (just before the RET instruction) to release the stack frame.\nIf the nesting level is 0, the processor pushes the frame pointer from the BP/EBP/RBP register onto the stack, copies the current stack pointer from the SP/ESP/RSP register into the BP/EBP/RBP register, and loads the SP/ESP/RSP register with the current stack-pointer value minus the value in the size operand. For nesting levels of 1 or greater, the processor pushes additional frame pointers on the stack before adjusting the stack pointer. These additional frame pointers provide the called procedure with access points to other nested frames on the stack. See “Procedure Calls for Block-Structured Languages” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the actions of the ENTER instruction.\nThe ENTER instruction causes a page fault whenever a write using the final value of the stack pointer (within the current stack segment) would do so.\nIn 64-bit mode, default operation size is 64 bits; 32-bit operation size cannot be encoded. Use of 66H prefix changes frame pointer operand size to 16 bits.\nWhen the 66H prefix is used and causing the OperandSize attribute to be less than the StackAddrSize, software is responsible for the following:", + "operation": "AllocSize := imm16;\nNestingLevel := imm8 MOD 32;\nIF (OperandSize = 64)\n THEN\n Push(RBP); (* RSP decrements by 8 *)\n FrameTemp := RSP;\n ELSE IF OperandSize = 32\n THEN\n Push(EBP); (* (E)SP decrements by 4 *)\n FrameTemp := ESP; FI;\n ELSE (* OperandSize = 16 *)\n Push(BP); (* RSP or (E)SP decrements by 2 *)\n FrameTemp := SP;\nFI;\nIF NestingLevel = 0\n THEN GOTO CONTINUE;\nFI;\nIF (NestingLevel > 1)\n THEN FOR i := 1 to (NestingLevel - 1)\n DO\n IF (OperandSize = 64)\n THEN\n RBP := RBP - 8;\n Push([RBP]); (* Quadword push *)\n ELSE IF OperandSize = 32\n THEN\n IF StackSize = 32\n EBP := EBP - 4;\n Push([EBP]); (* Doubleword push *)\n ELSE (* StackSize = 16 *)\n BP := BP - 4;\n Push([BP]); (* Doubleword push *)\n FI;\n FI;\n ELSE (* OperandSize = 16 *)\n IF StackSize = 64\n THEN\n RBP := RBP - 2;\n Push([RBP]); (* Word push *)\n ELSE IF StackSize = 32\n THEN\n EBP := EBP - 2;\n Push([EBP]); (* Word push *)\n ELSE (* StackSize = 16 *)\n BP := BP - 2;\n Push([BP]); (* Word push *)\n FI;\n FI;\n OD;\nFI;\nIF (OperandSize = 64) (* nestinglevel 1 *)\n THEN\n Push(FrameTemp); (* Quadword push and RSP decrements by 8 *)\n ELSE IF OperandSize = 32\n THEN\n Push(FrameTemp); FI; (* Doubleword push and (E)SP decrements by 4 *)\n ELSE (* OperandSize = 16 *)\n Push(FrameTemp); (* Word push and RSP|ESP|SP decrements by 2 *)\nFI;\nCONTINUE:\nIF 64-Bit Mode (StackSize = 64)\n THEN\n RBP := FrameTemp;\n RSP := RSP − AllocSize;\n ELSE IF OperandSize = 32\n THEN\n EBP := FrameTemp;\n ESP := ESP − AllocSize; FI;\n ELSE (* OperandSize = 16 *)\n BP := FrameTemp[15:1]; (* Bits 16 and above of applicable RBP/EBP are unmodified *)\n SP := SP − AllocSize;\nFI;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/enter" + }, + "enteraccs": { + "instruction": "ENTERACCS", + "title": "GETSEC[ENTERACCS]\n\t\t— Execute Authenticated Chipset Code", + "opcode": "NP 0F 37 (EAX = 2)", + "description": "The GETSEC[ENTERACCS] function loads, authenticates, and executes an authenticated code module using an Intel® TXT platform chipset's public key. The ENTERACCS leaf of GETSEC is selected with EAX set to 2 at entry.\nThere are certain restrictions enforced by the processor for the execution of the GETSEC[ENTERACCS] instruction:\nFailure to conform to the above conditions results in the processor signaling a general protection exception.\nPrior to execution of the ENTERACCS leaf, other logical processors, i.e., RLPs, in the platform must be:\nIf other logical processor(s) in the same package are not idle in one of these states, execution of ENTERACCS signals a general protection exception. The same requirement and action applies if the other logical processor(s) of the same package do not have CR0.CD = 0.\nA successful execution of ENTERACCS results in the ILP entering an authenticated code execution mode. Prior to reaching this point, the processor performs several checks. These include:\nThe GETSEC[ENTERACCS] function requires two additional input parameters in the general purpose registers EBX and ECX. EBX holds the authenticated code (AC) module physical base address (the AC module must reside below 4 GBytes in physical address space) and ECX holds the AC module size (in bytes). The physical base address and size are used to retrieve the code module from system memory and load it into the internal authenticated code execution area. The base physical address is checked to verify it is on a modulo-4096 byte boundary. The size is verified to be a multiple of 64, that it does not exceed the internal authenticated code execution area capacity (as reported by GETSEC[CAPABILITIES]), and that the top address of the AC module does not exceed 32 bits. An error condition results in an abort of the authenticated code execution launch and the signaling of a general protection exception.\nAs an integrity check for proper processor hardware operation, execution of GETSEC[ENTERACCS] will also check the contents of all the machine check status registers (as reported by the MSRs IA32_MCi_STATUS) for any valid uncorrectable error condition. In addition, the global machine check status register IA32_MCG_STATUS MCIP bit must be cleared and the IERR processor package pin (or its equivalent) must not be asserted, indicating that no machine check exception processing is currently in progress. These checks are performed prior to initiating the load of the authenticated code module. Any outstanding valid uncorrectable machine check error condition present in these status registers at this point will result in the processor signaling a general protection violation.\nThe ILP masks the response to the assertion of the external signals INIT#, A20M, NMI#, and SMI#. This masking remains active until optionally unmasked by GETSEC[EXITAC] (this defined unmasking behavior assumes GETSEC[ENTERACCS] was not executed by a prior GETSEC[SENTER]). The purpose of this masking control is to prevent exposure to existing external event handlers that may not be under the control of the authenticated code module.\nThe ILP sets an internal flag to indicate it has entered authenticated code execution mode. The state of the A20M pin is likewise masked and forced internally to a de-asserted state so that any external assertion is not recognized during authenticated code execution mode.\nTo prevent other (logical) processors from interfering with the ILP operating in authenticated code execution mode, memory (excluding implicit write-back transactions) access and I/O originating from other processor agents are blocked. This protection starts when the ILP enters into authenticated code execution mode. Only memory and I/O transactions initiated from the ILP are allowed to proceed. Exiting authenticated code execution mode is done by executing GETSEC[EXITAC]. The protection of memory and I/O activities remains in effect until the ILP executes GETSEC[EXITAC].\nPrior to launching the authenticated execution module using GETSEC[ENTERACCS] or GETSEC[SENTER], the processor’s MTRRs (Memory Type Range Registers) must first be initialized to map out the authenticated RAM addresses as WB (writeback). Failure to do so may affect the ability for the processor to maintain isolation of the loaded authenticated code module. If the processor detected this requirement is not met, it will signal an Intel® TXT reset condition with an error code during the loading of the authenticated code module.\nWhile physical addresses within the load module must be mapped as WB, the memory type for locations outside of the module boundaries must be mapped to one of the supported memory types as returned by GETSEC[PARAMETERS] (or UC as default).\nTo conform to the minimum granularity of MTRR MSRs for specifying the memory type, authenticated code RAM (ACRAM) is allocated to the processor in 4096 byte granular blocks. If an AC module size as specified in ECX is not a multiple of 4096 then the processor will allocate up to the next 4096 byte boundary for mapping as ACRAM with indeterminate data. This pad area will not be visible to the authenticated code module as external memory nor can it depend on the value of the data used to fill the pad area.\nAt the successful completion of GETSEC[ENTERACCS], the architectural state of the processor is partially initialized from contents held in the header of the authenticated code module. The processor GDTR, CS, and DS selectors are initialized from fields within the authenticated code module. Since the authenticated code module must be relocatable, all address references must be relative to the authenticated code module base address in EBX. The processor GDTR base value is initialized to the AC module header field GDTBasePtr + module base address held in EBX and the GDTR limit is set to the value in the GDTLimit field. The CS selector is initialized to the AC module header SegSel field, while the DS selector is initialized to CS + 8. The segment descriptor fields are implicitly initialized to BASE=0, LIMIT=FFFFFh, G=1, D=1, P=1, S=1, read/write access for DS, and execute/read access for CS. The processor begins the authenticated code module execution with the EIP set to the AC module header EntryPoint field + module base address (EBX). The AC module based fields used for initializing the processor state are checked for consistency and any failure results in a shutdown condition.\nA summary of the register state initialization after successful completion of GETSEC[ENTERACCS] is given for the processor in Table 7-4. The paging is disabled upon entry into authenticated code execution mode. The authenticated code module is loaded and initially executed using physical addresses. It is up to the system software after execution of GETSEC[ENTERACCS] to establish a new (or restore its previous) paging environment with an appropriate mapping to meet new protection requirements. EBP is initialized to the authenticated code module base physical address for initial execution in the authenticated environment. As a result, the authenticated code can reference EBP for relative address based references, given that the authenticated code module must be position independent.\nThe segmentation related processor state that has not been initialized by GETSEC[ENTERACCS] requires appropriate initialization before use. Since a new GDT context has been established, the previous state of the segment selector values held in ES, SS, FS, GS, TR, and LDTR might not be valid.\nThe MSR IA32_EFER is also unconditionally cleared as part of the processor state initialized by ENTERACCS. Since paging is disabled upon entering authenticated code execution mode, a new paging environment will have to be reestablished in order to establish IA-32e mode while operating in authenticated code execution mode.\nDebug exception and trap related signaling is also disabled as part of GETSEC[ENTERACCS]. This is achieved by resetting DR7, TF in EFLAGs, and the MSR IA32_DEBUGCTL. These debug functions are free to be re-enabled once supporting exception handler(s), descriptor tables, and debug registers have been properly initialized following entry into authenticated code execution mode. Also, any pending single-step trap condition will have been cleared upon entry into this mode.\nPerformance related counters and counter control registers are cleared as part of execution of ENTERACCS. This implies any active performance counters at any time of ENTERACCS execution will be disabled. To reactive the processor performance counters, this state must be re-initialized and re-enabled.\nThe IA32_MISC_ENABLE MSR is initialized upon entry into authenticated execution mode. Certain bits of this MSR are preserved because preserving these bits may be important to maintain previously established platform settings (See the footnote for Table 7-5.). The remaining bits are cleared for the purpose of establishing a more consistent environment for the execution of authenticated code modules. One of the impacts of initializing this MSR is any previous condition established by the MONITOR instruction will be cleared.\nTo support the possible return to the processor architectural state prior to execution of GETSEC[ENTERACCS], certain critical processor state is captured and stored in the general- purpose registers at instruction completion. [E|R]BX holds effective address ([E|R]IP) of the instruction that would execute next after GETSEC[ENTERACCS], ECX[15:0] holds the CS selector value, ECX[31:16] holds the GDTR limit field, and [E|R]DX holds the GDTR base field. The subsequent authenticated code can preserve the contents of these registers so that this state can be manually restored if needed, prior to exiting authenticated code execution mode with GETSEC[EXITAC]. For the processor state after exiting authenticated code execution mode, see the description of GETSEC[SEXIT].\nThe IDTR will also require reloading with a new IDT context after entering authenticated code execution mode, before any exceptions or the external interrupts INTR and NMI can be handled. Since external interrupts are reenabled at the completion of authenticated code execution mode (as terminated with EXITAC), it is recommended\nthat a new IDT context be established before this point. Until such a new IDT context is established, the programmer must take care in not executing an INT n instruction or any other operation that would result in an exception or trap signaling.\nPrior to completion of the GETSEC[ENTERACCS] instruction and after successful authentication of the AC module, the private configuration space of the Intel TXT chipset is unlocked. The authenticated code module alone can gain access to this normally restricted chipset state for the purpose of securing the platform.\nOnce the authenticated code module is launched at the completion of GETSEC[ENTERACCS], it is free to enable interrupts by setting EFLAGS.IF and enable NMI by execution of IRET. This presumes that it has re-established interrupt handling support through initialization of the IDT, GDT, and corresponding interrupt handling code.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/enteraccs" + }, + "epa": { + "instruction": "EPA", + "title": "EPA\n\t\t— Add Version Array", + "opcode": "EAX = 0AH ENCLS[EPA]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/epa" + }, + "erdinfo": { + "instruction": "ERDINFO", + "title": "ERDINFO\n\t\t— Read Type and Status Information About an EPC Page", + "opcode": "EAX = 10H ENCLS[ERDINFO]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/erdinfo" + }, + "eremove": { + "instruction": "EREMOVE", + "title": "EREMOVE\n\t\t— Remove a page from the EPC", + "opcode": "EAX = 03H ENCLS[EREMOVE]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eremove" + }, + "ereport": { + "instruction": "EREPORT", + "title": "EREPORT\n\t\t— Create a Cryptographic Report of the Enclave", + "opcode": "EAX = 00H ENCLU[EREPORT]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/ereport" + }, + "eresume": { + "instruction": "ERESUME", + "title": "ERESUME\n\t\t— Re-Enters an Enclave", + "opcode": "EAX = 03H ENCLU[ERESUME]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/eresume" + }, + "esetcontext": { + "instruction": "ESETCONTEXT", + "title": "ESETCONTEXT\n\t\t— Set the ENCLAVECONTEXT Field in SECS", + "opcode": "EAX = 02H ENCLV[ESETCONTEXT]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/esetcontext" + }, + "etrack": { + "instruction": "ETRACK", + "title": "ETRACK\n\t\t— Activates EBLOCK Checks", + "opcode": "EAX = 0CH ENCLS[ETRACK]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/etrack" + }, + "etrackc": { + "instruction": "ETRACKC", + "title": "ETRACKC\n\t\t— Activates EBLOCK Checks", + "opcode": "EAX = 11H ENCLS[ETRACKC]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/etrackc" + }, + "ewb": { + "instruction": "EWB", + "title": "EWB\n\t\t— Invalidate an EPC Page and Write out to Main Memory", + "opcode": "EAX = 0BH ENCLS[EWB]", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/ewb" + }, + "exitac": { + "instruction": "EXITAC", + "title": "GETSEC[EXITAC]\n\t\t— Exit Authenticated Code Execution Mode", + "opcode": "NP 0F 37 (EAX=3)", + "description": "The GETSEC[EXITAC] leaf function exits the ILP out of authenticated code execution mode established by GETSEC[ENTERACCS] or GETSEC[SENTER]. The EXITAC leaf of GETSEC is selected with EAX set to 3 at entry. EBX (or RBX, if in 64-bit mode) holds the near jump target offset for where the processor execution resumes upon exiting authenticated code execution mode. EDX contains additional parameter control information. Currently only an input value of 0 in EDX is supported. All other EDX settings are considered reserved and result in a general protection violation.\nGETSEC[EXITAC] can only be executed if the processor is in protected mode with CPL = 0 and EFLAGS.VM = 0. The processor must also be in authenticated code execution mode. To avoid potential operability conflicts between modes, the processor is not allowed to execute this instruction if it is in SMM or in VMX operation. A violation of these conditions results in a general protection violation.\nUpon completion of the GETSEC[EXITAC] operation, the processor unmasks responses to external event signals INIT#, NMI#, and SMI#. This unmasking is performed conditionally, based on whether the authenticated code execution mode was entered via execution of GETSEC[SENTER] or GETSEC[ENTERACCS]. If the processor is in authenticated code execution mode due to the execution of GETSEC[SENTER], then these external event signals will remain masked. In this case, A20M is kept disabled in the measured environment until the measured environment executes GETSEC[SEXIT]. INIT# is unconditionally unmasked by EXITAC. Note that any events that are pending, but have been blocked while in authenticated code execution mode, will be recognized at the completion of the GETSEC[EXITAC] instruction if the pin event is unmasked.\nThe intent of providing the ability to optionally leave the pin events SMI#, and NMI# masked is to support the completion of a measured environment bring-up that makes use of VMX. In this envisioned security usage scenario, these events will remain masked until an appropriate virtual machine has been established in order to field servicing of these events in a safer manner. Details on when and how events are masked and unmasked in VMX operation are described in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C. It should be cautioned that if no VMX environment is to be activated following GETSEC[EXITAC], that these events will remain masked until the measured environment is exited with GETSEC[SEXIT]. If this is not desired then the GETSEC function SMCTRL(0) can be used for unmasking SMI# in this context. NMI# can be correspondingly unmasked by execution of IRET.\nA successful exit of the authenticated code execution mode requires the ILP to perform additional steps as outlined below:\nThe content of the authenticated code execution area is invalidated by hardware in order to protect it from further use or visibility. This internal processor storage area can no longer be used or relied upon after GETSEC[EXITAC]. Data structures need to be re-established outside of the authenticated code execution area if they are to be referenced after EXITAC. Since addressed memory content formerly mapped to the authenticated code execution area may no longer be coherent with external system memory after EXITAC, processor TLBs in support of linear to physical address translation are also invalidated.\nUpon completion of GETSEC[EXITAC] a near absolute indirect transfer is performed with EIP loaded with the contents of EBX (based on the current operating mode size). In 64-bit mode, all 64 bits of RBX are loaded into RIP if REX.W precedes GETSEC[EXITAC]. Otherwise RBX is treated as 32 bits even while in 64-bit mode. Conventional CS limit checking is performed as part of this control transfer. Any exception conditions generated as part of this control transfer will be directed to the existing IDT; thus it is recommended that an IDTR should also be established prior to execution of the EXITAC function if there is a need for fault handling. In addition, any segmentation related (and paging) data structures to be used after EXITAC should be re-established or validated by the authenticated code prior to EXITAC.\nIn addition, any segmentation related (and paging) data structures to be used after EXITAC need to be re-established and mapped outside of the authenticated RAM designated area by the authenticated code prior to EXITAC. Any data structure held within the authenticated RAM allocated area will no longer be accessible after completion by EXITAC.", + "operation": "(* The state of the internal flag ACMODEFLAG and SENTERFLAG persist across instruction boundary *)\nIF (CR4.SMXE=0)\n THEN #UD;\nELSIF ( in VMX non-root operation)\n THEN VM Exit (reason=”GETSEC instruction”);\nELSIF (GETSEC leaf unsupported)\n THEN #UD;\nELSIF ((in VMX operation) or ( (in 64-bit mode) and ( RBX is non-canonical) )\n (CR0.PE=0) or (CPL>0) or (EFLAGS.VM=1) or\n (ACMODEFLAG=0) or (IN_SMM=1)) or (EDX ≠ 0))\n THEN #GP(0);\nIF (OperandSize = 32)\n THEN tempEIP := EBX;\nELSIF (OperandSize = 64)\n THEN tempEIP := RBX;\nELSE\n tempEIP := EBX AND 0000FFFFH;\nIF (tempEIP > code segment limit)\n THEN #GP(0);\nInvalidate ACRAM contents;\nInvalidate processor TLB(s);\nDrain outgoing messages;\nSignalTXTMsg(CloseLocality3);\nSignalTXTMsg(LockSMRAM);\nSignalTXTMsg(ProcessorRelease);\nUnmask INIT;\nIF (SENTERFLAG=0)\n THEN Unmask SMI, INIT, NMI, and A20M pin event;\nELSEIF (IA32_SMM_MONITOR_CTL[0] = 0)\n THEN Unmask SMI pin event;\nACMODEFLAG := 0;\nIF IA32_EFER.LMA == 1\n THEN CR3 := R8;\nEIP := tempEIP;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/exitac" + }, + "extractps": { + "instruction": "EXTRACTPS", + "title": "EXTRACTPS\n\t\t— Extract Packed Floating-Point Values", + "opcode": "66 0F 3A 17 /r ib EXTRACTPS reg/m32, xmm1, imm8", + "description": "Extracts a single precision floating-point value from the source operand (second operand) at the 32-bit offset specified from imm8. Immediate bits higher than the most significant offset for the vector length are ignored.\nThe extracted single precision floating-point value is stored in the low 32-bits of the destination operand\nIn 64-bit mode, destination register operand has default operand size of 64 bits. The upper 32-bits of the register are filled with zero. REX.W is ignored.\nVEX.128 and EVEX encoded version: When VEX.W1 or EVEX.W1 form is used in 64-bit mode with a general purpose register (GPR) as a destination operand, the packed single quantity is zero extended to 64 bits.\nVEX.vvvv/EVEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.\n128-bit Legacy SSE version: When a REX.W prefix is used in 64-bit mode with a general purpose register (GPR) as a destination operand, the packed single quantity is zero extended to 64 bits.\nThe source register is an XMM register. Imm8[1:0] determine the starting DWORD offset from which to extract the 32-bit floating-point value.\nIf VEXTRACTPS is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "SRC_OFFSET := IMM8[1:0]\nIF (64-Bit Mode and DEST is register)\n DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh\n DEST[63:32] := 0\nELSE\n DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh\nFI\n\n\nSRC_OFFSET := IMM8[1:0]\nIF (64-Bit Mode and DEST is register)\n DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh\n DEST[63:32] := 0\nELSE\n DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh\nFI\n", + "url": "https://www.felixcloutier.com/x86/extractps" + }, + "f2xm1": { + "instruction": "F2XM1", + "title": "F2XM1\n\t\t— Compute 2x–1", + "opcode": "D9 F0", + "description": "Computes the exponential value of 2 to the power of the source operand minus 1. The source operand is located in register ST(0) and the result is also stored in ST(0). The value of the source operand must lie in the range –1.0 to +1.0. If the source value is outside this range, the result is undefined.\nThe following table shows the results obtained when computing the exponential value of various classes of numbers, assuming that neither overflow nor underflow occurs.\nValues other than 2 can be exponentiated using the following formula:\nxy := 2(y ∗ log2x)\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(0) := (2ST(0) − 1);\n", + "url": "https://www.felixcloutier.com/x86/f2xm1" + }, + "fabs": { + "instruction": "FABS", + "title": "FABS\n\t\t— Absolute Value", + "opcode": "D9 E1", + "description": "Clears the sign bit of ST(0) to create the absolute value of the operand. The following table shows the results obtained when creating the absolute value of various classes of numbers.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(0) := |ST(0)|;\n", + "url": "https://www.felixcloutier.com/x86/fabs" + }, + "fadd": { + "instruction": "FADD", + "title": "FADD/FADDP/FIADD\n\t\t— Add", + "opcode": "D8 /0", + "description": "Adds the destination and source operands and stores the sum in the destination location. The destination operand is always an FPU register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction adds the contents of the ST(0) register to the ST(1) register. The one-operand version adds the contents of a memory location (either a floating-point or an integer value) to the contents of the ST(0) register. The two-operand version, adds the contents of the ST(0) register to the ST(i) register or vice versa. The value in ST(0) can be doubled by coding:\nFADD ST(0), ST(0);\nThe FADDP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. (The no-operand version of the floating-point add instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FADD rather than FADDP.)\nThe FIADD instructions convert an integer source operand to double extended-precision floating-point format before performing the addition.\nThe table on the following page shows the results obtained when adding various classes of numbers, assuming that neither overflow nor underflow occurs.\nWhen the sum of two operands with opposite signs is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. When the source operand is an integer 0, it is treated as a +0.\nWhen both operand are infinities of the same sign, the result is ∞ of the expected sign. If both operands are infinities of opposite signs, an invalid-operation exception is generated. See Table 3-18.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FIADD\n THEN\n DEST := DEST + ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST + SRC;\nFI;\nIF Instruction = FADDP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fadd:faddp:fiadd" + }, + "faddp": { + "instruction": "FADDP", + "title": "FADD/FADDP/FIADD\n\t\t— Add", + "opcode": "DE C0+i", + "description": "Adds the destination and source operands and stores the sum in the destination location. The destination operand is always an FPU register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction adds the contents of the ST(0) register to the ST(1) register. The one-operand version adds the contents of a memory location (either a floating-point or an integer value) to the contents of the ST(0) register. The two-operand version, adds the contents of the ST(0) register to the ST(i) register or vice versa. The value in ST(0) can be doubled by coding:\nFADD ST(0), ST(0);\nThe FADDP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. (The no-operand version of the floating-point add instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FADD rather than FADDP.)\nThe FIADD instructions convert an integer source operand to double extended-precision floating-point format before performing the addition.\nThe table on the following page shows the results obtained when adding various classes of numbers, assuming that neither overflow nor underflow occurs.\nWhen the sum of two operands with opposite signs is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. When the source operand is an integer 0, it is treated as a +0.\nWhen both operand are infinities of the same sign, the result is ∞ of the expected sign. If both operands are infinities of opposite signs, an invalid-operation exception is generated. See Table 3-18.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FIADD\n THEN\n DEST := DEST + ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST + SRC;\nFI;\nIF Instruction = FADDP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fadd:faddp:fiadd" + }, + "fbld": { + "instruction": "FBLD", + "title": "FBLD\n\t\t— Load Binary Coded Decimal", + "opcode": "DF /4", + "description": "Converts the BCD source operand into double extended-precision floating-point format and pushes the value onto the FPU stack. The source operand is loaded without rounding errors. The sign of the source operand is preserved, including that of −0.\nThe packed BCD digits are assumed to be in the range 0 through 9; the instruction does not check for invalid digits (AH through FH). Attempting to load an invalid encoding produces an undefined result.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := ConvertToDoubleExtendedPrecisionFP(SRC);\n", + "url": "https://www.felixcloutier.com/x86/fbld" + }, + "fbstp": { + "instruction": "FBSTP", + "title": "FBSTP\n\t\t— Store BCD Integer and Pop", + "opcode": "DF /6", + "description": "Converts the value in the ST(0) register to an 18-digit packed BCD integer, stores the result in the destination operand, and pops the register stack. If the source value is a non-integral value, it is rounded to an integer value, according to rounding mode specified by the RC field of the FPU control word. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThe destination operand specifies the address where the first byte destination value is to be stored. The BCD value (including its sign bit) requires 10 bytes of space in memory.\nThe following table shows the results obtained when storing various classes of numbers in packed BCD format.\nIf the converted value is too large for the destination format, or if the source operand is an ∞, SNaN, QNAN, or is in an unsupported format, an invalid-arithmetic-operand condition is signaled. If the invalid-operation exception is not masked, an invalid-arithmetic-operand exception (#IA) is generated and no value is stored in the destination operand. If the invalid-operation exception is masked, the packed BCD indefinite value is stored in memory.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := BCD(ST(0));\nPopRegisterStack;\n", + "url": "https://www.felixcloutier.com/x86/fbstp" + }, + "fchs": { + "instruction": "FCHS", + "title": "FCHS\n\t\t— Change Sign", + "opcode": "D9 E0", + "description": "Complements the sign bit of ST(0). This operation changes a positive value into a negative value of equal magnitude or vice versa. The following table shows the results obtained when changing the sign of various classes of numbers.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "SignBit(ST(0)) := NOT (SignBit(ST(0)));\n", + "url": "https://www.felixcloutier.com/x86/fchs" + }, + "fclex": { + "instruction": "FCLEX", + "title": "FCLEX/FNCLEX\n\t\t— Clear Exceptions", + "opcode": "9B DB E2", + "description": "Clears the floating-point exception flags (PE, UE, OE, ZE, DE, and IE), the exception summary status flag (ES), the stack fault flag (SF), and the busy flag (B) in the FPU status word. The FCLEX instruction checks for and handles any pending unmasked floating-point exceptions before clearing the exception flags; the FNCLEX instruction does not.\nThe assembler issues two instructions for the FCLEX instruction (an FWAIT instruction followed by an FNCLEX instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.", + "operation": "FPUStatusWord[0:7] := 0;\nFPUStatusWord[15] := 0;\n", + "url": "https://www.felixcloutier.com/x86/fclex:fnclex" + }, + "fcmovcc": { + "instruction": "FCMOVCC", + "title": "FCMOVcc\n\t\t— Floating-Point Conditional Move", + "opcode": "DA C0+i", + "description": "Tests the status flags in the EFLAGS register and moves the source operand (second operand) to the destination operand (first operand) if the given test condition is true. The condition for each mnemonic os given in the Description column above and in Chapter 8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. The source operand is always in the ST(i) register and the destination operand is always ST(0).\nThe FCMOVcc instructions are useful for optimizing small IF constructions. They also help eliminate branching overhead for IF operations and the possibility of branch mispredictions by the processor.\nA processor may not support the FCMOVcc instructions. Software can check if the FCMOVcc instructions are supported by checking the processor’s feature information with the CPUID instruction (see “COMISS—Compare Scalar Ordered Single Precision Floating-Point Values and Set EFLAGS” in this chapter). If both the CMOV and FPU feature bits are set, the FCMOVcc instructions are supported.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF condition TRUE\n THEN ST(0) := ST(i);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcmovcc" + }, + "fcom": { + "instruction": "FCOM", + "title": "FCOM/FCOMP/FCOMPP\n\t\t— Compare Floating-Point Values", + "opcode": "D8 /2", + "description": "Compares the contents of register ST(0) and source value and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below). The source operand can be a data register or a memory location. If no source operand is given, the value in ST(0) is compared with the value in ST(1). The sign of zero is ignored, so that –0.0 is equal to +0.0.\nThis instruction checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). If either operand is a NaN or is in an unsupported format, an invalid-arithmetic-operand exception (#IA) is raised and, if the exception is masked, the condition flags are set to “unordered.” If the invalid-arithmetic-operand exception is unmasked, the condition code flags are not set.\nThe FCOMP instruction pops the register stack following the comparison operation and the FCOMPP instruction pops the register stack twice following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThe FCOM instructions perform the same operation as the FUCOM instructions. The only difference is how they handle QNaN operands. The FCOM instructions raise an invalid-arithmetic-operand exception (#IA) when either or both of the operands is a NaN value or is in an unsupported format. The FUCOM instructions perform the same operation as the FCOM instructions, except that they do not generate an invalid-arithmetic-operand exception for QNaNs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST > SRC:\n C3, C2, C0 := 000;\n ST < SRC:\n C3, C2, C0 := 001;\n ST = SRC:\n C3, C2, C0 := 100;\nESAC;\nIF ST(0) or SRC = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n C3, C2, C0 := 111;\n FI;\nFI;\nIF Instruction = FCOMP\n THEN\n PopRegisterStack;\nFI;\nIF Instruction = FCOMPP\n THEN\n PopRegisterStack;\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcom:fcomp:fcompp" + }, + "fcomi": { + "instruction": "FCOMI", + "title": "FCOMI/FCOMIP/FUCOMI/FUCOMIP\n\t\t— Compare Floating-Point Values and Set EFLAGS", + "opcode": "DB F0+i", + "description": "Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results (see the table below). The sign of zero is ignored for comparisons, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOMI/FUCOMIP instructions perform the same operations as the FCOMI/FCOMIP instructions. The only difference is that the FUCOMI/FUCOMIP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOMI/FCOMIP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nIf the operation results in an invalid-arithmetic-operand exception being raised, the status flags in the EFLAGS register are set only if the exception is masked.\nThe FCOMI/FCOMIP and FUCOMI/FUCOMIP instructions set the OF, SF, and AF flags to zero in the EFLAGS register (regardless of whether an invalid-operation exception is detected).\nThe FCOMIP and FUCOMIP instructions also pop the register stack following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST(0) > ST(i):\n ZF, PF, CF := 000;\n ST(0) < ST(i):\n ZF, PF, CF := 001;\n ST(0) = ST(i):\n ZF, PF, CF := 100;\nESAC;\nIF Instruction is FCOMI or FCOMIP\n THEN\n IF ST(0) or ST(i) = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FUCOMI or FUCOMIP\n THEN\n IF ST(0) or ST(i) = QNaN, but not SNaN or unsupported format\n THEN\n ZF, PF, CF := 111;\n ELSE (* ST(0) or ST(i) is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FCOMIP or FUCOMIP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcomi:fcomip:fucomi:fucomip" + }, + "fcomip": { + "instruction": "FCOMIP", + "title": "FCOMI/FCOMIP/FUCOMI/FUCOMIP\n\t\t— Compare Floating-Point Values and Set EFLAGS", + "opcode": "DF F0+i", + "description": "Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results (see the table below). The sign of zero is ignored for comparisons, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOMI/FUCOMIP instructions perform the same operations as the FCOMI/FCOMIP instructions. The only difference is that the FUCOMI/FUCOMIP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOMI/FCOMIP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nIf the operation results in an invalid-arithmetic-operand exception being raised, the status flags in the EFLAGS register are set only if the exception is masked.\nThe FCOMI/FCOMIP and FUCOMI/FUCOMIP instructions set the OF, SF, and AF flags to zero in the EFLAGS register (regardless of whether an invalid-operation exception is detected).\nThe FCOMIP and FUCOMIP instructions also pop the register stack following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST(0) > ST(i):\n ZF, PF, CF := 000;\n ST(0) < ST(i):\n ZF, PF, CF := 001;\n ST(0) = ST(i):\n ZF, PF, CF := 100;\nESAC;\nIF Instruction is FCOMI or FCOMIP\n THEN\n IF ST(0) or ST(i) = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FUCOMI or FUCOMIP\n THEN\n IF ST(0) or ST(i) = QNaN, but not SNaN or unsupported format\n THEN\n ZF, PF, CF := 111;\n ELSE (* ST(0) or ST(i) is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FCOMIP or FUCOMIP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcomi:fcomip:fucomi:fucomip" + }, + "fcomp": { + "instruction": "FCOMP", + "title": "FCOM/FCOMP/FCOMPP\n\t\t— Compare Floating-Point Values", + "opcode": "D8 /3", + "description": "Compares the contents of register ST(0) and source value and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below). The source operand can be a data register or a memory location. If no source operand is given, the value in ST(0) is compared with the value in ST(1). The sign of zero is ignored, so that –0.0 is equal to +0.0.\nThis instruction checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). If either operand is a NaN or is in an unsupported format, an invalid-arithmetic-operand exception (#IA) is raised and, if the exception is masked, the condition flags are set to “unordered.” If the invalid-arithmetic-operand exception is unmasked, the condition code flags are not set.\nThe FCOMP instruction pops the register stack following the comparison operation and the FCOMPP instruction pops the register stack twice following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThe FCOM instructions perform the same operation as the FUCOM instructions. The only difference is how they handle QNaN operands. The FCOM instructions raise an invalid-arithmetic-operand exception (#IA) when either or both of the operands is a NaN value or is in an unsupported format. The FUCOM instructions perform the same operation as the FCOM instructions, except that they do not generate an invalid-arithmetic-operand exception for QNaNs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST > SRC:\n C3, C2, C0 := 000;\n ST < SRC:\n C3, C2, C0 := 001;\n ST = SRC:\n C3, C2, C0 := 100;\nESAC;\nIF ST(0) or SRC = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n C3, C2, C0 := 111;\n FI;\nFI;\nIF Instruction = FCOMP\n THEN\n PopRegisterStack;\nFI;\nIF Instruction = FCOMPP\n THEN\n PopRegisterStack;\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcom:fcomp:fcompp" + }, + "fcompp": { + "instruction": "FCOMPP", + "title": "FCOM/FCOMP/FCOMPP\n\t\t— Compare Floating-Point Values", + "opcode": "DE D9", + "description": "Compares the contents of register ST(0) and source value and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below). The source operand can be a data register or a memory location. If no source operand is given, the value in ST(0) is compared with the value in ST(1). The sign of zero is ignored, so that –0.0 is equal to +0.0.\nThis instruction checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). If either operand is a NaN or is in an unsupported format, an invalid-arithmetic-operand exception (#IA) is raised and, if the exception is masked, the condition flags are set to “unordered.” If the invalid-arithmetic-operand exception is unmasked, the condition code flags are not set.\nThe FCOMP instruction pops the register stack following the comparison operation and the FCOMPP instruction pops the register stack twice following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThe FCOM instructions perform the same operation as the FUCOM instructions. The only difference is how they handle QNaN operands. The FCOM instructions raise an invalid-arithmetic-operand exception (#IA) when either or both of the operands is a NaN value or is in an unsupported format. The FUCOM instructions perform the same operation as the FCOM instructions, except that they do not generate an invalid-arithmetic-operand exception for QNaNs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST > SRC:\n C3, C2, C0 := 000;\n ST < SRC:\n C3, C2, C0 := 001;\n ST = SRC:\n C3, C2, C0 := 100;\nESAC;\nIF ST(0) or SRC = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n C3, C2, C0 := 111;\n FI;\nFI;\nIF Instruction = FCOMP\n THEN\n PopRegisterStack;\nFI;\nIF Instruction = FCOMPP\n THEN\n PopRegisterStack;\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcom:fcomp:fcompp" + }, + "fcos": { + "instruction": "FCOS", + "title": "FCOS\n\t\t— Cosine", + "opcode": "D9 FF", + "description": "Computes the approximate cosine of the source operand in register ST(0) and stores the result in ST(0). The source operand must be given in radians and must be within the range −263 to +263. The following table shows the results obtained when taking the cosine of various classes of numbers.\nIf the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range − 263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2π. However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of π used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply FCOS only to arguments reduced accurately in software, to a value smaller in absolute value than 3π/8. See the sections titled “Approximation of Pi” and “Transcendental Instruction Accuracy” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a discussion of the proper value to use for π in performing such reductions.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF |ST(0)| < 263\nTHEN\n C2 := 0;\n ST(0) := FCOS(ST(0)); // approximation of cosine\nELSE (* Source operand is out-of-range *)\n C2 := 1;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcos" + }, + "fdecstp": { + "instruction": "FDECSTP", + "title": "FDECSTP\n\t\t— Decrement Stack-Top Pointer", + "opcode": "D9 F6", + "description": "Subtracts one from the TOP field of the FPU status word (decrements the top-of-stack pointer). If the TOP field contains a 0, it is set to 7. The effect of this instruction is to rotate the stack by one position. The contents of the FPU data registers and tag register are not affected.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF TOP = 0\n THEN TOP := 7;\n ELSE TOP := TOP – 1;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdecstp" + }, + "fdiv": { + "instruction": "FDIV", + "title": "FDIV/FDIVP/FIDIV\n\t\t— Divide", + "opcode": "D8 /6", + "description": "Divides the destination operand by the source operand and stores the result in the destination location. The destination operand (dividend) is always in an FPU register; the source operand (divisor) can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format, word or doubleword integer format.\nThe no-operand version of the instruction divides the contents of the ST(1) register by the contents of the ST(0) register. The one-operand version divides the contents of the ST(0) register by the contents of a memory location (either a floating-point or an integer value). The two-operand version, divides the contents of the ST(0) register by the contents of the ST(i) register or vice versa.\nThe FDIVP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point divide instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FDIV rather than FDIVP.\nThe FIDIV instructions convert an integer source operand to double extended-precision floating-point format before performing the division. When the source operand is an integer 0, it is treated as a +0.\nIf an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of the appropriate sign is stored in the destination operand.\nThe following table shows the results obtained when dividing various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF SRC = 0\n THEN\n #Z;\n ELSE\n IF Instruction is FIDIV\n THEN\n DEST := DEST / ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST / SRC;\n FI;\nFI;\nIF Instruction = FDIVP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdiv:fdivp:fidiv" + }, + "fdivp": { + "instruction": "FDIVP", + "title": "FDIV/FDIVP/FIDIV\n\t\t— Divide", + "opcode": "DE F8+i", + "description": "Divides the destination operand by the source operand and stores the result in the destination location. The destination operand (dividend) is always in an FPU register; the source operand (divisor) can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format, word or doubleword integer format.\nThe no-operand version of the instruction divides the contents of the ST(1) register by the contents of the ST(0) register. The one-operand version divides the contents of the ST(0) register by the contents of a memory location (either a floating-point or an integer value). The two-operand version, divides the contents of the ST(0) register by the contents of the ST(i) register or vice versa.\nThe FDIVP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point divide instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FDIV rather than FDIVP.\nThe FIDIV instructions convert an integer source operand to double extended-precision floating-point format before performing the division. When the source operand is an integer 0, it is treated as a +0.\nIf an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of the appropriate sign is stored in the destination operand.\nThe following table shows the results obtained when dividing various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF SRC = 0\n THEN\n #Z;\n ELSE\n IF Instruction is FIDIV\n THEN\n DEST := DEST / ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST / SRC;\n FI;\nFI;\nIF Instruction = FDIVP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdiv:fdivp:fidiv" + }, + "fdivr": { + "instruction": "FDIVR", + "title": "FDIVR/FDIVRP/FIDIVR\n\t\t— Reverse Divide", + "opcode": "D8 /7", + "description": "Divides the source operand by the destination operand and stores the result in the destination location. The destination operand (divisor) is always in an FPU register; the source operand (dividend) can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format, word or doubleword integer format.\nThese instructions perform the reverse operations of the FDIV, FDIVP, and FIDIV instructions. They are provided to support more efficient coding.\nThe no-operand version of the instruction divides the contents of the ST(0) register by the contents of the ST(1) register. The one-operand version divides the contents of a memory location (either a floating-point or an integer value) by the contents of the ST(0) register. The two-operand version, divides the contents of the ST(i) register by the contents of the ST(0) register or vice versa.\nThe FDIVRP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point divide instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FDIVR rather than FDIVRP.\nThe FIDIVR instructions convert an integer source operand to double extended-precision floating-point format before performing the division.\nIf an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of the appropriate sign is stored in the destination operand.\nThe following table shows the results obtained when dividing various classes of numbers, assuming that neither overflow nor underflow occurs.\nWhen the source operand is an integer 0, it is treated as a +0. This instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF DEST = 0\n THEN\n #Z;\n ELSE\n IF Instruction = FIDIVR\n THEN\n DEST := ConvertToDoubleExtendedPrecisionFP(SRC) / DEST;\n ELSE (* Source operand is floating-point value *)\n DEST := SRC / DEST;\n FI;\nFI;\nIF Instruction = FDIVRP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdivr:fdivrp:fidivr" + }, + "fdivrp": { + "instruction": "FDIVRP", + "title": "FDIVR/FDIVRP/FIDIVR\n\t\t— Reverse Divide", + "opcode": "DE F0+i", + "description": "Divides the source operand by the destination operand and stores the result in the destination location. The destination operand (divisor) is always in an FPU register; the source operand (dividend) can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format, word or doubleword integer format.\nThese instructions perform the reverse operations of the FDIV, FDIVP, and FIDIV instructions. They are provided to support more efficient coding.\nThe no-operand version of the instruction divides the contents of the ST(0) register by the contents of the ST(1) register. The one-operand version divides the contents of a memory location (either a floating-point or an integer value) by the contents of the ST(0) register. The two-operand version, divides the contents of the ST(i) register by the contents of the ST(0) register or vice versa.\nThe FDIVRP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point divide instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FDIVR rather than FDIVRP.\nThe FIDIVR instructions convert an integer source operand to double extended-precision floating-point format before performing the division.\nIf an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of the appropriate sign is stored in the destination operand.\nThe following table shows the results obtained when dividing various classes of numbers, assuming that neither overflow nor underflow occurs.\nWhen the source operand is an integer 0, it is treated as a +0. This instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF DEST = 0\n THEN\n #Z;\n ELSE\n IF Instruction = FIDIVR\n THEN\n DEST := ConvertToDoubleExtendedPrecisionFP(SRC) / DEST;\n ELSE (* Source operand is floating-point value *)\n DEST := SRC / DEST;\n FI;\nFI;\nIF Instruction = FDIVRP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdivr:fdivrp:fidivr" + }, + "ffree": { + "instruction": "FFREE", + "title": "FFREE\n\t\t— Free Floating-Point Register", + "opcode": "DD C0+i", + "description": "Sets the tag in the FPU tag register associated with register ST(i) to empty (11B). The contents of ST(i) and the FPU stack-top pointer (TOP) are not affected.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TAG(i) := 11B;\n", + "url": "https://www.felixcloutier.com/x86/ffree" + }, + "fiadd": { + "instruction": "FIADD", + "title": "FADD/FADDP/FIADD\n\t\t— Add", + "opcode": "DA /0", + "description": "Adds the destination and source operands and stores the sum in the destination location. The destination operand is always an FPU register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction adds the contents of the ST(0) register to the ST(1) register. The one-operand version adds the contents of a memory location (either a floating-point or an integer value) to the contents of the ST(0) register. The two-operand version, adds the contents of the ST(0) register to the ST(i) register or vice versa. The value in ST(0) can be doubled by coding:\nFADD ST(0), ST(0);\nThe FADDP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. (The no-operand version of the floating-point add instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FADD rather than FADDP.)\nThe FIADD instructions convert an integer source operand to double extended-precision floating-point format before performing the addition.\nThe table on the following page shows the results obtained when adding various classes of numbers, assuming that neither overflow nor underflow occurs.\nWhen the sum of two operands with opposite signs is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. When the source operand is an integer 0, it is treated as a +0.\nWhen both operand are infinities of the same sign, the result is ∞ of the expected sign. If both operands are infinities of opposite signs, an invalid-operation exception is generated. See Table 3-18.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FIADD\n THEN\n DEST := DEST + ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST + SRC;\nFI;\nIF Instruction = FADDP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fadd:faddp:fiadd" + }, + "ficom": { + "instruction": "FICOM", + "title": "FICOM/FICOMP\n\t\t— Compare Integer", + "opcode": "DE /2", + "description": "Compares the value in ST(0) with an integer source operand and sets the condition code flags C0, C2, and C3 in the FPU status word according to the results (see table below). The integer value is converted to double extended-precision floating-point format before the comparison is made.\nThese instructions perform an “unordered comparison.” An unordered comparison also checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). If either operand is a NaN or is in an undefined format, the condition flags are set to “unordered.”\nThe sign of zero is ignored, so that –0.0 := +0.0.\nThe FICOMP instructions pop the register stack following the comparison. To pop the register stack, the processor marks the ST(0) register empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST(0) > SRC:\n C3, C2, C0 := 000;\n ST(0) < SRC:\n C3, C2, C0 := 001;\n ST(0) = SRC:\n C3, C2, C0 := 100;\n Unordered:\n C3, C2, C0 := 111;\nESAC;\nIF Instruction = FICOMP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ficom:ficomp" + }, + "ficomp": { + "instruction": "FICOMP", + "title": "FICOM/FICOMP\n\t\t— Compare Integer", + "opcode": "DE /3", + "description": "Compares the value in ST(0) with an integer source operand and sets the condition code flags C0, C2, and C3 in the FPU status word according to the results (see table below). The integer value is converted to double extended-precision floating-point format before the comparison is made.\nThese instructions perform an “unordered comparison.” An unordered comparison also checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). If either operand is a NaN or is in an undefined format, the condition flags are set to “unordered.”\nThe sign of zero is ignored, so that –0.0 := +0.0.\nThe FICOMP instructions pop the register stack following the comparison. To pop the register stack, the processor marks the ST(0) register empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST(0) > SRC:\n C3, C2, C0 := 000;\n ST(0) < SRC:\n C3, C2, C0 := 001;\n ST(0) = SRC:\n C3, C2, C0 := 100;\n Unordered:\n C3, C2, C0 := 111;\nESAC;\nIF Instruction = FICOMP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ficom:ficomp" + }, + "fidiv": { + "instruction": "FIDIV", + "title": "FDIV/FDIVP/FIDIV\n\t\t— Divide", + "opcode": "DA /6", + "description": "Divides the destination operand by the source operand and stores the result in the destination location. The destination operand (dividend) is always in an FPU register; the source operand (divisor) can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format, word or doubleword integer format.\nThe no-operand version of the instruction divides the contents of the ST(1) register by the contents of the ST(0) register. The one-operand version divides the contents of the ST(0) register by the contents of a memory location (either a floating-point or an integer value). The two-operand version, divides the contents of the ST(0) register by the contents of the ST(i) register or vice versa.\nThe FDIVP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point divide instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FDIV rather than FDIVP.\nThe FIDIV instructions convert an integer source operand to double extended-precision floating-point format before performing the division. When the source operand is an integer 0, it is treated as a +0.\nIf an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of the appropriate sign is stored in the destination operand.\nThe following table shows the results obtained when dividing various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF SRC = 0\n THEN\n #Z;\n ELSE\n IF Instruction is FIDIV\n THEN\n DEST := DEST / ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST / SRC;\n FI;\nFI;\nIF Instruction = FDIVP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdiv:fdivp:fidiv" + }, + "fidivr": { + "instruction": "FIDIVR", + "title": "FDIVR/FDIVRP/FIDIVR\n\t\t— Reverse Divide", + "opcode": "DA /7", + "description": "Divides the source operand by the destination operand and stores the result in the destination location. The destination operand (divisor) is always in an FPU register; the source operand (dividend) can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format, word or doubleword integer format.\nThese instructions perform the reverse operations of the FDIV, FDIVP, and FIDIV instructions. They are provided to support more efficient coding.\nThe no-operand version of the instruction divides the contents of the ST(0) register by the contents of the ST(1) register. The one-operand version divides the contents of a memory location (either a floating-point or an integer value) by the contents of the ST(0) register. The two-operand version, divides the contents of the ST(i) register by the contents of the ST(0) register or vice versa.\nThe FDIVRP instructions perform the additional operation of popping the FPU register stack after storing the result. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point divide instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FDIVR rather than FDIVRP.\nThe FIDIVR instructions convert an integer source operand to double extended-precision floating-point format before performing the division.\nIf an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of the appropriate sign is stored in the destination operand.\nThe following table shows the results obtained when dividing various classes of numbers, assuming that neither overflow nor underflow occurs.\nWhen the source operand is an integer 0, it is treated as a +0. This instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF DEST = 0\n THEN\n #Z;\n ELSE\n IF Instruction = FIDIVR\n THEN\n DEST := ConvertToDoubleExtendedPrecisionFP(SRC) / DEST;\n ELSE (* Source operand is floating-point value *)\n DEST := SRC / DEST;\n FI;\nFI;\nIF Instruction = FDIVRP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fdivr:fdivrp:fidivr" + }, + "fild": { + "instruction": "FILD", + "title": "FILD\n\t\t— Load Integer", + "opcode": "DF /0", + "description": "Converts the signed-integer source operand into double extended-precision floating-point format and pushes the value onto the FPU register stack. The source operand can be a word, doubleword, or quadword integer. It is loaded without rounding errors. The sign of the source operand is preserved.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := ConvertToDoubleExtendedPrecisionFP(SRC);\n", + "url": "https://www.felixcloutier.com/x86/fild" + }, + "fimul": { + "instruction": "FIMUL", + "title": "FMUL/FMULP/FIMUL\n\t\t— Multiply", + "opcode": "DA /1", + "description": "Multiplies the destination and source operands and stores the product in the destination location. The destination operand is always an FPU data register; the source operand can be an FPU data register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction multiplies the contents of the ST(1) register by the contents of the ST(0) register and stores the product in the ST(1) register. The one-operand version multiplies the contents of the ST(0) register by the contents of a memory location (either a floating-point or an integer value) and stores the product in the ST(0) register. The two-operand version, multiplies the contents of the ST(0) register by the contents of the ST(i) register, or vice versa, with the result being stored in the register specified with the first operand (the destination operand).\nThe FMULP instructions perform the additional operation of popping the FPU register stack after storing the product. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point multiply instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FMUL rather than FMULP.\nThe FIMUL instructions convert an integer source operand to double extended-precision floating-point format before performing the multiplication.\nThe sign of the result is always the exclusive-OR of the source signs, even if one or more of the values being multiplied is 0 or ∞. When the source operand is an integer 0, it is treated as a +0.\nThe following table shows the results obtained when multiplying various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FIMUL\n THEN\n DEST := DEST ∗ ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST ∗ SRC;\nFI;\nIF Instruction = FMULP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fmul:fmulp:fimul" + }, + "fincstp": { + "instruction": "FINCSTP", + "title": "FINCSTP\n\t\t— Increment Stack-Top Pointer", + "opcode": "D9 F7", + "description": "Adds one to the TOP field of the FPU status word (increments the top-of-stack pointer). If the TOP field contains a 7, it is set to 0. The effect of this instruction is to rotate the stack by one position. The contents of the FPU data registers and tag register are not affected. This operation is not equivalent to popping the stack, because the tag for the previous top-of-stack register is not marked empty.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF TOP = 7\n THEN TOP := 0;\n ELSE TOP := TOP + 1;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fincstp" + }, + "finit": { + "instruction": "FINIT", + "title": "FINIT/FNINIT\n\t\t— Initialize Floating-Point Unit", + "opcode": "9B DB E3", + "description": "Sets the FPU control, status, tag, instruction pointer, and data pointer registers to their default states. The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). The status word is cleared (no exception flags set, TOP is set to 0). The data registers in the register stack are left unchanged, but they are all tagged as empty (11B). Both the instruction and data pointers are cleared.\nThe FINIT instruction checks for and handles any pending unmasked floating-point exceptions before performing the initialization; the FNINIT instruction does not.\nThe assembler issues two instructions for the FINIT instruction (an FWAIT instruction followed by an FNINIT instruction), and the processor executes each of these instructions in separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FPUControlWord := 037FH;\nFPUStatusWord := 0;\nFPUTagWord := FFFFH;\nFPUDataPointer := 0;\nFPUInstructionPointer := 0;\nFPULastInstructionOpcode := 0;\n", + "url": "https://www.felixcloutier.com/x86/finit:fninit" + }, + "fist": { + "instruction": "FIST", + "title": "FIST/FISTP\n\t\t— Store Integer", + "opcode": "DF /2", + "description": "The FIST instruction converts the value in the ST(0) register to a signed integer and stores the result in the destination operand. Values can be stored in word or doubleword integer format. The destination operand specifies the address where the first byte of the destination value is to be stored.\nThe FISTP instruction performs the same operation as the FIST instruction and then pops the register stack. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The FISTP instruction also stores values in quadword integer format.\nThe following table shows the results obtained when storing various classes of numbers in integer format.\nIf the source value is a non-integral value, it is rounded to an integer value, according to the rounding mode specified by the RC field of the FPU control word.\nIf the converted value is too large for the destination format, or if the source operand is an ∞, SNaN, QNAN, or is in an unsupported format, an invalid-arithmetic-operand condition is signaled. If the invalid-operation exception is not masked, an invalid-arithmetic-operand exception (#IA) is generated and no value is stored in the destination operand. If the invalid-operation exception is masked, the integer indefinite value is stored in memory.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := Integer(ST(0));\nIF Instruction = FISTP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fist:fistp" + }, + "fistp": { + "instruction": "FISTP", + "title": "FIST/FISTP\n\t\t— Store Integer", + "opcode": "DF /3", + "description": "The FIST instruction converts the value in the ST(0) register to a signed integer and stores the result in the destination operand. Values can be stored in word or doubleword integer format. The destination operand specifies the address where the first byte of the destination value is to be stored.\nThe FISTP instruction performs the same operation as the FIST instruction and then pops the register stack. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The FISTP instruction also stores values in quadword integer format.\nThe following table shows the results obtained when storing various classes of numbers in integer format.\nIf the source value is a non-integral value, it is rounded to an integer value, according to the rounding mode specified by the RC field of the FPU control word.\nIf the converted value is too large for the destination format, or if the source operand is an ∞, SNaN, QNAN, or is in an unsupported format, an invalid-arithmetic-operand condition is signaled. If the invalid-operation exception is not masked, an invalid-arithmetic-operand exception (#IA) is generated and no value is stored in the destination operand. If the invalid-operation exception is masked, the integer indefinite value is stored in memory.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := Integer(ST(0));\nIF Instruction = FISTP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fist:fistp" + }, + "fisttp": { + "instruction": "FISTTP", + "title": "FISTTP\n\t\t— Store Integer With Truncation", + "opcode": "DF /1", + "description": "FISTTP converts the value in ST into a signed integer using truncation (chop) as rounding mode, transfers the result to the destination, and pop ST. FISTTP accepts word, short integer, and long integer destinations.\nThe following table shows the results obtained when storing various classes of numbers in integer format.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := ST;\npop ST;\n", + "url": "https://www.felixcloutier.com/x86/fisttp" + }, + "fisub": { + "instruction": "FISUB", + "title": "FSUB/FSUBP/FISUB\n\t\t— Subtract", + "opcode": "DA /4", + "description": "Subtracts the source operand from the destination operand and stores the difference in the destination location. The destination operand is always an FPU data register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction subtracts the contents of the ST(0) register from the ST(1) register and stores the result in ST(1). The one-operand version subtracts the contents of a memory location (either a floating-point or an integer value) from the contents of the ST(0) register and stores the result in ST(0). The two-operand version, subtracts the contents of the ST(0) register from the ST(i) register or vice versa.\nThe FSUBP instructions perform the additional operation of popping the FPU register stack following the subtraction. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point subtract instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FSUB rather than FSUBP.\nThe FISUB instructions convert an integer source operand to double extended-precision floating-point format before performing the subtraction.\nTable 3-38 shows the results obtained when subtracting various classes of numbers from one another, assuming that neither overflow nor underflow occurs. Here, the SRC value is subtracted from the DEST value (DEST − SRC = result).\nWhen the difference between two operands of like sign is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. This instruction also guarantees that +0 − (−0) = +0, and that −0 − (+0) = −0. When the source operand is an integer 0, it is treated as a +0.\nWhen one operand is ∞, the result is ∞ of the expected sign. If both operands are ∞ of the same sign, an invalidoperation exception is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FISUB\n THEN\n DEST := DEST − ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST − SRC;\nFI;\nIF Instruction = FSUBP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fsub:fsubp:fisub" + }, + "fisubr": { + "instruction": "FISUBR", + "title": "FSUBR/FSUBRP/FISUBR\n\t\t— Reverse Subtract", + "opcode": "DA /5", + "description": "Subtracts the destination operand from the source operand and stores the difference in the destination location. The destination operand is always an FPU register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThese instructions perform the reverse operations of the FSUB, FSUBP, and FISUB instructions. They are provided to support more efficient coding.\nThe no-operand version of the instruction subtracts the contents of the ST(1) register from the ST(0) register and stores the result in ST(1). The one-operand version subtracts the contents of the ST(0) register from the contents of a memory location (either a floating-point or an integer value) and stores the result in ST(0). The two-operand version, subtracts the contents of the ST(i) register from the ST(0) register or vice versa.\nThe FSUBRP instructions perform the additional operation of popping the FPU register stack following the subtraction. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point reverse subtract instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FSUBR rather than FSUBRP.\nThe FISUBR instructions convert an integer source operand to double extended-precision floating-point format before performing the subtraction.\nThe following table shows the results obtained when subtracting various classes of numbers from one another, assuming that neither overflow nor underflow occurs. Here, the DEST value is subtracted from the SRC value (SRC − DEST = result).\nWhen the difference between two operands of like sign is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. This instruction also guarantees that +0 − (−0) = +0, and that −0 − (+0) = −0. When the source operand is an integer 0, it is treated as a +0.\nWhen one operand is ∞, the result is ∞ of the expected sign. If both operands are ∞ of the same sign, an invalidoperation exception is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FISUBR\n THEN\n DEST := ConvertToDoubleExtendedPrecisionFP(SRC) − DEST;\n ELSE (* Source operand is floating-point value *)\n DEST := SRC − DEST; FI;\nIF Instruction = FSUBRP\n THEN\n PopRegisterStack; FI;\n", + "url": "https://www.felixcloutier.com/x86/fsubr:fsubrp:fisubr" + }, + "fld": { + "instruction": "FLD", + "title": "FLD\n\t\t— Load Floating-Point Value", + "opcode": "D9 /0", + "description": "Pushes the source operand onto the FPU register stack. The source operand can be in single precision, double precision, or double extended-precision floating-point format. If the source operand is in single precision or double precision floating-point format, it is automatically converted to the double extended-precision floating-point format before being pushed on the stack.\nThe FLD instruction can also push the value in a selected FPU register [ST(i)] onto the stack. Here, pushing register ST(0) duplicates the stack top.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF SRC is ST(i)\n THEN\n temp := ST(i);\nFI;\nTOP := TOP − 1;\nIF SRC is memory-operand\n THEN\n ST(0) := ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* SRC is ST(i) *)\n ST(0) := temp;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fld" + }, + "fld1": { + "instruction": "FLD1", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 E8", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fldcw": { + "instruction": "FLDCW", + "title": "FLDCW\n\t\t— Load x87 FPU Control Word", + "opcode": "D9 /5", + "description": "Loads the 16-bit source operand into the FPU control word. The source operand is a memory location. This instruction is typically used to establish or change the FPU’s mode of operation.\nIf one or more exception flags are set in the FPU status word prior to loading a new FPU control word and the new control word unmasks one or more of those exceptions, a floating-point exception will be generated upon execution of the next floating-point instruction (except for the no-wait floating-point instructions, see the section titled “Software Exception Handling” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). To avoid raising exceptions when changing FPU operating modes, clear any pending exceptions (using the FCLEX or FNCLEX instruction) before loading the new control word.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FPUControlWord := SRC;\n", + "url": "https://www.felixcloutier.com/x86/fldcw" + }, + "fldenv": { + "instruction": "FLDENV", + "title": "FLDENV\n\t\t— Load x87 FPU Environment", + "opcode": "D9 /4", + "description": "Loads the complete x87 FPU operating environment from memory into the FPU registers. The source operand specifies the first byte of the operating-environment data in memory. This data is typically written to the specified memory location by a FSTENV or FNSTENV instruction.\nThe FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, show the layout in memory of the loaded environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used.\nThe FLDENV instruction should be executed in the same operating mode as the corresponding FSTENV/FNSTENV instruction.\nIf one or more unmasked exception flags are set in the new FPU status word, a floating-point exception will be generated upon execution of the next floating-point instruction (except for the no-wait floating-point instructions, see the section titled “Software Exception Handling” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). To avoid generating exceptions when loading a new environment, clear all the exception flags in the FPU status word that is being loaded.\nIf a page or limit fault occurs during the execution of this instruction, the state of the x87 FPU registers as seen by the fault handler may be different than the state being loaded from memory. In such situations, the fault handler should ignore the status of the x87 FPU registers, handle the fault, and return. The FLDENV instruction will then complete the loading of the x87 FPU registers with no resulting context inconsistency.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FPUControlWord := SRC[FPUControlWord];\nFPUStatusWord := SRC[FPUStatusWord];\nFPUTagWord := SRC[FPUTagWord];\nFPUDataPointer := SRC[FPUDataPointer];\nFPUInstructionPointer := SRC[FPUInstructionPointer];\nFPULastInstructionOpcode := SRC[FPULastInstructionOpcode];\n", + "url": "https://www.felixcloutier.com/x86/fldenv" + }, + "fldl2e": { + "instruction": "FLDL2E", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 EA", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fldl2t": { + "instruction": "FLDL2T", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 E9", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fldlg2": { + "instruction": "FLDLG2", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 EC", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fldln2": { + "instruction": "FLDLN2", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 ED", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fldpi": { + "instruction": "FLDPI", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 EB", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fldz": { + "instruction": "FLDZ", + "title": "FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ\n\t\t— Load Constant", + "opcode": "D9 EE", + "description": "Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, π, log102, and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.\nSee the section titled “Approximation of Pi” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the π constant.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TOP := TOP − 1;\nST(0) := CONSTANT;\n", + "url": "https://www.felixcloutier.com/x86/fld1:fldl2t:fldl2e:fldpi:fldlg2:fldln2:fldz" + }, + "fmul": { + "instruction": "FMUL", + "title": "FMUL/FMULP/FIMUL\n\t\t— Multiply", + "opcode": "D8 /1", + "description": "Multiplies the destination and source operands and stores the product in the destination location. The destination operand is always an FPU data register; the source operand can be an FPU data register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction multiplies the contents of the ST(1) register by the contents of the ST(0) register and stores the product in the ST(1) register. The one-operand version multiplies the contents of the ST(0) register by the contents of a memory location (either a floating-point or an integer value) and stores the product in the ST(0) register. The two-operand version, multiplies the contents of the ST(0) register by the contents of the ST(i) register, or vice versa, with the result being stored in the register specified with the first operand (the destination operand).\nThe FMULP instructions perform the additional operation of popping the FPU register stack after storing the product. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point multiply instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FMUL rather than FMULP.\nThe FIMUL instructions convert an integer source operand to double extended-precision floating-point format before performing the multiplication.\nThe sign of the result is always the exclusive-OR of the source signs, even if one or more of the values being multiplied is 0 or ∞. When the source operand is an integer 0, it is treated as a +0.\nThe following table shows the results obtained when multiplying various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FIMUL\n THEN\n DEST := DEST ∗ ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST ∗ SRC;\nFI;\nIF Instruction = FMULP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fmul:fmulp:fimul" + }, + "fmulp": { + "instruction": "FMULP", + "title": "FMUL/FMULP/FIMUL\n\t\t— Multiply", + "opcode": "DE C8+i", + "description": "Multiplies the destination and source operands and stores the product in the destination location. The destination operand is always an FPU data register; the source operand can be an FPU data register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction multiplies the contents of the ST(1) register by the contents of the ST(0) register and stores the product in the ST(1) register. The one-operand version multiplies the contents of the ST(0) register by the contents of a memory location (either a floating-point or an integer value) and stores the product in the ST(0) register. The two-operand version, multiplies the contents of the ST(0) register by the contents of the ST(i) register, or vice versa, with the result being stored in the register specified with the first operand (the destination operand).\nThe FMULP instructions perform the additional operation of popping the FPU register stack after storing the product. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point multiply instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FMUL rather than FMULP.\nThe FIMUL instructions convert an integer source operand to double extended-precision floating-point format before performing the multiplication.\nThe sign of the result is always the exclusive-OR of the source signs, even if one or more of the values being multiplied is 0 or ∞. When the source operand is an integer 0, it is treated as a +0.\nThe following table shows the results obtained when multiplying various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FIMUL\n THEN\n DEST := DEST ∗ ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST ∗ SRC;\nFI;\nIF Instruction = FMULP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fmul:fmulp:fimul" + }, + "fnclex": { + "instruction": "FNCLEX", + "title": "FCLEX/FNCLEX\n\t\t— Clear Exceptions", + "opcode": "DB E2", + "description": "Clears the floating-point exception flags (PE, UE, OE, ZE, DE, and IE), the exception summary status flag (ES), the stack fault flag (SF), and the busy flag (B) in the FPU status word. The FCLEX instruction checks for and handles any pending unmasked floating-point exceptions before clearing the exception flags; the FNCLEX instruction does not.\nThe assembler issues two instructions for the FCLEX instruction (an FWAIT instruction followed by an FNCLEX instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.", + "operation": "FPUStatusWord[0:7] := 0;\nFPUStatusWord[15] := 0;\n", + "url": "https://www.felixcloutier.com/x86/fclex:fnclex" + }, + "fninit": { + "instruction": "FNINIT", + "title": "FINIT/FNINIT\n\t\t— Initialize Floating-Point Unit", + "opcode": "DB E3", + "description": "Sets the FPU control, status, tag, instruction pointer, and data pointer registers to their default states. The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). The status word is cleared (no exception flags set, TOP is set to 0). The data registers in the register stack are left unchanged, but they are all tagged as empty (11B). Both the instruction and data pointers are cleared.\nThe FINIT instruction checks for and handles any pending unmasked floating-point exceptions before performing the initialization; the FNINIT instruction does not.\nThe assembler issues two instructions for the FINIT instruction (an FWAIT instruction followed by an FNINIT instruction), and the processor executes each of these instructions in separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FPUControlWord := 037FH;\nFPUStatusWord := 0;\nFPUTagWord := FFFFH;\nFPUDataPointer := 0;\nFPUInstructionPointer := 0;\nFPULastInstructionOpcode := 0;\n", + "url": "https://www.felixcloutier.com/x86/finit:fninit" + }, + "fnop": { + "instruction": "FNOP", + "title": "FNOP\n\t\t— No Operation", + "opcode": "D9 D0", + "description": "Performs no FPU operation. This instruction takes up space in the instruction stream but does not affect the FPU or machine context, except the EIP register and the FPU Instruction Pointer.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/fnop" + }, + "fnsave": { + "instruction": "FNSAVE", + "title": "FSAVE/FNSAVE\n\t\t— Store x87 FPU State", + "opcode": "DD /6", + "description": "Stores the current FPU state (operating environment and register stack) at the specified destination in memory, and then re-initializes the FPU. The FSAVE instruction checks for and handles pending unmasked floating-point exceptions before storing the FPU state; the FNSAVE instruction does not.\nThe FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used. The contents of the FPU register stack are stored in the 80 bytes immediately follow the operating environment image.\nThe saved image reflects the state of the FPU after all floating-point instructions preceding the FSAVE/FNSAVE instruction in the instruction stream have been executed.\nAfter the FPU state has been saved, the FPU is reset to the same default values it is set to with the FINIT/FNINIT instructions (see “FINIT/FNINIT—Initialize Floating-Point Unit” in this chapter).\nThe FSAVE/FNSAVE instructions are typically used when the operating system needs to perform a context switch, an exception handler needs to use the FPU, or an application program needs to pass a “clean” FPU to a procedure.\nThe assembler issues two instructions for the FSAVE instruction (an FWAIT instruction followed by an FNSAVE instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "(* Save FPU State and Registers *)\nDEST[FPUControlWord] := FPUControlWord;\nDEST[FPUStatusWord] := FPUStatusWord;\nDEST[FPUTagWord] := FPUTagWord;\nDEST[FPUDataPointer] := FPUDataPointer;\nDEST[FPUInstructionPointer] := FPUInstructionPointer;\nDEST[FPULastInstructionOpcode] := FPULastInstructionOpcode;\nDEST[ST(0)] := ST(0);\nDEST[ST(1)] := ST(1);\nDEST[ST(2)] := ST(2);\nDEST[ST(3)] := ST(3);\nDEST[ST(4)]:= ST(4);\nDEST[ST(5)] := ST(5);\nDEST[ST(6)] := ST(6);\nDEST[ST(7)] := ST(7);\n(* Initialize FPU *)\nFPUControlWord := 037FH;\nFPUStatusWord := 0;\nFPUTagWord := FFFFH;\nFPUDataPointer := 0;\nFPUInstructionPointer := 0;\nFPULastInstructionOpcode := 0;\n", + "url": "https://www.felixcloutier.com/x86/fsave:fnsave" + }, + "fnstcw": { + "instruction": "FNSTCW", + "title": "FSTCW/FNSTCW\n\t\t— Store x87 FPU Control Word", + "opcode": "D9 /7", + "description": "Stores the current value of the FPU control word at the specified destination in memory. The FSTCW instruction checks for and handles pending unmasked floating-point exceptions before storing the control word; the FNSTCW instruction does not.\nThe assembler issues two instructions for the FSTCW instruction (an FWAIT instruction followed by an FNSTCW instruction), and the processor executes each of these instructions in separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := FPUControlWord;\n", + "url": "https://www.felixcloutier.com/x86/fstcw:fnstcw" + }, + "fnstenv": { + "instruction": "FNSTENV", + "title": "FSTENV/FNSTENV\n\t\t— Store x87 FPU Environment", + "opcode": "D9 /6", + "description": "Saves the current FPU operating environment at the memory location specified with the destination operand, and then masks all floating-point exceptions. The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used.\nThe FSTENV instruction checks for and handles any pending unmasked floating-point exceptions before storing the FPU environment; the FNSTENV instruction does not. The saved image reflects the state of the FPU after all floating-point instructions preceding the FSTENV/FNSTENV instruction in the instruction stream have been executed.\nThese instructions are often used by exception handlers because they provide access to the FPU instruction and data pointers. The environment is typically saved in the stack. Masking all exceptions after saving the environment prevents floating-point exceptions from interrupting the exception handler.\nThe assembler issues two instructions for the FSTENV instruction (an FWAIT instruction followed by an FNSTENV instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST[FPUControlWord] := FPUControlWord;\nDEST[FPUStatusWord] := FPUStatusWord;\nDEST[FPUTagWord] := FPUTagWord;\nDEST[FPUDataPointer] := FPUDataPointer;\nDEST[FPUInstructionPointer] := FPUInstructionPointer;\nDEST[FPULastInstructionOpcode] := FPULastInstructionOpcode;\n", + "url": "https://www.felixcloutier.com/x86/fstenv:fnstenv" + }, + "fnstsw": { + "instruction": "FNSTSW", + "title": "FSTSW/FNSTSW\n\t\t— Store x87 FPU Status Word", + "opcode": "DD /7", + "description": "Stores the current value of the x87 FPU status word in the destination location. The destination operand can be either a two-byte memory location or the AX register. The FSTSW instruction checks for and handles pending unmasked floating-point exceptions before storing the status word; the FNSTSW instruction does not.\nThe FNSTSW AX form of the instruction is used primarily in conditional branching (for instance, after an FPU comparison instruction or an FPREM, FPREM1, or FXAM instruction), where the direction of the branch depends on the state of the FPU condition code flags. (See the section titled “Branching and Conditional Moves on FPU Condition Codes” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.) This instruction can also be used to invoke exception handlers (by examining the exception flags) in environments that do not use interrupts. When the FNSTSW AX instruction is executed, the AX register is updated before the processor executes any further instructions. The status stored in the AX register is thus guaranteed to be from the completion of the prior FPU instruction.\nThe assembler issues two instructions for the FSTSW instruction (an FWAIT instruction followed by an FNSTSW instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := FPUStatusWord;\n", + "url": "https://www.felixcloutier.com/x86/fstsw:fnstsw" + }, + "fpatan": { + "instruction": "FPATAN", + "title": "FPATAN\n\t\t— Partial Arctangent", + "opcode": "D9 F3", + "description": "Computes the arctangent of the source operand in register ST(1) divided by the source operand in register ST(0), stores the result in ST(1), and pops the FPU register stack. The result in register ST(0) has the same sign as the source operand ST(1) and a magnitude less than +π.\nThe FPATAN instruction returns the angle between the X axis and the line from the origin to the point (X,Y), where Y (the ordinate) is ST(1) and X (the abscissa) is ST(0). The angle depends on the sign of X and Y independently, not just on the sign of the ratio Y/X. This is because a point (−X,Y) is in the second quadrant, resulting in an angle between π/2 and π, while a point (X,−Y) is in the fourth quadrant, resulting in an angle between 0 and −π/2. A point (−X,−Y) is in the third quadrant, giving an angle between −π/2 and −π.\nThe following table shows the results obtained when computing the arctangent of various classes of numbers, assuming that underflow does not occur.\nThere is no restriction on the range of source operands that FPATAN can accept.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(1) := arctan(ST(1) / ST(0));\nPopRegisterStack;\n", + "url": "https://www.felixcloutier.com/x86/fpatan" + }, + "fprem": { + "instruction": "FPREM", + "title": "FPREM\n\t\t— Partial Remainder", + "opcode": "D9 F8", + "description": "Computes the remainder obtained from dividing the value in the ST(0) register (the dividend) by the value in the ST(1) register (the divisor or modulus), and stores the result in ST(0). The remainder represents the following value:\nRemainder := ST(0) − (Q ∗ ST(1))\nHere, Q is an integer value that is obtained by truncating the floating-point number quotient of [ST(0) / ST(1)] toward zero. The sign of the remainder is the same as the sign of the dividend. The magnitude of the remainder is less than that of the modulus, unless a partial remainder was computed (as described below).\nThis instruction produces an exact result; the inexact-result exception does not occur and the rounding control has no effect. The following table shows the results obtained when computing the remainder of various classes of numbers, assuming that underflow does not occur.\nWhen the result is 0, its sign is the same as that of the dividend. When the modulus is ∞, the result is equal to the value in ST(0).\nThe FPREM instruction does not compute the remainder specified in IEEE Std 754. The IEEE specified remainder can be computed with the FPREM1 instruction. The FPREM instruction is provided for compatibility with the Intel 8087 and Intel287 math coprocessors.\nThe FPREM instruction gets its name “partial remainder” because of the way it computes the remainder. This instruction arrives at a remainder through iterative subtraction. It can, however, reduce the exponent of ST(0) by no more than 63 in one execution of the instruction. If the instruction succeeds in producing a remainder that is less than the modulus, the operation is complete and the C2 flag in the FPU status word is cleared. Otherwise, C2 is set, and the result in ST(0) is called the partial remainder. The exponent of the partial remainder will be less than the exponent of the original dividend by at least 32. Software can re-execute the instruction (using the partial remainder in ST(0) as the dividend) until C2 is cleared. (Note that while executing such a remainder-computation loop, a higher-priority interrupting routine that needs the FPU can force a context switch in-between the instructions in the loop.)\nAn important use of the FPREM instruction is to reduce the arguments of periodic functions. When reduction is complete, the instruction stores the three least-significant bits of the quotient in the C3, C1, and C0 flags of the FPU\nstatus word. This information is important in argument reduction for the tangent function (using a modulus of π/4), because it locates the original angle in the correct one of eight sectors of the unit circle.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "D := exponent(ST(0)) – exponent(ST(1));\nIF D < 64\n THEN\n Q := Integer(TruncateTowardZero(ST(0) / ST(1)));\n ST(0) := ST(0) – (ST(1) ∗ Q);\n C2 := 0;\n C0, C3, C1 := LeastSignificantBits(Q); (* Q2, Q1, Q0 *)\n ELSE\n C2 := 1;\n N := An implementation-dependent number between 32 and 63;\n QQ := Integer(TruncateTowardZero((ST(0) / ST(1)) / 2(D − N)));\n ST(0) := ST(0) – (ST(1) ∗ QQ ∗ 2(D − N));\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fprem" + }, + "fprem1": { + "instruction": "FPREM1", + "title": "FPREM1\n\t\t— Partial Remainder", + "opcode": "D9 F5", + "description": "Computes the IEEE remainder obtained from dividing the value in the ST(0) register (the dividend) by the value in the ST(1) register (the divisor or modulus), and stores the result in ST(0). The remainder represents the following value:\nRemainder := ST(0) − (Q ∗ ST(1))\nHere, Q is an integer value that is obtained by rounding the floating-point number quotient of [ST(0) / ST(1)] toward the nearest integer value. The magnitude of the remainder is less than or equal to half the magnitude of the modulus, unless a partial remainder was computed (as described below).\nThis instruction produces an exact result; the precision (inexact) exception does not occur and the rounding control has no effect. The following table shows the results obtained when computing the remainder of various classes of numbers, assuming that underflow does not occur.\nWhen the result is 0, its sign is the same as that of the dividend. When the modulus is ∞, the result is equal to the value in ST(0).\nThe FPREM1 instruction computes the remainder specified in IEEE Standard 754. This instruction operates differently from the FPREM instruction in the way that it rounds the quotient of ST(0) divided by ST(1) to an integer (see the “Operation” section below).\nLike the FPREM instruction, FPREM1 computes the remainder through iterative subtraction, but can reduce the exponent of ST(0) by no more than 63 in one execution of the instruction. If the instruction succeeds in producing a remainder that is less than one half the modulus, the operation is complete and the C2 flag in the FPU status word is cleared. Otherwise, C2 is set, and the result in ST(0) is called the partial remainder. The exponent of the partial remainder will be less than the exponent of the original dividend by at least 32. Software can re-execute the instruction (using the partial remainder in ST(0) as the dividend) until C2 is cleared. (Note that while executing such a remainder-computation loop, a higher-priority interrupting routine that needs the FPU can force a context switch in-between the instructions in the loop.)\nAn important use of the FPREM1 instruction is to reduce the arguments of periodic functions. When reduction is complete, the instruction stores the three least-significant bits of the quotient in the C3, C1, and C0 flags of the FPU status word. This information is important in argument reduction for the tangent function (using a modulus of π/4), because it locates the original angle in the correct one of eight sectors of the unit circle.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "D := exponent(ST(0)) – exponent(ST(1));\nIF D < 64\n THEN\n Q := Integer(RoundTowardNearestInteger(ST(0) / ST(1)));\n ST(0) := ST(0) – (ST(1) ∗ Q);\n C2 := 0;\n C0, C3, C1 := LeastSignificantBits(Q); (* Q2, Q1, Q0 *)\n ELSE\n C2 := 1;\n N := An implementation-dependent number between 32 and 63;\n QQ := Integer(TruncateTowardZero((ST(0) / ST(1)) / 2(D − N)));\n ST(0) := ST(0) – (ST(1) ∗ QQ ∗ 2(D − N));\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fprem1" + }, + "fptan": { + "instruction": "FPTAN", + "title": "FPTAN\n\t\t— Partial Tangent", + "opcode": "D9 F2", + "description": "Computes the approximate tangent of the source operand in register ST(0), stores the result in ST(0), and pushes a 1.0 onto the FPU register stack. The source operand must be given in radians and must be less than ±263. The following table shows the unmasked results obtained when computing the partial tangent of various classes of numbers, assuming that underflow does not occur.\nIf the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range − 263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2π. However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of π used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply FPTAN only to arguments reduced accurately in software, to a value smaller in absolute value than 3π/8. See the sections titled “Approximation of Pi” and “Transcendental Instruction Accuracy” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a discussion of the proper value to use for π in performing such reductions.\nThe value 1.0 is pushed onto the register stack after the tangent has been computed to maintain compatibility with the Intel 8087 and Intel287 math coprocessors. This operation also simplifies the calculation of other trigonometric functions. For instance, the cotangent (which is the reciprocal of the tangent) can be computed by executing a FDIVR instruction after the FPTAN instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF ST(0) < 263\n THEN\n C2 := 0;\n ST(0) := fptan(ST(0)); // approximation of tan\n TOP := TOP − 1;\n ST(0) := 1.0;\n ELSE (* Source operand is out-of-range *)\n C2 := 1;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fptan" + }, + "frndint": { + "instruction": "FRNDINT", + "title": "FRNDINT\n\t\t— Round to Integer", + "opcode": "D9 FC", + "description": "Rounds the source value in the ST(0) register to the nearest integral value, depending on the current rounding mode (setting of the RC field of the FPU control word), and stores the result in ST(0).\nIf the source value is ∞, the value is not changed. If the source value is not an integral value, the floating-point inexact-result exception (#P) is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(0) := RoundToIntegralValue(ST(0));\n", + "url": "https://www.felixcloutier.com/x86/frndint" + }, + "frstor": { + "instruction": "FRSTOR", + "title": "FRSTOR\n\t\t— Restore x87 FPU State", + "opcode": "DD /4", + "description": "Loads the FPU state (operating environment and register stack) from the memory area specified with the source operand. This state data is typically written to the specified memory location by a previous FSAVE/FNSAVE instruction.\nThe FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used. The contents of the FPU register stack are stored in the 80 bytes immediately following the operating environment image.\nThe FRSTOR instruction should be executed in the same operating mode as the corresponding FSAVE/FNSAVE instruction.\nIf one or more unmasked exception bits are set in the new FPU status word, a floating-point exception will be generated upon execution of the next floating-point instruction (except for the no-wait floating-point instructions, see the section titled “Software Exception Handling” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). To avoid raising exceptions when loading a new operating environment, clear all the exception flags in the FPU status word that is being loaded.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FPUControlWord := SRC[FPUControlWord];\nFPUStatusWord := SRC[FPUStatusWord];\nFPUTagWord := SRC[FPUTagWord];\nFPUDataPointer := SRC[FPUDataPointer];\nFPUInstructionPointer := SRC[FPUInstructionPointer];\nFPULastInstructionOpcode := SRC[FPULastInstructionOpcode];\nST(0) := SRC[ST(0)];\nST(1) := SRC[ST(1)];\nST(2) := SRC[ST(2)];\nST(3) := SRC[ST(3)];\nST(4) := SRC[ST(4)];\nST(5) := SRC[ST(5)];\nST(6) := SRC[ST(6)];\nST(7) := SRC[ST(7)];\n", + "url": "https://www.felixcloutier.com/x86/frstor" + }, + "fsave": { + "instruction": "FSAVE", + "title": "FSAVE/FNSAVE\n\t\t— Store x87 FPU State", + "opcode": "9B DD /6", + "description": "Stores the current FPU state (operating environment and register stack) at the specified destination in memory, and then re-initializes the FPU. The FSAVE instruction checks for and handles pending unmasked floating-point exceptions before storing the FPU state; the FNSAVE instruction does not.\nThe FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used. The contents of the FPU register stack are stored in the 80 bytes immediately follow the operating environment image.\nThe saved image reflects the state of the FPU after all floating-point instructions preceding the FSAVE/FNSAVE instruction in the instruction stream have been executed.\nAfter the FPU state has been saved, the FPU is reset to the same default values it is set to with the FINIT/FNINIT instructions (see “FINIT/FNINIT—Initialize Floating-Point Unit” in this chapter).\nThe FSAVE/FNSAVE instructions are typically used when the operating system needs to perform a context switch, an exception handler needs to use the FPU, or an application program needs to pass a “clean” FPU to a procedure.\nThe assembler issues two instructions for the FSAVE instruction (an FWAIT instruction followed by an FNSAVE instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "(* Save FPU State and Registers *)\nDEST[FPUControlWord] := FPUControlWord;\nDEST[FPUStatusWord] := FPUStatusWord;\nDEST[FPUTagWord] := FPUTagWord;\nDEST[FPUDataPointer] := FPUDataPointer;\nDEST[FPUInstructionPointer] := FPUInstructionPointer;\nDEST[FPULastInstructionOpcode] := FPULastInstructionOpcode;\nDEST[ST(0)] := ST(0);\nDEST[ST(1)] := ST(1);\nDEST[ST(2)] := ST(2);\nDEST[ST(3)] := ST(3);\nDEST[ST(4)]:= ST(4);\nDEST[ST(5)] := ST(5);\nDEST[ST(6)] := ST(6);\nDEST[ST(7)] := ST(7);\n(* Initialize FPU *)\nFPUControlWord := 037FH;\nFPUStatusWord := 0;\nFPUTagWord := FFFFH;\nFPUDataPointer := 0;\nFPUInstructionPointer := 0;\nFPULastInstructionOpcode := 0;\n", + "url": "https://www.felixcloutier.com/x86/fsave:fnsave" + }, + "fscale": { + "instruction": "FSCALE", + "title": "FSCALE\n\t\t— Scale", + "opcode": "D9 FD", + "description": "Truncates the value in the source operand (toward 0) to an integral value and adds that value to the exponent of the destination operand. The destination and source operands are floating-point values located in registers ST(0) and ST(1), respectively. This instruction provides rapid multiplication or division by integral powers of 2. The following table shows the results obtained when scaling various classes of numbers, assuming that neither overflow nor underflow occurs.\nIn most cases, only the exponent is changed and the mantissa (significand) remains unchanged. However, when the value being scaled in ST(0) is a denormal value, the mantissa is also changed and the result may turn out to be a normalized number. Similarly, if overflow or underflow results from a scale operation, the resulting mantissa will differ from the source’s mantissa.\nThe FSCALE instruction can also be used to reverse the action of the FXTRACT instruction, as shown in the following example:\nFXTRACT;\nFSCALE;\nFSTP ST(1);\nIn this example, the FXTRACT instruction extracts the significand and exponent from the value in ST(0) and stores them in ST(0) and ST(1) respectively. The FSCALE then scales the significand in ST(0) by the exponent in ST(1), recreating the original value before the FXTRACT operation was performed. The FSTP ST(1) instruction overwrites the exponent (extracted by the FXTRACT instruction) with the recreated value, which returns the stack to its original state with only one register [ST(0)] occupied.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(0) := ST(0) ∗ 2RoundTowardZero(ST(1));\n", + "url": "https://www.felixcloutier.com/x86/fscale" + }, + "fsin": { + "instruction": "FSIN", + "title": "FSIN\n\t\t— Sine", + "opcode": "D9 FE", + "description": "Computes an approximation of the sine of the source operand in register ST(0) and stores the result in ST(0). The source operand must be given in radians and must be within the range −263 to +263. The following table shows the results obtained when taking the sine of various classes of numbers, assuming that underflow does not occur.\nIf the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range − 263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2π. However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of π used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply FSIN only to arguments reduced accurately in software, to a value smaller in absolute value than 3π/4. See the sections titled “Approximation of Pi” and “Transcendental Instruction Accuracy” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a discussion of the proper value to use for π in performing such reductions.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF -263 < ST(0) < 263\n THEN\n C2 := 0;\n ST(0) := fsin(ST(0)); // approximation of the mathematical sin function\n ELSE (* Source operand out of range *)\n C2 := 1;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fsin" + }, + "fsincos": { + "instruction": "FSINCOS", + "title": "FSINCOS\n\t\t— Sine and Cosine", + "opcode": "D9 FB", + "description": "Computes both the approximate sine and the cosine of the source operand in register ST(0), stores the sine in ST(0), and pushes the cosine onto the top of the FPU register stack. (This instruction is faster than executing the FSIN and FCOS instructions in succession.)\nThe source operand must be given in radians and must be within the range −263 to +263. The following table shows the results obtained when taking the sine and cosine of various classes of numbers, assuming that underflow does not occur.\nIf the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range − 263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2π. However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of π used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply FSINCOS only to arguments reduced accurately in software, to a value smaller in absolute value than 3π/8. See the sections titled “Approximation of Pi” and “Transcendental Instruction Accuracy” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a discussion of the proper value to use for π in performing such reductions.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF ST(0) < 263\n THEN\n C2 := 0;\n TEMP := fcos(ST(0)); // approximation of cosine\n ST(0) := fsin(ST(0)); // approximation of sine\n TOP := TOP − 1;\n ST(0) := TEMP;\n ELSE (* Source operand out of range *)\n C2 := 1;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fsincos" + }, + "fsqrt": { + "instruction": "FSQRT", + "title": "FSQRT\n\t\t— Square Root", + "opcode": "D9 FA", + "description": "Computes the square root of the source value in the ST(0) register and stores the result in ST(0).\nThe following table shows the results obtained when taking the square root of various classes of numbers, assuming that neither overflow nor underflow occurs.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(0) := SquareRoot(ST(0));\n", + "url": "https://www.felixcloutier.com/x86/fsqrt" + }, + "fst": { + "instruction": "FST", + "title": "FST/FSTP\n\t\t— Store Floating-Point Value", + "opcode": "D9 /2", + "description": "The FST instruction copies the value in the ST(0) register to the destination operand, which can be a memory location or another register in the FPU register stack. When storing the value in memory, the value is converted to single precision or double precision floating-point format.\nThe FSTP instruction performs the same operation as the FST instruction and then pops the register stack. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The FSTP instruction can also store values in memory in double extended-precision floating-point format.\nIf the destination operand is a memory location, the operand specifies the address where the first byte of the destination value is to be stored. If the destination operand is a register, the operand specifies a register in the register stack relative to the top of the stack.\nIf the destination size is single precision or double precision, the significand of the value being stored is rounded to the width of the destination (according to the rounding mode specified by the RC field of the FPU control word), and the exponent is converted to the width and bias of the destination format. If the value being stored is too large for the destination format, a numeric overflow exception (#O) is generated and, if the exception is unmasked, no value is stored in the destination operand. If the value being stored is a denormal value, the denormal exception (#D) is not generated. This condition is simply signaled as a numeric underflow exception (#U) condition.\nIf the value being stored is ±0, ±∞, or a NaN, the least-significant bits of the significand and the exponent are truncated to fit the destination format. This operation preserves the value’s identity as a 0, ∞, or NaN.\nIf the destination operand is a non-empty register, the invalid-operation exception is not generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := ST(0);\nIF Instruction = FSTP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fst:fstp" + }, + "fstcw": { + "instruction": "FSTCW", + "title": "FSTCW/FNSTCW\n\t\t— Store x87 FPU Control Word", + "opcode": "9B D9 /7", + "description": "Stores the current value of the FPU control word at the specified destination in memory. The FSTCW instruction checks for and handles pending unmasked floating-point exceptions before storing the control word; the FNSTCW instruction does not.\nThe assembler issues two instructions for the FSTCW instruction (an FWAIT instruction followed by an FNSTCW instruction), and the processor executes each of these instructions in separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := FPUControlWord;\n", + "url": "https://www.felixcloutier.com/x86/fstcw:fnstcw" + }, + "fstenv": { + "instruction": "FSTENV", + "title": "FSTENV/FNSTENV\n\t\t— Store x87 FPU Environment", + "opcode": "9B D9 /6", + "description": "Saves the current FPU operating environment at the memory location specified with the destination operand, and then masks all floating-point exceptions. The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used.\nThe FSTENV instruction checks for and handles any pending unmasked floating-point exceptions before storing the FPU environment; the FNSTENV instruction does not. The saved image reflects the state of the FPU after all floating-point instructions preceding the FSTENV/FNSTENV instruction in the instruction stream have been executed.\nThese instructions are often used by exception handlers because they provide access to the FPU instruction and data pointers. The environment is typically saved in the stack. Masking all exceptions after saving the environment prevents floating-point exceptions from interrupting the exception handler.\nThe assembler issues two instructions for the FSTENV instruction (an FWAIT instruction followed by an FNSTENV instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST[FPUControlWord] := FPUControlWord;\nDEST[FPUStatusWord] := FPUStatusWord;\nDEST[FPUTagWord] := FPUTagWord;\nDEST[FPUDataPointer] := FPUDataPointer;\nDEST[FPUInstructionPointer] := FPUInstructionPointer;\nDEST[FPULastInstructionOpcode] := FPULastInstructionOpcode;\n", + "url": "https://www.felixcloutier.com/x86/fstenv:fnstenv" + }, + "fstp": { + "instruction": "FSTP", + "title": "FST/FSTP\n\t\t— Store Floating-Point Value", + "opcode": "D9 /3", + "description": "The FST instruction copies the value in the ST(0) register to the destination operand, which can be a memory location or another register in the FPU register stack. When storing the value in memory, the value is converted to single precision or double precision floating-point format.\nThe FSTP instruction performs the same operation as the FST instruction and then pops the register stack. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The FSTP instruction can also store values in memory in double extended-precision floating-point format.\nIf the destination operand is a memory location, the operand specifies the address where the first byte of the destination value is to be stored. If the destination operand is a register, the operand specifies a register in the register stack relative to the top of the stack.\nIf the destination size is single precision or double precision, the significand of the value being stored is rounded to the width of the destination (according to the rounding mode specified by the RC field of the FPU control word), and the exponent is converted to the width and bias of the destination format. If the value being stored is too large for the destination format, a numeric overflow exception (#O) is generated and, if the exception is unmasked, no value is stored in the destination operand. If the value being stored is a denormal value, the denormal exception (#D) is not generated. This condition is simply signaled as a numeric underflow exception (#U) condition.\nIf the value being stored is ±0, ±∞, or a NaN, the least-significant bits of the significand and the exponent are truncated to fit the destination format. This operation preserves the value’s identity as a 0, ∞, or NaN.\nIf the destination operand is a non-empty register, the invalid-operation exception is not generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := ST(0);\nIF Instruction = FSTP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fst:fstp" + }, + "fstsw": { + "instruction": "FSTSW", + "title": "FSTSW/FNSTSW\n\t\t— Store x87 FPU Status Word", + "opcode": "9B DD /7", + "description": "Stores the current value of the x87 FPU status word in the destination location. The destination operand can be either a two-byte memory location or the AX register. The FSTSW instruction checks for and handles pending unmasked floating-point exceptions before storing the status word; the FNSTSW instruction does not.\nThe FNSTSW AX form of the instruction is used primarily in conditional branching (for instance, after an FPU comparison instruction or an FPREM, FPREM1, or FXAM instruction), where the direction of the branch depends on the state of the FPU condition code flags. (See the section titled “Branching and Conditional Moves on FPU Condition Codes” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.) This instruction can also be used to invoke exception handlers (by examining the exception flags) in environments that do not use interrupts. When the FNSTSW AX instruction is executed, the AX register is updated before the processor executes any further instructions. The status stored in the AX register is thus guaranteed to be from the completion of the prior FPU instruction.\nThe assembler issues two instructions for the FSTSW instruction (an FWAIT instruction followed by an FNSTSW instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := FPUStatusWord;\n", + "url": "https://www.felixcloutier.com/x86/fstsw:fnstsw" + }, + "fsub": { + "instruction": "FSUB", + "title": "FSUB/FSUBP/FISUB\n\t\t— Subtract", + "opcode": "D8 /4", + "description": "Subtracts the source operand from the destination operand and stores the difference in the destination location. The destination operand is always an FPU data register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction subtracts the contents of the ST(0) register from the ST(1) register and stores the result in ST(1). The one-operand version subtracts the contents of a memory location (either a floating-point or an integer value) from the contents of the ST(0) register and stores the result in ST(0). The two-operand version, subtracts the contents of the ST(0) register from the ST(i) register or vice versa.\nThe FSUBP instructions perform the additional operation of popping the FPU register stack following the subtraction. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point subtract instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FSUB rather than FSUBP.\nThe FISUB instructions convert an integer source operand to double extended-precision floating-point format before performing the subtraction.\nTable 3-38 shows the results obtained when subtracting various classes of numbers from one another, assuming that neither overflow nor underflow occurs. Here, the SRC value is subtracted from the DEST value (DEST − SRC = result).\nWhen the difference between two operands of like sign is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. This instruction also guarantees that +0 − (−0) = +0, and that −0 − (+0) = −0. When the source operand is an integer 0, it is treated as a +0.\nWhen one operand is ∞, the result is ∞ of the expected sign. If both operands are ∞ of the same sign, an invalidoperation exception is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FISUB\n THEN\n DEST := DEST − ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST − SRC;\nFI;\nIF Instruction = FSUBP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fsub:fsubp:fisub" + }, + "fsubp": { + "instruction": "FSUBP", + "title": "FSUB/FSUBP/FISUB\n\t\t— Subtract", + "opcode": "DE E8+i", + "description": "Subtracts the source operand from the destination operand and stores the difference in the destination location. The destination operand is always an FPU data register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThe no-operand version of the instruction subtracts the contents of the ST(0) register from the ST(1) register and stores the result in ST(1). The one-operand version subtracts the contents of a memory location (either a floating-point or an integer value) from the contents of the ST(0) register and stores the result in ST(0). The two-operand version, subtracts the contents of the ST(0) register from the ST(i) register or vice versa.\nThe FSUBP instructions perform the additional operation of popping the FPU register stack following the subtraction. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point subtract instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FSUB rather than FSUBP.\nThe FISUB instructions convert an integer source operand to double extended-precision floating-point format before performing the subtraction.\nTable 3-38 shows the results obtained when subtracting various classes of numbers from one another, assuming that neither overflow nor underflow occurs. Here, the SRC value is subtracted from the DEST value (DEST − SRC = result).\nWhen the difference between two operands of like sign is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. This instruction also guarantees that +0 − (−0) = +0, and that −0 − (+0) = −0. When the source operand is an integer 0, it is treated as a +0.\nWhen one operand is ∞, the result is ∞ of the expected sign. If both operands are ∞ of the same sign, an invalidoperation exception is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FISUB\n THEN\n DEST := DEST − ConvertToDoubleExtendedPrecisionFP(SRC);\n ELSE (* Source operand is floating-point value *)\n DEST := DEST − SRC;\nFI;\nIF Instruction = FSUBP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fsub:fsubp:fisub" + }, + "fsubr": { + "instruction": "FSUBR", + "title": "FSUBR/FSUBRP/FISUBR\n\t\t— Reverse Subtract", + "opcode": "D8 /5", + "description": "Subtracts the destination operand from the source operand and stores the difference in the destination location. The destination operand is always an FPU register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThese instructions perform the reverse operations of the FSUB, FSUBP, and FISUB instructions. They are provided to support more efficient coding.\nThe no-operand version of the instruction subtracts the contents of the ST(1) register from the ST(0) register and stores the result in ST(1). The one-operand version subtracts the contents of the ST(0) register from the contents of a memory location (either a floating-point or an integer value) and stores the result in ST(0). The two-operand version, subtracts the contents of the ST(i) register from the ST(0) register or vice versa.\nThe FSUBRP instructions perform the additional operation of popping the FPU register stack following the subtraction. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point reverse subtract instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FSUBR rather than FSUBRP.\nThe FISUBR instructions convert an integer source operand to double extended-precision floating-point format before performing the subtraction.\nThe following table shows the results obtained when subtracting various classes of numbers from one another, assuming that neither overflow nor underflow occurs. Here, the DEST value is subtracted from the SRC value (SRC − DEST = result).\nWhen the difference between two operands of like sign is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. This instruction also guarantees that +0 − (−0) = +0, and that −0 − (+0) = −0. When the source operand is an integer 0, it is treated as a +0.\nWhen one operand is ∞, the result is ∞ of the expected sign. If both operands are ∞ of the same sign, an invalidoperation exception is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FISUBR\n THEN\n DEST := ConvertToDoubleExtendedPrecisionFP(SRC) − DEST;\n ELSE (* Source operand is floating-point value *)\n DEST := SRC − DEST; FI;\nIF Instruction = FSUBRP\n THEN\n PopRegisterStack; FI;\n", + "url": "https://www.felixcloutier.com/x86/fsubr:fsubrp:fisubr" + }, + "fsubrp": { + "instruction": "FSUBRP", + "title": "FSUBR/FSUBRP/FISUBR\n\t\t— Reverse Subtract", + "opcode": "DE E0+i", + "description": "Subtracts the destination operand from the source operand and stores the difference in the destination location. The destination operand is always an FPU register; the source operand can be a register or a memory location. Source operands in memory can be in single precision or double precision floating-point format or in word or doubleword integer format.\nThese instructions perform the reverse operations of the FSUB, FSUBP, and FISUB instructions. They are provided to support more efficient coding.\nThe no-operand version of the instruction subtracts the contents of the ST(1) register from the ST(0) register and stores the result in ST(1). The one-operand version subtracts the contents of the ST(0) register from the contents of a memory location (either a floating-point or an integer value) and stores the result in ST(0). The two-operand version, subtracts the contents of the ST(i) register from the ST(0) register or vice versa.\nThe FSUBRP instructions perform the additional operation of popping the FPU register stack following the subtraction. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The no-operand version of the floating-point reverse subtract instructions always results in the register stack being popped. In some assemblers, the mnemonic for this instruction is FSUBR rather than FSUBRP.\nThe FISUBR instructions convert an integer source operand to double extended-precision floating-point format before performing the subtraction.\nThe following table shows the results obtained when subtracting various classes of numbers from one another, assuming that neither overflow nor underflow occurs. Here, the DEST value is subtracted from the SRC value (SRC − DEST = result).\nWhen the difference between two operands of like sign is 0, the result is +0, except for the round toward −∞ mode, in which case the result is −0. This instruction also guarantees that +0 − (−0) = +0, and that −0 − (+0) = −0. When the source operand is an integer 0, it is treated as a +0.\nWhen one operand is ∞, the result is ∞ of the expected sign. If both operands are ∞ of the same sign, an invalidoperation exception is generated.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF Instruction = FISUBR\n THEN\n DEST := ConvertToDoubleExtendedPrecisionFP(SRC) − DEST;\n ELSE (* Source operand is floating-point value *)\n DEST := SRC − DEST; FI;\nIF Instruction = FSUBRP\n THEN\n PopRegisterStack; FI;\n", + "url": "https://www.felixcloutier.com/x86/fsubr:fsubrp:fisubr" + }, + "ftst": { + "instruction": "FTST", + "title": "FTST\n\t\t— TEST", + "opcode": "D9 E4", + "description": "Compares the value in the ST(0) register with 0.0 and sets the condition code flags C0, C2, and C3 in the FPU status word according to the results (see table below).\nThis instruction performs an “unordered comparison.” An unordered comparison also checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). If the value in register ST(0) is a NaN or is in an undefined format, the condition flags are set to “unordered” and the invalid operation exception is generated.\nThe sign of zero is ignored, so that (– 0.0 := +0.0).\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n Not comparable:\n C3, C2, C0 := 111;\n ST(0) > 0.0:\n C3, C2, C0 := 000;\n ST(0) < 0.0:\n C3, C2, C0 := 001;\n ST(0) = 0.0:\n C3, C2, C0 := 100;\nESAC;\n", + "url": "https://www.felixcloutier.com/x86/ftst" + }, + "fucom": { + "instruction": "FUCOM", + "title": "FUCOM/FUCOMP/FUCOMPP\n\t\t— Unordered Compare Floating-Point Values", + "opcode": "DD E0+i", + "description": "Performs an unordered comparison of the contents of register ST(0) and ST(i) and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below). If no operand is specified, the contents of registers ST(0) and ST(1) are compared. The sign of zero is ignored, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOM/FUCOMP/FUCOMPP instructions perform the same operations as the FCOM/FCOMP/FCOMPP instructions. The only difference is that the FUCOM/FUCOMP/FUCOMPP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOM/FCOMP/FCOMPP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nAs with the FCOM/FCOMP/FCOMPP instructions, if the operation results in an invalid-arithmetic-operand exception being raised, the condition code flags are set only if the exception is masked.\nThe FUCOMP instruction pops the register stack following the comparison operation and the FUCOMPP instruction pops the register stack twice following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST > SRC:\n C3, C2, C0 := 000;\n ST < SRC:\n C3, C2, C0 := 001;\n ST = SRC:\n C3, C2, C0 := 100;\nESAC;\nIF ST(0) or SRC = QNaN, but not SNaN or unsupported format\n THEN\n C3, C2, C0 := 111;\n ELSE (* ST(0) or SRC is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n C3, C2, C0 := 111;\n FI;\nFI;\nIF Instruction = FUCOMP\n THEN\n PopRegisterStack;\nFI;\nIF Instruction = FUCOMPP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fucom:fucomp:fucompp" + }, + "fucomi": { + "instruction": "FUCOMI", + "title": "FCOMI/FCOMIP/FUCOMI/FUCOMIP\n\t\t— Compare Floating-Point Values and Set EFLAGS", + "opcode": "DB E8+i", + "description": "Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results (see the table below). The sign of zero is ignored for comparisons, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOMI/FUCOMIP instructions perform the same operations as the FCOMI/FCOMIP instructions. The only difference is that the FUCOMI/FUCOMIP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOMI/FCOMIP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nIf the operation results in an invalid-arithmetic-operand exception being raised, the status flags in the EFLAGS register are set only if the exception is masked.\nThe FCOMI/FCOMIP and FUCOMI/FUCOMIP instructions set the OF, SF, and AF flags to zero in the EFLAGS register (regardless of whether an invalid-operation exception is detected).\nThe FCOMIP and FUCOMIP instructions also pop the register stack following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST(0) > ST(i):\n ZF, PF, CF := 000;\n ST(0) < ST(i):\n ZF, PF, CF := 001;\n ST(0) = ST(i):\n ZF, PF, CF := 100;\nESAC;\nIF Instruction is FCOMI or FCOMIP\n THEN\n IF ST(0) or ST(i) = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FUCOMI or FUCOMIP\n THEN\n IF ST(0) or ST(i) = QNaN, but not SNaN or unsupported format\n THEN\n ZF, PF, CF := 111;\n ELSE (* ST(0) or ST(i) is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FCOMIP or FUCOMIP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcomi:fcomip:fucomi:fucomip" + }, + "fucomip": { + "instruction": "FUCOMIP", + "title": "FCOMI/FCOMIP/FUCOMI/FUCOMIP\n\t\t— Compare Floating-Point Values and Set EFLAGS", + "opcode": "DF E8+i", + "description": "Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results (see the table below). The sign of zero is ignored for comparisons, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOMI/FUCOMIP instructions perform the same operations as the FCOMI/FCOMIP instructions. The only difference is that the FUCOMI/FUCOMIP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOMI/FCOMIP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nIf the operation results in an invalid-arithmetic-operand exception being raised, the status flags in the EFLAGS register are set only if the exception is masked.\nThe FCOMI/FCOMIP and FUCOMI/FUCOMIP instructions set the OF, SF, and AF flags to zero in the EFLAGS register (regardless of whether an invalid-operation exception is detected).\nThe FCOMIP and FUCOMIP instructions also pop the register stack following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST(0) > ST(i):\n ZF, PF, CF := 000;\n ST(0) < ST(i):\n ZF, PF, CF := 001;\n ST(0) = ST(i):\n ZF, PF, CF := 100;\nESAC;\nIF Instruction is FCOMI or FCOMIP\n THEN\n IF ST(0) or ST(i) = NaN or unsupported format\n THEN\n #IA\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FUCOMI or FUCOMIP\n THEN\n IF ST(0) or ST(i) = QNaN, but not SNaN or unsupported format\n THEN\n ZF, PF, CF := 111;\n ELSE (* ST(0) or ST(i) is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n ZF, PF, CF := 111;\n FI;\n FI;\nFI;\nIF Instruction is FCOMIP or FUCOMIP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fcomi:fcomip:fucomi:fucomip" + }, + "fucomp": { + "instruction": "FUCOMP", + "title": "FUCOM/FUCOMP/FUCOMPP\n\t\t— Unordered Compare Floating-Point Values", + "opcode": "DD E8+i", + "description": "Performs an unordered comparison of the contents of register ST(0) and ST(i) and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below). If no operand is specified, the contents of registers ST(0) and ST(1) are compared. The sign of zero is ignored, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOM/FUCOMP/FUCOMPP instructions perform the same operations as the FCOM/FCOMP/FCOMPP instructions. The only difference is that the FUCOM/FUCOMP/FUCOMPP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOM/FCOMP/FCOMPP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nAs with the FCOM/FCOMP/FCOMPP instructions, if the operation results in an invalid-arithmetic-operand exception being raised, the condition code flags are set only if the exception is masked.\nThe FUCOMP instruction pops the register stack following the comparison operation and the FUCOMPP instruction pops the register stack twice following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST > SRC:\n C3, C2, C0 := 000;\n ST < SRC:\n C3, C2, C0 := 001;\n ST = SRC:\n C3, C2, C0 := 100;\nESAC;\nIF ST(0) or SRC = QNaN, but not SNaN or unsupported format\n THEN\n C3, C2, C0 := 111;\n ELSE (* ST(0) or SRC is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n C3, C2, C0 := 111;\n FI;\nFI;\nIF Instruction = FUCOMP\n THEN\n PopRegisterStack;\nFI;\nIF Instruction = FUCOMPP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fucom:fucomp:fucompp" + }, + "fucompp": { + "instruction": "FUCOMPP", + "title": "FUCOM/FUCOMP/FUCOMPP\n\t\t— Unordered Compare Floating-Point Values", + "opcode": "DA E9", + "description": "Performs an unordered comparison of the contents of register ST(0) and ST(i) and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below). If no operand is specified, the contents of registers ST(0) and ST(1) are compared. The sign of zero is ignored, so that –0.0 is equal to +0.0.\nAn unordered comparison checks the class of the numbers being compared (see “FXAM—Examine Floating-Point” in this chapter). The FUCOM/FUCOMP/FUCOMPP instructions perform the same operations as the FCOM/FCOMP/FCOMPP instructions. The only difference is that the FUCOM/FUCOMP/FUCOMPP instructions raise the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be generated. The FCOM/FCOMP/FCOMPP instructions raise an invalid-operation exception when either or both of the operands are a NaN value of any kind or are in an unsupported format.\nAs with the FCOM/FCOMP/FCOMPP instructions, if the operation results in an invalid-arithmetic-operand exception being raised, the condition code flags are set only if the exception is masked.\nThe FUCOMP instruction pops the register stack following the comparison operation and the FUCOMPP instruction pops the register stack twice following the comparison operation. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CASE (relation of operands) OF\n ST > SRC:\n C3, C2, C0 := 000;\n ST < SRC:\n C3, C2, C0 := 001;\n ST = SRC:\n C3, C2, C0 := 100;\nESAC;\nIF ST(0) or SRC = QNaN, but not SNaN or unsupported format\n THEN\n C3, C2, C0 := 111;\n ELSE (* ST(0) or SRC is SNaN or unsupported format *)\n #IA;\n IF FPUControlWord.IM = 1\n THEN\n C3, C2, C0 := 111;\n FI;\nFI;\nIF Instruction = FUCOMP\n THEN\n PopRegisterStack;\nFI;\nIF Instruction = FUCOMPP\n THEN\n PopRegisterStack;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fucom:fucomp:fucompp" + }, + "fwait": { + "instruction": "FWAIT", + "title": "WAIT/FWAIT\n\t\t— Wait", + "opcode": "9B", + "description": "Causes the processor to check for and handle pending, unmasked, floating-point exceptions before proceeding. (FWAIT is an alternate mnemonic for WAIT.)\nThis instruction is useful for synchronizing exceptions in critical sections of code. Coding a WAIT instruction after a floating-point instruction ensures that any unmasked floating-point exceptions the instruction may raise are handled before the processor can modify the instruction’s results. See the section titled “Floating-Point Exception Synchronization” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on using the WAIT/FWAIT instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CheckForPendingUnmaskedFloatingPointExceptions;\n", + "url": "https://www.felixcloutier.com/x86/wait:fwait" + }, + "fxam": { + "instruction": "FXAM", + "title": "FXAM\n\t\t— Examine Floating-Point", + "opcode": "D9 E5", + "description": "Examines the contents of the ST(0) register and sets the condition code flags C0, C2, and C3 in the FPU status word to indicate the class of value or number in the register (see the table below).\nThe C1 flag is set to the sign of the value in ST(0), regardless of whether the register is empty or full.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "C1 := sign bit of ST; (* 0 for positive, 1 for negative *)\nCASE (class of value or number in ST(0)) OF\n Unsupported:C3, C2, C0 := 000;\n NaN:\n C3, C2, C0 := 001;\n Normal:\n C3, C2, C0 := 010;\n Infinity:\n C3, C2, C0 := 011;\n Zero:\n C3, C2, C0 := 100;\n Empty:\n C3, C2, C0 := 101;\n Denormal:\n C3, C2, C0 := 110;\nESAC;\n", + "url": "https://www.felixcloutier.com/x86/fxam" + }, + "fxch": { + "instruction": "FXCH", + "title": "FXCH\n\t\t— Exchange Register Contents", + "opcode": "D9 C8+i", + "description": "Exchanges the contents of registers ST(0) and ST(i). If no source operand is specified, the contents of ST(0) and ST(1) are exchanged.\nThis instruction provides a simple means of moving values in the FPU register stack to the top of the stack [ST(0)], so that they can be operated on by those floating-point instructions that can only operate on values in ST(0). For example, the following instruction sequence takes the square root of the third register from the top of the register stack:\nFXCH ST(3);\nFSQRT;\nFXCH ST(3);\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF (Number-of-operands) is 1\n THEN\n temp := ST(0);\n ST(0) := SRC;\n SRC := temp;\n ELSE\n temp := ST(0);\n ST(0) := ST(1);\n ST(1) := temp;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fxch" + }, + "fxrstor": { + "instruction": "FXRSTOR", + "title": "FXRSTOR\n\t\t— Restore x87 FPU, MMX, XMM, and MXCSR State", + "opcode": "NP 0F AE /1 FXRSTOR m512byte", + "description": "Reloads the x87 FPU, MMX technology, XMM, and MXCSR registers from the 512-byte memory image specified in the source operand. This data should have been written to memory previously using the FXSAVE instruction, and in the same format as required by the operating modes. The first byte of the data should be located on a 16-byte boundary. There are three distinct layouts of the FXSAVE state map: one for legacy and compatibility mode, a second format for 64-bit mode FXSAVE/FXRSTOR with REX.W=0, and the third format is for 64-bit mode with FXSAVE64/FXRSTOR64. Table 3-43 shows the layout of the legacy/compatibility mode state information in memory and describes the fields in the memory image for the FXRSTOR and FXSAVE instructions. Table 3-46 shows the layout of the 64-bit mode state information when REX.W is set (FXSAVE64/FXRSTOR64). Table 3-47 shows the layout of the 64-bit mode state information when REX.W is clear (FXSAVE/FXRSTOR).\nThe state image referenced with an FXRSTOR instruction must have been saved using an FXSAVE instruction or be in the same format as required by Table 3-43, Table 3-46, or Table 3-47. Referencing a state image saved with an FSAVE, FNSAVE instruction or incompatible field layout will result in an incorrect state restoration.\nThe FXRSTOR instruction does not flush pending x87 FPU exceptions. To check and raise exceptions when loading x87 FPU state information with the FXRSTOR instruction, use an FWAIT instruction after the FXRSTOR instruction.\nIf the OSFXSR bit in control register CR4 is not set, the FXRSTOR instruction may not restore the states of the XMM and MXCSR registers. This behavior is implementation dependent.\nIf the MXCSR state contains an unmasked exception with a corresponding status flag also set, loading the register with the FXRSTOR instruction will not result in a SIMD floating-point error condition being generated. Only the next occurrence of this unmasked exception will result in the exception being generated.\nBits 16 through 32 of the MXCSR register are defined as reserved and should be set to 0. Attempting to write a 1 in any of these bits from the saved state image will result in a general protection exception (#GP) being generated.\nBytes 464:511 of an FXSAVE image are available for software use. FXRSTOR ignores the content of bytes 464:511 in an FXSAVE state image.", + "operation": "IF 64-Bit Mode\n THEN\n (x87 FPU, MMX, XMM15-XMM0, MXCSR)\n Load(SRC);\n ELSE\n (x87 FPU, MMX, XMM7-XMM0, MXCSR) := Load(SRC);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fxrstor" + }, + "fxsave": { + "instruction": "FXSAVE", + "title": "FXSAVE\n\t\t— Save x87 FPU, MMX Technology, and SSE State", + "opcode": "NP 0F AE /0 FXSAVE m512byte", + "description": "Saves the current state of the x87 FPU, MMX technology, XMM, and MXCSR registers to a 512-byte memory location specified in the destination operand. The content layout of the 512 byte region depends on whether the processor is operating in non-64-bit operating modes or 64-bit sub-mode of IA-32e mode.\nBytes 464:511 are available to software use. The processor does not write to bytes 464:511 of an FXSAVE area.\nThe operation of FXSAVE in non-64-bit modes is described first.", + "operation": "IF 64-Bit Mode\n THEN\n IF REX.W = 1\n THEN\n DEST := Save64BitPromotedFxsave(x87 FPU, MMX, XMM15-XMM0,\n MXCSR);\n ELSE\n DEST := Save64BitDefaultFxsave(x87 FPU, MMX, XMM15-XMM0, MXCSR);\n FI;\n ELSE\n DEST := SaveLegacyFxsave(x87 FPU, MMX, XMM7-XMM0, MXCSR);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/fxsave" + }, + "fxtract": { + "instruction": "FXTRACT", + "title": "FXTRACT\n\t\t— Extract Exponent and Significand", + "opcode": "D9 F4 FXTRACT", + "description": "Separates the source value in the ST(0) register into its exponent and significand, stores the exponent in ST(0), and pushes the significand onto the register stack. Following this operation, the new top-of-stack register ST(0) contains the value of the original significand expressed as a floating-point value. The sign and significand of this value are the same as those found in the source operand, and the exponent is 3FFFH (biased value for a true exponent of zero). The ST(1) register contains the value of the original operand’s true (unbiased) exponent expressed as a floating-point value. (The operation performed by this instruction is a superset of the IEEE-recommended logb(x) function.)\nThis instruction and the F2XM1 instruction are useful for performing power and range scaling operations. The FXTRACT instruction is also useful for converting numbers in double extended-precision floating-point format to decimal representations (e.g., for printing or displaying).\nIf the floating-point zero-divide exception (#Z) is masked and the source operand is zero, an exponent value of –∞ is stored in register ST(1) and 0 with the sign of the source operand is stored in register ST(0).\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "TEMP := Significand(ST(0));\nST(0) := Exponent(ST(0));\nTOP := TOP − 1;\nST(0) := TEMP;\n", + "url": "https://www.felixcloutier.com/x86/fxtract" + }, + "fyl2x": { + "instruction": "FYL2X", + "title": "FYL2X\n\t\t— Compute y ∗ log2x", + "opcode": "D9 F1", + "description": "Computes (ST(1) ∗ log2 (ST(0))), stores the result in register ST(1), and pops the FPU register stack. The source operand in ST(0) must be a non-zero positive number.\nThe following table shows the results obtained when taking the log of various classes of numbers, assuming that neither overflow nor underflow occurs.\nIf the divide-by-zero exception is masked and register ST(0) contains ±0, the instruction returns ∞ with a sign that is the opposite of the sign of the source operand in register ST(1).\nThe FYL2X instruction is designed with a built-in multiplication to optimize the calculation of logarithms with an arbitrary positive base (b):\nlogbx := (log2b)–1 ∗ log2x\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(1) := ST(1) ∗ log2ST(0);\nPopRegisterStack;\n", + "url": "https://www.felixcloutier.com/x86/fyl2x" + }, + "fyl2xp1": { + "instruction": "FYL2XP1", + "title": "FYL2XP1\n\t\t— Compute y ∗ log2(x +1)", + "opcode": "D9 F9", + "description": "Computes (ST(1) ∗ log2(ST(0) + 1.0)), stores the result in register ST(1), and pops the FPU register stack. The source operand in ST(0) must be in the range:\nThe source operand in ST(1) can range from −∞ to +∞. If the ST(0) operand is outside of its acceptable range, the result is undefined and software should not rely on an exception being generated. Under some circumstances exceptions may be generated when ST(0) is out of range, but this behavior is implementation specific and not guaranteed.\nThe following table shows the results obtained when taking the log epsilon of various classes of numbers, assuming that underflow does not occur.\nThis instruction provides optimal accuracy for values of epsilon [the value in register ST(0)] that are close to 0. For small epsilon (ε) values, more significant digits can be retained by using the FYL2XP1 instruction than by using (ε+1) as an argument to the FYL2X instruction. The (ε+1) expression is commonly found in compound interest and annuity calculations. The result can be simply converted into a value in another logarithm base by including a scale factor in the ST(1) source operand. The following equation is used to calculate the scale factor for a particular logarithm base, where n is the logarithm base desired for the result of the FYL2XP1 instruction:\nscale factor := logn 2\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "ST(1) := ST(1) ∗ log2(ST(0) + 1.0);\nPopRegisterStack;\n", + "url": "https://www.felixcloutier.com/x86/fyl2xp1" + }, + "gf2p8affineinvqb": { + "instruction": "GF2P8AFFINEINVQB", + "title": "GF2P8AFFINEINVQB\n\t\t— Galois Field Affine Transformation Inverse", + "opcode": "66 0F3A CF /r /ib GF2P8AFFINEINVQB xmm1, xmm2/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/gf2p8affineinvqb" + }, + "gf2p8affineqb": { + "instruction": "GF2P8AFFINEQB", + "title": "GF2P8AFFINEQB\n\t\t— Galois Field Affine Transformation", + "opcode": "66 0F3A CE /r /ib GF2P8AFFINEQB xmm1, xmm2/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/gf2p8affineqb" + }, + "gf2p8mulb": { + "instruction": "GF2P8MULB", + "title": "GF2P8MULB\n\t\t— Galois Field Multiply Bytes", + "opcode": "66 0F38 CF /r GF2P8MULB xmm1, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/gf2p8mulb" + }, + "haddpd": { + "instruction": "HADDPD", + "title": "HADDPD\n\t\t— Packed Double Precision Floating-Point Horizontal Add", + "opcode": "66 0F 7C /r HADDPD xmm1, xmm2/m128", + "description": "Adds the double precision floating-point values in the high and low quadwords of the destination operand and stores the result in the low quadword of the destination operand.\nAdds the double precision floating-point values in the high and low quadwords of the source operand and stores the result in the high quadword of the destination operand.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).\nSee Figure 3-17 for HADDPD; see Figure 3-18 for VHADDPD.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "DEST[63:0] := SRC1[127:64] + SRC1[63:0]\nDEST[127:64] := SRC2[127:64] + SRC2[63:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[127:64] + SRC1[63:0]\nDEST[127:64] := SRC2[127:64] + SRC2[63:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[127:64] + SRC1[63:0]\nDEST[127:64] := SRC2[127:64] + SRC2[63:0]\nDEST[191:128] := SRC1[255:192] + SRC1[191:128]\nDEST[255:192] := SRC2[255:192] + SRC2[191:128]\n", + "url": "https://www.felixcloutier.com/x86/haddpd" + }, + "haddps": { + "instruction": "HADDPS", + "title": "HADDPS\n\t\t— Packed Single Precision Floating-Point Horizontal Add", + "opcode": "F2 0F 7C /r HADDPS xmm1, xmm2/m128", + "description": "Adds the single precision floating-point values in the first and second dwords of the destination operand and stores the result in the first dword of the destination operand.\nAdds single precision floating-point values in the third and fourth dword of the destination operand and stores the result in the second dword of the destination operand.\nAdds single precision floating-point values in the first and second dword of the source operand and stores the result in the third dword of the destination operand.\nAdds single precision floating-point values in the third and fourth dword of the source operand and stores the result in the fourth dword of the destination operand.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).\nSee Figure 3-19 for HADDPS; see Figure 3-20 for VHADDPS.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "DEST[31:0] := SRC1[63:32] + SRC1[31:0]\nDEST[63:32] := SRC1[127:96] + SRC1[95:64]\nDEST[95:64] := SRC2[63:32] + SRC2[31:0]\nDEST[127:96] := SRC2[127:96] + SRC2[95:64]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := SRC1[63:32] + SRC1[31:0]\nDEST[63:32] := SRC1[127:96] + SRC1[95:64]\nDEST[95:64] := SRC2[63:32] + SRC2[31:0]\nDEST[127:96] := SRC2[127:96] + SRC2[95:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[63:32] + SRC1[31:0]\nDEST[63:32] := SRC1[127:96] + SRC1[95:64]\nDEST[95:64] := SRC2[63:32] + SRC2[31:0]\nDEST[127:96] := SRC2[127:96] + SRC2[95:64]\nDEST[159:128] := SRC1[191:160] + SRC1[159:128]\nDEST[191:160] := SRC1[255:224] + SRC1[223:192]\nDEST[223:192] := SRC2[191:160] + SRC2[159:128]\nDEST[255:224] := SRC2[255:224] + SRC2[223:192]\n", + "url": "https://www.felixcloutier.com/x86/haddps" + }, + "hlt": { + "instruction": "HLT", + "title": "HLT\n\t\t— Halt", + "opcode": "F4", + "description": "Stops instruction execution and places the processor in a HALT state. An enabled interrupt (including NMI and SMI), a debug exception, the BINIT# signal, the INIT# signal, or the RESET# signal will resume execution. If an interrupt (including NMI) is used to resume execution after a HLT instruction, the saved instruction pointer (CS:EIP) points to the instruction following the HLT instruction.\nWhen a HLT instruction is executed on an Intel 64 or IA-32 processor supporting Intel Hyper-Threading Technology, only the logical processor that executes the instruction is halted. The other logical processors in the physical processor remain active, unless they are each individually halted by executing a HLT instruction.\nThe HLT instruction is a privileged instruction. When the processor is running in protected or virtual-8086 mode, the privilege level of a program or procedure must be 0 to execute the HLT instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "Enter Halt state;\n", + "url": "https://www.felixcloutier.com/x86/hlt" + }, + "hreset": { + "instruction": "HRESET", + "title": "HRESET\n\t\t— History Reset", + "opcode": "F3 0F 3A F0 C0 /ib HRESET imm8, ", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/hreset" + }, + "hsubpd": { + "instruction": "HSUBPD", + "title": "HSUBPD\n\t\t— Packed Double Precision Floating-Point Horizontal Subtract", + "opcode": "66 0F 7D /r HSUBPD xmm1, xmm2/m128", + "description": "The HSUBPD instruction subtracts horizontally the packed double precision floating-point numbers of both operands.\nSubtracts the double precision floating-point value in the high quadword of the destination operand from the low quadword of the destination operand and stores the result in the low quadword of the destination operand.\nSubtracts the double precision floating-point value in the high quadword of the source operand from the low quadword of the source operand and stores the result in the high quadword of the destination operand.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).\nSee Figure 3-21 for HSUBPD; see Figure 3-22 for VHSUBPD.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "DEST[63:0] := SRC1[63:0] - SRC1[127:64]\nDEST[127:64] := SRC2[63:0] - SRC2[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[63:0] - SRC1[127:64]\nDEST[127:64] := SRC2[63:0] - SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0] - SRC1[127:64]\nDEST[127:64] := SRC2[63:0] - SRC2[127:64]\nDEST[191:128] := SRC1[191:128] - SRC1[255:192]\nDEST[255:192] := SRC2[191:128] - SRC2[255:192]\n", + "url": "https://www.felixcloutier.com/x86/hsubpd" + }, + "hsubps": { + "instruction": "HSUBPS", + "title": "HSUBPS\n\t\t— Packed Single Precision Floating-Point Horizontal Subtract", + "opcode": "F2 0F 7D /r HSUBPS xmm1, xmm2/m128", + "description": "Subtracts the single precision floating-point value in the second dword of the destination operand from the first dword of the destination operand and stores the result in the first dword of the destination operand.\nSubtracts the single precision floating-point value in the fourth dword of the destination operand from the third dword of the destination operand and stores the result in the second dword of the destination operand.\nSubtracts the single precision floating-point value in the second dword of the source operand from the first dword of the source operand and stores the result in the third dword of the destination operand.\nSubtracts the single precision floating-point value in the fourth dword of the source operand from the third dword of the source operand and stores the result in the fourth dword of the destination operand.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).\nSee Figure 3-23 for HSUBPS; see Figure 3-24 for VHSUBPS.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "DEST[31:0] := SRC1[31:0] - SRC1[63:32]\nDEST[63:32] := SRC1[95:64] - SRC1[127:96]\nDEST[95:64] := SRC2[31:0] - SRC2[63:32]\nDEST[127:96] := SRC2[95:64] - SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := SRC1[31:0] - SRC1[63:32]\nDEST[63:32] := SRC1[95:64] - SRC1[127:96]\nDEST[95:64] := SRC2[31:0] - SRC2[63:32]\nDEST[127:96] := SRC2[95:64] - SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC1[63:32]\nDEST[63:32] := SRC1[95:64] - SRC1[127:96]\nDEST[95:64] := SRC2[31:0] - SRC2[63:32]\nDEST[127:96] := SRC2[95:64] - SRC2[127:96]\nDEST[159:128] := SRC1[159:128] - SRC1[191:160]\nDEST[191:160] := SRC1[223:192] - SRC1[255:224]\nDEST[223:192] := SRC2[159:128] - SRC2[191:160]\nDEST[255:224] := SRC2[223:192] - SRC2[255:224]\n", + "url": "https://www.felixcloutier.com/x86/hsubps" + }, + "idiv": { + "instruction": "IDIV", + "title": "IDIV\n\t\t— Signed Divide", + "opcode": "F6 /7", + "description": "Divides the (signed) value in the AX, DX:AX, or EDX:EAX (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers. The source operand can be a general-purpose register or a memory location. The action of this instruction depends on the operand size (dividend/divisor).\nNon-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magnitude. Overflow is indicated with the #DE (divide error) exception rather than with the CF flag.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is applied, the instruction divides the signed value in RDX:RAX by the source operand. RAX contains a 64-bit quotient; RDX contains a 64-bit remainder.\nSee the summary chart at the beginning of this section for encoding data and limits. See Table 3-51.", + "operation": "IF SRC = 0\n THEN #DE; (* Divide error *)\nFI;\nIF OperandSize = 8 (* Word/byte operation *)\n THEN\n temp := AX / SRC; (* Signed division *)\n IF (temp > 7FH) or (temp < 80H)\n (* If a positive result is greater than 7FH or a negative result is less than 80H *)\n THEN #DE; (* Divide error *)\n ELSE\n AL := temp;\n AH := AX SignedModulus SRC;\n FI;\n ELSE IF OperandSize = 16 (* Doubleword/word operation *)\n THEN\n temp := DX:AX / SRC; (* Signed division *)\n IF (temp > 7FFFH) or (temp < 8000H)\n (* If a positive result is greater than 7FFFH\n or a negative result is less than 8000H *)\n THEN\n #DE; (* Divide error *)\n ELSE\n AX := temp;\n DX := DX:AX SignedModulus SRC;\n FI;\n FI;\n ELSE IF OperandSize = 32 (* Quadword/doubleword operation *)\n temp := EDX:EAX / SRC; (* Signed division *)\n IF (temp > 7FFFFFFFH) or (temp < 80000000H)\n (* If a positive result is greater than 7FFFFFFFH\n or a negative result is less than 80000000H *)\n THEN\n #DE; (* Divide error *)\n ELSE\n EAX := temp;\n EDX := EDXE:AX SignedModulus SRC;\n FI;\n FI;\n ELSE IF OperandSize = 64 (* Doublequadword/quadword operation *)\n temp := RDX:RAX / SRC; (* Signed division *)\n IF (temp > 7FFFFFFFFFFFFFFFH) or (temp < 8000000000000000H)\n (* If a positive result is greater than 7FFFFFFFFFFFFFFFH\n or a negative result is less than 8000000000000000H *)\n THEN\n #DE; (* Divide error *)\n ELSE\n RAX := temp;\n RDX := RDE:RAX SignedModulus SRC;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/idiv" + }, + "imul": { + "instruction": "IMUL", + "title": "IMUL\n\t\t— Signed Multiply", + "opcode": "F6 /5", + "description": "Performs a signed multiplication of two operands. This instruction has three forms, depending on the number of operands.\nWhen an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.\nThe CF and OF flags are set when the signed integer value of the intermediate product differs from the sign extended operand-size-truncated product, otherwise the CF and OF flags are cleared.\nThe three forms of the IMUL instruction are similar in that the length of the product is calculated to twice the length of the operands. With the one-operand form, the product is stored exactly in the destination. With the two- and three- operand forms, however, the result is truncated to the length of the destination before it is stored in the destination register. Because of this truncation, the CF or OF flag should be tested to ensure that no significant bits are lost.\nThe two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned. The CF and OF flags, however, cannot be used to determine if the upper half of the result is non-zero.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. Use of REX.W modifies the three forms of the instruction as follows.", + "operation": "IF (NumberOfOperands = 1)\n THEN IF (OperandSize = 8)\n THEN\n TMP_XP := AL ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *);\n AX := TMP_XP[15:0];\n IF SignExtend(TMP_XP[7:0]) = TMP_XP\n THEN CF := 0; OF := 0;\n ELSE CF := 1; OF := 1; FI;\n ELSE IF OperandSize = 16\n THEN\n TMP_XP := AX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)\n DX:AX := TMP_XP[31:0];\n IF SignExtend(TMP_XP[15:0]) = TMP_XP\n THEN CF := 0; OF := 0;\n ELSE CF := 1; OF := 1; FI;\n ELSE IF OperandSize = 32\n THEN\n TMP_XP := EAX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC*)\n EDX:EAX := TMP_XP[63:0];\n IF SignExtend(TMP_XP[31:0]) = TMP_XP\n THEN CF := 0; OF := 0;\n ELSE CF := 1; OF := 1; FI;\n ELSE (* OperandSize = 64 *)\n TMP_XP := RAX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)\n EDX:EAX := TMP_XP[127:0];\n IF SignExtend(TMP_XP[63:0]) = TMP_XP\n THEN CF := 0; OF := 0;\n ELSE CF := 1; OF := 1; FI;\n FI;\n FI;\n ELSE IF (NumberOfOperands = 2)\n THEN\n TMP_XP := DEST ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)\n DEST := TruncateToOperandSize(TMP_XP);\n IF SignExtend(DEST) ≠ TMP_XP\n THEN CF := 1; OF := 1;\n ELSE CF := 0; OF := 0; FI;\n ELSE (* NumberOfOperands = 3 *)\n TMP_XP := SRC1 ∗ SRC2 (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC1 *)\n DEST := TruncateToOperandSize(TMP_XP);\n IF SignExtend(DEST) ≠ TMP_XP\n THEN CF := 1; OF := 1;\n ELSE CF := 0; OF := 0; FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/imul" + }, + "in": { + "instruction": "IN", + "title": "IN\n\t\t— Input From Port", + "opcode": "E4 ib", + "description": "Copies the value from the I/O port specified with the second operand (source operand) to the destination operand (first operand). The source operand can be a byte-immediate or the DX register; the destination operand can be register AL, AX, or EAX, depending on the size of the port being accessed (8, 16, or 32 bits, respectively). Using the DX register as a source operand allows I/O port addresses from 0 to 65,535 to be accessed; using a byte immediate allows I/O port addresses 0 to 255 to be accessed.\nWhen accessing an 8-bit I/O port, the opcode determines the port size; when accessing a 16- and 32-bit I/O port, the operand-size attribute determines the port size. At the machine code level, I/O instructions are shorter when accessing 8-bit I/O ports. Here, the upper eight bits of the port address will be 0.\nThis instruction is only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE ( * I/O operation is allowed *)\n DEST := SRC; (* Read from selected I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode with CPL ≤ IOPL *)\n DEST := SRC; (* Read from selected I/O port *)\nFI;\n", + "url": "https://www.felixcloutier.com/x86/in" + }, + "inc": { + "instruction": "INC", + "title": "INC\n\t\t— Increment by 1", + "opcode": "FE /0", + "description": "Adds 1 to the destination operand, while preserving the state of the CF flag. The destination operand can be a register or a memory location. This instruction allows a loop counter to be updated without disturbing the CF flag. (Use a ADD instruction with an immediate operand of 1 to perform an increment operation that does updates the CF flag.)\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, INC r16 and INC r32 are not encodable (because opcodes 40H through 47H are REX prefixes). Otherwise, the instruction’s 64-bit mode default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits.", + "operation": "DEST := DEST + 1;\n", + "url": "https://www.felixcloutier.com/x86/inc" + }, + "incsspd": { + "instruction": "INCSSPD", + "title": "INCSSPD/INCSSPQ\n\t\t— Increment Shadow Stack Pointer", + "opcode": "F3 0F AE /05 INCSSPD r32", + "description": "This instruction can be used to increment the current shadow stack pointer by the operand size of the instruction times the unsigned 8-bit value specified by bits 7:0 in the source operand. The instruction performs a pop and discard of the first and last element on the shadow stack in the range specified by the unsigned 8-bit value in bits 7:0 of the source operand.", + "operation": "IF CPL = 3\n IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nELSE\n IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nFI;\nIF (operand size is 64-bit)\n THEN\n Range := R64[7:0];\n shadow_stack_load 8 bytes from SSP;\n IF Range > 0\n THEN shadow_stack_load 8 bytes from SSP + 8 * (Range - 1);\n FI;\n SSP := SSP + Range * 8;\n ELSE\n Range := R32[7:0];\n shadow_stack_load 4 bytes from SSP;\n IF Range > 0\n THEN shadow_stack_load 4 bytes from SSP + 4 * (Range - 1);\n FI;\n SSP := SSP + Range * 4;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/incsspd:incsspq" + }, + "incsspq": { + "instruction": "INCSSPQ", + "title": "INCSSPD/INCSSPQ\n\t\t— Increment Shadow Stack Pointer", + "opcode": "F3 0F AE /05 INCSSPD r32", + "description": "This instruction can be used to increment the current shadow stack pointer by the operand size of the instruction times the unsigned 8-bit value specified by bits 7:0 in the source operand. The instruction performs a pop and discard of the first and last element on the shadow stack in the range specified by the unsigned 8-bit value in bits 7:0 of the source operand.", + "operation": "IF CPL = 3\n IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nELSE\n IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nFI;\nIF (operand size is 64-bit)\n THEN\n Range := R64[7:0];\n shadow_stack_load 8 bytes from SSP;\n IF Range > 0\n THEN shadow_stack_load 8 bytes from SSP + 8 * (Range - 1);\n FI;\n SSP := SSP + Range * 8;\n ELSE\n Range := R32[7:0];\n shadow_stack_load 4 bytes from SSP;\n IF Range > 0\n THEN shadow_stack_load 4 bytes from SSP + 4 * (Range - 1);\n FI;\n SSP := SSP + Range * 4;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/incsspd:incsspq" + }, + "ins": { + "instruction": "INS", + "title": "INS/INSB/INSW/INSD\n\t\t— Input from Port to String", + "opcode": "6C", + "description": "Copies the data from the I/O port specified with the source operand (second operand) to the destination operand (first operand). The source operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The destination operand is a memory location, the address of which is read from either the ES:DI, ES:EDI or the RDI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The ES segment cannot be overridden with a segment override prefix.) The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the INS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand must be “DX,” and the destination operand should be a symbol that indicates the size of the I/O port and the destination address. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI registers, which must be loaded correctly before the INS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the INS instructions. Here also DX is assumed by the processor to be the source operand and ES:(E)DI is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: INSB (byte), INSW (word), or INSD (doubleword).\nAfter the byte, word, or doubleword is transfer from the I/O port to the memory location, the DI/EDI/RDI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented.) The (E)DI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nThe INS, INSB, INSW, and INSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nThese instructions are only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, default address size is 64 bits, 32 bit address size is supported using the prefix 67H. The address of the memory destination is specified by RDI or EDI. 16-bit address size is not supported in 64-bit mode. The operand size is not promoted.\nThese instructions may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g. #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Read from I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode with CPL IOPL *)\n DEST := SRC; (* Read from I/O port *)\nFI;\nNon-64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\nFI64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 1;\n ELSE (E|R)DI := (E|R)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 4;\n ELSE (E|R)DI := (E|R)DI – 4; FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ins:insb:insw:insd" + }, + "insb": { + "instruction": "INSB", + "title": "INS/INSB/INSW/INSD\n\t\t— Input from Port to String", + "opcode": "6C", + "description": "Copies the data from the I/O port specified with the source operand (second operand) to the destination operand (first operand). The source operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The destination operand is a memory location, the address of which is read from either the ES:DI, ES:EDI or the RDI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The ES segment cannot be overridden with a segment override prefix.) The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the INS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand must be “DX,” and the destination operand should be a symbol that indicates the size of the I/O port and the destination address. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI registers, which must be loaded correctly before the INS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the INS instructions. Here also DX is assumed by the processor to be the source operand and ES:(E)DI is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: INSB (byte), INSW (word), or INSD (doubleword).\nAfter the byte, word, or doubleword is transfer from the I/O port to the memory location, the DI/EDI/RDI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented.) The (E)DI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nThe INS, INSB, INSW, and INSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nThese instructions are only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, default address size is 64 bits, 32 bit address size is supported using the prefix 67H. The address of the memory destination is specified by RDI or EDI. 16-bit address size is not supported in 64-bit mode. The operand size is not promoted.\nThese instructions may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g. #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Read from I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode with CPL IOPL *)\n DEST := SRC; (* Read from I/O port *)\nFI;\nNon-64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\nFI64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 1;\n ELSE (E|R)DI := (E|R)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 4;\n ELSE (E|R)DI := (E|R)DI – 4; FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ins:insb:insw:insd" + }, + "insd": { + "instruction": "INSD", + "title": "INS/INSB/INSW/INSD\n\t\t— Input from Port to String", + "opcode": "6D", + "description": "Copies the data from the I/O port specified with the source operand (second operand) to the destination operand (first operand). The source operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The destination operand is a memory location, the address of which is read from either the ES:DI, ES:EDI or the RDI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The ES segment cannot be overridden with a segment override prefix.) The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the INS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand must be “DX,” and the destination operand should be a symbol that indicates the size of the I/O port and the destination address. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI registers, which must be loaded correctly before the INS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the INS instructions. Here also DX is assumed by the processor to be the source operand and ES:(E)DI is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: INSB (byte), INSW (word), or INSD (doubleword).\nAfter the byte, word, or doubleword is transfer from the I/O port to the memory location, the DI/EDI/RDI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented.) The (E)DI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nThe INS, INSB, INSW, and INSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nThese instructions are only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, default address size is 64 bits, 32 bit address size is supported using the prefix 67H. The address of the memory destination is specified by RDI or EDI. 16-bit address size is not supported in 64-bit mode. The operand size is not promoted.\nThese instructions may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g. #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Read from I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode with CPL IOPL *)\n DEST := SRC; (* Read from I/O port *)\nFI;\nNon-64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\nFI64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 1;\n ELSE (E|R)DI := (E|R)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 4;\n ELSE (E|R)DI := (E|R)DI – 4; FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ins:insb:insw:insd" + }, + "insertps": { + "instruction": "INSERTPS", + "title": "INSERTPS\n\t\t— Insert Scalar Single Precision Floating-Point Value", + "opcode": "66 0F 3A 21 /r ib INSERTPS xmm1, xmm2/m32, imm8", + "description": "(register source form)\nCopy a single precision scalar floating-point element into a 128-bit vector register. The immediate operand has three fields, where the ZMask bits specify which elements of the destination will be set to zero, the Count_D bits specify which element of the destination will be overwritten with the scalar value, and for vector register sources the Count_S bits specify which element of the source will be copied. When the scalar source is a memory operand the Count_S bits are ignored.\n(memory source form)\nLoad a floating-point element from a 32-bit memory location and destination operand it into the first source at the location indicated by the Count_D bits of the immediate operand. Store in the destination and zero out destination elements based on the ZMask bits of the immediate operand.\n128-bit Legacy SSE version: The first source register is an XMM register. The second source operand is either an XMM register or a 32-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.\nVEX.128 and EVEX encoded version: The destination and first source register is an XMM register. The second source operand is either an XMM register or a 32-bit memory location. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\nIf VINSERTPS is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "IF (SRC = REG) THEN COUNT_S := imm8[7:6]\n ELSE COUNT_S := 0\nCOUNT_D := imm8[5:4]\nZMASK := imm8[3:0]\nCASE (COUNT_S) OF\n 0: TMP := SRC2[31:0]\n 1: TMP := SRC2[63:32]\n 2: TMP := SRC2[95:64]\n 3: TMP := SRC2[127:96]\nESAC;\nCASE (COUNT_D) OF\n 0: TMP2[31:0] := TMP\n TMP2[127:32] := SRC1[127:32]\n 1: TMP2[63:32] := TMP\n TMP2[31:0] := SRC1[31:0]\n TMP2[127:64] := SRC1[127:64]\n 2: TMP2[95:64] := TMP\n TMP2[63:0] := SRC1[63:0]\n TMP2[127:96] := SRC1[127:96]\n 3: TMP2[127:96] := TMP\n TMP2[95:0] := SRC1[95:0]\nESAC;\nIF (ZMASK[0] = 1) THEN DEST[31:0] := 00000000H\n ELSE DEST[31:0] := TMP2[31:0]\nIF (ZMASK[1] = 1) THEN DEST[63:32] := 00000000H\n ELSE DEST[63:32] := TMP2[63:32]\nIF (ZMASK[2] = 1) THEN DEST[95:64] := 00000000H\n ELSE DEST[95:64] := TMP2[95:64]\nIF (ZMASK[3] = 1) THEN DEST[127:96] := 00000000H\n ELSE DEST[127:96] := TMP2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nIF (SRC = REG) THEN COUNT_S :=imm8[7:6]\n ELSE COUNT_S :=0\nCOUNT_D := imm8[5:4]\nZMASK := imm8[3:0]\nCASE (COUNT_S) OF\n 0: TMP := SRC[31:0]\n 1: TMP := SRC[63:32]\n 2: TMP := SRC[95:64]\n 3: TMP := SRC[127:96]\nESAC;\nCASE (COUNT_D) OF\n 0: TMP2[31:0] := TMP\n TMP2[127:32] := DEST[127:32]\n 1: TMP2[63:32] := TMP\n TMP2[31:0] := DEST[31:0]\n TMP2[127:64] := DEST[127:64]\n 2: TMP2[95:64] := TMP\n TMP2[63:0] := DEST[63:0]\n TMP2[127:96] := DEST[127:96]\n 3: TMP2[127:96] := TMP\n TMP2[95:0] := DEST[95:0]\nESAC;\nIF (ZMASK[0] = 1) THEN DEST[31:0] := 00000000H\n ELSE DEST[31:0] := TMP2[31:0]\nIF (ZMASK[1] = 1) THEN DEST[63:32] := 00000000H\n ELSE DEST[63:32] := TMP2[63:32]\nIF (ZMASK[2] = 1) THEN DEST[95:64] := 00000000H\n ELSE DEST[95:64] := TMP2[95:64]\nIF (ZMASK[3] = 1) THEN DEST[127:96] := 00000000H\n ELSE DEST[127:96] := TMP2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/insertps" + }, + "insw": { + "instruction": "INSW", + "title": "INS/INSB/INSW/INSD\n\t\t— Input from Port to String", + "opcode": "6D", + "description": "Copies the data from the I/O port specified with the source operand (second operand) to the destination operand (first operand). The source operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The destination operand is a memory location, the address of which is read from either the ES:DI, ES:EDI or the RDI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The ES segment cannot be overridden with a segment override prefix.) The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the INS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand must be “DX,” and the destination operand should be a symbol that indicates the size of the I/O port and the destination address. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI registers, which must be loaded correctly before the INS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the INS instructions. Here also DX is assumed by the processor to be the source operand and ES:(E)DI is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: INSB (byte), INSW (word), or INSD (doubleword).\nAfter the byte, word, or doubleword is transfer from the I/O port to the memory location, the DI/EDI/RDI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented.) The (E)DI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nThe INS, INSB, INSW, and INSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.\nThese instructions are only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, default address size is 64 bits, 32 bit address size is supported using the prefix 67H. The address of the memory destination is specified by RDI or EDI. 16-bit address size is not supported in 64-bit mode. The operand size is not promoted.\nThese instructions may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g. #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Read from I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode with CPL IOPL *)\n DEST := SRC; (* Read from I/O port *)\nFI;\nNon-64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\nFI64-bit Mode:\nIF (Byte transfer)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 1;\n ELSE (E|R)DI := (E|R)DI – 1; FI;\n ELSE IF (Word transfer)\n THENIFDF =0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n ELSE (* Doubleword transfer *)\n THEN IF DF = 0\n THEN (E|R)DI := (E|R)DI + 4;\n ELSE (E|R)DI := (E|R)DI – 4; FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ins:insb:insw:insd" + }, + "int": { + "instruction": "INT", + "title": "INT n/INTO/INT3/INT1\n\t\t— Call to Interrupt Procedure", + "opcode": "CC", + "description": "The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand (see the section titled “Interrupts and Exceptions” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). The destination operand specifies a vector from 0 to 255, encoded as an 8-bit unsigned intermediate value. Each vector provides an index to a gate descriptor in the IDT. The first 32 vectors are reserved by Intel for system use. Some of these vectors are used for internally generated exceptions.\nThe INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. The INTO instruction is a special mnemonic for calling overflow exception (#OF), exception 4. The overflow interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler if the OF flag is set to 1. (The INTO instruction cannot be used in 64-bit mode.)\nThe INT3 instruction uses a one-byte opcode (CC) and is intended for calling the debug exception handler with a breakpoint exception (#BP). (This one-byte form is useful because it can replace the first byte of any instruction at which a breakpoint is desired, including other one-byte instructions, without overwriting other instructions.)\nThe INT1 instruction also uses a one-byte opcode (F1) and generates a debug exception (#DB) without setting any bits in DR6.1 Hardware vendors may use the INT1 instruction for hardware debug. For that reason, Intel recommends software vendors instead use the INT3 instruction for software breakpoints.\nAn interrupt generated by the INTO, INT3, or INT1 instruction differs from one generated by INT n in the following ways:\n(These features do not pertain to CD03, the “normal” 2-byte opcode for INT 3. Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic, but this opcode can be created by direct numeric code definition or by self-modifying code.)\nThe action of the INT n instruction (including the INTO, INT3, and INT1 instructions) is similar to that of a far call made with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed onto the stack before the return address. (The return address is a far address consisting of the current values of the CS and EIP registers.) Returns from interrupt procedures are handled with the IRET instruction, which pops the EFLAGS information and return address from the stack.\nEach of the INT n, INTO, and INT3 instructions generates a general-protection exception (#GP) if the CPL is greater than the DPL value in the selected gate descriptor in the IDT. In contrast, the INT1 instruction can deliver a #DB\neven if the CPL is greater than the DPL of descriptor 1 in the IDT. (This behavior supports the use of INT1 by hardware vendors performing hardware debug.)\nThe vector specifies an interrupt descriptor in the interrupt descriptor table (IDT); that is, it provides index into the IDT. The selected interrupt descriptor in turn contains a pointer to an interrupt or exception handler procedure. In protected mode, the IDT contains an array of 8-byte descriptors, each of which is an interrupt gate, trap gate, or task gate. In real-address mode, the IDT is an array of 4-byte far pointers (2-byte code segment selector and a 2-byte instruction pointer), each of which point directly to a procedure in the selected segment. (Note that in real-address mode, the IDT is called the interrupt vector table, and its pointers are called interrupt vectors.)\nThe following decision table indicates which action in the lower portion of the table is taken given the conditions in the upper portion of the table. Each Y in the lower section of the decision table represents a procedure defined in the “Operation” section for this instruction (except #GP).\nWhen the processor is executing in virtual-8086 mode, the IOPL determines the action of the INT n instruction. If the IOPL is less than 3, the processor generates a #GP(selector) exception; if the IOPL is 3, the processor executes a protected mode interrupt to privilege level 0. The interrupt gate's DPL must be set to 3 and the target CPL of the interrupt handler procedure must be 0 to execute the protected mode interrupt to privilege level 0.\nThe interrupt descriptor table register (IDTR) specifies the base linear address and limit of the IDT. The initial base address value of the IDTR after the processor is powered up or reset is 0.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. Instructions following an INT n may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the INT n have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible). This applies also to the INTO, INT3, and INT1 instructions, but not to executions of INTO when EFLAGS.OF = 0.", + "operation": "The following operational description applies not only to the INT n, INTO, INT3, or INT1 instructions, but also to\nexternal interrupts, nonmaskable interrupts (NMIs), and exceptions. Some of these events push onto the stack an\nerror code.\nThe operational description specifies numerous checks whose failure may result in delivery of a nested exception.\nIn these cases, the original event is not delivered.\nThe operational description specifies the error code delivered by any nested exception. In some cases, the error\ncode is specified with a pseudofunction error_code(num,idt,ext), where idt and ext are bit values. The pseudofunc-\ntion produces an error code as follows: (1) if idt is 0, the error code is (num & FCH) | ext; (2) if idt is 1, the error\ncode is (num « 3) | 2 | ext.\nIn many cases, the pseudofunction error_code is invoked with a pseudovariable EXT. The value of EXT depends on\nthe nature of the event whose delivery encountered a nested exception: if that event is a software interrupt (INT n,\nINT3, or INTO), EXT is 0; otherwise (including INT1), EXT is 1.\nIF PE = 0\n THEN\n GOTO REAL-ADDRESS-MODE;\n ELSE (* PE = 1 *)\n IF (EFLAGS.VM = 1 AND CR4.VME = 0 AND IOPL < 3 AND INT n)\n THEN\n #GP(0); (* Bit 0 of error code is 0 because INT n *)\n ELSE\n IF (EFLAGS.VM = 1 AND CR4.VME = 1 AND INT n)\n THEN\n Consult bit n of the software interrupt redirection bit map in the TSS;\n IF bit n is clear\n THEN (* redirect interrupt to 8086 program interrupt handler *)\n Push EFLAGS[15:0]; (* if IOPL < 3, save VIF in IF position and save IOPL position as 3 *)\n Push CS;\n Push IP;\n IF IOPL = 3\n THEN IF := 0; (* Clear interrupt flag *)\n ELSE VIF := 0; (* Clear virtual interrupt flag *)\n FI;\n TF := 0; (* Clear trap flag *)\n load CS and EIP (lower 16 bits only) from entry n in interrupt vector table referenced from TSS;\n ELSE\n IF IOPL = 3\n THEN GOTO PROTECTED-MODE;\n ELSE #GP(0); (* Bit 0 of error code is 0 because INT n *)\n FI;\n FI;\n ELSE (* Protected mode, IA-32e mode, or virtual-8086 mode interrupt *)\n IF (IA32_EFER.LMA = 0)\n THEN (* Protected mode, or virtual-8086 mode interrupt *)\n GOTO PROTECTED-MODE;\n ELSE (* IA-32e mode interrupt *)\n GOTO IA-32e-MODE;\n FI;\n FI;\n FI;\nFI;\nREAL-ADDRESS-MODE:\n IF ((vector_number « 2) + 3) is not within IDT limit\n THEN #GP; FI;\n IF stack not large enough for a 6-byte return information\n THEN #SS; FI;\n Push (EFLAGS[15:0]);\n IF := 0; (* Clear interrupt flag *)\n TF := 0; (* Clear trap flag *)\n AC := 0; (* Clear AC flag *)\n Push(CS);\n Push(IP);\n (* No error codes are pushed in real-address mode*)\n CS := IDT(Descriptor (vector_number « 2), selector));\n EIP := IDT(Descriptor (vector_number « 2), offset)); (* 16 bit offset AND 0000FFFFH *)\nEND;\nPROTECTED-MODE:\n IF ((vector_number « 3) + 7) is not within IDT limits\n or selected IDT descriptor is not an interrupt-, trap-, or task-gate type\n THEN #GP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0)); FI;\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF task gate (* Specified in the selected interrupt table descriptor *)\n THEN GOTO TASK-GATE;\n ELSE GOTO TRAP-OR-INTERRUPT-GATE; (* PE = 1, trap/interrupt gate *)\n FI;\nEND;\nIA-32e-MODE:\n IF INTO and CS.L = 1 (64-bit mode)\n THEN #UD;\n FI;\n IF ((vector_number « 4) + 15) is not in IDT limits\n or selected IDT descriptor is not an interrupt-, or trap-gate type\n THEN #GP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0));\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n GOTO TRAP-OR-INTERRUPT-GATE; (* Trap/interrupt gate *)\nEND;\nTASK-GATE: (* PE = 1, task gate *)\n Read TSS selector in task gate (IDT descriptor);\n IF local/global bit is set to local or index not within GDT limits\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Access TSS descriptor in GDT;\n IF TSS descriptor specifies that the TSS is busy (low-order 5 bits set to 00001)\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF TSS not present\n THEN #NP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n SWITCH-TASKS (with nesting) to TSS;\n IF interrupt caused by fault with error code\n THEN\n IF stack limit does not allow push of error code\n THEN #SS(EXT); FI;\n Push(error code);\n FI;\n IF EIP not within code segment limit\n THEN #GP(EXT); FI;\nEND;\nTRAP-OR-INTERRUPT-GATE:\n Read new code-segment selector for trap or interrupt gate (IDT descriptor);\n IF new code-segment selector is NULL\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n IF new code-segment selector is not within its descriptor table limits\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read descriptor referenced by new code-segment selector;\n IF descriptor does not indicate a code segment or new code-segment DPL > CPL\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code-segment descriptor is not present,\n THEN #NP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is non-conforming with DPL < CPL\n THEN\n IF VM = 0\n THEN\n GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;\n (* PE = 1, VM = 0, interrupt or trap gate, nonconforming code segment,\n DPL < CPL *)\n ELSE (* VM = 1 *)\n IF new code-segment DPL ≠ 0\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n GOTO INTERRUPT-FROM-VIRTUAL-8086-MODE; FI;\n (* PE = 1, interrupt or trap gate, DPL < CPL, VM = 1 *)\n FI;\n ELSE (* PE = 1, interrupt or trap gate, DPL ≥ CPL *)\n IF VM = 1\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is conforming or new code-segment DPL = CPL\n THEN\n GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;\n ELSE (* PE = 1, interrupt or trap gate, nonconforming code segment, DPL > CPL *)\n #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n FI;\nEND;\nINTER-PRIVILEGE-LEVEL-INTERRUPT:\n (* PE = 1, interrupt or trap gate, non-conforming code segment, DPL < CPL *)\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n (* Identify stack-segment selector for new privilege level in current TSS *)\n IF current TSS is 32-bit\n THEN\n TSSstackAddress := (new code-segment DPL « 3) + 4;\n IF (TSSstackAddress + 5) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);\n NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);\n ELSE (* current TSS is 16-bit *)\n TSSstackAddress := (new code-segment DPL « 2) + 2\n IF (TSSstackAddress + 3) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);\n NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI;\n IF NewSS index is not within its descriptor-table limits\n or NewSS RPL ≠ new code-segment DPL\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ new code-segment DPL\n or new stack-segment Type does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF NewSS is not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE (* IA-32e mode *)\n IF IDT-gate IST = 0\n THEN TSSstackAddress := (new code-segment DPL « 3) + 4;\n ELSE TSSstackAddress := (IDT gate IST « 3) + 28;\n FI;\n IF (TSSstackAddress + 7) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)\n IF IDT-gate IST = 0\n THEN\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT-gate IST « 3)\n (* Check if shadow stacks are enabled at CPL 0 *)\n IF ShadowStackEnabled(CPL 0)\n THEN NewSSP := 8 bytes loaded from NewSSPAddress; FI;\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 24 bytes (error code pushed)\n or 20 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI\n ELSE\n IF IDT gate is 16-bit\n THEN\n IF new stack does not have room for 12 bytes (error code pushed)\n or 10 bytes (no error code pushed);\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* 64-bit IDT gate*)\n IF StackAddress is non-canonical\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ESP := NewESP;\n SS := NewSS; (* Segment descriptor information also loaded *)\n ELSE (* IA-32e mode *)\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n SS := NewSS;\n FI;\n IF IDT gate is 32-bit\n THEN\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n ELSE\n IF IDT gate 16-bit\n THEN\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n ELSE (* 64-bit IDT gate *)\n CS:RIP := Gate(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and ESP, 3 words padded to 4 *)\n Push(EFLAGS);\n Push(far pointer to return instruction);\n (* Old CS and EIP, 3 words padded to 4 *)\n Push(ErrorCode); (* If needed, 4 bytes *)\n ELSE\n IF IDT gate 16-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and SP, 2 words *)\n Push(EFLAGS(15:0]);\n Push(far pointer to return instruction);\n (* Old CS and IP, 2 words *)\n Push(ErrorCode); (* If needed, 2 bytes *)\n ELSE (* 64-bit IDT gate *)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8-bytes *)\n FI;\n FI;\n IF ShadowStackEnabled(CPL) AND CPL = 3\n THEN\n IF IA32_EFER.LMA = 0\n THEN IA32_PL3_SSP := SSP;\n ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n FI;\n FI;\n CPL := new code-segment DPL;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n IF oldSS.DPL != 3\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(oldSSP);\n FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0 (* Interrupt flag set to 0, interrupts disabled *); FI;\n TF := 0;\n VM := 0;\n RF := 0;\n NT := 0;\nEND;\nINTERRUPT-FROM-VIRTUAL-8086-MODE:\n (* Identify stack-segment selector for privilege level 0 in current TSS *)\n IF current TSS is 32-bit\n THEN\n IF TSS limit < 9\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 8);\n NewESP := 4 bytes loaded from (current TSS base + 4);\n ELSE (* current TSS is 16-bit *)\n IF TSS limit < 5\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 4);\n NewESP := 2 bytes loaded from (current TSS base + 2);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI; (* Error code contains NULL selector *)\n IF NewSS index is not within its descriptor table limits\n or NewSS RPL ≠ 0\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ 0 or stack segment does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new stack segment not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PL0_SSP (* the new code-segment DPL must be 0 *)\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 40 bytes (error code pushed)\n or 36 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* IDT gate is 16-bit)\n IF new stack does not have room for 20 bytes (error code pushed)\n or 18 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n tempEFLAGS := EFLAGS;\n VM := 0;\n TF := 0;\n RF := 0;\n NT := 0;\n IF service through interrupt gate\n THEN IF = 0; FI;\n TempSS := SS;\n TempESP := ESP;\n SS := NewSS;\n ESP := NewESP;\n (* Following pushes are 16 bits for 16-bit IDT gates and 32 bits for 32-bit IDT gates;\n Segment selector pushes in 32-bit mode are padded to two words *)\n Push(GS);\n Push(FS);\n Push(DS);\n Push(ES);\n Push(TempSS);\n Push(TempESP);\n Push(TempEFlags);\n Push(CS);\n Push(EIP);\n GS := 0; (* Segment registers made NULL, invalid for use in protected mode *)\n FS := 0;\n DS := 0;\n ES := 0;\n CS := Gate(CS); (* Segment descriptor information also loaded *)\n CS(RPL) := 0;\n CPL := 0;\n IF IDT gate is 32-bit\n THEN\n EIP := Gate(instruction pointer);\n ELSE (* IDT gate is 16-bit *)\n EIP := Gate(instruction pointer) AND 0000FFFFH;\n FI;\n IF ShadowStackEnabled(0)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n(* Start execution of new routine in Protected Mode *)\nEND;\nINTRA-PRIVILEGE-LEVEL-INTERRUPT:\n NewSSP = SSP;\n CHECK_SS_TOKEN = 0\n (* PE = 1, DPL = CPL or conforming segment *)\n IF IA32_EFER.LMA = 1 (* IA-32e mode *)\n IF IDT-descriptor IST ≠ 0\n THEN\n TSSstackAddress := (IDT-descriptor IST « 3) + 28;\n IF (TSSstackAddress + 7) > TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n ELSE NewRSP := RSP;\n FI;\n IF IDT-descriptor IST ≠ 0\n IF ShadowStackEnabled(CPL)\n THEN\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT gate IST « 3)\n NewSSP := 8 bytes loaded from NewSSPAddress\n CHECK_SS_TOKEN = 1\n FI;\n FI;\n FI;\n IF 32-bit gate (* implies IA32_EFER.LMA = 0 *)\n THEN\n IF current stack does not have room for 16 bytes (error code pushed)\n or 12 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE IF 16-bit gate (* implies IA32_EFER.LMA = 0 *)\n IF current stack does not have room for 8 bytes (error code pushed)\n or 6 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n IF NewRSP contains a non-canonical address\n THEN #SS(EXT); (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limit\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ELSE\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n FI;\n IF IDT gate is 32-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (EFLAGS);\n Push (far pointer to return instruction); (* 3 words padded to 4 *)\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE\n IF IDT gate is 16-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (FLAGS);\n Push (far pointer to return location); (* 2 words *)\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8 bytes *)\n CS:RIP := GATE(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n IF CHECK_SS_TOKEN == 1\n THEN\n IF NewSSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (NewSSP & ~0x1F) != ((NewSSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND NewSSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = NewSSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = NewSSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(NewSSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n (* Align to next 8 byte boundary *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (NewSSP − 4)\n SSP = newSSP & 0xFFFFFFFFFFFFFFF8H;\n (* push cs:lip:ssp on shadow stack *)\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled (CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0; FI; (* Interrupt flag set to 0; interrupts disabled *)\n TF := 0;\n NT := 0;\n VM := 0;\n RF := 0;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/intn:into:int3:int1" + }, + "int1": { + "instruction": "INT1", + "title": "INT n/INTO/INT3/INT1\n\t\t— Call to Interrupt Procedure", + "opcode": "F1", + "description": "The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand (see the section titled “Interrupts and Exceptions” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). The destination operand specifies a vector from 0 to 255, encoded as an 8-bit unsigned intermediate value. Each vector provides an index to a gate descriptor in the IDT. The first 32 vectors are reserved by Intel for system use. Some of these vectors are used for internally generated exceptions.\nThe INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. The INTO instruction is a special mnemonic for calling overflow exception (#OF), exception 4. The overflow interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler if the OF flag is set to 1. (The INTO instruction cannot be used in 64-bit mode.)\nThe INT3 instruction uses a one-byte opcode (CC) and is intended for calling the debug exception handler with a breakpoint exception (#BP). (This one-byte form is useful because it can replace the first byte of any instruction at which a breakpoint is desired, including other one-byte instructions, without overwriting other instructions.)\nThe INT1 instruction also uses a one-byte opcode (F1) and generates a debug exception (#DB) without setting any bits in DR6.1 Hardware vendors may use the INT1 instruction for hardware debug. For that reason, Intel recommends software vendors instead use the INT3 instruction for software breakpoints.\nAn interrupt generated by the INTO, INT3, or INT1 instruction differs from one generated by INT n in the following ways:\n(These features do not pertain to CD03, the “normal” 2-byte opcode for INT 3. Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic, but this opcode can be created by direct numeric code definition or by self-modifying code.)\nThe action of the INT n instruction (including the INTO, INT3, and INT1 instructions) is similar to that of a far call made with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed onto the stack before the return address. (The return address is a far address consisting of the current values of the CS and EIP registers.) Returns from interrupt procedures are handled with the IRET instruction, which pops the EFLAGS information and return address from the stack.\nEach of the INT n, INTO, and INT3 instructions generates a general-protection exception (#GP) if the CPL is greater than the DPL value in the selected gate descriptor in the IDT. In contrast, the INT1 instruction can deliver a #DB\neven if the CPL is greater than the DPL of descriptor 1 in the IDT. (This behavior supports the use of INT1 by hardware vendors performing hardware debug.)\nThe vector specifies an interrupt descriptor in the interrupt descriptor table (IDT); that is, it provides index into the IDT. The selected interrupt descriptor in turn contains a pointer to an interrupt or exception handler procedure. In protected mode, the IDT contains an array of 8-byte descriptors, each of which is an interrupt gate, trap gate, or task gate. In real-address mode, the IDT is an array of 4-byte far pointers (2-byte code segment selector and a 2-byte instruction pointer), each of which point directly to a procedure in the selected segment. (Note that in real-address mode, the IDT is called the interrupt vector table, and its pointers are called interrupt vectors.)\nThe following decision table indicates which action in the lower portion of the table is taken given the conditions in the upper portion of the table. Each Y in the lower section of the decision table represents a procedure defined in the “Operation” section for this instruction (except #GP).\nWhen the processor is executing in virtual-8086 mode, the IOPL determines the action of the INT n instruction. If the IOPL is less than 3, the processor generates a #GP(selector) exception; if the IOPL is 3, the processor executes a protected mode interrupt to privilege level 0. The interrupt gate's DPL must be set to 3 and the target CPL of the interrupt handler procedure must be 0 to execute the protected mode interrupt to privilege level 0.\nThe interrupt descriptor table register (IDTR) specifies the base linear address and limit of the IDT. The initial base address value of the IDTR after the processor is powered up or reset is 0.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. Instructions following an INT n may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the INT n have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible). This applies also to the INTO, INT3, and INT1 instructions, but not to executions of INTO when EFLAGS.OF = 0.", + "operation": "The following operational description applies not only to the INT n, INTO, INT3, or INT1 instructions, but also to\nexternal interrupts, nonmaskable interrupts (NMIs), and exceptions. Some of these events push onto the stack an\nerror code.\nThe operational description specifies numerous checks whose failure may result in delivery of a nested exception.\nIn these cases, the original event is not delivered.\nThe operational description specifies the error code delivered by any nested exception. In some cases, the error\ncode is specified with a pseudofunction error_code(num,idt,ext), where idt and ext are bit values. The pseudofunc-\ntion produces an error code as follows: (1) if idt is 0, the error code is (num & FCH) | ext; (2) if idt is 1, the error\ncode is (num « 3) | 2 | ext.\nIn many cases, the pseudofunction error_code is invoked with a pseudovariable EXT. The value of EXT depends on\nthe nature of the event whose delivery encountered a nested exception: if that event is a software interrupt (INT n,\nINT3, or INTO), EXT is 0; otherwise (including INT1), EXT is 1.\nIF PE = 0\n THEN\n GOTO REAL-ADDRESS-MODE;\n ELSE (* PE = 1 *)\n IF (EFLAGS.VM = 1 AND CR4.VME = 0 AND IOPL < 3 AND INT n)\n THEN\n #GP(0); (* Bit 0 of error code is 0 because INT n *)\n ELSE\n IF (EFLAGS.VM = 1 AND CR4.VME = 1 AND INT n)\n THEN\n Consult bit n of the software interrupt redirection bit map in the TSS;\n IF bit n is clear\n THEN (* redirect interrupt to 8086 program interrupt handler *)\n Push EFLAGS[15:0]; (* if IOPL < 3, save VIF in IF position and save IOPL position as 3 *)\n Push CS;\n Push IP;\n IF IOPL = 3\n THEN IF := 0; (* Clear interrupt flag *)\n ELSE VIF := 0; (* Clear virtual interrupt flag *)\n FI;\n TF := 0; (* Clear trap flag *)\n load CS and EIP (lower 16 bits only) from entry n in interrupt vector table referenced from TSS;\n ELSE\n IF IOPL = 3\n THEN GOTO PROTECTED-MODE;\n ELSE #GP(0); (* Bit 0 of error code is 0 because INT n *)\n FI;\n FI;\n ELSE (* Protected mode, IA-32e mode, or virtual-8086 mode interrupt *)\n IF (IA32_EFER.LMA = 0)\n THEN (* Protected mode, or virtual-8086 mode interrupt *)\n GOTO PROTECTED-MODE;\n ELSE (* IA-32e mode interrupt *)\n GOTO IA-32e-MODE;\n FI;\n FI;\n FI;\nFI;\nREAL-ADDRESS-MODE:\n IF ((vector_number « 2) + 3) is not within IDT limit\n THEN #GP; FI;\n IF stack not large enough for a 6-byte return information\n THEN #SS; FI;\n Push (EFLAGS[15:0]);\n IF := 0; (* Clear interrupt flag *)\n TF := 0; (* Clear trap flag *)\n AC := 0; (* Clear AC flag *)\n Push(CS);\n Push(IP);\n (* No error codes are pushed in real-address mode*)\n CS := IDT(Descriptor (vector_number « 2), selector));\n EIP := IDT(Descriptor (vector_number « 2), offset)); (* 16 bit offset AND 0000FFFFH *)\nEND;\nPROTECTED-MODE:\n IF ((vector_number « 3) + 7) is not within IDT limits\n or selected IDT descriptor is not an interrupt-, trap-, or task-gate type\n THEN #GP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0)); FI;\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF task gate (* Specified in the selected interrupt table descriptor *)\n THEN GOTO TASK-GATE;\n ELSE GOTO TRAP-OR-INTERRUPT-GATE; (* PE = 1, trap/interrupt gate *)\n FI;\nEND;\nIA-32e-MODE:\n IF INTO and CS.L = 1 (64-bit mode)\n THEN #UD;\n FI;\n IF ((vector_number « 4) + 15) is not in IDT limits\n or selected IDT descriptor is not an interrupt-, or trap-gate type\n THEN #GP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0));\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n GOTO TRAP-OR-INTERRUPT-GATE; (* Trap/interrupt gate *)\nEND;\nTASK-GATE: (* PE = 1, task gate *)\n Read TSS selector in task gate (IDT descriptor);\n IF local/global bit is set to local or index not within GDT limits\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Access TSS descriptor in GDT;\n IF TSS descriptor specifies that the TSS is busy (low-order 5 bits set to 00001)\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF TSS not present\n THEN #NP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n SWITCH-TASKS (with nesting) to TSS;\n IF interrupt caused by fault with error code\n THEN\n IF stack limit does not allow push of error code\n THEN #SS(EXT); FI;\n Push(error code);\n FI;\n IF EIP not within code segment limit\n THEN #GP(EXT); FI;\nEND;\nTRAP-OR-INTERRUPT-GATE:\n Read new code-segment selector for trap or interrupt gate (IDT descriptor);\n IF new code-segment selector is NULL\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n IF new code-segment selector is not within its descriptor table limits\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read descriptor referenced by new code-segment selector;\n IF descriptor does not indicate a code segment or new code-segment DPL > CPL\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code-segment descriptor is not present,\n THEN #NP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is non-conforming with DPL < CPL\n THEN\n IF VM = 0\n THEN\n GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;\n (* PE = 1, VM = 0, interrupt or trap gate, nonconforming code segment,\n DPL < CPL *)\n ELSE (* VM = 1 *)\n IF new code-segment DPL ≠ 0\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n GOTO INTERRUPT-FROM-VIRTUAL-8086-MODE; FI;\n (* PE = 1, interrupt or trap gate, DPL < CPL, VM = 1 *)\n FI;\n ELSE (* PE = 1, interrupt or trap gate, DPL ≥ CPL *)\n IF VM = 1\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is conforming or new code-segment DPL = CPL\n THEN\n GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;\n ELSE (* PE = 1, interrupt or trap gate, nonconforming code segment, DPL > CPL *)\n #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n FI;\nEND;\nINTER-PRIVILEGE-LEVEL-INTERRUPT:\n (* PE = 1, interrupt or trap gate, non-conforming code segment, DPL < CPL *)\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n (* Identify stack-segment selector for new privilege level in current TSS *)\n IF current TSS is 32-bit\n THEN\n TSSstackAddress := (new code-segment DPL « 3) + 4;\n IF (TSSstackAddress + 5) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);\n NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);\n ELSE (* current TSS is 16-bit *)\n TSSstackAddress := (new code-segment DPL « 2) + 2\n IF (TSSstackAddress + 3) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);\n NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI;\n IF NewSS index is not within its descriptor-table limits\n or NewSS RPL ≠ new code-segment DPL\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ new code-segment DPL\n or new stack-segment Type does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF NewSS is not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE (* IA-32e mode *)\n IF IDT-gate IST = 0\n THEN TSSstackAddress := (new code-segment DPL « 3) + 4;\n ELSE TSSstackAddress := (IDT gate IST « 3) + 28;\n FI;\n IF (TSSstackAddress + 7) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)\n IF IDT-gate IST = 0\n THEN\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT-gate IST « 3)\n (* Check if shadow stacks are enabled at CPL 0 *)\n IF ShadowStackEnabled(CPL 0)\n THEN NewSSP := 8 bytes loaded from NewSSPAddress; FI;\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 24 bytes (error code pushed)\n or 20 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI\n ELSE\n IF IDT gate is 16-bit\n THEN\n IF new stack does not have room for 12 bytes (error code pushed)\n or 10 bytes (no error code pushed);\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* 64-bit IDT gate*)\n IF StackAddress is non-canonical\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ESP := NewESP;\n SS := NewSS; (* Segment descriptor information also loaded *)\n ELSE (* IA-32e mode *)\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n SS := NewSS;\n FI;\n IF IDT gate is 32-bit\n THEN\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n ELSE\n IF IDT gate 16-bit\n THEN\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n ELSE (* 64-bit IDT gate *)\n CS:RIP := Gate(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and ESP, 3 words padded to 4 *)\n Push(EFLAGS);\n Push(far pointer to return instruction);\n (* Old CS and EIP, 3 words padded to 4 *)\n Push(ErrorCode); (* If needed, 4 bytes *)\n ELSE\n IF IDT gate 16-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and SP, 2 words *)\n Push(EFLAGS(15:0]);\n Push(far pointer to return instruction);\n (* Old CS and IP, 2 words *)\n Push(ErrorCode); (* If needed, 2 bytes *)\n ELSE (* 64-bit IDT gate *)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8-bytes *)\n FI;\n FI;\n IF ShadowStackEnabled(CPL) AND CPL = 3\n THEN\n IF IA32_EFER.LMA = 0\n THEN IA32_PL3_SSP := SSP;\n ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n FI;\n FI;\n CPL := new code-segment DPL;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n IF oldSS.DPL != 3\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(oldSSP);\n FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0 (* Interrupt flag set to 0, interrupts disabled *); FI;\n TF := 0;\n VM := 0;\n RF := 0;\n NT := 0;\nEND;\nINTERRUPT-FROM-VIRTUAL-8086-MODE:\n (* Identify stack-segment selector for privilege level 0 in current TSS *)\n IF current TSS is 32-bit\n THEN\n IF TSS limit < 9\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 8);\n NewESP := 4 bytes loaded from (current TSS base + 4);\n ELSE (* current TSS is 16-bit *)\n IF TSS limit < 5\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 4);\n NewESP := 2 bytes loaded from (current TSS base + 2);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI; (* Error code contains NULL selector *)\n IF NewSS index is not within its descriptor table limits\n or NewSS RPL ≠ 0\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ 0 or stack segment does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new stack segment not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PL0_SSP (* the new code-segment DPL must be 0 *)\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 40 bytes (error code pushed)\n or 36 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* IDT gate is 16-bit)\n IF new stack does not have room for 20 bytes (error code pushed)\n or 18 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n tempEFLAGS := EFLAGS;\n VM := 0;\n TF := 0;\n RF := 0;\n NT := 0;\n IF service through interrupt gate\n THEN IF = 0; FI;\n TempSS := SS;\n TempESP := ESP;\n SS := NewSS;\n ESP := NewESP;\n (* Following pushes are 16 bits for 16-bit IDT gates and 32 bits for 32-bit IDT gates;\n Segment selector pushes in 32-bit mode are padded to two words *)\n Push(GS);\n Push(FS);\n Push(DS);\n Push(ES);\n Push(TempSS);\n Push(TempESP);\n Push(TempEFlags);\n Push(CS);\n Push(EIP);\n GS := 0; (* Segment registers made NULL, invalid for use in protected mode *)\n FS := 0;\n DS := 0;\n ES := 0;\n CS := Gate(CS); (* Segment descriptor information also loaded *)\n CS(RPL) := 0;\n CPL := 0;\n IF IDT gate is 32-bit\n THEN\n EIP := Gate(instruction pointer);\n ELSE (* IDT gate is 16-bit *)\n EIP := Gate(instruction pointer) AND 0000FFFFH;\n FI;\n IF ShadowStackEnabled(0)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n(* Start execution of new routine in Protected Mode *)\nEND;\nINTRA-PRIVILEGE-LEVEL-INTERRUPT:\n NewSSP = SSP;\n CHECK_SS_TOKEN = 0\n (* PE = 1, DPL = CPL or conforming segment *)\n IF IA32_EFER.LMA = 1 (* IA-32e mode *)\n IF IDT-descriptor IST ≠ 0\n THEN\n TSSstackAddress := (IDT-descriptor IST « 3) + 28;\n IF (TSSstackAddress + 7) > TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n ELSE NewRSP := RSP;\n FI;\n IF IDT-descriptor IST ≠ 0\n IF ShadowStackEnabled(CPL)\n THEN\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT gate IST « 3)\n NewSSP := 8 bytes loaded from NewSSPAddress\n CHECK_SS_TOKEN = 1\n FI;\n FI;\n FI;\n IF 32-bit gate (* implies IA32_EFER.LMA = 0 *)\n THEN\n IF current stack does not have room for 16 bytes (error code pushed)\n or 12 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE IF 16-bit gate (* implies IA32_EFER.LMA = 0 *)\n IF current stack does not have room for 8 bytes (error code pushed)\n or 6 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n IF NewRSP contains a non-canonical address\n THEN #SS(EXT); (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limit\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ELSE\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n FI;\n IF IDT gate is 32-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (EFLAGS);\n Push (far pointer to return instruction); (* 3 words padded to 4 *)\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE\n IF IDT gate is 16-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (FLAGS);\n Push (far pointer to return location); (* 2 words *)\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8 bytes *)\n CS:RIP := GATE(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n IF CHECK_SS_TOKEN == 1\n THEN\n IF NewSSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (NewSSP & ~0x1F) != ((NewSSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND NewSSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = NewSSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = NewSSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(NewSSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n (* Align to next 8 byte boundary *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (NewSSP − 4)\n SSP = newSSP & 0xFFFFFFFFFFFFFFF8H;\n (* push cs:lip:ssp on shadow stack *)\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled (CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0; FI; (* Interrupt flag set to 0; interrupts disabled *)\n TF := 0;\n NT := 0;\n VM := 0;\n RF := 0;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/intn:into:int3:int1" + }, + "int3": { + "instruction": "INT3", + "title": "INT n/INTO/INT3/INT1\n\t\t— Call to Interrupt Procedure", + "opcode": "CC", + "description": "The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand (see the section titled “Interrupts and Exceptions” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). The destination operand specifies a vector from 0 to 255, encoded as an 8-bit unsigned intermediate value. Each vector provides an index to a gate descriptor in the IDT. The first 32 vectors are reserved by Intel for system use. Some of these vectors are used for internally generated exceptions.\nThe INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. The INTO instruction is a special mnemonic for calling overflow exception (#OF), exception 4. The overflow interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler if the OF flag is set to 1. (The INTO instruction cannot be used in 64-bit mode.)\nThe INT3 instruction uses a one-byte opcode (CC) and is intended for calling the debug exception handler with a breakpoint exception (#BP). (This one-byte form is useful because it can replace the first byte of any instruction at which a breakpoint is desired, including other one-byte instructions, without overwriting other instructions.)\nThe INT1 instruction also uses a one-byte opcode (F1) and generates a debug exception (#DB) without setting any bits in DR6.1 Hardware vendors may use the INT1 instruction for hardware debug. For that reason, Intel recommends software vendors instead use the INT3 instruction for software breakpoints.\nAn interrupt generated by the INTO, INT3, or INT1 instruction differs from one generated by INT n in the following ways:\n(These features do not pertain to CD03, the “normal” 2-byte opcode for INT 3. Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic, but this opcode can be created by direct numeric code definition or by self-modifying code.)\nThe action of the INT n instruction (including the INTO, INT3, and INT1 instructions) is similar to that of a far call made with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed onto the stack before the return address. (The return address is a far address consisting of the current values of the CS and EIP registers.) Returns from interrupt procedures are handled with the IRET instruction, which pops the EFLAGS information and return address from the stack.\nEach of the INT n, INTO, and INT3 instructions generates a general-protection exception (#GP) if the CPL is greater than the DPL value in the selected gate descriptor in the IDT. In contrast, the INT1 instruction can deliver a #DB\neven if the CPL is greater than the DPL of descriptor 1 in the IDT. (This behavior supports the use of INT1 by hardware vendors performing hardware debug.)\nThe vector specifies an interrupt descriptor in the interrupt descriptor table (IDT); that is, it provides index into the IDT. The selected interrupt descriptor in turn contains a pointer to an interrupt or exception handler procedure. In protected mode, the IDT contains an array of 8-byte descriptors, each of which is an interrupt gate, trap gate, or task gate. In real-address mode, the IDT is an array of 4-byte far pointers (2-byte code segment selector and a 2-byte instruction pointer), each of which point directly to a procedure in the selected segment. (Note that in real-address mode, the IDT is called the interrupt vector table, and its pointers are called interrupt vectors.)\nThe following decision table indicates which action in the lower portion of the table is taken given the conditions in the upper portion of the table. Each Y in the lower section of the decision table represents a procedure defined in the “Operation” section for this instruction (except #GP).\nWhen the processor is executing in virtual-8086 mode, the IOPL determines the action of the INT n instruction. If the IOPL is less than 3, the processor generates a #GP(selector) exception; if the IOPL is 3, the processor executes a protected mode interrupt to privilege level 0. The interrupt gate's DPL must be set to 3 and the target CPL of the interrupt handler procedure must be 0 to execute the protected mode interrupt to privilege level 0.\nThe interrupt descriptor table register (IDTR) specifies the base linear address and limit of the IDT. The initial base address value of the IDTR after the processor is powered up or reset is 0.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. Instructions following an INT n may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the INT n have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible). This applies also to the INTO, INT3, and INT1 instructions, but not to executions of INTO when EFLAGS.OF = 0.", + "operation": "The following operational description applies not only to the INT n, INTO, INT3, or INT1 instructions, but also to\nexternal interrupts, nonmaskable interrupts (NMIs), and exceptions. Some of these events push onto the stack an\nerror code.\nThe operational description specifies numerous checks whose failure may result in delivery of a nested exception.\nIn these cases, the original event is not delivered.\nThe operational description specifies the error code delivered by any nested exception. In some cases, the error\ncode is specified with a pseudofunction error_code(num,idt,ext), where idt and ext are bit values. The pseudofunc-\ntion produces an error code as follows: (1) if idt is 0, the error code is (num & FCH) | ext; (2) if idt is 1, the error\ncode is (num « 3) | 2 | ext.\nIn many cases, the pseudofunction error_code is invoked with a pseudovariable EXT. The value of EXT depends on\nthe nature of the event whose delivery encountered a nested exception: if that event is a software interrupt (INT n,\nINT3, or INTO), EXT is 0; otherwise (including INT1), EXT is 1.\nIF PE = 0\n THEN\n GOTO REAL-ADDRESS-MODE;\n ELSE (* PE = 1 *)\n IF (EFLAGS.VM = 1 AND CR4.VME = 0 AND IOPL < 3 AND INT n)\n THEN\n #GP(0); (* Bit 0 of error code is 0 because INT n *)\n ELSE\n IF (EFLAGS.VM = 1 AND CR4.VME = 1 AND INT n)\n THEN\n Consult bit n of the software interrupt redirection bit map in the TSS;\n IF bit n is clear\n THEN (* redirect interrupt to 8086 program interrupt handler *)\n Push EFLAGS[15:0]; (* if IOPL < 3, save VIF in IF position and save IOPL position as 3 *)\n Push CS;\n Push IP;\n IF IOPL = 3\n THEN IF := 0; (* Clear interrupt flag *)\n ELSE VIF := 0; (* Clear virtual interrupt flag *)\n FI;\n TF := 0; (* Clear trap flag *)\n load CS and EIP (lower 16 bits only) from entry n in interrupt vector table referenced from TSS;\n ELSE\n IF IOPL = 3\n THEN GOTO PROTECTED-MODE;\n ELSE #GP(0); (* Bit 0 of error code is 0 because INT n *)\n FI;\n FI;\n ELSE (* Protected mode, IA-32e mode, or virtual-8086 mode interrupt *)\n IF (IA32_EFER.LMA = 0)\n THEN (* Protected mode, or virtual-8086 mode interrupt *)\n GOTO PROTECTED-MODE;\n ELSE (* IA-32e mode interrupt *)\n GOTO IA-32e-MODE;\n FI;\n FI;\n FI;\nFI;\nREAL-ADDRESS-MODE:\n IF ((vector_number « 2) + 3) is not within IDT limit\n THEN #GP; FI;\n IF stack not large enough for a 6-byte return information\n THEN #SS; FI;\n Push (EFLAGS[15:0]);\n IF := 0; (* Clear interrupt flag *)\n TF := 0; (* Clear trap flag *)\n AC := 0; (* Clear AC flag *)\n Push(CS);\n Push(IP);\n (* No error codes are pushed in real-address mode*)\n CS := IDT(Descriptor (vector_number « 2), selector));\n EIP := IDT(Descriptor (vector_number « 2), offset)); (* 16 bit offset AND 0000FFFFH *)\nEND;\nPROTECTED-MODE:\n IF ((vector_number « 3) + 7) is not within IDT limits\n or selected IDT descriptor is not an interrupt-, trap-, or task-gate type\n THEN #GP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0)); FI;\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF task gate (* Specified in the selected interrupt table descriptor *)\n THEN GOTO TASK-GATE;\n ELSE GOTO TRAP-OR-INTERRUPT-GATE; (* PE = 1, trap/interrupt gate *)\n FI;\nEND;\nIA-32e-MODE:\n IF INTO and CS.L = 1 (64-bit mode)\n THEN #UD;\n FI;\n IF ((vector_number « 4) + 15) is not in IDT limits\n or selected IDT descriptor is not an interrupt-, or trap-gate type\n THEN #GP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0));\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n GOTO TRAP-OR-INTERRUPT-GATE; (* Trap/interrupt gate *)\nEND;\nTASK-GATE: (* PE = 1, task gate *)\n Read TSS selector in task gate (IDT descriptor);\n IF local/global bit is set to local or index not within GDT limits\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Access TSS descriptor in GDT;\n IF TSS descriptor specifies that the TSS is busy (low-order 5 bits set to 00001)\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF TSS not present\n THEN #NP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n SWITCH-TASKS (with nesting) to TSS;\n IF interrupt caused by fault with error code\n THEN\n IF stack limit does not allow push of error code\n THEN #SS(EXT); FI;\n Push(error code);\n FI;\n IF EIP not within code segment limit\n THEN #GP(EXT); FI;\nEND;\nTRAP-OR-INTERRUPT-GATE:\n Read new code-segment selector for trap or interrupt gate (IDT descriptor);\n IF new code-segment selector is NULL\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n IF new code-segment selector is not within its descriptor table limits\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read descriptor referenced by new code-segment selector;\n IF descriptor does not indicate a code segment or new code-segment DPL > CPL\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code-segment descriptor is not present,\n THEN #NP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is non-conforming with DPL < CPL\n THEN\n IF VM = 0\n THEN\n GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;\n (* PE = 1, VM = 0, interrupt or trap gate, nonconforming code segment,\n DPL < CPL *)\n ELSE (* VM = 1 *)\n IF new code-segment DPL ≠ 0\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n GOTO INTERRUPT-FROM-VIRTUAL-8086-MODE; FI;\n (* PE = 1, interrupt or trap gate, DPL < CPL, VM = 1 *)\n FI;\n ELSE (* PE = 1, interrupt or trap gate, DPL ≥ CPL *)\n IF VM = 1\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is conforming or new code-segment DPL = CPL\n THEN\n GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;\n ELSE (* PE = 1, interrupt or trap gate, nonconforming code segment, DPL > CPL *)\n #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n FI;\nEND;\nINTER-PRIVILEGE-LEVEL-INTERRUPT:\n (* PE = 1, interrupt or trap gate, non-conforming code segment, DPL < CPL *)\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n (* Identify stack-segment selector for new privilege level in current TSS *)\n IF current TSS is 32-bit\n THEN\n TSSstackAddress := (new code-segment DPL « 3) + 4;\n IF (TSSstackAddress + 5) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);\n NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);\n ELSE (* current TSS is 16-bit *)\n TSSstackAddress := (new code-segment DPL « 2) + 2\n IF (TSSstackAddress + 3) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);\n NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI;\n IF NewSS index is not within its descriptor-table limits\n or NewSS RPL ≠ new code-segment DPL\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ new code-segment DPL\n or new stack-segment Type does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF NewSS is not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE (* IA-32e mode *)\n IF IDT-gate IST = 0\n THEN TSSstackAddress := (new code-segment DPL « 3) + 4;\n ELSE TSSstackAddress := (IDT gate IST « 3) + 28;\n FI;\n IF (TSSstackAddress + 7) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)\n IF IDT-gate IST = 0\n THEN\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT-gate IST « 3)\n (* Check if shadow stacks are enabled at CPL 0 *)\n IF ShadowStackEnabled(CPL 0)\n THEN NewSSP := 8 bytes loaded from NewSSPAddress; FI;\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 24 bytes (error code pushed)\n or 20 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI\n ELSE\n IF IDT gate is 16-bit\n THEN\n IF new stack does not have room for 12 bytes (error code pushed)\n or 10 bytes (no error code pushed);\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* 64-bit IDT gate*)\n IF StackAddress is non-canonical\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ESP := NewESP;\n SS := NewSS; (* Segment descriptor information also loaded *)\n ELSE (* IA-32e mode *)\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n SS := NewSS;\n FI;\n IF IDT gate is 32-bit\n THEN\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n ELSE\n IF IDT gate 16-bit\n THEN\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n ELSE (* 64-bit IDT gate *)\n CS:RIP := Gate(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and ESP, 3 words padded to 4 *)\n Push(EFLAGS);\n Push(far pointer to return instruction);\n (* Old CS and EIP, 3 words padded to 4 *)\n Push(ErrorCode); (* If needed, 4 bytes *)\n ELSE\n IF IDT gate 16-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and SP, 2 words *)\n Push(EFLAGS(15:0]);\n Push(far pointer to return instruction);\n (* Old CS and IP, 2 words *)\n Push(ErrorCode); (* If needed, 2 bytes *)\n ELSE (* 64-bit IDT gate *)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8-bytes *)\n FI;\n FI;\n IF ShadowStackEnabled(CPL) AND CPL = 3\n THEN\n IF IA32_EFER.LMA = 0\n THEN IA32_PL3_SSP := SSP;\n ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n FI;\n FI;\n CPL := new code-segment DPL;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n IF oldSS.DPL != 3\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(oldSSP);\n FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0 (* Interrupt flag set to 0, interrupts disabled *); FI;\n TF := 0;\n VM := 0;\n RF := 0;\n NT := 0;\nEND;\nINTERRUPT-FROM-VIRTUAL-8086-MODE:\n (* Identify stack-segment selector for privilege level 0 in current TSS *)\n IF current TSS is 32-bit\n THEN\n IF TSS limit < 9\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 8);\n NewESP := 4 bytes loaded from (current TSS base + 4);\n ELSE (* current TSS is 16-bit *)\n IF TSS limit < 5\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 4);\n NewESP := 2 bytes loaded from (current TSS base + 2);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI; (* Error code contains NULL selector *)\n IF NewSS index is not within its descriptor table limits\n or NewSS RPL ≠ 0\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ 0 or stack segment does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new stack segment not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PL0_SSP (* the new code-segment DPL must be 0 *)\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 40 bytes (error code pushed)\n or 36 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* IDT gate is 16-bit)\n IF new stack does not have room for 20 bytes (error code pushed)\n or 18 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n tempEFLAGS := EFLAGS;\n VM := 0;\n TF := 0;\n RF := 0;\n NT := 0;\n IF service through interrupt gate\n THEN IF = 0; FI;\n TempSS := SS;\n TempESP := ESP;\n SS := NewSS;\n ESP := NewESP;\n (* Following pushes are 16 bits for 16-bit IDT gates and 32 bits for 32-bit IDT gates;\n Segment selector pushes in 32-bit mode are padded to two words *)\n Push(GS);\n Push(FS);\n Push(DS);\n Push(ES);\n Push(TempSS);\n Push(TempESP);\n Push(TempEFlags);\n Push(CS);\n Push(EIP);\n GS := 0; (* Segment registers made NULL, invalid for use in protected mode *)\n FS := 0;\n DS := 0;\n ES := 0;\n CS := Gate(CS); (* Segment descriptor information also loaded *)\n CS(RPL) := 0;\n CPL := 0;\n IF IDT gate is 32-bit\n THEN\n EIP := Gate(instruction pointer);\n ELSE (* IDT gate is 16-bit *)\n EIP := Gate(instruction pointer) AND 0000FFFFH;\n FI;\n IF ShadowStackEnabled(0)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n(* Start execution of new routine in Protected Mode *)\nEND;\nINTRA-PRIVILEGE-LEVEL-INTERRUPT:\n NewSSP = SSP;\n CHECK_SS_TOKEN = 0\n (* PE = 1, DPL = CPL or conforming segment *)\n IF IA32_EFER.LMA = 1 (* IA-32e mode *)\n IF IDT-descriptor IST ≠ 0\n THEN\n TSSstackAddress := (IDT-descriptor IST « 3) + 28;\n IF (TSSstackAddress + 7) > TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n ELSE NewRSP := RSP;\n FI;\n IF IDT-descriptor IST ≠ 0\n IF ShadowStackEnabled(CPL)\n THEN\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT gate IST « 3)\n NewSSP := 8 bytes loaded from NewSSPAddress\n CHECK_SS_TOKEN = 1\n FI;\n FI;\n FI;\n IF 32-bit gate (* implies IA32_EFER.LMA = 0 *)\n THEN\n IF current stack does not have room for 16 bytes (error code pushed)\n or 12 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE IF 16-bit gate (* implies IA32_EFER.LMA = 0 *)\n IF current stack does not have room for 8 bytes (error code pushed)\n or 6 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n IF NewRSP contains a non-canonical address\n THEN #SS(EXT); (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limit\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ELSE\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n FI;\n IF IDT gate is 32-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (EFLAGS);\n Push (far pointer to return instruction); (* 3 words padded to 4 *)\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE\n IF IDT gate is 16-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (FLAGS);\n Push (far pointer to return location); (* 2 words *)\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8 bytes *)\n CS:RIP := GATE(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n IF CHECK_SS_TOKEN == 1\n THEN\n IF NewSSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (NewSSP & ~0x1F) != ((NewSSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND NewSSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = NewSSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = NewSSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(NewSSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n (* Align to next 8 byte boundary *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (NewSSP − 4)\n SSP = newSSP & 0xFFFFFFFFFFFFFFF8H;\n (* push cs:lip:ssp on shadow stack *)\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled (CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0; FI; (* Interrupt flag set to 0; interrupts disabled *)\n TF := 0;\n NT := 0;\n VM := 0;\n RF := 0;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/intn:into:int3:int1" + }, + "into": { + "instruction": "INTO", + "title": "INT n/INTO/INT3/INT1\n\t\t— Call to Interrupt Procedure", + "opcode": "CE", + "description": "The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand (see the section titled “Interrupts and Exceptions” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). The destination operand specifies a vector from 0 to 255, encoded as an 8-bit unsigned intermediate value. Each vector provides an index to a gate descriptor in the IDT. The first 32 vectors are reserved by Intel for system use. Some of these vectors are used for internally generated exceptions.\nThe INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. The INTO instruction is a special mnemonic for calling overflow exception (#OF), exception 4. The overflow interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler if the OF flag is set to 1. (The INTO instruction cannot be used in 64-bit mode.)\nThe INT3 instruction uses a one-byte opcode (CC) and is intended for calling the debug exception handler with a breakpoint exception (#BP). (This one-byte form is useful because it can replace the first byte of any instruction at which a breakpoint is desired, including other one-byte instructions, without overwriting other instructions.)\nThe INT1 instruction also uses a one-byte opcode (F1) and generates a debug exception (#DB) without setting any bits in DR6.1 Hardware vendors may use the INT1 instruction for hardware debug. For that reason, Intel recommends software vendors instead use the INT3 instruction for software breakpoints.\nAn interrupt generated by the INTO, INT3, or INT1 instruction differs from one generated by INT n in the following ways:\n(These features do not pertain to CD03, the “normal” 2-byte opcode for INT 3. Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic, but this opcode can be created by direct numeric code definition or by self-modifying code.)\nThe action of the INT n instruction (including the INTO, INT3, and INT1 instructions) is similar to that of a far call made with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed onto the stack before the return address. (The return address is a far address consisting of the current values of the CS and EIP registers.) Returns from interrupt procedures are handled with the IRET instruction, which pops the EFLAGS information and return address from the stack.\nEach of the INT n, INTO, and INT3 instructions generates a general-protection exception (#GP) if the CPL is greater than the DPL value in the selected gate descriptor in the IDT. In contrast, the INT1 instruction can deliver a #DB\neven if the CPL is greater than the DPL of descriptor 1 in the IDT. (This behavior supports the use of INT1 by hardware vendors performing hardware debug.)\nThe vector specifies an interrupt descriptor in the interrupt descriptor table (IDT); that is, it provides index into the IDT. The selected interrupt descriptor in turn contains a pointer to an interrupt or exception handler procedure. In protected mode, the IDT contains an array of 8-byte descriptors, each of which is an interrupt gate, trap gate, or task gate. In real-address mode, the IDT is an array of 4-byte far pointers (2-byte code segment selector and a 2-byte instruction pointer), each of which point directly to a procedure in the selected segment. (Note that in real-address mode, the IDT is called the interrupt vector table, and its pointers are called interrupt vectors.)\nThe following decision table indicates which action in the lower portion of the table is taken given the conditions in the upper portion of the table. Each Y in the lower section of the decision table represents a procedure defined in the “Operation” section for this instruction (except #GP).\nWhen the processor is executing in virtual-8086 mode, the IOPL determines the action of the INT n instruction. If the IOPL is less than 3, the processor generates a #GP(selector) exception; if the IOPL is 3, the processor executes a protected mode interrupt to privilege level 0. The interrupt gate's DPL must be set to 3 and the target CPL of the interrupt handler procedure must be 0 to execute the protected mode interrupt to privilege level 0.\nThe interrupt descriptor table register (IDTR) specifies the base linear address and limit of the IDT. The initial base address value of the IDTR after the processor is powered up or reset is 0.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. Instructions following an INT n may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the INT n have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible). This applies also to the INTO, INT3, and INT1 instructions, but not to executions of INTO when EFLAGS.OF = 0.", + "operation": "The following operational description applies not only to the INT n, INTO, INT3, or INT1 instructions, but also to\nexternal interrupts, nonmaskable interrupts (NMIs), and exceptions. Some of these events push onto the stack an\nerror code.\nThe operational description specifies numerous checks whose failure may result in delivery of a nested exception.\nIn these cases, the original event is not delivered.\nThe operational description specifies the error code delivered by any nested exception. In some cases, the error\ncode is specified with a pseudofunction error_code(num,idt,ext), where idt and ext are bit values. The pseudofunc-\ntion produces an error code as follows: (1) if idt is 0, the error code is (num & FCH) | ext; (2) if idt is 1, the error\ncode is (num « 3) | 2 | ext.\nIn many cases, the pseudofunction error_code is invoked with a pseudovariable EXT. The value of EXT depends on\nthe nature of the event whose delivery encountered a nested exception: if that event is a software interrupt (INT n,\nINT3, or INTO), EXT is 0; otherwise (including INT1), EXT is 1.\nIF PE = 0\n THEN\n GOTO REAL-ADDRESS-MODE;\n ELSE (* PE = 1 *)\n IF (EFLAGS.VM = 1 AND CR4.VME = 0 AND IOPL < 3 AND INT n)\n THEN\n #GP(0); (* Bit 0 of error code is 0 because INT n *)\n ELSE\n IF (EFLAGS.VM = 1 AND CR4.VME = 1 AND INT n)\n THEN\n Consult bit n of the software interrupt redirection bit map in the TSS;\n IF bit n is clear\n THEN (* redirect interrupt to 8086 program interrupt handler *)\n Push EFLAGS[15:0]; (* if IOPL < 3, save VIF in IF position and save IOPL position as 3 *)\n Push CS;\n Push IP;\n IF IOPL = 3\n THEN IF := 0; (* Clear interrupt flag *)\n ELSE VIF := 0; (* Clear virtual interrupt flag *)\n FI;\n TF := 0; (* Clear trap flag *)\n load CS and EIP (lower 16 bits only) from entry n in interrupt vector table referenced from TSS;\n ELSE\n IF IOPL = 3\n THEN GOTO PROTECTED-MODE;\n ELSE #GP(0); (* Bit 0 of error code is 0 because INT n *)\n FI;\n FI;\n ELSE (* Protected mode, IA-32e mode, or virtual-8086 mode interrupt *)\n IF (IA32_EFER.LMA = 0)\n THEN (* Protected mode, or virtual-8086 mode interrupt *)\n GOTO PROTECTED-MODE;\n ELSE (* IA-32e mode interrupt *)\n GOTO IA-32e-MODE;\n FI;\n FI;\n FI;\nFI;\nREAL-ADDRESS-MODE:\n IF ((vector_number « 2) + 3) is not within IDT limit\n THEN #GP; FI;\n IF stack not large enough for a 6-byte return information\n THEN #SS; FI;\n Push (EFLAGS[15:0]);\n IF := 0; (* Clear interrupt flag *)\n TF := 0; (* Clear trap flag *)\n AC := 0; (* Clear AC flag *)\n Push(CS);\n Push(IP);\n (* No error codes are pushed in real-address mode*)\n CS := IDT(Descriptor (vector_number « 2), selector));\n EIP := IDT(Descriptor (vector_number « 2), offset)); (* 16 bit offset AND 0000FFFFH *)\nEND;\nPROTECTED-MODE:\n IF ((vector_number « 3) + 7) is not within IDT limits\n or selected IDT descriptor is not an interrupt-, trap-, or task-gate type\n THEN #GP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0)); FI;\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT)); FI;\n (* idt operand to error_code set because vector is used *)\n IF task gate (* Specified in the selected interrupt table descriptor *)\n THEN GOTO TASK-GATE;\n ELSE GOTO TRAP-OR-INTERRUPT-GATE; (* PE = 1, trap/interrupt gate *)\n FI;\nEND;\nIA-32e-MODE:\n IF INTO and CS.L = 1 (64-bit mode)\n THEN #UD;\n FI;\n IF ((vector_number « 4) + 15) is not in IDT limits\n or selected IDT descriptor is not an interrupt-, or trap-gate type\n THEN #GP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n IF software interrupt (* Generated by INT n, INT3, or INTO; does not apply to INT1 *)\n THEN\n IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)\n THEN #GP(error_code(vector_number,1,0));\n (* idt operand to error_code set because vector is used *)\n (* ext operand to error_code is 0 because INT n, INT3, or INTO*)\n FI;\n FI;\n IF gate not present\n THEN #NP(error_code(vector_number,1,EXT));\n (* idt operand to error_code set because vector is used *)\n FI;\n GOTO TRAP-OR-INTERRUPT-GATE; (* Trap/interrupt gate *)\nEND;\nTASK-GATE: (* PE = 1, task gate *)\n Read TSS selector in task gate (IDT descriptor);\n IF local/global bit is set to local or index not within GDT limits\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Access TSS descriptor in GDT;\n IF TSS descriptor specifies that the TSS is busy (low-order 5 bits set to 00001)\n THEN #GP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF TSS not present\n THEN #NP(error_code(TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n SWITCH-TASKS (with nesting) to TSS;\n IF interrupt caused by fault with error code\n THEN\n IF stack limit does not allow push of error code\n THEN #SS(EXT); FI;\n Push(error code);\n FI;\n IF EIP not within code segment limit\n THEN #GP(EXT); FI;\nEND;\nTRAP-OR-INTERRUPT-GATE:\n Read new code-segment selector for trap or interrupt gate (IDT descriptor);\n IF new code-segment selector is NULL\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n IF new code-segment selector is not within its descriptor table limits\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read descriptor referenced by new code-segment selector;\n IF descriptor does not indicate a code segment or new code-segment DPL > CPL\n THEN #GP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code-segment descriptor is not present,\n THEN #NP(error_code(new code-segment selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is non-conforming with DPL < CPL\n THEN\n IF VM = 0\n THEN\n GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;\n (* PE = 1, VM = 0, interrupt or trap gate, nonconforming code segment,\n DPL < CPL *)\n ELSE (* VM = 1 *)\n IF new code-segment DPL ≠ 0\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n GOTO INTERRUPT-FROM-VIRTUAL-8086-MODE; FI;\n (* PE = 1, interrupt or trap gate, DPL < CPL, VM = 1 *)\n FI;\n ELSE (* PE = 1, interrupt or trap gate, DPL ≥ CPL *)\n IF VM = 1\n THEN #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n IF new code segment is conforming or new code-segment DPL = CPL\n THEN\n GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;\n ELSE (* PE = 1, interrupt or trap gate, nonconforming code segment, DPL > CPL *)\n #GP(error_code(new code-segment selector,0,EXT));\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n FI;\nEND;\nINTER-PRIVILEGE-LEVEL-INTERRUPT:\n (* PE = 1, interrupt or trap gate, non-conforming code segment, DPL < CPL *)\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n (* Identify stack-segment selector for new privilege level in current TSS *)\n IF current TSS is 32-bit\n THEN\n TSSstackAddress := (new code-segment DPL « 3) + 4;\n IF (TSSstackAddress + 5) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);\n NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);\n ELSE (* current TSS is 16-bit *)\n TSSstackAddress := (new code-segment DPL « 2) + 2\n IF (TSSstackAddress + 3) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);\n NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI;\n IF NewSS index is not within its descriptor-table limits\n or NewSS RPL ≠ new code-segment DPL\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ new code-segment DPL\n or new stack-segment Type does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF NewSS is not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE (* IA-32e mode *)\n IF IDT-gate IST = 0\n THEN TSSstackAddress := (new code-segment DPL « 3) + 4;\n ELSE TSSstackAddress := (IDT gate IST « 3) + 28;\n FI;\n IF (TSSstackAddress + 7) > current TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)\n IF IDT-gate IST = 0\n THEN\n NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)\n ELSE\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT-gate IST « 3)\n (* Check if shadow stacks are enabled at CPL 0 *)\n IF ShadowStackEnabled(CPL 0)\n THEN NewSSP := 8 bytes loaded from NewSSPAddress; FI;\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 24 bytes (error code pushed)\n or 20 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI\n ELSE\n IF IDT gate is 16-bit\n THEN\n IF new stack does not have room for 12 bytes (error code pushed)\n or 10 bytes (no error code pushed);\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* 64-bit IDT gate*)\n IF StackAddress is non-canonical\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ESP := NewESP;\n SS := NewSS; (* Segment descriptor information also loaded *)\n ELSE (* IA-32e mode *)\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n SS := NewSS;\n FI;\n IF IDT gate is 32-bit\n THEN\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n ELSE\n IF IDT gate 16-bit\n THEN\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n ELSE (* 64-bit IDT gate *)\n CS:RIP := Gate(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n IF IDT gate is 32-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and ESP, 3 words padded to 4 *)\n Push(EFLAGS);\n Push(far pointer to return instruction);\n (* Old CS and EIP, 3 words padded to 4 *)\n Push(ErrorCode); (* If needed, 4 bytes *)\n ELSE\n IF IDT gate 16-bit\n THEN\n Push(far pointer to old stack);\n (* Old SS and SP, 2 words *)\n Push(EFLAGS(15:0]);\n Push(far pointer to return instruction);\n (* Old CS and IP, 2 words *)\n Push(ErrorCode); (* If needed, 2 bytes *)\n ELSE (* 64-bit IDT gate *)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8-bytes *)\n FI;\n FI;\n IF ShadowStackEnabled(CPL) AND CPL = 3\n THEN\n IF IA32_EFER.LMA = 0\n THEN IA32_PL3_SSP := SSP;\n ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n FI;\n FI;\n CPL := new code-segment DPL;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n IF oldSS.DPL != 3\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(oldSSP);\n FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0 (* Interrupt flag set to 0, interrupts disabled *); FI;\n TF := 0;\n VM := 0;\n RF := 0;\n NT := 0;\nEND;\nINTERRUPT-FROM-VIRTUAL-8086-MODE:\n (* Identify stack-segment selector for privilege level 0 in current TSS *)\n IF current TSS is 32-bit\n THEN\n IF TSS limit < 9\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 8);\n NewESP := 4 bytes loaded from (current TSS base + 4);\n ELSE (* current TSS is 16-bit *)\n IF TSS limit < 5\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSS := 2 bytes loaded from (current TSS base + 4);\n NewESP := 2 bytes loaded from (current TSS base + 2);\n FI;\n IF NewSS is NULL\n THEN #TS(EXT); FI; (* Error code contains NULL selector *)\n IF NewSS index is not within its descriptor table limits\n or NewSS RPL ≠ 0\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n Read new stack-segment descriptor for NewSS in GDT or LDT;\n IF new stack-segment DPL ≠ 0 or stack segment does not indicate writable data segment\n THEN #TS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n IF new stack segment not present\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewSSP := IA32_PL0_SSP (* the new code-segment DPL must be 0 *)\n IF IDT gate is 32-bit\n THEN\n IF new stack does not have room for 40 bytes (error code pushed)\n or 36 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n ELSE (* IDT gate is 16-bit)\n IF new stack does not have room for 20 bytes (error code pushed)\n or 18 bytes (no error code pushed)\n THEN #SS(error_code(NewSS,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n FI;\n IF instruction pointer from IDT gate is not within new code-segment limits\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n tempEFLAGS := EFLAGS;\n VM := 0;\n TF := 0;\n RF := 0;\n NT := 0;\n IF service through interrupt gate\n THEN IF = 0; FI;\n TempSS := SS;\n TempESP := ESP;\n SS := NewSS;\n ESP := NewESP;\n (* Following pushes are 16 bits for 16-bit IDT gates and 32 bits for 32-bit IDT gates;\n Segment selector pushes in 32-bit mode are padded to two words *)\n Push(GS);\n Push(FS);\n Push(DS);\n Push(ES);\n Push(TempSS);\n Push(TempESP);\n Push(TempEFlags);\n Push(CS);\n Push(EIP);\n GS := 0; (* Segment registers made NULL, invalid for use in protected mode *)\n FS := 0;\n DS := 0;\n ES := 0;\n CS := Gate(CS); (* Segment descriptor information also loaded *)\n CS(RPL) := 0;\n CPL := 0;\n IF IDT gate is 32-bit\n THEN\n EIP := Gate(instruction pointer);\n ELSE (* IDT gate is 16-bit *)\n EIP := Gate(instruction pointer) AND 0000FFFFH;\n FI;\n IF ShadowStackEnabled(0)\n oldSSP := SSP\n SSP := NewSSP\n IF SSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = SSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = SSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n IF EndbranchEnabled (CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n(* Start execution of new routine in Protected Mode *)\nEND;\nINTRA-PRIVILEGE-LEVEL-INTERRUPT:\n NewSSP = SSP;\n CHECK_SS_TOKEN = 0\n (* PE = 1, DPL = CPL or conforming segment *)\n IF IA32_EFER.LMA = 1 (* IA-32e mode *)\n IF IDT-descriptor IST ≠ 0\n THEN\n TSSstackAddress := (IDT-descriptor IST « 3) + 28;\n IF (TSSstackAddress + 7) > TSS limit\n THEN #TS(error_code(current TSS selector,0,EXT)); FI;\n (* idt operand to error_code is 0 because selector is used *)\n NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);\n ELSE NewRSP := RSP;\n FI;\n IF IDT-descriptor IST ≠ 0\n IF ShadowStackEnabled(CPL)\n THEN\n NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT gate IST « 3)\n NewSSP := 8 bytes loaded from NewSSPAddress\n CHECK_SS_TOKEN = 1\n FI;\n FI;\n FI;\n IF 32-bit gate (* implies IA32_EFER.LMA = 0 *)\n THEN\n IF current stack does not have room for 16 bytes (error code pushed)\n or 12 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE IF 16-bit gate (* implies IA32_EFER.LMA = 0 *)\n IF current stack does not have room for 8 bytes (error code pushed)\n or 6 bytes (no error code pushed)\n THEN #SS(EXT); FI; (* Error code contains NULL selector *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n IF NewRSP contains a non-canonical address\n THEN #SS(EXT); (* Error code contains NULL selector *)\n FI;\n FI;\n IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)\n THEN\n IF instruction pointer from IDT gate is not within new code-segment limit\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n ELSE\n IF instruction pointer from IDT gate contains a non-canonical address\n THEN #GP(EXT); FI; (* Error code contains NULL selector *)\n RSP := NewRSP & FFFFFFFFFFFFFFF0H;\n FI;\n IF IDT gate is 32-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (EFLAGS);\n Push (far pointer to return instruction); (* 3 words padded to 4 *)\n CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE\n IF IDT gate is 16-bit (* implies IA32_EFER.LMA = 0 *)\n THEN\n Push (FLAGS);\n Push (far pointer to return location); (* 2 words *)\n CS:IP := Gate(CS:IP);\n (* Segment descriptor information also loaded *)\n Push (ErrorCode); (* If any *)\n ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)\n Push(far pointer to old stack);\n (* Old SS and SP, each an 8-byte push *)\n Push(RFLAGS); (* 8-byte push *)\n Push(far pointer to return instruction);\n (* Old CS and RIP, each an 8-byte push *)\n Push(ErrorCode); (* If needed, 8 bytes *)\n CS:RIP := GATE(CS:RIP);\n (* Segment descriptor information also loaded *)\n FI;\n FI;\n CS(RPL) := CPL;\n IF ShadowStackEnabled(CPL)\n IF CHECK_SS_TOKEN == 1\n THEN\n IF NewSSP & 0x07 != 0\n THEN #GP(0); FI;\n (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *)\n IF (NewSSP & ~0x1F) != ((NewSSP – 24) & ~0x1F)\n #GP(0); FI;\n IF ((IA32_EFER.LMA and CS.L) = 0 AND NewSSP[63:32] != 0)\n THEN #GP(0); FI;\n expected_token_value = NewSSP (* busy bit - bit position 0 - must be clear *)\n new_token_value = NewSSP | BUSY_BIT (* Set the busy bit *)\n IF shadow_stack_lock_cmpxchg8b(NewSSP, new_token_value, expected_token_value) != expected_token_value\n THEN #GP(0); FI;\n FI;\n (* Align to next 8 byte boundary *)\n tempSSP = SSP;\n Shadow_stack_store 4 bytes of 0 to (NewSSP − 4)\n SSP = newSSP & 0xFFFFFFFFFFFFFFF8H;\n (* push cs:lip:ssp on shadow stack *)\n ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *)\n ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*)\n ShadowStackPush8B(tempSSP);\n FI;\n IF EndbranchEnabled (CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\n IF IDT gate is interrupt gate\n THEN IF := 0; FI; (* Interrupt flag set to 0; interrupts disabled *)\n TF := 0;\n NT := 0;\n VM := 0;\n RF := 0;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/intn:into:int3:int1" + }, + "invd": { + "instruction": "INVD", + "title": "INVD\n\t\t— Invalidate Internal Caches", + "opcode": "0F 08", + "description": "Invalidates (flushes) the processor’s internal caches and issues a special-function bus cycle that directs external caches to also flush themselves. Data held in internal caches is not written back to main memory.\nAfter executing this instruction, the processor does not wait for the external caches to complete their flushing operation before proceeding with instruction execution. It is the responsibility of hardware to respond to the cache flush signal.\nThe INVD instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a program or procedure must be 0 to execute this instruction.\nThe INVD instruction may be used when the cache is used as temporary memory and the cache contents need to be invalidated rather than written back to memory. When the cache is used as temporary memory, no external device should be actively writing data to main memory.\nUse this instruction with care. Data cached internally and not written back to main memory will be lost. Note that any data from an external device to main memory (for example, via a PCIWrite) can be temporarily stored in the caches; these data can be lost when an INVD instruction is executed. Unless there is a specific requirement or benefit to flushing caches without writing back modified cache lines (for example, temporary memory, testing, or fault recovery where cache coherency with main memory is not a concern), software should instead use the WBINVD instruction.\nOn processors that support processor reserved memory, the INVD instruction cannot be executed when processor reserved memory protections are activated. See Section 36.5, “EPC and Management of EPC Pages,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3D.\nSome processors prevent execution of INVD after BIOS execution is complete. They report this by enumerating CPUID.(EAX=07H,ECX=1H):EAX[bit 30] as 1. On such processors, INVD cannot be executed if bit 0 of SR_BIOS_DONE (MSR address 151H) is 1.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "Flush(InternalCaches);\nSignalFlush(ExternalCaches);\nContinue (* Continue execution *)\n", + "url": "https://www.felixcloutier.com/x86/invd" + }, + "invept": { + "instruction": "INVEPT", + "title": "INVEPT\n\t\t— Invalidate Translations Derived from EPT", + "opcode": "66 0F 38 80 INVEPT r64, m128", + "description": "Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches that were derived from extended page tables (EPT). (See Chapter 29, “VMX Support for Address Translation.”) Invalidation is based on the INVEPT type specified in the register operand and the INVEPT descriptor specified in the memory operand.\nOutside IA-32e mode, the register operand is always 32 bits, regardless of the value of CS.D; in 64-bit mode, the register operand has 64 bits (the instruction cannot be executed in compatibility mode).\nThe INVEPT types supported by a logical processors are reported in the IA32_VMX_EPT_VPID_CAP MSR (see Appendix A, “VMX Capability Reporting Facility”). There are two INVEPT types currently defined:\nIf an unsupported INVEPT type is specified, the instruction fails.\nINVEPT invalidates all the specified mappings for the indicated EPTP(s) regardless of the VPID and PCID values with which those mappings may be associated.\nThe INVEPT descriptor comprises 128 bits and contains a 64-bit EPTP value in bits 63:0 (see Figure 31-1).", + "operation": "IF (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VM exit;\nELSIF CPL > 0\n THEN #GP(0);\n ELSE\n INVEPT_TYPE := value of register operand;\n IF IA32_VMX_EPT_VPID_CAP MSR indicates that processor does not support INVEPT_TYPE\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE // INVEPT_TYPE must be 1 or 2\n INVEPT_DESC := value of memory operand;\n EPTP := INVEPT_DESC[63:0];\n CASE INVEPT_TYPE OF\n 1:\n // single-context invalidation\n IF VM entry with the “enable EPT“ VM execution control set to 1\n would fail due to the EPTP value\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE\n Invalidate mappings associated with EPTP[51:12];\n VMsucceed;\n FI;\n BREAK;\n 2:\n // global invalidation\n Invalidate mappings associated with all EPTPs;\n VMsucceed;\n BREAK;\n ESAC;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/invept" + }, + "invlpg": { + "instruction": "INVLPG", + "title": "INVLPG\n\t\t— Invalidate TLB Entries", + "opcode": "0F 01/7", + "description": "Invalidates any translation lookaside buffer (TLB) entries specified with the source operand. The source operand is a memory address. The processor determines the page that contains that address and flushes all TLB entries for that page.1\nThe INVLPG instruction is a privileged instruction. When the processor is running in protected mode, the CPL must be 0 to execute this instruction.\nThe INVLPG instruction normally flushes TLB entries only for the specified page; however, in some cases, it may flush more entries, even the entire TLB. The instruction invalidates TLB entries associated with the current PCID and may or may not do so for TLB entries associated with other PCIDs. (If PCIDs are disabled — CR4.PCIDE = 0 — the current PCID is 000H.) The instruction also invalidates any global TLB entries for the specified page, regardless of PCID.\nFor more details on operations that flush the TLB, see “MOV—Move to/from Control Registers” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, and Section 4.10.4.1, “Operations that Invalidate TLBs and Paging-Structure Caches,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nThis instruction’s operation is the same in all non-64-bit modes. It also operates the same in 64-bit mode, except if the memory address is in non-canonical form. In this case, INVLPG is the same as a NOP.", + "operation": "Invalidate(RelevantTLBEntries);\nContinue; (* Continue execution *)\n", + "url": "https://www.felixcloutier.com/x86/invlpg" + }, + "invpcid": { + "instruction": "INVPCID", + "title": "INVPCID\n\t\t— Invalidate Process-Context Identifier", + "opcode": "66 0F 38 82 /r INVPCID r32, m128", + "description": "Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches based on process-context identifier (PCID). (See Section 4.10, “Caching Translation Information,” in the Intel 64 and IA-32 Architecture Software Developer’s Manual, Volume 3A.) Invalidation is based on the INVPCID type specified in the register operand and the INVPCID descriptor specified in the memory operand.\nOutside 64-bit mode, the register operand is always 32 bits, regardless of the value of CS.D. In 64-bit mode the register operand has 64 bits.\nThere are four INVPCID types currently defined:\nThe INVPCID descriptor comprises 128 bits and consists of a PCID and a linear address as shown in Figure 3-25. For INVPCID type 0, the processor uses the full 64 bits of the linear address even outside 64-bit mode; the linear address is not used for other INVPCID types.\nIf CR4.PCIDE = 0, a logical processor does not cache information for any PCID other than 000H. In this case, executions with INVPCID types 0 and 1 are allowed only if the PCID specified in the INVPCID descriptor is 000H; executions with INVPCID types 2 and 3 invalidate mappings only for PCID 000H. Note that CR4.PCIDE must be 0 outside IA-32e mode (see Section 4.10.1, “Process-Context Identifiers (PCIDs),” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A).", + "operation": "INVPCID_TYPE := value of register operand; // must be in the range of 0–3\nINVPCID_DESC := value of memory operand;\nCASE INVPCID_TYPE OF\n 0:\n // individual-address invalidation\n PCID := INVPCID_DESC[11:0];\n L_ADDR := INVPCID_DESC[127:64];\n Invalidate mappings for L_ADDR associated with PCID except global translations;\n BREAK;\n 1:\n // single PCID invalidation\n PCID := INVPCID_DESC[11:0];\n Invalidate all mappings associated with PCID except global translations;\n BREAK;\n 2:\n // all PCID invalidation including global translations\n Invalidate all mappings for all PCIDs, including global translations;\n BREAK;\n 3:\n // all PCID invalidation retaining global translations\n Invalidate all mappings for all PCIDs except global translations;\n BREAK;\nESAC;\n", + "url": "https://www.felixcloutier.com/x86/invpcid" + }, + "invvpid": { + "instruction": "INVVPID", + "title": "INVVPID\n\t\t— Invalidate Translations Based on VPID", + "opcode": "66 0F 38 81 INVVPID r64, m128", + "description": "Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches based on virtualprocessor identifier (VPID). (See Chapter 29, “VMX Support for Address Translation.”) Invalidation is based on the INVVPID type specified in the register operand and the INVVPID descriptor specified in the memory operand.\nOutside IA-32e mode, the register operand is always 32 bits, regardless of the value of CS.D; in 64-bit mode, the register operand has 64 bits (the instruction cannot be executed in compatibility mode).\nThe INVVPID types supported by a logical processors are reported in the IA32_VMX_EPT_VPID_CAP MSR (see Appendix A, “VMX Capability Reporting Facility”). There are four INVVPID types currently defined:\nIf an unsupported INVVPID type is specified, the instruction fails.\nINVVPID invalidates all the specified mappings for the indicated VPID(s) regardless of the EPTP and PCID values with which those mappings may be associated.\nThe INVVPID descriptor comprises 128 bits and consists of a VPID and a linear address as shown in Figure 31-2.", + "operation": "IF (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VM exit;\nELSIF CPL > 0\n THEN #GP(0);\n ELSE\n INVVPID_TYPE := value of register operand;\n IF IA32_VMX_EPT_VPID_CAP MSR indicates that processor does not support\n INVVPID_TYPE\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE // INVVPID_TYPE must be in the range 0–3\n INVVPID_DESC := value of memory operand;\n IF INVVPID_DESC[63:16] ≠ 0\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE\n CASE INVVPID_TYPE OF\n 0:\n // individual-address invalidation\n VPID := INVVPID_DESC[15:0];\n IF VPID = 0\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE\n GL_ADDR := INVVPID_DESC[127:64];\n IF (GL_ADDR is not in a canonical form)\n THEN\n VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE\n Invalidate mappings for GL_ADDR tagged with VPID;\n VMsucceed;\n FI;\n FI;\n BREAK;\n 1:\n // single-context invalidation\n VPID := INVVPID_DESC[15:0];\n IF VPID = 0\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE\n Invalidate all mappings tagged with VPID;\n VMsucceed;\n FI;\n BREAK;\n 2:\n // all-context invalidation\n Invalidate all mappings tagged with all non-zero VPIDs;\n VMsucceed;\n BREAK;\n 3:\n // single-context invalidation retaining globals\n VPID := INVVPID_DESC[15:0];\n IF VPID = 0\n THEN VMfail(Invalid operand to INVEPT/INVVPID);\n ELSE\n Invalidate all mappings tagged with VPID except global translations;\n VMsucceed;\n FI;\n BREAK;\n ESAC;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/invvpid" + }, + "iret": { + "instruction": "IRET", + "title": "IRET/IRETD/IRETQ\n\t\t— Interrupt Return", + "opcode": "CF", + "description": "Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or when an interrupt or exception causes a task switch to an interrupt or exception handler.) See the section titled “Task Linking” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nIRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the IRET mnemonic interchangeably for both operand sizes.\nIn Real-Address Mode, the IRET instruction performs a far return to the interrupted program or procedure. During this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure.\nIn Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting of these flags, the processor performs the following types of interrupt returns:\nIf the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch. The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack).\nAs with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the data segment registers from the stack.\nIf the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a CALL instruction, an interrupt, or an exception) back to the calling or interrupted task. The updated state of the task executing the IRET instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET instruction is executed.\nIf the NT flag is set and the processor is in IA-32e mode, the IRET instruction causes a general protection exception.\nIf nonmaskable interrupts (NMIs) are blocked (see Section 6.7.1, “Handling Multiple NMIs” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A), execution of the IRET instruction unblocks NMIs.\nThis unblocking occurs even if the instruction causes a fault. In such a case, NMIs are unmasked before the exception handler is invoked.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.W prefix promotes operation to 64 bits (IRETQ). See the summary chart at the beginning of this section for encoding data and limits.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. IRET is a serializing instruction. See Section 9.3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "IF PE = 0\n THEN GOTO REAL-ADDRESS-MODE;\nELSIF (IA32_EFER.LMA = 0)\n THEN\n IF (EFLAGS.VM = 1)\n THEN GOTO RETURN-FROM-VIRTUAL-8086-MODE;\n ELSE GOTO PROTECTED-MODE;\n FI;\n ELSE GOTO IA-32e-MODE;\nFI;\nREAL-ADDRESS-MODE;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n tempEFLAGS := Pop();\n EFLAGS := (tempEFLAGS AND 257FD5H) OR (EFLAGS AND 1A0000H);\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)\n CS := Pop(); (* 16-bit pop *)\n EFLAGS[15:0] := Pop();\n FI;\n END;\nRETURN-FROM-VIRTUAL-8086-MODE:\n(* Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode *)\n IF IOPL = 3 (* Virtual mode: PE = 1, VM = 1, IOPL = 3 *)\n THEN IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n EFLAGS := Pop();\n (* VM, IOPL,VIP and VIF EFLAG bits not modified by pop *)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)\n CS := Pop(); (* 16-bit pop *)\n EFLAGS[15:0] := Pop(); (* IOPL in EFLAGS not modified by pop *)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n FI;\n ELSE\n #GP(0); (* Trap to virtual-8086 monitor: PE = 1, VM = 1, IOPL < 3 *)\n FI;\nEND;\nPROTECTED-MODE:\n IF NT = 1\n THEN GOTO TASK-RETURN; (* PE = 1, VM = 0, NT = 1 *)\n FI;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n tempEFLAGS := Pop();\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper bits *)\n CS := Pop(); (* 16-bit pop *)\n tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)\n FI;\n IF tempEFLAGS(VM) = 1 and CPL = 0\n THEN GOTO RETURN-TO-VIRTUAL-8086-MODE;\n ELSE GOTO PROTECTED-MODE-RETURN;\n FI;\nTASK-RETURN:(*PE=1,VM =0,NT =1*)\n SWITCH-TASKS (without nesting) to TSS specified in link field of current TSS;\n Mark the task just abandoned as NOT BUSY;\n IF EIP is not within CS limit\n THEN #GP(0); FI;\nEND;\nRETURN-TO-VIRTUAL-8086-MODE:\n (* Interrupted procedure was in virtual-8086 mode: PE = 1, CPL=0, VM = 1 in flag image *)\n (* If shadow stack or indirect branch tracking at CPL3 then #GP(0) *)\n IF CR4.CET AND (IA32_U_CET.ENDBR_EN OR IA32_U_CET.SHSTK_EN)\n THEN #GP(0); FI;\n shadowStackEnabled = ShadowStackEnabled(CPL)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n EFLAGS := tempEFLAGS;\n ESP := Pop();\n SS := Pop(); (* Pop 2 words; throw away high-order word *)\n ES := Pop(); (* Pop 2 words; throw away high-order word *)\n DS := Pop(); (* Pop 2 words; throw away high-order word *)\n FS := Pop(); (* Pop 2 words; throw away high-order word *)\n GS := Pop(); (* Pop 2 words; throw away high-order word *)\n IF shadowStackEnabled\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n CPL := 3;\n (* Resume execution in Virtual-8086 mode *)\n tempOldSSP = SSP;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF shadowStackEnabled\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\nEND;\nPROTECTED-MODE-RETURN: (* PE = 1 *)\n IF CS(RPL) > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;\nEND;\nRETURN-TO-OUTER-PRIVILEGE-LEVEL:\n IF OperandSize = 32\n THEN\n tempESP := Pop();\n tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE IF OperandSize = 16\n THEN\n tempESP := Pop(); (* 16-bit pop; clear upper bits *)\n tempSS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n tempRSP := Pop();\n tempSS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\n IF new mode ≠ 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;\n IF CPL ≤ IOPL\n THEN EFLAGS(IF) := tempEFLAGS; FI;\n IF CPL = 0\n THEN\n EFLAGS(IOPL) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;\n FI;\n IF ShadowStackEnabled(CPL)\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n IF CS(RPL) != 3\n THEN\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n (* Do 64 bit compare to detect bits beyond 15 being set *)\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS\n THEN #CP(FAR-RET/IRET); FI;\n (* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)\n IF CSBASE + RIP != tempSsEIP\n THEN #CP(FAR-RET/IRET); FI;\n (* check if 4 byte aligned *)\n IF tempSSP AND 0x3 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n FI;\n tempOldCPL = CPL;\n CPL := CS(RPL);\n IF OperandSize = 64\n THEN\n RSP := tempRSP;\n SS := tempSS;\n ELSE\n ESP := tempESP;\n SS := tempSS;\n FI;\n IF new mode != 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n tempOldSSP = SSP;\n IF ShadowStackEnabled(CPL)\n IF CPL = 3\n THEN tempSSP := IA32_PL3_SSP; FI;\n IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR\n ((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n SSP := tempSSP\n FI;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF ShadowStackEnabled(tempOldCPL)\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\n FOR each SegReg in (ES, FS, GS, and DS)\n DO\n tempDesc := descriptor cache for SegReg (* hidden part of segment register *)\n IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))\n THEN (* Segment register invalid *)\n SegmentSelector := 0; (*Segment selector becomes null*)\n FI;\n OD;\nEND;\nRETURN-TO-SAME-PRIVILEGE-LEVEL: (* PE = 1, RPL = CPL *)\n IF new mode ≠ 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;\n IF CPL ≤ IOPL\n THEN EFLAGS(IF) := tempEFLAGS; FI;\n IF CPL = 0\n THEN\n EFLAGS(IOPL) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)\n THEN #CP(FAR-RET/IRET); FI;\n IF CSBASE + RIP != tempSsLIP (* 64 bit compare; CSBASE+RIP zero padded to 64 bit for 32 bit LIP *)\n THEN #CP(FAR-RET/IRET); FI;\n IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR\n ((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF IA32_EFER.LMA = 1\n (* In IA-32e-mode the IRET may be switching stacks if the interrupt/exception was delivered\n through an IDT with a non-zero IST *)\n (* In IA-32e mode for same CPL IRET there is always a stack switch. The below check verifies if the\n stack switch was to self stack and if so, do not try to free the token on this shadow stack. If the\n tempSSP was not to same stack then there was a stack switch so do attempt to free the token *)\n IF tempSSP != SSP\n THEN\n expected_token_value = SSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = SSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value)\n FI;\n FI;\n SSP := tempSSP\n FI;\nEND;\nIA-32e-MODE:\n IF NT = 1\n THEN #GP(0);\n ELSE IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop();\n tempEFLAGS := Pop();\n ELSE IF OperandSize = 16\n THEN\n EIP := Pop(); (* 16-bit pop; clear upper bits *)\n CS := Pop(); (* 16-bit pop *)\n tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)\n FI;\n ELSE (* OperandSize = 64 *)\n THEN\n RIP := Pop();\n CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n tempRFLAGS := Pop();\n FI;\n IF CS.RPL > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE\n IF instruction began in 64-Bit Mode\n THEN\n IF OperandSize = 32\n THEN\n ESP := Pop();\n SS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE IF OperandSize = 16\n THEN\n ESP := Pop(); (* 16-bit pop; clear upper bits *)\n SS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n RSP := Pop();\n SS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\n FI;\n GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/iret:iretd:iretq" + }, + "iretd": { + "instruction": "IRETD", + "title": "IRET/IRETD/IRETQ\n\t\t— Interrupt Return", + "opcode": "CF", + "description": "Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or when an interrupt or exception causes a task switch to an interrupt or exception handler.) See the section titled “Task Linking” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nIRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the IRET mnemonic interchangeably for both operand sizes.\nIn Real-Address Mode, the IRET instruction performs a far return to the interrupted program or procedure. During this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure.\nIn Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting of these flags, the processor performs the following types of interrupt returns:\nIf the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch. The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack).\nAs with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the data segment registers from the stack.\nIf the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a CALL instruction, an interrupt, or an exception) back to the calling or interrupted task. The updated state of the task executing the IRET instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET instruction is executed.\nIf the NT flag is set and the processor is in IA-32e mode, the IRET instruction causes a general protection exception.\nIf nonmaskable interrupts (NMIs) are blocked (see Section 6.7.1, “Handling Multiple NMIs” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A), execution of the IRET instruction unblocks NMIs.\nThis unblocking occurs even if the instruction causes a fault. In such a case, NMIs are unmasked before the exception handler is invoked.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.W prefix promotes operation to 64 bits (IRETQ). See the summary chart at the beginning of this section for encoding data and limits.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. IRET is a serializing instruction. See Section 9.3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "IF PE = 0\n THEN GOTO REAL-ADDRESS-MODE;\nELSIF (IA32_EFER.LMA = 0)\n THEN\n IF (EFLAGS.VM = 1)\n THEN GOTO RETURN-FROM-VIRTUAL-8086-MODE;\n ELSE GOTO PROTECTED-MODE;\n FI;\n ELSE GOTO IA-32e-MODE;\nFI;\nREAL-ADDRESS-MODE;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n tempEFLAGS := Pop();\n EFLAGS := (tempEFLAGS AND 257FD5H) OR (EFLAGS AND 1A0000H);\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)\n CS := Pop(); (* 16-bit pop *)\n EFLAGS[15:0] := Pop();\n FI;\n END;\nRETURN-FROM-VIRTUAL-8086-MODE:\n(* Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode *)\n IF IOPL = 3 (* Virtual mode: PE = 1, VM = 1, IOPL = 3 *)\n THEN IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n EFLAGS := Pop();\n (* VM, IOPL,VIP and VIF EFLAG bits not modified by pop *)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)\n CS := Pop(); (* 16-bit pop *)\n EFLAGS[15:0] := Pop(); (* IOPL in EFLAGS not modified by pop *)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n FI;\n ELSE\n #GP(0); (* Trap to virtual-8086 monitor: PE = 1, VM = 1, IOPL < 3 *)\n FI;\nEND;\nPROTECTED-MODE:\n IF NT = 1\n THEN GOTO TASK-RETURN; (* PE = 1, VM = 0, NT = 1 *)\n FI;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n tempEFLAGS := Pop();\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper bits *)\n CS := Pop(); (* 16-bit pop *)\n tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)\n FI;\n IF tempEFLAGS(VM) = 1 and CPL = 0\n THEN GOTO RETURN-TO-VIRTUAL-8086-MODE;\n ELSE GOTO PROTECTED-MODE-RETURN;\n FI;\nTASK-RETURN:(*PE=1,VM =0,NT =1*)\n SWITCH-TASKS (without nesting) to TSS specified in link field of current TSS;\n Mark the task just abandoned as NOT BUSY;\n IF EIP is not within CS limit\n THEN #GP(0); FI;\nEND;\nRETURN-TO-VIRTUAL-8086-MODE:\n (* Interrupted procedure was in virtual-8086 mode: PE = 1, CPL=0, VM = 1 in flag image *)\n (* If shadow stack or indirect branch tracking at CPL3 then #GP(0) *)\n IF CR4.CET AND (IA32_U_CET.ENDBR_EN OR IA32_U_CET.SHSTK_EN)\n THEN #GP(0); FI;\n shadowStackEnabled = ShadowStackEnabled(CPL)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n EFLAGS := tempEFLAGS;\n ESP := Pop();\n SS := Pop(); (* Pop 2 words; throw away high-order word *)\n ES := Pop(); (* Pop 2 words; throw away high-order word *)\n DS := Pop(); (* Pop 2 words; throw away high-order word *)\n FS := Pop(); (* Pop 2 words; throw away high-order word *)\n GS := Pop(); (* Pop 2 words; throw away high-order word *)\n IF shadowStackEnabled\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n CPL := 3;\n (* Resume execution in Virtual-8086 mode *)\n tempOldSSP = SSP;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF shadowStackEnabled\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\nEND;\nPROTECTED-MODE-RETURN: (* PE = 1 *)\n IF CS(RPL) > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;\nEND;\nRETURN-TO-OUTER-PRIVILEGE-LEVEL:\n IF OperandSize = 32\n THEN\n tempESP := Pop();\n tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE IF OperandSize = 16\n THEN\n tempESP := Pop(); (* 16-bit pop; clear upper bits *)\n tempSS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n tempRSP := Pop();\n tempSS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\n IF new mode ≠ 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;\n IF CPL ≤ IOPL\n THEN EFLAGS(IF) := tempEFLAGS; FI;\n IF CPL = 0\n THEN\n EFLAGS(IOPL) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;\n FI;\n IF ShadowStackEnabled(CPL)\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n IF CS(RPL) != 3\n THEN\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n (* Do 64 bit compare to detect bits beyond 15 being set *)\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS\n THEN #CP(FAR-RET/IRET); FI;\n (* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)\n IF CSBASE + RIP != tempSsEIP\n THEN #CP(FAR-RET/IRET); FI;\n (* check if 4 byte aligned *)\n IF tempSSP AND 0x3 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n FI;\n tempOldCPL = CPL;\n CPL := CS(RPL);\n IF OperandSize = 64\n THEN\n RSP := tempRSP;\n SS := tempSS;\n ELSE\n ESP := tempESP;\n SS := tempSS;\n FI;\n IF new mode != 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n tempOldSSP = SSP;\n IF ShadowStackEnabled(CPL)\n IF CPL = 3\n THEN tempSSP := IA32_PL3_SSP; FI;\n IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR\n ((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n SSP := tempSSP\n FI;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF ShadowStackEnabled(tempOldCPL)\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\n FOR each SegReg in (ES, FS, GS, and DS)\n DO\n tempDesc := descriptor cache for SegReg (* hidden part of segment register *)\n IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))\n THEN (* Segment register invalid *)\n SegmentSelector := 0; (*Segment selector becomes null*)\n FI;\n OD;\nEND;\nRETURN-TO-SAME-PRIVILEGE-LEVEL: (* PE = 1, RPL = CPL *)\n IF new mode ≠ 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;\n IF CPL ≤ IOPL\n THEN EFLAGS(IF) := tempEFLAGS; FI;\n IF CPL = 0\n THEN\n EFLAGS(IOPL) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)\n THEN #CP(FAR-RET/IRET); FI;\n IF CSBASE + RIP != tempSsLIP (* 64 bit compare; CSBASE+RIP zero padded to 64 bit for 32 bit LIP *)\n THEN #CP(FAR-RET/IRET); FI;\n IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR\n ((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF IA32_EFER.LMA = 1\n (* In IA-32e-mode the IRET may be switching stacks if the interrupt/exception was delivered\n through an IDT with a non-zero IST *)\n (* In IA-32e mode for same CPL IRET there is always a stack switch. The below check verifies if the\n stack switch was to self stack and if so, do not try to free the token on this shadow stack. If the\n tempSSP was not to same stack then there was a stack switch so do attempt to free the token *)\n IF tempSSP != SSP\n THEN\n expected_token_value = SSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = SSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value)\n FI;\n FI;\n SSP := tempSSP\n FI;\nEND;\nIA-32e-MODE:\n IF NT = 1\n THEN #GP(0);\n ELSE IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop();\n tempEFLAGS := Pop();\n ELSE IF OperandSize = 16\n THEN\n EIP := Pop(); (* 16-bit pop; clear upper bits *)\n CS := Pop(); (* 16-bit pop *)\n tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)\n FI;\n ELSE (* OperandSize = 64 *)\n THEN\n RIP := Pop();\n CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n tempRFLAGS := Pop();\n FI;\n IF CS.RPL > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE\n IF instruction began in 64-Bit Mode\n THEN\n IF OperandSize = 32\n THEN\n ESP := Pop();\n SS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE IF OperandSize = 16\n THEN\n ESP := Pop(); (* 16-bit pop; clear upper bits *)\n SS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n RSP := Pop();\n SS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\n FI;\n GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/iret:iretd:iretq" + }, + "iretq": { + "instruction": "IRETQ", + "title": "IRET/IRETD/IRETQ\n\t\t— Interrupt Return", + "opcode": "REX.W + CF", + "description": "Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or when an interrupt or exception causes a task switch to an interrupt or exception handler.) See the section titled “Task Linking” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nIRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the IRET mnemonic interchangeably for both operand sizes.\nIn Real-Address Mode, the IRET instruction performs a far return to the interrupted program or procedure. During this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure.\nIn Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting of these flags, the processor performs the following types of interrupt returns:\nIf the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch. The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack).\nAs with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the data segment registers from the stack.\nIf the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a CALL instruction, an interrupt, or an exception) back to the calling or interrupted task. The updated state of the task executing the IRET instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET instruction is executed.\nIf the NT flag is set and the processor is in IA-32e mode, the IRET instruction causes a general protection exception.\nIf nonmaskable interrupts (NMIs) are blocked (see Section 6.7.1, “Handling Multiple NMIs” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A), execution of the IRET instruction unblocks NMIs.\nThis unblocking occurs even if the instruction causes a fault. In such a case, NMIs are unmasked before the exception handler is invoked.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.W prefix promotes operation to 64 bits (IRETQ). See the summary chart at the beginning of this section for encoding data and limits.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. IRET is a serializing instruction. See Section 9.3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "IF PE = 0\n THEN GOTO REAL-ADDRESS-MODE;\nELSIF (IA32_EFER.LMA = 0)\n THEN\n IF (EFLAGS.VM = 1)\n THEN GOTO RETURN-FROM-VIRTUAL-8086-MODE;\n ELSE GOTO PROTECTED-MODE;\n FI;\n ELSE GOTO IA-32e-MODE;\nFI;\nREAL-ADDRESS-MODE;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n tempEFLAGS := Pop();\n EFLAGS := (tempEFLAGS AND 257FD5H) OR (EFLAGS AND 1A0000H);\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)\n CS := Pop(); (* 16-bit pop *)\n EFLAGS[15:0] := Pop();\n FI;\n END;\nRETURN-FROM-VIRTUAL-8086-MODE:\n(* Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode *)\n IF IOPL = 3 (* Virtual mode: PE = 1, VM = 1, IOPL = 3 *)\n THEN IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n EFLAGS := Pop();\n (* VM, IOPL,VIP and VIF EFLAG bits not modified by pop *)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)\n CS := Pop(); (* 16-bit pop *)\n EFLAGS[15:0] := Pop(); (* IOPL in EFLAGS not modified by pop *)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n FI;\n ELSE\n #GP(0); (* Trap to virtual-8086 monitor: PE = 1, VM = 1, IOPL < 3 *)\n FI;\nEND;\nPROTECTED-MODE:\n IF NT = 1\n THEN GOTO TASK-RETURN; (* PE = 1, VM = 0, NT = 1 *)\n FI;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n tempEFLAGS := Pop();\n ELSE (* OperandSize = 16 *)\n EIP := Pop(); (* 16-bit pop; clear upper bits *)\n CS := Pop(); (* 16-bit pop *)\n tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)\n FI;\n IF tempEFLAGS(VM) = 1 and CPL = 0\n THEN GOTO RETURN-TO-VIRTUAL-8086-MODE;\n ELSE GOTO PROTECTED-MODE-RETURN;\n FI;\nTASK-RETURN:(*PE=1,VM =0,NT =1*)\n SWITCH-TASKS (without nesting) to TSS specified in link field of current TSS;\n Mark the task just abandoned as NOT BUSY;\n IF EIP is not within CS limit\n THEN #GP(0); FI;\nEND;\nRETURN-TO-VIRTUAL-8086-MODE:\n (* Interrupted procedure was in virtual-8086 mode: PE = 1, CPL=0, VM = 1 in flag image *)\n (* If shadow stack or indirect branch tracking at CPL3 then #GP(0) *)\n IF CR4.CET AND (IA32_U_CET.ENDBR_EN OR IA32_U_CET.SHSTK_EN)\n THEN #GP(0); FI;\n shadowStackEnabled = ShadowStackEnabled(CPL)\n IF EIP not within CS limit\n THEN #GP(0); FI;\n EFLAGS := tempEFLAGS;\n ESP := Pop();\n SS := Pop(); (* Pop 2 words; throw away high-order word *)\n ES := Pop(); (* Pop 2 words; throw away high-order word *)\n DS := Pop(); (* Pop 2 words; throw away high-order word *)\n FS := Pop(); (* Pop 2 words; throw away high-order word *)\n GS := Pop(); (* Pop 2 words; throw away high-order word *)\n IF shadowStackEnabled\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n CPL := 3;\n (* Resume execution in Virtual-8086 mode *)\n tempOldSSP = SSP;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF shadowStackEnabled\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\nEND;\nPROTECTED-MODE-RETURN: (* PE = 1 *)\n IF CS(RPL) > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;\nEND;\nRETURN-TO-OUTER-PRIVILEGE-LEVEL:\n IF OperandSize = 32\n THEN\n tempESP := Pop();\n tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE IF OperandSize = 16\n THEN\n tempESP := Pop(); (* 16-bit pop; clear upper bits *)\n tempSS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n tempRSP := Pop();\n tempSS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\n IF new mode ≠ 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;\n IF CPL ≤ IOPL\n THEN EFLAGS(IF) := tempEFLAGS; FI;\n IF CPL = 0\n THEN\n EFLAGS(IOPL) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;\n FI;\n IF ShadowStackEnabled(CPL)\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n IF CS(RPL) != 3\n THEN\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n (* Do 64 bit compare to detect bits beyond 15 being set *)\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS\n THEN #CP(FAR-RET/IRET); FI;\n (* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)\n IF CSBASE + RIP != tempSsEIP\n THEN #CP(FAR-RET/IRET); FI;\n (* check if 4 byte aligned *)\n IF tempSSP AND 0x3 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n FI;\n tempOldCPL = CPL;\n CPL := CS(RPL);\n IF OperandSize = 64\n THEN\n RSP := tempRSP;\n SS := tempSS;\n ELSE\n ESP := tempESP;\n SS := tempSS;\n FI;\n IF new mode != 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n tempOldSSP = SSP;\n IF ShadowStackEnabled(CPL)\n IF CPL = 3\n THEN tempSSP := IA32_PL3_SSP; FI;\n IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR\n ((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n SSP := tempSSP\n FI;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF ShadowStackEnabled(tempOldCPL)\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\n FOR each SegReg in (ES, FS, GS, and DS)\n DO\n tempDesc := descriptor cache for SegReg (* hidden part of segment register *)\n IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))\n THEN (* Segment register invalid *)\n SegmentSelector := 0; (*Segment selector becomes null*)\n FI;\n OD;\nEND;\nRETURN-TO-SAME-PRIVILEGE-LEVEL: (* PE = 1, RPL = CPL *)\n IF new mode ≠ 64-Bit Mode\n THEN\n IF EIP is not within CS limit\n THEN #GP(0); FI;\n ELSE (* new mode = 64-bit mode *)\n IF RIP is non-canonical\n THEN #GP(0); FI;\n FI;\n EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;\n IF CPL ≤ IOPL\n THEN EFLAGS(IF) := tempEFLAGS; FI;\n IF CPL = 0\n THEN\n EFLAGS(IOPL) := tempEFLAGS;\n IF OperandSize = 32 or OperandSize = 64\n THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)\n THEN #CP(FAR-RET/IRET); FI;\n IF CSBASE + RIP != tempSsLIP (* 64 bit compare; CSBASE+RIP zero padded to 64 bit for 32 bit LIP *)\n THEN #CP(FAR-RET/IRET); FI;\n IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR\n ((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n FI;\n IF ShadowStackEnabled(CPL)\n IF IA32_EFER.LMA = 1\n (* In IA-32e-mode the IRET may be switching stacks if the interrupt/exception was delivered\n through an IDT with a non-zero IST *)\n (* In IA-32e mode for same CPL IRET there is always a stack switch. The below check verifies if the\n stack switch was to self stack and if so, do not try to free the token on this shadow stack. If the\n tempSSP was not to same stack then there was a stack switch so do attempt to free the token *)\n IF tempSSP != SSP\n THEN\n expected_token_value = SSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = SSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value)\n FI;\n FI;\n SSP := tempSSP\n FI;\nEND;\nIA-32e-MODE:\n IF NT = 1\n THEN #GP(0);\n ELSE IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop();\n tempEFLAGS := Pop();\n ELSE IF OperandSize = 16\n THEN\n EIP := Pop(); (* 16-bit pop; clear upper bits *)\n CS := Pop(); (* 16-bit pop *)\n tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)\n FI;\n ELSE (* OperandSize = 64 *)\n THEN\n RIP := Pop();\n CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n tempRFLAGS := Pop();\n FI;\n IF CS.RPL > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE\n IF instruction began in 64-Bit Mode\n THEN\n IF OperandSize = 32\n THEN\n ESP := Pop();\n SS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE IF OperandSize = 16\n THEN\n ESP := Pop(); (* 16-bit pop; clear upper bits *)\n SS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n RSP := Pop();\n SS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\n FI;\n GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/iret:iretd:iretq" + }, + "jcc": { + "instruction": "JCC", + "title": "Jcc\n\t\t— Jump if Condition Is Met", + "opcode": "77 cb", + "description": "Checks the state of one or more of the status flags in the EFLAGS register (CF, OF, PF, SF, and ZF) and, if the flags are in the specified state (condition), performs a jump to the target instruction specified by the destination operand. A condition code (cc) is associated with each instruction to indicate the condition being tested for. If the condition is not satisfied, the jump is not performed and execution continues with the instruction following the Jcc instruction.\nThe target instruction is specified with a relative offset (a signed offset relative to the current value of the instruction pointer in the EIP register). A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code level, it is encoded as a signed, 8-bit or 32-bit immediate value, which is added to the instruction pointer. Instruction coding is most efficient for offsets of –128 to +127. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits.\nThe conditions for each Jcc mnemonic are given in the “Description” column of the table on the preceding page. The terms “less” and “greater” are used for comparisons of signed integers and the terms “above” and “below” are used for unsigned integers.\nBecause a particular state of the status flags can sometimes be interpreted in two ways, two mnemonics are defined for some opcodes. For example, the JA (jump if above) instruction and the JNBE (jump if not below or equal) instruction are alternate mnemonics for the opcode 77H.\nThe Jcc instruction does not support far jumps (jumps to other code segments). When the target for the conditional jump is in a different segment, use the opposite condition from the condition being tested for the Jcc instruction, and then access the target with an unconditional far jump (JMP instruction) to the other segment. For example, the following conditional far jump is illegal:\nJZ FARLABEL;\nTo accomplish this far jump, use the following two instructions:\nJNZ BEYOND;\nJMP FARLABEL;\nBEYOND:\nThe JRCXZ, JECXZ, and JCXZ instructions differ from other Jcc instructions because they do not check status flags. Instead, they check RCX, ECX or CX for 0. The register checked is determined by the address-size attribute. These instructions are useful when used at the beginning of a loop that terminates with a conditional loop instruction (such as LOOPNE). They can be used to prevent an instruction sequence from entering a loop when RCX, ECX or CX is 0. This would cause the loop to execute 264, 232 or 64K times (not zero times).\nAll conditional jumps are converted to code fetches of one or two cache lines, regardless of jump address or cache-ability.\nIn 64-bit mode, operand size is fixed at 64 bits. JMP Short is RIP = RIP + 8-bit offset sign extended to 64 bits. JMP Near is RIP = RIP + 32-bit offset sign extended to 64 bits.", + "operation": "IF condition\n THEN\n tempEIP := EIP + SignExtend(DEST);\n IF OperandSize = 16\n THEN tempEIP := tempEIP AND 0000FFFFH;\n FI;\n IF tempEIP is not within code segment limit\n THEN #GP(0);\n ELSE EIP := tempEIP\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/jcc" + }, + "jmp": { + "instruction": "JMP", + "title": "JMP\n\t\t— Jump", + "opcode": "EB cb", + "description": "Transfers program control to a different point in the instruction stream without recording return information. The destination (target) operand specifies the address of the instruction being jumped to. This operand can be an immediate value, a general-purpose register, or a memory location.\nThis instruction can be used to execute four different types of jumps:\nA task switch can only be executed in protected mode (see Chapter 8, in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for information on performing task switches with the JMP instruction).\nNear and Short Jumps. When executing a near jump, the processor jumps to the address (within the current code segment) that is specified with the target operand. The target operand specifies either an absolute offset (that is an offset from the base of the code segment) or a relative offset (a signed displacement relative to the current\nvalue of the instruction pointer in the EIP register). A near jump to a relative offset of 8-bits (rel8) is referred to as a short jump. The CS register is not changed on near and short jumps.\nAn absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16 or r/m32). The operand-size attribute determines the size of the target operand (16 or 32 bits). Absolute offsets are loaded directly into the EIP register. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits.\nA relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code level, it is encoded as a signed 8-, 16-, or 32-bit immediate value. This value is added to the value in the EIP register. (Here, the EIP register contains the address of the instruction following the JMP instruction). When using relative offsets, the opcode (for short vs. near jumps) and the operand-size attribute (for near relative jumps) determines the size of the target operand (8, 16, or 32 bits).\nFar Jumps in Real-Address or Virtual-8086 Mode. When executing a far jump in real-address or virtual-8086 mode, the processor jumps to the code segment and offset specified with the target operand. Here the target operand specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). With the pointer method, the segment and address of the called procedure is encoded in the instruction, using a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address immediate. With the indirect method, the target operand specifies a memory location that contains a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address. The far address is loaded directly into the CS and EIP registers. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.\nFar Jumps in Protected Mode. When the processor is operating in protected mode, the JMP instruction can be used to perform the following three types of far jumps:\n(The JMP instruction cannot be used to perform inter-privilege-level far jumps.)\nIn protected mode, the processor always uses the segment selector part of the far address to access the corresponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access rights determine the type of jump to be performed.\nIf the selected descriptor is for a code segment, a far jump to a code segment at the same privilege level is performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming, a general-protection exception is generated.) A far jump to the same privilege level in protected mode is very similar to one carried out in real-address or virtual-8086 mode. The target operand specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment selector and its descriptor are loaded into CS register, and the offset from the instruction is loaded into the EIP register. Note that a call gate (described in the next paragraph) can also be used to perform far call to a code segment at the same privilege level. Using this mechanism provides an extra level of indirection and is the preferred method of making jumps between 16-bit and 32-bit code segments.\nWhen executing a far jump through a call gate, the segment selector specified by the target operand identifies the call gate. (The offset part of the target operand is ignored.) The processor then jumps to the code segment specified in the call gate descriptor and begins executing the instruction at the offset specified in the call gate. No stack switch occurs. Here again, the target operand can specify the far address of the call gate either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32).\nExecuting a task switch with the JMP instruction is somewhat similar to executing a jump through a call gate. Here the target operand specifies the segment selector of the task gate for the task being switched to (and the offset part of the target operand is ignored). The task gate in turn points to the TSS for the task, which contains the segment selectors for the task’s code and stack segments. The TSS also contains the EIP value for the next instruction that was to be executed before the task was suspended. This instruction pointer value is loaded into the EIP register so that the task begins executing again at this next instruction.\nThe JMP instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of the task gate. See Chapter 8 in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for detailed information on the mechanics of a task switch.\nNote that when you execute at task switch with a JMP instruction, the nested task flag (NT) is not set in the EFLAGS register and the new TSS’s previous task link field is not loaded with the old task’s TSS selector. A return to the previous task can thus not be carried out by executing the IRET instruction. Switching tasks with the JMP instruction differs in this regard from the CALL instruction which does set the NT flag and save the previous task link information, allowing a return to the calling task with an IRET instruction.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-flow Enforcement Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nIn 64-Bit Mode. The instruction’s operation size is fixed at 64 bits. If a selector points to a gate, then RIP equals the 64-bit displacement taken from gate; else RIP equals the zero-extended offset from the far pointer referenced in the instruction.\nSee the summary chart at the beginning of this section for encoding data and limits.\nInstruction ordering. Instructions following a far jump may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the far jump have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).\nInstructions sequentially following a near indirect JMP instruction (i.e., those not at the target) may be executed speculatively. If software needs to prevent this (e.g., in order to prevent a speculative execution side channel), then an INT3 or LFENCE instruction opcode can be placed after the near indirect JMP in order to block speculative execution.", + "operation": "IF near jump\n IF 64-bit Mode\n THEN\n IF near relative jump\n THEN\n tempRIP := RIP + DEST; (* RIP is instruction following JMP instruction*)\n ELSE (* Near absolute jump *)\n tempRIP := DEST;\n FI;\n ELSE\n IF near relative jump\n THEN\n tempEIP := EIP + DEST; (* EIP is instruction following JMP instruction*)\n ELSE (* Near absolute jump *)\n tempEIP := DEST;\n FI;\n FI;\n IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode)\n and tempEIP outside code segment limit\n THEN #GP(0); FI\n IF 64-bit mode and tempRIP is not canonical\n THEN #GP(0);\n FI;\n IF OperandSize = 32\n THEN\n EIP := tempEIP;\n ELSE\n IF OperandSize = 16\n THEN (* OperandSize = 16 *)\n EIP := tempEIP AND 0000FFFFH;\n ELSE (* OperandSize = 64)\n RIP := tempRIP;\n FI;\n FI;\n IF (JMP near indirect, absolute indirect)\n IF EndbranchEnabledAndNotSuppressed(CPL)\n IF CPL = 3\n THEN\n IF ( no 3EH prefix OR IA32_U_CET.NO_TRACK_EN == 0 )\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n FI;\n ELSE\n IF ( no 3EH prefix OR IA32_S_CET.NO_TRACK_EN == 0 )\n THEN\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n FI;\n FI;\n FI;\n FI;\nFI;\nIF far jump and (PE = 0 or (PE = 1 AND VM = 1)) (* Real-address or virtual-8086 mode *)\n THEN\n tempEIP := DEST(Offset); (* DEST is ptr16:32 or [m16:32] *)\n IF tempEIP is beyond code segment limit\n THEN #GP(0); FI;\n CS := DEST(segment selector); (* DEST is ptr16:32 or [m16:32] *)\n IF OperandSize = 32\n THEN\n EIP := tempEIP; (* DEST is ptr16:32 or [m16:32] *)\n ELSE (* OperandSize = 16 *)\n EIP := tempEIP AND 0000FFFFH; (* Clear upper 16 bits *)\n FI;\nFI;\nIF far jump and (PE = 1 and VM = 0)\n(* IA-32e mode or protected mode, not virtual-8086 mode *)\n THEN\n IF effective address in the CS, DS, ES, FS, GS, or SS segment is illegal\n or segment selector in target operand NULL\n THEN #GP(0); FI;\n IF segment selector index not within descriptor table limits\n THEN #GP(new selector); FI;\n Read type and access rights of segment descriptor;\n IF (IA32_EFER.LMA = 0)\n THEN\n IF segment type is not a conforming or nonconforming code\n segment, call gate, task gate, or TSS\n THEN #GP(segment selector); FI;\n ELSE\n IF segment type is not a conforming or nonconforming code segment\n call gate\n THEN #GP(segment selector); FI;\n FI;\n Depending on type and access rights:\n GO TO CONFORMING-CODE-SEGMENT;\n GO TO NONCONFORMING-CODE-SEGMENT;\n GO TO CALL-GATE;\n GO TO TASK-GATE;\n GO TO TASK-STATE-SEGMENT;\n ELSE\n #GP(segment selector);\nFI;\nCONFORMING-CODE-SEGMENT:\n IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1\n THEN GP(new code segment selector); FI;\n IF DPL > CPL\n THEN #GP(segment selector); FI;\n IF segment not present\n THEN #NP(segment selector); FI;\n tempEIP := DEST(Offset);\n IF OperandSize = 16\n THEN tempEIP := tempEIP AND 0000FFFFH;\n FI;\n IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and\n tempEIP outside code segment limit\n THEN #GP(0); FI\n IF tempEIP is non-canonical\n THEN #GP(0); FI;\n IF ShadowStackEnabled(CPL)\n IF (IA32_EFER.LMA and DEST(segment selector).L) = 0\n (* If target is legacy or compatibility mode then the SSP must be in low 4GB *)\n IF (SSP & 0xFFFFFFFF00000000 != 0)\n THEN #GP(0); FI;\n FI;\n FI;\n CS := DEST[segment selector]; (* Segment descriptor information also loaded *)\n CS(RPL) := CPL\n EIP := tempEIP;\n IF EndbranchEnabled(CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\nEND;\nNONCONFORMING-CODE-SEGMENT:\n IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1\n THEN GP(new code segment selector); FI;\n IF (RPL > CPL) OR (DPL ≠ CPL)\n THEN #GP(code segment selector); FI;\n IF segment not present\n THEN #NP(segment selector); FI;\n tempEIP := DEST(Offset);\n IF OperandSize = 16\n THEN tempEIP := tempEIP AND 0000FFFFH; FI;\n IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode)\n and tempEIP outside code segment limit\n THEN #GP(0); FI\n IF tempEIP is non-canonical THEN #GP(0); FI;\n IF ShadowStackEnabled(CPL)\n IF (IA32_EFER.LMA and DEST(segment selector).L) = 0\n (* If target is legacy or compatibility mode then the SSP must be in low 4GB *)\n IF (SSP & 0xFFFFFFFF00000000 != 0)\n THEN #GP(0); FI;\n FI;\n FI;\n CS := DEST[segment selector]; (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n EIP := tempEIP;\n IF EndbranchEnabled(CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\nEND;\nCALL-GATE:\n IF call gate DPL < CPL\n or call gate DPL < call gate segment-selector RPL\n THEN #GP(call gate selector); FI;\n IF call gate not present\n THEN #NP(call gate selector); FI;\n IF call gate code-segment selector is NULL\n THEN #GP(0); FI;\n IF call gate code-segment selector index outside descriptor table limits\n THEN #GP(code segment selector); FI;\n Read code segment descriptor;\n IF code-segment segment descriptor does not indicate a code segment\n or code-segment segment descriptor is conforming and DPL > CPL\n or code-segment segment descriptor is non-conforming and DPL ≠ CPL\n THEN #GP(code segment selector); FI;\n IF IA32_EFER.LMA = 1 and (code-segment descriptor is not a 64-bit code segment\n or code-segment segment descriptor has both L-Bit and D-bit set)\n THEN #GP(code segment selector); FI;\n IF code segment is not present\n THEN #NP(code-segment selector); FI;\n tempEIP := DEST(Offset);\n IF GateSize = 16\n THEN tempEIP := tempEIP AND 0000FFFFH; FI;\n IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode) AND tempEIP\n outside code segment limit\n THEN #GP(0); FI\n CS := DEST[SegmentSelector]; (* Segment descriptor information also loaded *)\n CS(RPL) := CPL;\n EIP := tempEIP;\n IF EndbranchEnabled(CPL)\n IF CPL = 3\n THEN\n IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_U_CET.SUPPRESS = 0\n ELSE\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;\n IA32_S_CET.SUPPRESS = 0\n FI;\n FI;\nEND;\nTASK-GATE:\n IF task gate DPL < CPL\n or task gate DPL < task gate segment-selector RPL\n THEN #GP(task gate selector); FI;\n IF task gate not present\n THEN #NP(gate selector); FI;\n Read the TSS segment selector in the task-gate descriptor;\n IF TSS segment selector local/global bit is set to local\n or index not within GDT limits\n or descriptor is not a TSS segment\n or TSS descriptor specifies that the TSS is busy\n THEN #GP(TSS selector); FI;\n IF TSS not present\n THEN #NP(TSS selector); FI;\n SWITCH-TASKS to TSS;\n IF EIP not within code segment limit\n THEN #GP(0); FI;\nEND;\nTASK-STATE-SEGMENT:\n IF TSS DPL < CPL\n or TSS DPL < TSS segment-selector RPL\n or TSS descriptor indicates TSS not available\n THEN #GP(TSS selector); FI;\n IF TSS is not present\n THEN #NP(TSS selector); FI;\n SWITCH-TASKS to TSS;\n IF EIP not within code segment limit\n THEN #GP(0); FI;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/jmp" + }, + "kaddb": { + "instruction": "KADDB", + "title": "KADDW/KADDB/KADDQ/KADDD\n\t\t— ADD Two Masks", + "opcode": "VEX.L1.0F.W0 4A /r KADDW k1, k2, k3", + "description": "Adds the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] + SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kaddw:kaddb:kaddq:kaddd" + }, + "kaddd": { + "instruction": "KADDD", + "title": "KADDW/KADDB/KADDQ/KADDD\n\t\t— ADD Two Masks", + "opcode": "VEX.L1.0F.W0 4A /r KADDW k1, k2, k3", + "description": "Adds the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] + SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kaddw:kaddb:kaddq:kaddd" + }, + "kaddq": { + "instruction": "KADDQ", + "title": "KADDW/KADDB/KADDQ/KADDD\n\t\t— ADD Two Masks", + "opcode": "VEX.L1.0F.W0 4A /r KADDW k1, k2, k3", + "description": "Adds the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] + SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kaddw:kaddb:kaddq:kaddd" + }, + "kaddw": { + "instruction": "KADDW", + "title": "KADDW/KADDB/KADDQ/KADDD\n\t\t— ADD Two Masks", + "opcode": "VEX.L1.0F.W0 4A /r KADDW k1, k2, k3", + "description": "Adds the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] + SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kaddw:kaddb:kaddq:kaddd" + }, + "kandb": { + "instruction": "KANDB", + "title": "KANDW/KANDB/KANDQ/KANDD\n\t\t— Bitwise Logical AND Masks", + "opcode": "VEX.L1.0F.W0 41 /r KANDW k1, k2, k3", + "description": "Performs a bitwise AND between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandw:kandb:kandq:kandd" + }, + "kandd": { + "instruction": "KANDD", + "title": "KANDW/KANDB/KANDQ/KANDD\n\t\t— Bitwise Logical AND Masks", + "opcode": "VEX.L1.0F.W0 41 /r KANDW k1, k2, k3", + "description": "Performs a bitwise AND between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandw:kandb:kandq:kandd" + }, + "kandnb": { + "instruction": "KANDNB", + "title": "KANDNW/KANDNB/KANDNQ/KANDND\n\t\t— Bitwise Logical AND NOT Masks", + "opcode": "VEX.L1.0F.W0 42 /r KANDNW k1, k2, k3", + "description": "Performs a bitwise AND NOT between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := (BITWISE NOT SRC1[15:0]) BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := (BITWISE NOT SRC1[7:0]) BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := (BITWISE NOT SRC1[63:0]) BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := (BITWISE NOT SRC1[31:0]) BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandnw:kandnb:kandnq:kandnd" + }, + "kandnd": { + "instruction": "KANDND", + "title": "KANDNW/KANDNB/KANDNQ/KANDND\n\t\t— Bitwise Logical AND NOT Masks", + "opcode": "VEX.L1.0F.W0 42 /r KANDNW k1, k2, k3", + "description": "Performs a bitwise AND NOT between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := (BITWISE NOT SRC1[15:0]) BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := (BITWISE NOT SRC1[7:0]) BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := (BITWISE NOT SRC1[63:0]) BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := (BITWISE NOT SRC1[31:0]) BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandnw:kandnb:kandnq:kandnd" + }, + "kandnq": { + "instruction": "KANDNQ", + "title": "KANDNW/KANDNB/KANDNQ/KANDND\n\t\t— Bitwise Logical AND NOT Masks", + "opcode": "VEX.L1.0F.W0 42 /r KANDNW k1, k2, k3", + "description": "Performs a bitwise AND NOT between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := (BITWISE NOT SRC1[15:0]) BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := (BITWISE NOT SRC1[7:0]) BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := (BITWISE NOT SRC1[63:0]) BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := (BITWISE NOT SRC1[31:0]) BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandnw:kandnb:kandnq:kandnd" + }, + "kandnw": { + "instruction": "KANDNW", + "title": "KANDNW/KANDNB/KANDNQ/KANDND\n\t\t— Bitwise Logical AND NOT Masks", + "opcode": "VEX.L1.0F.W0 42 /r KANDNW k1, k2, k3", + "description": "Performs a bitwise AND NOT between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := (BITWISE NOT SRC1[15:0]) BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := (BITWISE NOT SRC1[7:0]) BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := (BITWISE NOT SRC1[63:0]) BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := (BITWISE NOT SRC1[31:0]) BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandnw:kandnb:kandnq:kandnd" + }, + "kandq": { + "instruction": "KANDQ", + "title": "KANDW/KANDB/KANDQ/KANDD\n\t\t— Bitwise Logical AND Masks", + "opcode": "VEX.L1.0F.W0 41 /r KANDW k1, k2, k3", + "description": "Performs a bitwise AND between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandw:kandb:kandq:kandd" + }, + "kandw": { + "instruction": "KANDW", + "title": "KANDW/KANDB/KANDQ/KANDD\n\t\t— Bitwise Logical AND Masks", + "opcode": "VEX.L1.0F.W0 41 /r KANDW k1, k2, k3", + "description": "Performs a bitwise AND between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE AND SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE AND SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kandw:kandb:kandq:kandd" + }, + "kmovb": { + "instruction": "KMOVB", + "title": "KMOVW/KMOVB/KMOVQ/KMOVD\n\t\t— Move From and to Mask Registers", + "opcode": "VEX.L0.0F.W0 90 /r KMOVW k1, k2/m16", + "description": "Copies values from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be mask registers, memory location or general purpose. The instruction cannot be used to transfer data between general purpose registers and or memory locations.\nWhen moving to a mask register, the result is zero extended to MAX_KL size (i.e., 64 bits currently). When moving to a general-purpose register (GPR), the result is zero-extended to the size of the destination. In 32-bit mode, the default GPR destination’s size is 32 bits. In 64-bit mode, the default GPR destination’s size is 64 bits. Note that VEX.W can only be used to modify the size of the GPR operand in 64b mode.", + "operation": "IF *destination is a memory location*\n DEST[15:0] := SRC[15:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[15:0])\n\n\nIF *destination is a memory location*\n DEST[7:0] := SRC[7:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[7:0])\n\n\nIF *destination is a memory location or a GPR*\n DEST[63:0] := SRC[63:0]\nIF *destination is a mask register*\n DEST := ZeroExtension(SRC[63:0])\n\n\nIF *destination is a memory location*\n DEST[31:0] := SRC[31:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[31:0])\n", + "url": "https://www.felixcloutier.com/x86/kmovw:kmovb:kmovq:kmovd" + }, + "kmovd": { + "instruction": "KMOVD", + "title": "KMOVW/KMOVB/KMOVQ/KMOVD\n\t\t— Move From and to Mask Registers", + "opcode": "VEX.L0.0F.W0 90 /r KMOVW k1, k2/m16", + "description": "Copies values from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be mask registers, memory location or general purpose. The instruction cannot be used to transfer data between general purpose registers and or memory locations.\nWhen moving to a mask register, the result is zero extended to MAX_KL size (i.e., 64 bits currently). When moving to a general-purpose register (GPR), the result is zero-extended to the size of the destination. In 32-bit mode, the default GPR destination’s size is 32 bits. In 64-bit mode, the default GPR destination’s size is 64 bits. Note that VEX.W can only be used to modify the size of the GPR operand in 64b mode.", + "operation": "IF *destination is a memory location*\n DEST[15:0] := SRC[15:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[15:0])\n\n\nIF *destination is a memory location*\n DEST[7:0] := SRC[7:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[7:0])\n\n\nIF *destination is a memory location or a GPR*\n DEST[63:0] := SRC[63:0]\nIF *destination is a mask register*\n DEST := ZeroExtension(SRC[63:0])\n\n\nIF *destination is a memory location*\n DEST[31:0] := SRC[31:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[31:0])\n", + "url": "https://www.felixcloutier.com/x86/kmovw:kmovb:kmovq:kmovd" + }, + "kmovq": { + "instruction": "KMOVQ", + "title": "KMOVW/KMOVB/KMOVQ/KMOVD\n\t\t— Move From and to Mask Registers", + "opcode": "VEX.L0.0F.W0 90 /r KMOVW k1, k2/m16", + "description": "Copies values from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be mask registers, memory location or general purpose. The instruction cannot be used to transfer data between general purpose registers and or memory locations.\nWhen moving to a mask register, the result is zero extended to MAX_KL size (i.e., 64 bits currently). When moving to a general-purpose register (GPR), the result is zero-extended to the size of the destination. In 32-bit mode, the default GPR destination’s size is 32 bits. In 64-bit mode, the default GPR destination’s size is 64 bits. Note that VEX.W can only be used to modify the size of the GPR operand in 64b mode.", + "operation": "IF *destination is a memory location*\n DEST[15:0] := SRC[15:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[15:0])\n\n\nIF *destination is a memory location*\n DEST[7:0] := SRC[7:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[7:0])\n\n\nIF *destination is a memory location or a GPR*\n DEST[63:0] := SRC[63:0]\nIF *destination is a mask register*\n DEST := ZeroExtension(SRC[63:0])\n\n\nIF *destination is a memory location*\n DEST[31:0] := SRC[31:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[31:0])\n", + "url": "https://www.felixcloutier.com/x86/kmovw:kmovb:kmovq:kmovd" + }, + "kmovw": { + "instruction": "KMOVW", + "title": "KMOVW/KMOVB/KMOVQ/KMOVD\n\t\t— Move From and to Mask Registers", + "opcode": "VEX.L0.0F.W0 90 /r KMOVW k1, k2/m16", + "description": "Copies values from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be mask registers, memory location or general purpose. The instruction cannot be used to transfer data between general purpose registers and or memory locations.\nWhen moving to a mask register, the result is zero extended to MAX_KL size (i.e., 64 bits currently). When moving to a general-purpose register (GPR), the result is zero-extended to the size of the destination. In 32-bit mode, the default GPR destination’s size is 32 bits. In 64-bit mode, the default GPR destination’s size is 64 bits. Note that VEX.W can only be used to modify the size of the GPR operand in 64b mode.", + "operation": "IF *destination is a memory location*\n DEST[15:0] := SRC[15:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[15:0])\n\n\nIF *destination is a memory location*\n DEST[7:0] := SRC[7:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[7:0])\n\n\nIF *destination is a memory location or a GPR*\n DEST[63:0] := SRC[63:0]\nIF *destination is a mask register*\n DEST := ZeroExtension(SRC[63:0])\n\n\nIF *destination is a memory location*\n DEST[31:0] := SRC[31:0]\nIF *destination is a mask register or a GPR *\n DEST := ZeroExtension(SRC[31:0])\n", + "url": "https://www.felixcloutier.com/x86/kmovw:kmovb:kmovq:kmovd" + }, + "knotb": { + "instruction": "KNOTB", + "title": "KNOTW/KNOTB/KNOTQ/KNOTD\n\t\t— NOT Mask Register", + "opcode": "VEX.L0.0F.W0 44 /r KNOTW k1, k2", + "description": "Performs a bitwise NOT of vector mask k2 and writes the result into vector mask k1.", + "operation": "DEST[15:0] := BITWISE NOT SRC[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := BITWISE NOT SRC[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := BITWISE NOT SRC[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := BITWISE NOT SRC[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/knotw:knotb:knotq:knotd" + }, + "knotd": { + "instruction": "KNOTD", + "title": "KNOTW/KNOTB/KNOTQ/KNOTD\n\t\t— NOT Mask Register", + "opcode": "VEX.L0.0F.W0 44 /r KNOTW k1, k2", + "description": "Performs a bitwise NOT of vector mask k2 and writes the result into vector mask k1.", + "operation": "DEST[15:0] := BITWISE NOT SRC[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := BITWISE NOT SRC[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := BITWISE NOT SRC[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := BITWISE NOT SRC[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/knotw:knotb:knotq:knotd" + }, + "knotq": { + "instruction": "KNOTQ", + "title": "KNOTW/KNOTB/KNOTQ/KNOTD\n\t\t— NOT Mask Register", + "opcode": "VEX.L0.0F.W0 44 /r KNOTW k1, k2", + "description": "Performs a bitwise NOT of vector mask k2 and writes the result into vector mask k1.", + "operation": "DEST[15:0] := BITWISE NOT SRC[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := BITWISE NOT SRC[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := BITWISE NOT SRC[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := BITWISE NOT SRC[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/knotw:knotb:knotq:knotd" + }, + "knotw": { + "instruction": "KNOTW", + "title": "KNOTW/KNOTB/KNOTQ/KNOTD\n\t\t— NOT Mask Register", + "opcode": "VEX.L0.0F.W0 44 /r KNOTW k1, k2", + "description": "Performs a bitwise NOT of vector mask k2 and writes the result into vector mask k1.", + "operation": "DEST[15:0] := BITWISE NOT SRC[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := BITWISE NOT SRC[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := BITWISE NOT SRC[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := BITWISE NOT SRC[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/knotw:knotb:knotq:knotd" + }, + "korb": { + "instruction": "KORB", + "title": "KORW/KORB/KORQ/KORD\n\t\t— Bitwise Logical OR Masks", + "opcode": "VEX.L1.0F.W0 45 /r KORW k1, k2, k3", + "description": "Performs a bitwise OR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE OR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE OR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/korw:korb:korq:kord" + }, + "kord": { + "instruction": "KORD", + "title": "KORW/KORB/KORQ/KORD\n\t\t— Bitwise Logical OR Masks", + "opcode": "VEX.L1.0F.W0 45 /r KORW k1, k2, k3", + "description": "Performs a bitwise OR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE OR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE OR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/korw:korb:korq:kord" + }, + "korq": { + "instruction": "KORQ", + "title": "KORW/KORB/KORQ/KORD\n\t\t— Bitwise Logical OR Masks", + "opcode": "VEX.L1.0F.W0 45 /r KORW k1, k2, k3", + "description": "Performs a bitwise OR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE OR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE OR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/korw:korb:korq:kord" + }, + "kortestb": { + "instruction": "KORTESTB", + "title": "KORTESTW/KORTESTB/KORTESTQ/KORTESTD\n\t\t— OR Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 98 /r KORTESTW k1, k2", + "description": "Performs a bitwise OR between the vector mask register k2, and the vector mask register k1, and sets CF and ZF based on the operation result.\nZF flag is set if both sources are 0x0. CF is set if, after the OR operation is done, the operation result is all 1’s.", + "operation": "TMP[15:0] := DEST[15:0] BITWISE OR SRC[15:0]\nIF(TMP[15:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[15:0]=FFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[7:0] := DEST[7:0] BITWISE OR SRC[7:0]\nIF(TMP[7:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[7:0]==FFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[63:0] := DEST[63:0] BITWISE OR SRC[63:0]\nIF(TMP[63:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[63:0]==FFFFFFFF_FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[31:0] := DEST[31:0] BITWISE OR SRC[31:0]\nIF(TMP[31:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[31:0]=FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kortestw:kortestb:kortestq:kortestd" + }, + "kortestd": { + "instruction": "KORTESTD", + "title": "KORTESTW/KORTESTB/KORTESTQ/KORTESTD\n\t\t— OR Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 98 /r KORTESTW k1, k2", + "description": "Performs a bitwise OR between the vector mask register k2, and the vector mask register k1, and sets CF and ZF based on the operation result.\nZF flag is set if both sources are 0x0. CF is set if, after the OR operation is done, the operation result is all 1’s.", + "operation": "TMP[15:0] := DEST[15:0] BITWISE OR SRC[15:0]\nIF(TMP[15:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[15:0]=FFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[7:0] := DEST[7:0] BITWISE OR SRC[7:0]\nIF(TMP[7:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[7:0]==FFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[63:0] := DEST[63:0] BITWISE OR SRC[63:0]\nIF(TMP[63:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[63:0]==FFFFFFFF_FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[31:0] := DEST[31:0] BITWISE OR SRC[31:0]\nIF(TMP[31:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[31:0]=FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kortestw:kortestb:kortestq:kortestd" + }, + "kortestq": { + "instruction": "KORTESTQ", + "title": "KORTESTW/KORTESTB/KORTESTQ/KORTESTD\n\t\t— OR Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 98 /r KORTESTW k1, k2", + "description": "Performs a bitwise OR between the vector mask register k2, and the vector mask register k1, and sets CF and ZF based on the operation result.\nZF flag is set if both sources are 0x0. CF is set if, after the OR operation is done, the operation result is all 1’s.", + "operation": "TMP[15:0] := DEST[15:0] BITWISE OR SRC[15:0]\nIF(TMP[15:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[15:0]=FFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[7:0] := DEST[7:0] BITWISE OR SRC[7:0]\nIF(TMP[7:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[7:0]==FFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[63:0] := DEST[63:0] BITWISE OR SRC[63:0]\nIF(TMP[63:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[63:0]==FFFFFFFF_FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[31:0] := DEST[31:0] BITWISE OR SRC[31:0]\nIF(TMP[31:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[31:0]=FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kortestw:kortestb:kortestq:kortestd" + }, + "kortestw": { + "instruction": "KORTESTW", + "title": "KORTESTW/KORTESTB/KORTESTQ/KORTESTD\n\t\t— OR Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 98 /r KORTESTW k1, k2", + "description": "Performs a bitwise OR between the vector mask register k2, and the vector mask register k1, and sets CF and ZF based on the operation result.\nZF flag is set if both sources are 0x0. CF is set if, after the OR operation is done, the operation result is all 1’s.", + "operation": "TMP[15:0] := DEST[15:0] BITWISE OR SRC[15:0]\nIF(TMP[15:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[15:0]=FFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[7:0] := DEST[7:0] BITWISE OR SRC[7:0]\nIF(TMP[7:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[7:0]==FFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[63:0] := DEST[63:0] BITWISE OR SRC[63:0]\nIF(TMP[63:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[63:0]==FFFFFFFF_FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n\n\nTMP[31:0] := DEST[31:0] BITWISE OR SRC[31:0]\nIF(TMP[31:0]=0)\n THEN ZF := 1\n ELSE ZF := 0\nFI;\nIF(TMP[31:0]=FFFFFFFFh)\n THEN CF := 1\n ELSE CF := 0\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kortestw:kortestb:kortestq:kortestd" + }, + "korw": { + "instruction": "KORW", + "title": "KORW/KORB/KORQ/KORD\n\t\t— Bitwise Logical OR Masks", + "opcode": "VEX.L1.0F.W0 45 /r KORW k1, k2, k3", + "description": "Performs a bitwise OR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE OR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE OR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/korw:korb:korq:kord" + }, + "kshiftlb": { + "instruction": "KSHIFTLB", + "title": "KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD\n\t\t— Shift Left Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 32 /r KSHIFTLW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) left by the count specified in immediate byte and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] << COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftlw:kshiftlb:kshiftlq:kshiftld" + }, + "kshiftld": { + "instruction": "KSHIFTLD", + "title": "KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD\n\t\t— Shift Left Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 32 /r KSHIFTLW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) left by the count specified in immediate byte and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] << COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftlw:kshiftlb:kshiftlq:kshiftld" + }, + "kshiftlq": { + "instruction": "KSHIFTLQ", + "title": "KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD\n\t\t— Shift Left Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 32 /r KSHIFTLW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) left by the count specified in immediate byte and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] << COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftlw:kshiftlb:kshiftlq:kshiftld" + }, + "kshiftlw": { + "instruction": "KSHIFTLW", + "title": "KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD\n\t\t— Shift Left Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 32 /r KSHIFTLW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) left by the count specified in immediate byte and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] << COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] << COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftlw:kshiftlb:kshiftlq:kshiftld" + }, + "kshiftrb": { + "instruction": "KSHIFTRB", + "title": "KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD\n\t\t— Shift Right Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 30 /r KSHIFTRW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) right by the count specified in immediate and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] >> COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftrw:kshiftrb:kshiftrq:kshiftrd" + }, + "kshiftrd": { + "instruction": "KSHIFTRD", + "title": "KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD\n\t\t— Shift Right Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 30 /r KSHIFTRW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) right by the count specified in immediate and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] >> COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftrw:kshiftrb:kshiftrq:kshiftrd" + }, + "kshiftrq": { + "instruction": "KSHIFTRQ", + "title": "KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD\n\t\t— Shift Right Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 30 /r KSHIFTRW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) right by the count specified in immediate and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] >> COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftrw:kshiftrb:kshiftrq:kshiftrd" + }, + "kshiftrw": { + "instruction": "KSHIFTRW", + "title": "KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD\n\t\t— Shift Right Mask Registers", + "opcode": "VEX.L0.66.0F3A.W1 30 /r KSHIFTRW k1, k2, imm8", + "description": "Shifts 8/16/32/64 bits in the second operand (source operand) right by the count specified in immediate and place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift), 31 (for doubleword shift) or 63 (for quadword shift).", + "operation": "COUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=15\n THEN DEST[15:0] := SRC1[15:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=7\n THEN DEST[7:0] := SRC1[7:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=63\n THEN DEST[63:0] := SRC1[63:0] >> COUNT;\nFI;\n\n\nCOUNT := imm8[7:0]\nDEST[MAX_KL-1:0] := 0\nIF COUNT <=31\n THEN DEST[31:0] := SRC1[31:0] >> COUNT;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/kshiftrw:kshiftrb:kshiftrq:kshiftrd" + }, + "ktestb": { + "instruction": "KTESTB", + "title": "KTESTW/KTESTB/KTESTQ/KTESTD\n\t\t— Packed Bit Test Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 99 /r KTESTW k1, k2", + "description": "Performs a bitwise comparison of the bits of the first source operand and corresponding bits in the second source operand. If the AND operation produces all zeros, the ZF is set else the ZF is clear. If the bitwise AND operation of the inverted first source operand with the second source operand produces all zeros the CF is set else the CF is clear. Only the EFLAGS register is updated.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "TEMP[15:0] := SRC2[15:0] AND SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[15:0] := SRC2[15:0] AND NOT SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[7:0] := SRC2[7:0] AND SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[7:0] := SRC2[7:0] AND NOT SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[63:0] := SRC2[63:0] AND SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[63:0] := SRC2[63:0] AND NOT SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[31:0] := SRC2[31:0] AND SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[31:0] := SRC2[31:0] AND NOT SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/ktestw:ktestb:ktestq:ktestd" + }, + "ktestd": { + "instruction": "KTESTD", + "title": "KTESTW/KTESTB/KTESTQ/KTESTD\n\t\t— Packed Bit Test Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 99 /r KTESTW k1, k2", + "description": "Performs a bitwise comparison of the bits of the first source operand and corresponding bits in the second source operand. If the AND operation produces all zeros, the ZF is set else the ZF is clear. If the bitwise AND operation of the inverted first source operand with the second source operand produces all zeros the CF is set else the CF is clear. Only the EFLAGS register is updated.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "TEMP[15:0] := SRC2[15:0] AND SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[15:0] := SRC2[15:0] AND NOT SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[7:0] := SRC2[7:0] AND SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[7:0] := SRC2[7:0] AND NOT SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[63:0] := SRC2[63:0] AND SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[63:0] := SRC2[63:0] AND NOT SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[31:0] := SRC2[31:0] AND SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[31:0] := SRC2[31:0] AND NOT SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/ktestw:ktestb:ktestq:ktestd" + }, + "ktestq": { + "instruction": "KTESTQ", + "title": "KTESTW/KTESTB/KTESTQ/KTESTD\n\t\t— Packed Bit Test Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 99 /r KTESTW k1, k2", + "description": "Performs a bitwise comparison of the bits of the first source operand and corresponding bits in the second source operand. If the AND operation produces all zeros, the ZF is set else the ZF is clear. If the bitwise AND operation of the inverted first source operand with the second source operand produces all zeros the CF is set else the CF is clear. Only the EFLAGS register is updated.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "TEMP[15:0] := SRC2[15:0] AND SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[15:0] := SRC2[15:0] AND NOT SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[7:0] := SRC2[7:0] AND SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[7:0] := SRC2[7:0] AND NOT SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[63:0] := SRC2[63:0] AND SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[63:0] := SRC2[63:0] AND NOT SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[31:0] := SRC2[31:0] AND SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[31:0] := SRC2[31:0] AND NOT SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/ktestw:ktestb:ktestq:ktestd" + }, + "ktestw": { + "instruction": "KTESTW", + "title": "KTESTW/KTESTB/KTESTQ/KTESTD\n\t\t— Packed Bit Test Masks and Set Flags", + "opcode": "VEX.L0.0F.W0 99 /r KTESTW k1, k2", + "description": "Performs a bitwise comparison of the bits of the first source operand and corresponding bits in the second source operand. If the AND operation produces all zeros, the ZF is set else the ZF is clear. If the bitwise AND operation of the inverted first source operand with the second source operand produces all zeros the CF is set else the CF is clear. Only the EFLAGS register is updated.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "TEMP[15:0] := SRC2[15:0] AND SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[15:0] := SRC2[15:0] AND NOT SRC1[15:0]\nIF (TEMP[15:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[7:0] := SRC2[7:0] AND SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[7:0] := SRC2[7:0] AND NOT SRC1[7:0]\nIF (TEMP[7:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[63:0] := SRC2[63:0] AND SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[63:0] := SRC2[63:0] AND NOT SRC1[63:0]\nIF (TEMP[63:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n\n\nTEMP[31:0] := SRC2[31:0] AND SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN ZF :=1;\n ELSE ZF := 0;\nFI;\nTEMP[31:0] := SRC2[31:0] AND NOT SRC1[31:0]\nIF (TEMP[31:0] = = 0)\n THEN CF :=1;\n ELSE CF := 0;\nFI;\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/ktestw:ktestb:ktestq:ktestd" + }, + "kunpckbw": { + "instruction": "KUNPCKBW", + "title": "KUNPCKBW/KUNPCKWD/KUNPCKDQ\n\t\t— Unpack for Mask Registers", + "opcode": "VEX.L1.66.0F.W0 4B /r KUNPCKBW k1, k2, k3", + "description": "Unpacks the lower 8/16/32 bits of the second and third operands (source operands) into the low part of the first operand (destination operand), starting from the low bytes. The result is zero-extended in the destination.", + "operation": "DEST[7:0] := SRC2[7:0]\nDEST[15:8] := SRC1[7:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[15:0] := SRC2[15:0]\nDEST[31:16] := SRC1[15:0]\nDEST[MAX_KL-1:32] := 0\n\n\nDEST[31:0] := SRC2[31:0]\nDEST[63:32] := SRC1[31:0]\nDEST[MAX_KL-1:64] := 0\n", + "url": "https://www.felixcloutier.com/x86/kunpckbw:kunpckwd:kunpckdq" + }, + "kunpckdq": { + "instruction": "KUNPCKDQ", + "title": "KUNPCKBW/KUNPCKWD/KUNPCKDQ\n\t\t— Unpack for Mask Registers", + "opcode": "VEX.L1.66.0F.W0 4B /r KUNPCKBW k1, k2, k3", + "description": "Unpacks the lower 8/16/32 bits of the second and third operands (source operands) into the low part of the first operand (destination operand), starting from the low bytes. The result is zero-extended in the destination.", + "operation": "DEST[7:0] := SRC2[7:0]\nDEST[15:8] := SRC1[7:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[15:0] := SRC2[15:0]\nDEST[31:16] := SRC1[15:0]\nDEST[MAX_KL-1:32] := 0\n\n\nDEST[31:0] := SRC2[31:0]\nDEST[63:32] := SRC1[31:0]\nDEST[MAX_KL-1:64] := 0\n", + "url": "https://www.felixcloutier.com/x86/kunpckbw:kunpckwd:kunpckdq" + }, + "kunpckwd": { + "instruction": "KUNPCKWD", + "title": "KUNPCKBW/KUNPCKWD/KUNPCKDQ\n\t\t— Unpack for Mask Registers", + "opcode": "VEX.L1.66.0F.W0 4B /r KUNPCKBW k1, k2, k3", + "description": "Unpacks the lower 8/16/32 bits of the second and third operands (source operands) into the low part of the first operand (destination operand), starting from the low bytes. The result is zero-extended in the destination.", + "operation": "DEST[7:0] := SRC2[7:0]\nDEST[15:8] := SRC1[7:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[15:0] := SRC2[15:0]\nDEST[31:16] := SRC1[15:0]\nDEST[MAX_KL-1:32] := 0\n\n\nDEST[31:0] := SRC2[31:0]\nDEST[63:32] := SRC1[31:0]\nDEST[MAX_KL-1:64] := 0\n", + "url": "https://www.felixcloutier.com/x86/kunpckbw:kunpckwd:kunpckdq" + }, + "kxnorb": { + "instruction": "KXNORB", + "title": "KXNORW/KXNORB/KXNORQ/KXNORD\n\t\t— Bitwise Logical XNOR Masks", + "opcode": "VEX.L1.0F.W0 46 /r KXNORW k1, k2, k3", + "description": "Performs a bitwise XNOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := NOT (SRC1[15:0] BITWISE XOR SRC2[15:0])\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := NOT (SRC1[7:0] BITWISE XOR SRC2[7:0])\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := NOT (SRC1[63:0] BITWISE XOR SRC2[63:0])\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := NOT (SRC1[31:0] BITWISE XOR SRC2[31:0])\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxnorw:kxnorb:kxnorq:kxnord" + }, + "kxnord": { + "instruction": "KXNORD", + "title": "KXNORW/KXNORB/KXNORQ/KXNORD\n\t\t— Bitwise Logical XNOR Masks", + "opcode": "VEX.L1.0F.W0 46 /r KXNORW k1, k2, k3", + "description": "Performs a bitwise XNOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := NOT (SRC1[15:0] BITWISE XOR SRC2[15:0])\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := NOT (SRC1[7:0] BITWISE XOR SRC2[7:0])\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := NOT (SRC1[63:0] BITWISE XOR SRC2[63:0])\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := NOT (SRC1[31:0] BITWISE XOR SRC2[31:0])\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxnorw:kxnorb:kxnorq:kxnord" + }, + "kxnorq": { + "instruction": "KXNORQ", + "title": "KXNORW/KXNORB/KXNORQ/KXNORD\n\t\t— Bitwise Logical XNOR Masks", + "opcode": "VEX.L1.0F.W0 46 /r KXNORW k1, k2, k3", + "description": "Performs a bitwise XNOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := NOT (SRC1[15:0] BITWISE XOR SRC2[15:0])\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := NOT (SRC1[7:0] BITWISE XOR SRC2[7:0])\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := NOT (SRC1[63:0] BITWISE XOR SRC2[63:0])\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := NOT (SRC1[31:0] BITWISE XOR SRC2[31:0])\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxnorw:kxnorb:kxnorq:kxnord" + }, + "kxnorw": { + "instruction": "KXNORW", + "title": "KXNORW/KXNORB/KXNORQ/KXNORD\n\t\t— Bitwise Logical XNOR Masks", + "opcode": "VEX.L1.0F.W0 46 /r KXNORW k1, k2, k3", + "description": "Performs a bitwise XNOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := NOT (SRC1[15:0] BITWISE XOR SRC2[15:0])\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := NOT (SRC1[7:0] BITWISE XOR SRC2[7:0])\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := NOT (SRC1[63:0] BITWISE XOR SRC2[63:0])\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := NOT (SRC1[31:0] BITWISE XOR SRC2[31:0])\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxnorw:kxnorb:kxnorq:kxnord" + }, + "kxorb": { + "instruction": "KXORB", + "title": "KXORW/KXORB/KXORQ/KXORD\n\t\t— Bitwise Logical XOR Masks", + "opcode": "VEX.L1.0F.W0 47 /r KXORW k1, k2, k3", + "description": "Performs a bitwise XOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE XOR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE XOR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE XOR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE XOR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxorw:kxorb:kxorq:kxord" + }, + "kxord": { + "instruction": "KXORD", + "title": "KXORW/KXORB/KXORQ/KXORD\n\t\t— Bitwise Logical XOR Masks", + "opcode": "VEX.L1.0F.W0 47 /r KXORW k1, k2, k3", + "description": "Performs a bitwise XOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE XOR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE XOR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE XOR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE XOR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxorw:kxorb:kxorq:kxord" + }, + "kxorq": { + "instruction": "KXORQ", + "title": "KXORW/KXORB/KXORQ/KXORD\n\t\t— Bitwise Logical XOR Masks", + "opcode": "VEX.L1.0F.W0 47 /r KXORW k1, k2, k3", + "description": "Performs a bitwise XOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE XOR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE XOR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE XOR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE XOR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxorw:kxorb:kxorq:kxord" + }, + "kxorw": { + "instruction": "KXORW", + "title": "KXORW/KXORB/KXORQ/KXORD\n\t\t— Bitwise Logical XOR Masks", + "opcode": "VEX.L1.0F.W0 47 /r KXORW k1, k2, k3", + "description": "Performs a bitwise XOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask k1 (three-operand form).", + "operation": "DEST[15:0] := SRC1[15:0] BITWISE XOR SRC2[15:0]\nDEST[MAX_KL-1:16] := 0\n\n\nDEST[7:0] := SRC1[7:0] BITWISE XOR SRC2[7:0]\nDEST[MAX_KL-1:8] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE XOR SRC2[63:0]\nDEST[MAX_KL-1:64] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE XOR SRC2[31:0]\nDEST[MAX_KL-1:32] := 0\n", + "url": "https://www.felixcloutier.com/x86/kxorw:kxorb:kxorq:kxord" + }, + "lahf": { + "instruction": "LAHF", + "title": "LAHF\n\t\t— Load Status Flags Into AH Register", + "opcode": "9F", + "description": "This instruction executes as described above in compatibility mode and legacy mode. It is valid in 64-bit mode only if CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1.", + "operation": "IF 64-Bit Mode\n THEN\n IF CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1;\n THEN AH := RFLAGS(SF:ZF:0:AF:0:PF:1:CF);\n ELSE #UD;\n FI;\n ELSE\n AH := EFLAGS(SF:ZF:0:AF:0:PF:1:CF);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lahf" + }, + "lar": { + "instruction": "LAR", + "title": "LAR\n\t\t— Load Access Rights Byte", + "opcode": "0F 02 /r", + "description": "Loads the access rights from the segment descriptor specified by the second operand (source operand) into the first operand (destination operand) and sets the ZF flag in the flag register. The source operand (which can be a register or a memory location) contains the segment selector for the segment descriptor being accessed. If the source operand is a memory address, only 16 bits of data are accessed. The destination operand is a general-purpose register.\nThe processor performs access checks as part of the loading process. Once loaded in the destination register, software can perform additional checks on the access rights information.\nThe access rights for a segment descriptor include fields located in the second doubleword (bytes 4–7) of the segment descriptor. The following fields are loaded by the LAR instruction:\nThis instruction performs the following checks before it loads the access rights in the destination register:\nIf the segment descriptor cannot be accessed or is an invalid type for the instruction, the ZF flag is cleared and no access rights are loaded in the destination operand.\nThe LAR instruction can only be executed in protected mode and IA-32e mode.", + "operation": "IF Offset(SRC) > descriptor table limit\n THEN\n ZF := 0;\n ELSE\n SegmentDescriptor := descriptor referenced by SRC;\n IF SegmentDescriptor(Type) ≠ conforming code segment\n and (CPL > DPL) or (RPL > DPL)\n or SegmentDescriptor(Type) is not valid for instruction\n THEN\n ZF := 0;\n ELSE\n DEST := access rights from SegmentDescriptor as given in Description section;\n ZF := 1;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lar" + }, + "lddqu": { + "instruction": "LDDQU", + "title": "LDDQU\n\t\t— Load Unaligned Integer 128 Bits", + "opcode": "F2 0F F0 /r LDDQU xmm1, mem", + "description": "The instruction is functionally similar to (V)MOVDQU ymm/xmm, m256/m128 for loading from memory. That is: 32/16 bytes of data starting at an address specified by the source memory operand (second operand) are fetched from memory and placed in a destination register (first operand). The source operand need not be aligned on a 32/16-byte boundary. Up to 64/32 bytes may be loaded from memory; this is implementation dependent.\nThis instruction may improve performance relative to (V)MOVDQU if the source operand crosses a cache line boundary. In situations that require the data loaded by (V)LDDQU be modified and stored to the same location, use (V)MOVDQU or (V)MOVDQA instead of (V)LDDQU. To move a double quadword to or from memory locations that are known to be aligned on 16-byte boundaries, use the (V)MOVDQA instruction.", + "operation": "DEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := SRC[255:0]\n", + "url": "https://www.felixcloutier.com/x86/lddqu" + }, + "ldmxcsr": { + "instruction": "LDMXCSR", + "title": "LDMXCSR\n\t\t— Load MXCSR Register", + "opcode": "NP 0F AE /2 LDMXCSR m32", + "description": "Loads the source operand into the MXCSR control/status register. The source operand is a 32-bit memory location. See “MXCSR Control and Status Register” in Chapter 10, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for a description of the MXCSR register and its contents.\nThe LDMXCSR instruction is typically used in conjunction with the (V)STMXCSR instruction, which stores the contents of the MXCSR register in memory.\nThe default MXCSR value at reset is 1F80H.\nIf a (V)LDMXCSR instruction clears a SIMD floating-point exception mask bit and sets the corresponding exception flag bit, a SIMD floating-point exception will not be immediately generated. The exception will be generated only upon the execution of the next instruction that meets both conditions below:\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.\nIf VLDMXCSR is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "MXCSR := m32;\n", + "url": "https://www.felixcloutier.com/x86/ldmxcsr" + }, + "lds": { + "instruction": "LDS", + "title": "LDS/LES/LFS/LGS/LSS\n\t\t— Load Far Pointer", + "opcode": "C5 /r", + "description": "Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.\nIf one of these instructions is executed in protected mode, additional information from the segment descriptor pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment register.\nAlso in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to the segment occurs.)\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "64-BIT_MODE\n IF SS is loaded\n THEN\n IF SegmentSelector = NULL and ( (RPL = 3) or\n (RPL ≠ 3 and RPL ≠ CPL) )\n THEN #GP(0);\n ELSE IF descriptor is in non-canonical space\n THEN #GP(selector); FI;\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF attempt to load DS, or ES\n THEN #UD;\n ELSE IF FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and ( RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) ;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nPREOTECTED MODE OR COMPATIBILITY MODE;\n IF SS is loaded\n THEN\n IF SegementSelector = NULL\n THEN #GP(0);\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF DS, ES, FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and (RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) AND RPL;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF DS, ES, FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nReal-Address or Virtual-8086 Mode\n SegmentRegister := SegmentSelector(SRC); FI;\n DEST := Offset(SRC);\n", + "url": "https://www.felixcloutier.com/x86/lds:les:lfs:lgs:lss" + }, + "ldtilecfg": { + "instruction": "LDTILECFG", + "title": "LDTILECFG\n\t\t— Load Tile Configuration", + "opcode": "VEX.128.NP.0F38.W0 49 !(11):000:bbb LDTILECFG m512", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/ldtilecfg" + }, + "lea": { + "instruction": "LEA", + "title": "LEA\n\t\t— Load Effective Address", + "opcode": "8D /r", + "description": "Computes the effective address of the second operand (the source operand) and stores it in the first operand (destination operand). The source operand is a memory address (offset part) specified with one of the processors addressing modes; the destination operand is a general-purpose register. The address-size and operand-size attributes affect the action performed by this instruction, as shown in the following table. The operand-size attribute of the instruction is determined by the chosen register; the address-size attribute is determined by the attribute of the code segment.\nDifferent assemblers may use different algorithms based on the size attribute and symbolic reference of the source operand.\nIn 64-bit mode, the instruction’s destination operand is governed by operand size attribute, the default operand size is 32 bits. Address calculation is governed by address size attribute, the default address size is 64-bits. In 64-bit mode, address size of 16 bits is not encodable. See Table 3-55.", + "operation": "IF OperandSize = 16 and AddressSize = 16\n THEN\n DEST := EffectiveAddress(SRC); (* 16-bit address *)\n ELSE IF OperandSize = 16 and AddressSize = 32\n THEN\n temp := EffectiveAddress(SRC); (* 32-bit address *)\n DEST := temp[0:15]; (* 16-bit address *)\n FI;\n ELSE IF OperandSize = 32 and AddressSize = 16\n THEN\n temp := EffectiveAddress(SRC); (* 16-bit address *)\n DEST := ZeroExtend(temp); (* 32-bit address *)\n FI;\n ELSE IF OperandSize = 32 and AddressSize = 32\n THEN\n DEST := EffectiveAddress(SRC); (* 32-bit address *)\n FI;\n ELSE IF OperandSize = 16 and AddressSize = 64\n THEN\n temp := EffectiveAddress(SRC); (* 64-bit address *)\n DEST := temp[0:15]; (* 16-bit address *)\n FI;\n ELSE IF OperandSize = 32 and AddressSize = 64\n THEN\n temp := EffectiveAddress(SRC); (* 64-bit address *)\n DEST := temp[0:31]; (* 16-bit address *)\n FI;\n ELSE IF OperandSize = 64 and AddressSize = 64\n THEN\n DEST := EffectiveAddress(SRC); (* 64-bit address *)\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lea" + }, + "leave": { + "instruction": "LEAVE", + "title": "LEAVE\n\t\t— High Level Procedure Exit", + "opcode": "C9", + "description": "Releases the stack frame set up by an earlier ENTER instruction. The LEAVE instruction copies the frame pointer (in the EBP register) into the stack pointer register (ESP), which releases the stack space allocated to the stack frame. The old frame pointer (the frame pointer for the calling procedure that was saved by the ENTER instruction) is then popped from the stack into the EBP register, restoring the calling procedure’s stack frame.\nA RET instruction is commonly executed following a LEAVE instruction to return program control to the calling procedure.\nSee “Procedure Calls for Block-Structured Languages” in Chapter 7 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for detailed information on the use of the ENTER and LEAVE instructions.\nIn 64-bit mode, the instruction’s default operation size is 64 bits; 32-bit operation cannot be encoded. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF StackAddressSize = 32\n THEN\n ESP := EBP;\n ELSE IF StackAddressSize = 64\n THEN RSP := RBP; FI;\n ELSE IF StackAddressSize = 16\n THEN SP := BP; FI;\nFI;\nIF OperandSize = 32\n THEN EBP := Pop();\n ELSE IF OperandSize = 64\n THEN RBP := Pop(); FI;\n ELSE IF OperandSize = 16\n THEN BP := Pop(); FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/leave" + }, + "les": { + "instruction": "LES", + "title": "LDS/LES/LFS/LGS/LSS\n\t\t— Load Far Pointer", + "opcode": "C4 /r", + "description": "Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.\nIf one of these instructions is executed in protected mode, additional information from the segment descriptor pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment register.\nAlso in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to the segment occurs.)\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "64-BIT_MODE\n IF SS is loaded\n THEN\n IF SegmentSelector = NULL and ( (RPL = 3) or\n (RPL ≠ 3 and RPL ≠ CPL) )\n THEN #GP(0);\n ELSE IF descriptor is in non-canonical space\n THEN #GP(selector); FI;\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF attempt to load DS, or ES\n THEN #UD;\n ELSE IF FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and ( RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) ;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nPREOTECTED MODE OR COMPATIBILITY MODE;\n IF SS is loaded\n THEN\n IF SegementSelector = NULL\n THEN #GP(0);\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF DS, ES, FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and (RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) AND RPL;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF DS, ES, FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nReal-Address or Virtual-8086 Mode\n SegmentRegister := SegmentSelector(SRC); FI;\n DEST := Offset(SRC);\n", + "url": "https://www.felixcloutier.com/x86/lds:les:lfs:lgs:lss" + }, + "lfence": { + "instruction": "LFENCE", + "title": "LFENCE\n\t\t— Load Fence", + "opcode": "NP 0F AE E8 LFENCE", + "description": "Performs a serializing operation on all load-from-memory instructions that were issued prior the LFENCE instruction. Specifically, LFENCE does not execute until all prior instructions have completed locally, and no later instruction begins execution until LFENCE completes. In particular, an instruction that loads from memory and that precedes an LFENCE receives data from memory prior to completion of the LFENCE. (An LFENCE that follows an instruction that stores to memory might complete before the data being stored have become globally visible.) Instructions following an LFENCE may be fetched from memory before the LFENCE, but they will not execute (even speculatively) until the LFENCE completes.\nWeakly ordered memory types can be used to achieve higher processor performance through such techniques as out-of-order issue and speculative reads. The degree to which a consumer of data recognizes or knows that the data is weakly ordered varies among applications and may be unknown to the producer of this data. The LFENCE instruction provides a performance-efficient way of ensuring load ordering between routines that produce weakly-ordered results and routines that consume that data.\nProcessors are free to fetch and cache data speculatively from regions of system memory that use the WB, WC, and WT memory types. This speculative fetching can occur at any time and is not tied to instruction execution. Thus, it is not ordered with respect to executions of the LFENCE instruction; data can be brought into the caches speculatively just before, during, or after the execution of an LFENCE instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.\nSpecification of the instruction's opcode above indicates a ModR/M byte of E8. For this instruction, the processor ignores the r/m field of the ModR/M byte. Thus, LFENCE is encoded by any opcode of the form 0F AE Ex, where x is in the range 8-F.", + "operation": "Wait_On_Following_Instructions_Until(preceding_instructions_complete);\n", + "url": "https://www.felixcloutier.com/x86/lfence" + }, + "lfs": { + "instruction": "LFS", + "title": "LDS/LES/LFS/LGS/LSS\n\t\t— Load Far Pointer", + "opcode": "0F B4 /r", + "description": "Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.\nIf one of these instructions is executed in protected mode, additional information from the segment descriptor pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment register.\nAlso in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to the segment occurs.)\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "64-BIT_MODE\n IF SS is loaded\n THEN\n IF SegmentSelector = NULL and ( (RPL = 3) or\n (RPL ≠ 3 and RPL ≠ CPL) )\n THEN #GP(0);\n ELSE IF descriptor is in non-canonical space\n THEN #GP(selector); FI;\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF attempt to load DS, or ES\n THEN #UD;\n ELSE IF FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and ( RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) ;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nPREOTECTED MODE OR COMPATIBILITY MODE;\n IF SS is loaded\n THEN\n IF SegementSelector = NULL\n THEN #GP(0);\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF DS, ES, FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and (RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) AND RPL;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF DS, ES, FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nReal-Address or Virtual-8086 Mode\n SegmentRegister := SegmentSelector(SRC); FI;\n DEST := Offset(SRC);\n", + "url": "https://www.felixcloutier.com/x86/lds:les:lfs:lgs:lss" + }, + "lgdt": { + "instruction": "LGDT", + "title": "LGDT/LIDT\n\t\t— Load Global/Interrupt Descriptor Table Register", + "opcode": "0F 01 /2", + "description": "Loads the values in the source operand into the global descriptor table register (GDTR) or the interrupt descriptor table register (IDTR). The source operand specifies a 6-byte memory location that contains the base address (a linear address) and the limit (size of table in bytes) of the global descriptor table (GDT) or the interrupt descriptor table (IDT). If operand-size attribute is 32 bits, a 16-bit limit (lower 2 bytes of the 6-byte data operand) and a 32-bit base address (upper 4 bytes of the data operand) are loaded into the register. If the operand-size attribute is 16 bits, a 16-bit limit (lower 2 bytes) and a 24-bit base address (third, fourth, and fifth byte) are loaded. Here, the high-order byte of the operand is not used and the high-order byte of the base address in the GDTR or IDTR is filled with zeros.\nThe LGDT and LIDT instructions are used only in operating-system software; they are not used in application programs. They are the only instructions that directly load a linear address (that is, not a segment-relative address) and a limit in protected mode. They are commonly executed in real-address mode to allow processor initialization prior to switching to protected mode.\nIn 64-bit mode, the instruction’s operand size is fixed at 8+2 bytes (an 8-byte base and a 2-byte limit). See the summary chart at the beginning of this section for encoding data and limits.\nSee “SGDT—Store Global Descriptor Table Register” in Chapter 4, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for information on storing the contents of the GDTR and IDTR.", + "operation": "IF Instruction is LIDT\n THEN\n IF OperandSize = 16\n THEN\n IDTR(Limit) := SRC[0:15];\n IDTR(Base) := SRC[16:47] AND 00FFFFFFH;\n ELSE IF 32-bit Operand Size\n THEN\n IDTR(Limit) := SRC[0:15];\n IDTR(Base) := SRC[16:47];\n FI;\n ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)\n THEN\n IDTR(Limit) := SRC[0:15];\n IDTR(Base) := SRC[16:79];\n FI;\n FI;\n ELSE (* Instruction is LGDT *)\n IF OperandSize = 16\n THEN\n GDTR(Limit) := SRC[0:15];\n GDTR(Base) := SRC[16:47] AND 00FFFFFFH;\n ELSE IF 32-bit Operand Size\n THEN\n GDTR(Limit) := SRC[0:15];\n GDTR(Base) := SRC[16:47];\n FI;\n ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)\n THEN\n GDTR(Limit) := SRC[0:15];\n GDTR(Base) := SRC[16:79];\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lgdt:lidt" + }, + "lgs": { + "instruction": "LGS", + "title": "LDS/LES/LFS/LGS/LSS\n\t\t— Load Far Pointer", + "opcode": "0F B5 /r", + "description": "Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.\nIf one of these instructions is executed in protected mode, additional information from the segment descriptor pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment register.\nAlso in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to the segment occurs.)\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "64-BIT_MODE\n IF SS is loaded\n THEN\n IF SegmentSelector = NULL and ( (RPL = 3) or\n (RPL ≠ 3 and RPL ≠ CPL) )\n THEN #GP(0);\n ELSE IF descriptor is in non-canonical space\n THEN #GP(selector); FI;\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF attempt to load DS, or ES\n THEN #UD;\n ELSE IF FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and ( RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) ;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nPREOTECTED MODE OR COMPATIBILITY MODE;\n IF SS is loaded\n THEN\n IF SegementSelector = NULL\n THEN #GP(0);\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF DS, ES, FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and (RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) AND RPL;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF DS, ES, FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nReal-Address or Virtual-8086 Mode\n SegmentRegister := SegmentSelector(SRC); FI;\n DEST := Offset(SRC);\n", + "url": "https://www.felixcloutier.com/x86/lds:les:lfs:lgs:lss" + }, + "lidt": { + "instruction": "LIDT", + "title": "LGDT/LIDT\n\t\t— Load Global/Interrupt Descriptor Table Register", + "opcode": "0F 01 /3", + "description": "Loads the values in the source operand into the global descriptor table register (GDTR) or the interrupt descriptor table register (IDTR). The source operand specifies a 6-byte memory location that contains the base address (a linear address) and the limit (size of table in bytes) of the global descriptor table (GDT) or the interrupt descriptor table (IDT). If operand-size attribute is 32 bits, a 16-bit limit (lower 2 bytes of the 6-byte data operand) and a 32-bit base address (upper 4 bytes of the data operand) are loaded into the register. If the operand-size attribute is 16 bits, a 16-bit limit (lower 2 bytes) and a 24-bit base address (third, fourth, and fifth byte) are loaded. Here, the high-order byte of the operand is not used and the high-order byte of the base address in the GDTR or IDTR is filled with zeros.\nThe LGDT and LIDT instructions are used only in operating-system software; they are not used in application programs. They are the only instructions that directly load a linear address (that is, not a segment-relative address) and a limit in protected mode. They are commonly executed in real-address mode to allow processor initialization prior to switching to protected mode.\nIn 64-bit mode, the instruction’s operand size is fixed at 8+2 bytes (an 8-byte base and a 2-byte limit). See the summary chart at the beginning of this section for encoding data and limits.\nSee “SGDT—Store Global Descriptor Table Register” in Chapter 4, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for information on storing the contents of the GDTR and IDTR.", + "operation": "IF Instruction is LIDT\n THEN\n IF OperandSize = 16\n THEN\n IDTR(Limit) := SRC[0:15];\n IDTR(Base) := SRC[16:47] AND 00FFFFFFH;\n ELSE IF 32-bit Operand Size\n THEN\n IDTR(Limit) := SRC[0:15];\n IDTR(Base) := SRC[16:47];\n FI;\n ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)\n THEN\n IDTR(Limit) := SRC[0:15];\n IDTR(Base) := SRC[16:79];\n FI;\n FI;\n ELSE (* Instruction is LGDT *)\n IF OperandSize = 16\n THEN\n GDTR(Limit) := SRC[0:15];\n GDTR(Base) := SRC[16:47] AND 00FFFFFFH;\n ELSE IF 32-bit Operand Size\n THEN\n GDTR(Limit) := SRC[0:15];\n GDTR(Base) := SRC[16:47];\n FI;\n ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)\n THEN\n GDTR(Limit) := SRC[0:15];\n GDTR(Base) := SRC[16:79];\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lgdt:lidt" + }, + "lldt": { + "instruction": "LLDT", + "title": "LLDT\n\t\t— Load Local Descriptor Table Register", + "opcode": "0F 00 /2", + "description": "Loads the source operand into the segment selector field of the local descriptor table register (LDTR). The source operand (a general-purpose register or a memory location) contains a segment selector that points to a local descriptor table (LDT). After the segment selector is loaded in the LDTR, the processor uses the segment selector to locate the segment descriptor for the LDT in the global descriptor table (GDT). It then loads the segment limit and base address for the LDT from the segment descriptor into the LDTR. The segment registers DS, ES, SS, FS, GS, and CS are not affected by this instruction, nor is the LDTR field in the task state segment (TSS) for the current task.\nIf bits 2-15 of the source operand are 0, LDTR is marked invalid and the LLDT instruction completes silently. However, all subsequent references to descriptors in the LDT (except by the LAR, VERR, VERW or LSL instructions) cause a general protection exception (#GP).\nThe operand-size attribute has no effect on this instruction.\nThe LLDT instruction is provided for use in operating-system software; it should not be used in application programs. This instruction can only be executed in protected mode or 64-bit mode.\nIn 64-bit mode, the operand size is fixed at 16 bits.", + "operation": "IF SRC(Offset) > descriptor table limit\n THEN #GP(segment selector); FI;\nIF segment selector is valid\n Read segment descriptor;\n IF SegmentDescriptor(Type) ≠ LDT\n THEN #GP(segment selector); FI;\n IF segment descriptor is not present\n THEN #NP(segment selector); FI;\n LDTR(SegmentSelector) := SRC;\n LDTR(SegmentDescriptor) := GDTSegmentDescriptor;\nELSE LDTR := INVALID\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lldt" + }, + "lmsw": { + "instruction": "LMSW", + "title": "LMSW\n\t\t— Load Machine Status Word", + "opcode": "0F 01 /6", + "description": "Loads the source operand into the machine status word, bits 0 through 15 of register CR0. The source operand can be a 16-bit general-purpose register or a memory location. Only the low-order 4 bits of the source operand (which contains the PE, MP, EM, and TS flags) are loaded into CR0. The PG, CD, NW, AM, WP, NE, and ET flags of CR0 are not affected. The operand-size attribute has no effect on this instruction.\nIf the PE flag of the source operand (bit 0) is set to 1, the instruction causes the processor to switch to protected mode. While in protected mode, the LMSW instruction cannot be used to clear the PE flag and force a switch back to real-address mode.\nThe LMSW instruction is provided for use in operating-system software; it should not be used in application programs. In protected or virtual-8086 mode, it can only be executed at CPL 0.\nThis instruction is provided for compatibility with the Intel 286 processor; programs and procedures intended to run on IA-32 and Intel 64 processors beginning with Intel386 processors should use the MOV (control registers) instruction to load the whole CR0 register. The MOV CR0 instruction can be used to set and clear the PE flag in CR0, allowing a procedure or program to switch between protected and real-address modes.\nThis instruction is a serializing instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode. Note that the operand size is fixed at 16 bits.\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "CR0[0:3] := SRC[0:3];\n", + "url": "https://www.felixcloutier.com/x86/lmsw" + }, + "loadiwkey": { + "instruction": "LOADIWKEY", + "title": "LOADIWKEY\n\t\t— Load Internal Wrapping Key With Key Locker", + "opcode": "F3 0F 38 DC 11:rrr:bbb LOADIWKEY xmm1, xmm2, , ", + "description": "The LOADIWKEY1 instruction writes the Key Locker internal wrapping key, which is called IWKey. This IWKey is used by the ENCODEKEY* instructions to wrap keys into handles. Conversely, the AESENC/DEC*KL instructions use IWKey to unwrap those keys from the handles and help verify the handle integrity. For security reasons, no instruction is designed to allow software to directly read the IWKey value.\nIWKey includes two cryptographic keys as well as metadata. The two cryptographic keys are loaded from register sources so that LOADIWKEY can be executed without the keys ever being in memory.\nThe key input operands are:\nThe implicit operand EAX specifies the KeySource and whether backing up the key is permitted:\n1. Further details on Key Locker and usage of this instruction can be found here:", + "operation": "IF CPL > 0\n // LOADKWKEY only allowed at ring 0 (supervisor mode)\n THEN #GP (0); FI;\nIF EAX[4:1] > 1\n // Reserved KeySource encoding used\n THEN #GP (0); FI;\nIF EAX[31:5] != 0\n // Reserved bit in EAX is set\n THEN #GP (0); FI;\nIF EAX[0] AND (CPUID.19H.ECX[0] == 0)\n // NoBackup is not supported on this part\n THEN #GP (0); FI;\nIF (EAX[4:1] == 1) AND (CPUID.19H.ECX[1] == 0)\n // KeySource of 1 is not supported on this part\n THEN #GP (0); FI;\nIF (EAX[4:1] == 0) // KeySource of 0\n THEN\n IWKey.Encryption Key[127:0] := SRC2[127:0]:\n IWKey.Encryption Key[255:128] := SRC1[127:0];\n IWKey.IntegrityKey[127:0] := XMM0[127:0];\n IWKey.NoBackup = EAX [0];\n IWKey.KeySource = EAX [4:1];\n RFLAGS.ZF := 0;\n ELSE // KeySource of 1. See RDSEED definition for details of randomness\n IF HW_NRND_GEN.ready == 1 // Full-entropy random data from RDSEED hardware block was received\n THEN\n IWKey.Encryption Key[127:0] := SRC2[127:0] XOR HW_NRND_GEN.data[127:0];\n IWKey.Encryption Key[255:128] := SRC1[127:0] XOR HW_NRND_GEN.data[255:128];\n IWKey.IntegrityKey[127:0] := XMM0[127:0] XOR HW_NRND_GEN.data[383:256];\n IWKey.NoBackup = EAX [0];\n IWKey.KeySource = EAX [4:1];\n RFLAGS.ZF := 0;\n ELSE // Random data was not returned from RDSEED hardware block. IWKey was not loaded\n RFLAGS.ZF := 1;\n FI;\nFI;\nRFLAGS.OF, SF, AF, PF, CF := 0;\n", + "url": "https://www.felixcloutier.com/x86/loadiwkey" + }, + "lock": { + "instruction": "LOCK", + "title": "LOCK\n\t\t— Assert LOCK# Signal Prefix", + "opcode": "F0", + "description": "Causes the processor’s LOCK# signal to be asserted during execution of the accompanying instruction (turns the instruction into an atomic instruction). In a multiprocessor environment, the LOCK# signal ensures that the processor has exclusive use of any shared memory while the signal is asserted.\nIn most IA-32 and all Intel 64 processors, locking may occur without the LOCK# signal being asserted. See the “IA-32 Architecture Compatibility” section below for more details.\nThe LOCK prefix can be prepended only to the following instructions and only to those forms of the instructions where the destination operand is a memory operand: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG. If the LOCK prefix is used with one of these instructions and the source operand is a memory operand, an undefined opcode exception (#UD) may be generated. An undefined opcode exception will also be generated if the LOCK prefix is used with any instruction not in the above list. The XCHG instruction always asserts the LOCK# signal regardless of the presence or absence of the LOCK prefix.\nThe LOCK prefix is typically used with the BTS instruction to perform a read-modify-write operation on a memory location in shared memory environment.\nThe integrity of the LOCK prefix is not affected by the alignment of the memory field. Memory locking is observed for arbitrarily misaligned fields.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "AssertLOCK#(DurationOfAccompaningInstruction);\n", + "url": "https://www.felixcloutier.com/x86/lock" + }, + "lods": { + "instruction": "LODS", + "title": "LODS/LODSB/LODSW/LODSD/LODSQ\n\t\t— Load String", + "opcode": "AC", + "description": "Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the LODS mnemonic) allows the source operand to be specified explicitly. Here, the source operand should be a symbol that indicates the size and location of the source value. The destination operand is then automatically selected to match the size of the source operand (the AL register for byte operands, AX for word operands, and EAX for doubleword operands). This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI registers, which must be loaded correctly before the load string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the LODS instructions. Here also DS:(E)SI is assumed to be the source operand and the AL, AX, or EAX register is assumed to be the destination operand. The size of the source and destination operands is selected with the mnemonic: LODSB (byte loaded into register AL), LODSW (word loaded into AX), or LODSD (doubleword loaded into EAX).\nAfter the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the (E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.) The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. LODS/LODSQ load the quadword at address (R)SI into RAX. The (R)SI register is then incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register.\nThe LODS, LODSB, LODSW, and LODSD instructions can be preceded by the REP prefix for block loads of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because further processing of the data moved into the register is usually necessary before the next transfer can be made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.", + "operation": "IF AL := SRC; (* Byte load *)\n THEN AL := SRC; (* Byte load *)\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\nELSE IF AX := SRC; (* Word load *)\n THEN IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n IF;\n FI;\nELSE IF EAX := SRC; (* Doubleword load *)\n THENIFDF =0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\nELSE IF RAX := SRC; (* Quadword load *)\n THEN IF DF = 0\n THEN (R)SI := (R)SI + 8;\n ELSE (R)SI := (R)SI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq" + }, + "lodsb": { + "instruction": "LODSB", + "title": "LODS/LODSB/LODSW/LODSD/LODSQ\n\t\t— Load String", + "opcode": "AC", + "description": "Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the LODS mnemonic) allows the source operand to be specified explicitly. Here, the source operand should be a symbol that indicates the size and location of the source value. The destination operand is then automatically selected to match the size of the source operand (the AL register for byte operands, AX for word operands, and EAX for doubleword operands). This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI registers, which must be loaded correctly before the load string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the LODS instructions. Here also DS:(E)SI is assumed to be the source operand and the AL, AX, or EAX register is assumed to be the destination operand. The size of the source and destination operands is selected with the mnemonic: LODSB (byte loaded into register AL), LODSW (word loaded into AX), or LODSD (doubleword loaded into EAX).\nAfter the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the (E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.) The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. LODS/LODSQ load the quadword at address (R)SI into RAX. The (R)SI register is then incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register.\nThe LODS, LODSB, LODSW, and LODSD instructions can be preceded by the REP prefix for block loads of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because further processing of the data moved into the register is usually necessary before the next transfer can be made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.", + "operation": "IF AL := SRC; (* Byte load *)\n THEN AL := SRC; (* Byte load *)\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\nELSE IF AX := SRC; (* Word load *)\n THEN IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n IF;\n FI;\nELSE IF EAX := SRC; (* Doubleword load *)\n THENIFDF =0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\nELSE IF RAX := SRC; (* Quadword load *)\n THEN IF DF = 0\n THEN (R)SI := (R)SI + 8;\n ELSE (R)SI := (R)SI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq" + }, + "lodsd": { + "instruction": "LODSD", + "title": "LODS/LODSB/LODSW/LODSD/LODSQ\n\t\t— Load String", + "opcode": "AD", + "description": "Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the LODS mnemonic) allows the source operand to be specified explicitly. Here, the source operand should be a symbol that indicates the size and location of the source value. The destination operand is then automatically selected to match the size of the source operand (the AL register for byte operands, AX for word operands, and EAX for doubleword operands). This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI registers, which must be loaded correctly before the load string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the LODS instructions. Here also DS:(E)SI is assumed to be the source operand and the AL, AX, or EAX register is assumed to be the destination operand. The size of the source and destination operands is selected with the mnemonic: LODSB (byte loaded into register AL), LODSW (word loaded into AX), or LODSD (doubleword loaded into EAX).\nAfter the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the (E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.) The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. LODS/LODSQ load the quadword at address (R)SI into RAX. The (R)SI register is then incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register.\nThe LODS, LODSB, LODSW, and LODSD instructions can be preceded by the REP prefix for block loads of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because further processing of the data moved into the register is usually necessary before the next transfer can be made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.", + "operation": "IF AL := SRC; (* Byte load *)\n THEN AL := SRC; (* Byte load *)\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\nELSE IF AX := SRC; (* Word load *)\n THEN IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n IF;\n FI;\nELSE IF EAX := SRC; (* Doubleword load *)\n THENIFDF =0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\nELSE IF RAX := SRC; (* Quadword load *)\n THEN IF DF = 0\n THEN (R)SI := (R)SI + 8;\n ELSE (R)SI := (R)SI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq" + }, + "lodsq": { + "instruction": "LODSQ", + "title": "LODS/LODSB/LODSW/LODSD/LODSQ\n\t\t— Load String", + "opcode": "REX.W + AD", + "description": "Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the LODS mnemonic) allows the source operand to be specified explicitly. Here, the source operand should be a symbol that indicates the size and location of the source value. The destination operand is then automatically selected to match the size of the source operand (the AL register for byte operands, AX for word operands, and EAX for doubleword operands). This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI registers, which must be loaded correctly before the load string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the LODS instructions. Here also DS:(E)SI is assumed to be the source operand and the AL, AX, or EAX register is assumed to be the destination operand. The size of the source and destination operands is selected with the mnemonic: LODSB (byte loaded into register AL), LODSW (word loaded into AX), or LODSD (doubleword loaded into EAX).\nAfter the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the (E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.) The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. LODS/LODSQ load the quadword at address (R)SI into RAX. The (R)SI register is then incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register.\nThe LODS, LODSB, LODSW, and LODSD instructions can be preceded by the REP prefix for block loads of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because further processing of the data moved into the register is usually necessary before the next transfer can be made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.", + "operation": "IF AL := SRC; (* Byte load *)\n THEN AL := SRC; (* Byte load *)\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\nELSE IF AX := SRC; (* Word load *)\n THEN IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n IF;\n FI;\nELSE IF EAX := SRC; (* Doubleword load *)\n THENIFDF =0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\nELSE IF RAX := SRC; (* Quadword load *)\n THEN IF DF = 0\n THEN (R)SI := (R)SI + 8;\n ELSE (R)SI := (R)SI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq" + }, + "lodsw": { + "instruction": "LODSW", + "title": "LODS/LODSB/LODSW/LODSD/LODSQ\n\t\t— Load String", + "opcode": "AD", + "description": "Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the LODS mnemonic) allows the source operand to be specified explicitly. Here, the source operand should be a symbol that indicates the size and location of the source value. The destination operand is then automatically selected to match the size of the source operand (the AL register for byte operands, AX for word operands, and EAX for doubleword operands). This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI registers, which must be loaded correctly before the load string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the LODS instructions. Here also DS:(E)SI is assumed to be the source operand and the AL, AX, or EAX register is assumed to be the destination operand. The size of the source and destination operands is selected with the mnemonic: LODSB (byte loaded into register AL), LODSW (word loaded into AX), or LODSD (doubleword loaded into EAX).\nAfter the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the (E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.) The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.\nIn 64-bit mode, use of the REX.W prefix promotes operation to 64 bits. LODS/LODSQ load the quadword at address (R)SI into RAX. The (R)SI register is then incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register.\nThe LODS, LODSB, LODSW, and LODSD instructions can be preceded by the REP prefix for block loads of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because further processing of the data moved into the register is usually necessary before the next transfer can be made. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a description of the REP prefix.", + "operation": "IF AL := SRC; (* Byte load *)\n THEN AL := SRC; (* Byte load *)\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\nELSE IF AX := SRC; (* Word load *)\n THEN IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n IF;\n FI;\nELSE IF EAX := SRC; (* Doubleword load *)\n THENIFDF =0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\nELSE IF RAX := SRC; (* Quadword load *)\n THEN IF DF = 0\n THEN (R)SI := (R)SI + 8;\n ELSE (R)SI := (R)SI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lods:lodsb:lodsw:lodsd:lodsq" + }, + "loop": { + "instruction": "LOOP", + "title": "LOOP/LOOPcc\n\t\t— Loop According to ECX Counter", + "opcode": "E2 cb", + "description": "Performs a loop operation using the RCX, ECX or CX register as a counter (depending on whether address size is 64 bits, 32 bits, or 16 bits). Note that the LOOP instruction ignores REX.W; but 64-bit address size can be over-ridden using a 67H prefix.\nEach time the LOOP instruction is executed, the count register is decremented, then checked for 0. If the count is 0, the loop is terminated and program execution continues with the instruction following the LOOP instruction. If the count is not zero, a near jump is performed to the destination (target) operand, which is presumably the instruction at the beginning of the loop.\nThe target instruction is specified with a relative offset (a signed offset relative to the current value of the instruction pointer in the IP/EIP/RIP register). This offset is generally specified as a label in assembly code, but at the machine code level, it is encoded as a signed, 8-bit immediate value, which is added to the instruction pointer. Offsets of –128 to +127 are allowed with this instruction.\nSome forms of the loop instruction (LOOPcc) also accept the ZF flag as a condition for terminating the loop before the count reaches zero. With these forms of the instruction, a condition code (cc) is associated with each instruction to indicate the condition being tested for. Here, the LOOPcc instruction itself does not affect the state of the ZF flag; the ZF flag is changed by other instructions in the loop.", + "operation": "IF (AddressSize = 32)\n THEN Count is ECX;\nELSE IF (AddressSize = 64)\n Count is RCX;\nELSE Count is CX;\nFI;\nCount := Count – 1;\nIF Instruction is not LOOP\n THEN\n IF (Instruction := LOOPE) or (Instruction := LOOPZ)\n THEN IF (ZF = 1) and (Count ≠ 0)\n THEN BranchCond := 1;\n ELSE BranchCond := 0;\n FI;\n ELSE (Instruction = LOOPNE) or (Instruction = LOOPNZ)\n IF (ZF = 0 ) and (Count ≠ 0)\n THEN BranchCond := 1;\n ELSE BranchCond := 0;\n FI;\n ELSE (* Instruction = LOOP *)\n IF (Count ≠ 0)\n THEN BranchCond := 1;\n ELSE BranchCond := 0;\n FI;\nFI;\nIF BranchCond = 1\n THEN\n IF in 64-bit mode (* OperandSize = 64 *)\n THEN\n tempRIP := RIP + SignExtend(DEST);\n IF tempRIP is not canonical\n THEN #GP(0);\n ELSE RIP := tempRIP;\n FI;\n ELSE\n tempEIP := EIP SignExtend(DEST);\n IF OperandSize 16\n THEN tempEIP := tempEIP AND 0000FFFFH;\n FI;\n IF tempEIP is not within code segment limit\n THEN #GP(0);\n ELSE EIP := tempEIP;\n FI;\n FI;\n ELSE\n Terminate loop and continue program execution at (R/E)IP;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/loop:loopcc" + }, + "loopcc": { + "instruction": "LOOPCC", + "title": "LOOP/LOOPcc\n\t\t— Loop According to ECX Counter", + "opcode": "E2 cb", + "description": "Performs a loop operation using the RCX, ECX or CX register as a counter (depending on whether address size is 64 bits, 32 bits, or 16 bits). Note that the LOOP instruction ignores REX.W; but 64-bit address size can be over-ridden using a 67H prefix.\nEach time the LOOP instruction is executed, the count register is decremented, then checked for 0. If the count is 0, the loop is terminated and program execution continues with the instruction following the LOOP instruction. If the count is not zero, a near jump is performed to the destination (target) operand, which is presumably the instruction at the beginning of the loop.\nThe target instruction is specified with a relative offset (a signed offset relative to the current value of the instruction pointer in the IP/EIP/RIP register). This offset is generally specified as a label in assembly code, but at the machine code level, it is encoded as a signed, 8-bit immediate value, which is added to the instruction pointer. Offsets of –128 to +127 are allowed with this instruction.\nSome forms of the loop instruction (LOOPcc) also accept the ZF flag as a condition for terminating the loop before the count reaches zero. With these forms of the instruction, a condition code (cc) is associated with each instruction to indicate the condition being tested for. Here, the LOOPcc instruction itself does not affect the state of the ZF flag; the ZF flag is changed by other instructions in the loop.", + "operation": "IF (AddressSize = 32)\n THEN Count is ECX;\nELSE IF (AddressSize = 64)\n Count is RCX;\nELSE Count is CX;\nFI;\nCount := Count – 1;\nIF Instruction is not LOOP\n THEN\n IF (Instruction := LOOPE) or (Instruction := LOOPZ)\n THEN IF (ZF = 1) and (Count ≠ 0)\n THEN BranchCond := 1;\n ELSE BranchCond := 0;\n FI;\n ELSE (Instruction = LOOPNE) or (Instruction = LOOPNZ)\n IF (ZF = 0 ) and (Count ≠ 0)\n THEN BranchCond := 1;\n ELSE BranchCond := 0;\n FI;\n ELSE (* Instruction = LOOP *)\n IF (Count ≠ 0)\n THEN BranchCond := 1;\n ELSE BranchCond := 0;\n FI;\nFI;\nIF BranchCond = 1\n THEN\n IF in 64-bit mode (* OperandSize = 64 *)\n THEN\n tempRIP := RIP + SignExtend(DEST);\n IF tempRIP is not canonical\n THEN #GP(0);\n ELSE RIP := tempRIP;\n FI;\n ELSE\n tempEIP := EIP SignExtend(DEST);\n IF OperandSize 16\n THEN tempEIP := tempEIP AND 0000FFFFH;\n FI;\n IF tempEIP is not within code segment limit\n THEN #GP(0);\n ELSE EIP := tempEIP;\n FI;\n FI;\n ELSE\n Terminate loop and continue program execution at (R/E)IP;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/loop:loopcc" + }, + "lsl": { + "instruction": "LSL", + "title": "LSL\n\t\t— Load Segment Limit", + "opcode": "0F 03 /r", + "description": "Loads the unscrambled segment limit from the segment descriptor specified with the second operand (source operand) into the first operand (destination operand) and sets the ZF flag in the EFLAGS register. The source operand (which can be a register or a memory location) contains the segment selector for the segment descriptor being accessed. The destination operand is a general-purpose register.\nThe processor performs access checks as part of the loading process. Once loaded in the destination register, software can compare the segment limit with the offset of a pointer.\nThe segment limit is a 20-bit value contained in bytes 0 and 1 and in the first 4 bits of byte 6 of the segment descriptor. If the descriptor has a byte granular segment limit (the granularity flag is set to 0), the destination operand is loaded with a byte granular value (byte limit). If the descriptor has a page granular segment limit (the granularity flag is set to 1), the LSL instruction will translate the page granular limit (page limit) into a byte limit before loading it into the destination operand. The translation is performed by shifting the 20-bit “raw” limit left 12 bits and filling the low-order 12 bits with 1s.\nWhen the operand size is 32 bits, the 32-bit byte limit is stored in the destination operand. When the operand size is 16 bits, a valid 32-bit limit is computed; however, the upper 16 bits are truncated and only the low-order 16 bits are loaded into the destination operand.\nThis instruction performs the following checks before it loads the segment limit into the destination register:\nIf the segment descriptor cannot be accessed or is an invalid type for the instruction, the ZF flag is cleared and no value is loaded in the destination operand.", + "operation": "IF SRC(Offset) > descriptor table limit\n THEN ZF := 0; FI;\nRead segment descriptor;\nIF SegmentDescriptor(Type) ≠ conforming code segment\nand (CPL > DPL) OR (RPL > DPL)\nor Segment type is not valid for instruction\n THEN\n ZF := 0;\n ELSE\n temp := SegmentLimit([SRC]);\n IF (SegmentDescriptor(G) = 1)\n THEN temp := (temp << 12) OR 00000FFFH;\n ELSE IF OperandSize = 32\n THEN DEST := temp; FI;\n ELSE IF OperandSize = 64 (* REX.W used *)\n THEN DEST := temp(* Zero-extended *); FI;\n ELSE (* OperandSize = 16 *)\n DEST := temp AND FFFFH;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/lsl" + }, + "lss": { + "instruction": "LSS", + "title": "LDS/LES/LFS/LGS/LSS\n\t\t— Load Far Pointer", + "opcode": "0F B2 /r", + "description": "Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.\nIf one of these instructions is executed in protected mode, additional information from the segment descriptor pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment register.\nAlso in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to the segment occurs.)\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "64-BIT_MODE\n IF SS is loaded\n THEN\n IF SegmentSelector = NULL and ( (RPL = 3) or\n (RPL ≠ 3 and RPL ≠ CPL) )\n THEN #GP(0);\n ELSE IF descriptor is in non-canonical space\n THEN #GP(selector); FI;\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF attempt to load DS, or ES\n THEN #UD;\n ELSE IF FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and ( RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) ;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nPREOTECTED MODE OR COMPATIBILITY MODE;\n IF SS is loaded\n THEN\n IF SegementSelector = NULL\n THEN #GP(0);\n ELSE IF Segment selector index is not within descriptor table limits\n or segment selector RPL ≠ CPL\n or access rights indicate nonwritable data segment\n or DPL ≠ CPL\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #SS(selector); FI;\n FI;\n SS := SegmentSelector(SRC);\n SS := SegmentDescriptor([SRC]);\n ELSE IF DS, ES, FS, or GS is loaded with non-NULL segment selector\n THEN IF Segment selector index is not within descriptor table limits\n or access rights indicate segment neither data nor readable code segment\n or segment is data or nonconforming-code segment\n and (RPL > DPL or CPL > DPL)\n THEN #GP(selector); FI;\n ELSE IF Segment marked not present\n THEN #NP(selector); FI;\n FI;\n SegmentRegister := SegmentSelector(SRC) AND RPL;\n SegmentRegister := SegmentDescriptor([SRC]);\n FI;\n ELSE IF DS, ES, FS, or GS is loaded with a NULL selector:\n THEN\n SegmentRegister := NULLSelector;\n SegmentRegister(DescriptorValidBit) := 0; FI; (* Hidden flag;\n not accessible by software *)\n FI;\n DEST := Offset(SRC);\nReal-Address or Virtual-8086 Mode\n SegmentRegister := SegmentSelector(SRC); FI;\n DEST := Offset(SRC);\n", + "url": "https://www.felixcloutier.com/x86/lds:les:lfs:lgs:lss" + }, + "ltr": { + "instruction": "LTR", + "title": "LTR\n\t\t— Load Task Register", + "opcode": "0F 00 /3", + "description": "Loads the source operand into the segment selector field of the task register. The source operand (a general-purpose register or a memory location) contains a segment selector that points to a task state segment (TSS). After the segment selector is loaded in the task register, the processor uses the segment selector to locate the segment descriptor for the TSS in the global descriptor table (GDT). It then loads the segment limit and base address for the TSS from the segment descriptor into the task register. The task pointed to by the task register is marked busy, but a switch to the task does not occur.\nThe LTR instruction is provided for use in operating-system software; it should not be used in application programs. It can only be executed in protected mode when the CPL is 0. It is commonly used in initialization code to establish the first task to be executed.\nThe operand-size attribute has no effect on this instruction.\nIn 64-bit mode, the operand size is still fixed at 16 bits. The instruction references a 16-byte descriptor to load the 64-bit base.", + "operation": "IF SRC is a NULL selector\n THEN #GP(0);\nIF SRC(Offset) > descriptor table limit OR IF SRC(type) ≠ global\n THEN #GP(segment selector); FI;\nRead segment descriptor;\nIF segment descriptor is not for an available TSS\n THEN #GP(segment selector); FI;\nIF segment descriptor is not present\n THEN #NP(segment selector); FI;\nTSSsegmentDescriptor(busy) := 1;\n(* Locked read-modify-write operation on the entire descriptor when setting busy flag *)\nTaskRegister(SegmentSelector) := SRC;\nTaskRegister(SegmentDescriptor) := TSSSegmentDescriptor;\n", + "url": "https://www.felixcloutier.com/x86/ltr" + }, + "lzcnt": { + "instruction": "LZCNT", + "title": "LZCNT\n\t\t— Count the Number of Leading Zero Bits", + "opcode": "F3 0F BD /r LZCNT r16, r/m16", + "description": "Counts the number of leading most significant zero bits in a source operand (second operand) returning the result into a destination (first operand).\nLZCNT differs from BSR. For example, LZCNT will produce the operand size when the input operand is zero. It should be noted that on processors that do not support LZCNT, the instruction byte encoding is executed as BSR.\nIn 64-bit mode 64-bit operand size requires REX.W=1.", + "operation": "temp := OperandSize - 1\nDEST := 0\nWHILE (temp >= 0) AND (Bit(SRC, temp) = 0)\nDO\n temp := temp - 1\n DEST := DEST+ 1\nOD\nIF DEST = OperandSize\n CF := 1\nELSE\n CF := 0\nFI\nIF DEST = 0\n ZF := 1\nELSE\n ZF := 0\nFI\n", + "url": "https://www.felixcloutier.com/x86/lzcnt" + }, + "maskmovdqu": { + "instruction": "MASKMOVDQU", + "title": "MASKMOVDQU\n\t\t— Store Selected Bytes of Double Quadword", + "opcode": "66 0F F7 /r MASKMOVDQU xmm1, xmm2", + "description": "Stores selected bytes from the source operand (first operand) into an 128-bit memory location. The mask operand (second operand) selects which bytes from the source operand are written to memory. The source and mask operands are XMM registers. The memory location specified by the effective address in the DI/EDI/RDI register (the default segment register is DS, but this may be overridden with a segment-override prefix). The memory location does not need to be aligned on a natural boundary. (The size of the store address depends on the address-size attribute.)\nThe most significant bit in each byte of the mask operand determines whether the corresponding byte in the source operand is written to the corresponding byte location in memory: 0 indicates no write and 1 indicates write.\nThe MASKMOVDQU instruction generates a non-temporal hint to the processor to minimize cache pollution. The non-temporal hint is implemented by using a write combining (WC) memory type protocol (see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). Because the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with MASKMOVDQU instructions if multiple processors might use different memory types to read/write the destination memory locations.\nBehavior with a mask of all 0s is as follows:\nThe MASKMOVDQU instruction can be used to improve performance of algorithms that need to merge data on a byte-by-byte basis. MASKMOVDQU should not cause a read for ownership; doing so generates unnecessary bandwidth since data is to be written directly using the byte-mask without allocating old data prior to the store.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.\nIf VMASKMOVDQU is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "IF (MASK[7] = 1)\n THEN DEST[DI/EDI] := SRC[7:0] ELSE (* Memory location unchanged *); FI;\nIF (MASK[15] = 1)\n THEN DEST[DI/EDI +1] := SRC[15:8] ELSE (* Memory location unchanged *); FI;\n (* Repeat operation for 3rd through 14th bytes in source operand *)\nIF (MASK[127] = 1)\n THEN DEST[DI/EDI +15] := SRC[127:120] ELSE (* Memory location unchanged *); FI;\n", + "url": "https://www.felixcloutier.com/x86/maskmovdqu" + }, + "maskmovq": { + "instruction": "MASKMOVQ", + "title": "MASKMOVQ\n\t\t— Store Selected Bytes of Quadword", + "opcode": "NP 0F F7 /r MASKMOVQ mm1, mm2", + "description": "Stores selected bytes from the source operand (first operand) into a 64-bit memory location. The mask operand (second operand) selects which bytes from the source operand are written to memory. The source and mask operands are MMX technology registers. The memory location specified by the effective address in the DI/EDI/RDI register (the default segment register is DS, but this may be overridden with a segment-override prefix). The memory location does not need to be aligned on a natural boundary. (The size of the store address depends on the address-size attribute.)\nThe most significant bit in each byte of the mask operand determines whether the corresponding byte in the source operand is written to the corresponding byte location in memory: 0 indicates no write and 1 indicates write.\nThe MASKMOVQ instruction generates a non-temporal hint to the processor to minimize cache pollution. The non-temporal hint is implemented by using a write combining (WC) memory type protocol (see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). Because the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with MASKMOVQ instructions if multiple processors might use different memory types to read/write the destination memory locations.\nThis instruction causes a transition from x87 FPU to MMX technology state (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]).\nThe behavior of the MASKMOVQ instruction with a mask of all 0s is as follows:\nThe MASKMOVQ instruction can be used to improve performance for algorithms that need to merge data on a byteby-byte basis. It should not cause a read for ownership; doing so generates unnecessary bandwidth since data is to be written directly using the byte-mask without allocating old data prior to the store.\nIn 64-bit mode, the memory address is specified by DS:RDI.", + "operation": "IF (MASK[7] = 1)\n THEN DEST[DI/EDI] := SRC[7:0] ELSE (* Memory location unchanged *); FI;\nIF (MASK[15] = 1)\n THEN DEST[DI/EDI +1] := SRC[15:8] ELSE (* Memory location unchanged *); FI;\n (* Repeat operation for 3rd through 6th bytes in source operand *)\nIF (MASK[63] = 1)\n THEN DEST[DI/EDI +15] := SRC[63:56] ELSE (* Memory location unchanged *); FI;\n", + "url": "https://www.felixcloutier.com/x86/maskmovq" + }, + "maxpd": { + "instruction": "MAXPD", + "title": "MAXPD\n\t\t— Maximum of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 5F /r MAXPD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed double precision floating-point values in the first source operand and the second source operand and returns the maximum value for each pair of values to the destination operand.\nIf the values being compared are both 0.0s (of either sign), the value in the second operand (source operand) is returned. If a value in the second operand is an SNaN, then SNaN is forwarded unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second operand (source operand), either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN source operand (from either the first or second operand) be returned, the action of MAXPD can be emulated using a sequence of instructions, such as a comparison followed by AND, ANDN, and OR.\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "MAX(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 > SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := MAX(SRC1[i+63:i], SRC2[63:0])\n ELSE\n DEST[i+63:i] := MAX(SRC1[i+63:i], SRC2[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := MAX(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := MAX(SRC1[127:64], SRC2[127:64])\nDEST[191:128] := MAX(SRC1[191:128], SRC2[191:128])\nDEST[255:192] := MAX(SRC1[255:192], SRC2[255:192])\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := MAX(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := MAX(SRC1[127:64], SRC2[127:64])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := MAX(DEST[63:0], SRC[63:0])\nDEST[127:64] := MAX(DEST[127:64], SRC[127:64])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/maxpd" + }, + "maxps": { + "instruction": "MAXPS", + "title": "MAXPS\n\t\t— Maximum of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 5F /r MAXPS xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed single precision floating-point values in the first source operand and the second source operand and returns the maximum value for each pair of values to the destination operand.\nIf the values being compared are both 0.0s (of either sign), the value in the second operand (source operand) is returned. If a value in the second operand is an SNaN, then SNaN is forwarded unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second operand (source operand), either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN source operand (from either the first or second operand) be returned, the action of MAXPS can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "MAX(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 > SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+31:i] := MAX(SRC1[i+31:i], SRC2[31:0])\n ELSE\n DEST[i+31:i] := MAX(SRC1[i+31:i], SRC2[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := MAX(SRC1[31:0], SRC2[31:0])\nDEST[63:32] := MAX(SRC1[63:32], SRC2[63:32])\nDEST[95:64] := MAX(SRC1[95:64], SRC2[95:64])\nDEST[127:96] := MAX(SRC1[127:96], SRC2[127:96])\nDEST[159:128] := MAX(SRC1[159:128], SRC2[159:128])\nDEST[191:160] := MAX(SRC1[191:160], SRC2[191:160])\nDEST[223:192] := MAX(SRC1[223:192], SRC2[223:192])\nDEST[255:224] := MAX(SRC1[255:224], SRC2[255:224])\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := MAX(SRC1[31:0], SRC2[31:0])\nDEST[63:32] := MAX(SRC1[63:32], SRC2[63:32])\nDEST[95:64] := MAX(SRC1[95:64], SRC2[95:64])\nDEST[127:96] := MAX(SRC1[127:96], SRC2[127:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := MAX(DEST[31:0], SRC[31:0])\nDEST[63:32] := MAX(DEST[63:32], SRC[63:32])\nDEST[95:64] := MAX(DEST[95:64], SRC[95:64])\nDEST[127:96] := MAX(DEST[127:96], SRC[127:96])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/maxps" + }, + "maxsd": { + "instruction": "MAXSD", + "title": "MAXSD\n\t\t— Return Maximum Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 5F /r MAXSD xmm1, xmm2/m64", + "description": "Compares the low double precision floating-point values in the first source operand and the second source operand, and returns the maximum value to the low quadword of the destination operand. The second source operand can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers. When the second source operand is a memory operand, only 64 bits are accessed.\nIf the values being compared are both 0.0s (of either sign), the value in the second source operand is returned. If a value in the second source operand is an SNaN, that SNaN is returned unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second source operand, either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN of either source operand be returned, the action of MAXSD can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\n128-bit Legacy SSE version: The destination and first source operand are the same. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded version: Bits (127:64) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low quadword element of the destination operand is updated according to the writemask.\nSoftware should ensure VMAXSD is encoded with VEX.L=0. Encoding VMAXSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "MAX(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 > SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := MAX(SRC1[63:0], SRC2[63:0])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := MAX(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := MAX(DEST[63:0], SRC[63:0])\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/maxsd" + }, + "maxss": { + "instruction": "MAXSS", + "title": "MAXSS\n\t\t— Return Maximum Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F 5F /r MAXSS xmm1, xmm2/m32", + "description": "Compares the low single precision floating-point values in the first source operand and the second source operand, and returns the maximum value to the low doubleword of the destination operand.\nIf the values being compared are both 0.0s (of either sign), the value in the second source operand is returned. If a value in the second source operand is an SNaN, that SNaN is returned unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second source operand, either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN from either source operand be returned, the action of MAXSS can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\nThe second source operand can be an XMM register or a 32-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The destination and first source operand are the same. Bits (MAXVL:32) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded version: The first source operand is an xmm register encoded by VEX.vvvv. Bits (127:32) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL:128) of the destination register are zeroed.\nEVEX encoded version: The low doubleword element of the destination operand is updated according to the writemask.\nSoftware should ensure VMAXSS is encoded with VEX.L=0. Encoding VMAXSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "MAX(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 > SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := MAX(SRC1[31:0], SRC2[31:0])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := MAX(SRC1[31:0], SRC2[31:0])\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := MAX(DEST[31:0], SRC[31:0])\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/maxss" + }, + "mfence": { + "instruction": "MFENCE", + "title": "MFENCE\n\t\t— Memory Fence", + "opcode": "NP 0F AE F0 MFENCE", + "description": "Performs a serializing operation on all load-from-memory and store-to-memory instructions that were issued prior the MFENCE instruction. This serializing operation guarantees that every load and store instruction that precedes the MFENCE instruction in program order becomes globally visible before any load or store instruction that follows the MFENCE instruction.1 The MFENCE instruction is ordered with respect to all load and store instructions, other MFENCE instructions, any LFENCE and SFENCE instructions, and any serializing instructions (such as the CPUID instruction). MFENCE does not serialize the instruction stream.\nWeakly ordered memory types can be used to achieve higher processor performance through such techniques as out-of-order issue, speculative reads, write-combining, and write-collapsing. The degree to which a consumer of data recognizes or knows that the data is weakly ordered varies among applications and may be unknown to the producer of this data. The MFENCE instruction provides a performance-efficient way of ensuring load and store ordering between routines that produce weakly-ordered results and routines that consume that data.\nProcessors are free to fetch and cache data speculatively from regions of system memory that use the WB, WC, and WT memory types. This speculative fetching can occur at any time and is not tied to instruction execution. Thus, it is not ordered with respect to executions of the MFENCE instruction; data can be brought into the caches speculatively just before, during, or after the execution of an MFENCE instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.\nSpecification of the instruction's opcode above indicates a ModR/M byte of F0. For this instruction, the processor ignores the r/m field of the ModR/M byte. Thus, MFENCE is encoded by any opcode of the form 0F AE Fx, where x is in the range 0-7.", + "operation": "Wait_On_Following_Loads_And_Stores_Until(preceding_loads_and_stores_globally_visible);\n", + "url": "https://www.felixcloutier.com/x86/mfence" + }, + "minpd": { + "instruction": "MINPD", + "title": "MINPD\n\t\t— Minimum of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 5D /r MINPD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed double precision floating-point values in the first source operand and the second source operand and returns the minimum value for each pair of values to the destination operand.\nIf the values being compared are both 0.0s (of either sign), the value in the second operand (source operand) is returned. If a value in the second operand is an SNaN, then SNaN is forwarded unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second operand (source operand), either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN source operand (from either the first or second operand) be returned, the action of MINPD can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "MIN(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 < SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := MIN(SRC1[i+63:i], SRC2[63:0])\n ELSE\n DEST[i+63:i] := MIN(SRC1[i+63:i], SRC2[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := MIN(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := MIN(SRC1[127:64], SRC2[127:64])\nDEST[191:128] := MIN(SRC1[191:128], SRC2[191:128])\nDEST[255:192] := MIN(SRC1[255:192], SRC2[255:192])\n\n\nDEST[63:0] := MIN(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := MIN(SRC1[127:64], SRC2[127:64])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := MIN(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := MIN(SRC1[127:64], SRC2[127:64])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/minpd" + }, + "minps": { + "instruction": "MINPS", + "title": "MINPS\n\t\t— Minimum of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 5D /r MINPS xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed single precision floating-point values in the first source operand and the second source operand and returns the minimum value for each pair of values to the destination operand.\nIf the values being compared are both 0.0s (of either sign), the value in the second operand (source operand) is returned. If a value in the second operand is an SNaN, then SNaN is forwarded unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second operand (source operand), either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN source operand (from either the first or second operand) be returned, the action of MINPS can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "MIN(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 < SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+31:i] := MIN(SRC1[i+31:i], SRC2[31:0])\n ELSE\n DEST[i+31:i] := MIN(SRC1[i+31:i], SRC2[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := MIN(SRC1[31:0], SRC2[31:0])\nDEST[63:32] := MIN(SRC1[63:32], SRC2[63:32])\nDEST[95:64] := MIN(SRC1[95:64], SRC2[95:64])\nDEST[127:96] := MIN(SRC1[127:96], SRC2[127:96])\nDEST[159:128] := MIN(SRC1[159:128], SRC2[159:128])\nDEST[191:160] := MIN(SRC1[191:160], SRC2[191:160])\nDEST[223:192] := MIN(SRC1[223:192], SRC2[223:192])\nDEST[255:224] := MIN(SRC1[255:224], SRC2[255:224])\n\n\nDEST[31:0] := MIN(SRC1[31:0], SRC2[31:0])\nDEST[63:32] := MIN(SRC1[63:32], SRC2[63:32])\nDEST[95:64] := MIN(SRC1[95:64], SRC2[95:64])\nDEST[127:96] := MIN(SRC1[127:96], SRC2[127:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := MIN(SRC1[31:0], SRC2[31:0])\nDEST[63:32] := MIN(SRC1[63:32], SRC2[63:32])\nDEST[95:64] := MIN(SRC1[95:64], SRC2[95:64])\nDEST[127:96] := MIN(SRC1[127:96], SRC2[127:96])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/minps" + }, + "minsd": { + "instruction": "MINSD", + "title": "MINSD\n\t\t— Return Minimum Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 5D /r MINSD xmm1, xmm2/m64", + "description": "Compares the low double precision floating-point values in the first source operand and the second source operand, and returns the minimum value to the low quadword of the destination operand. When the source operand is a memory operand, only the 64 bits are accessed.\nIf the values being compared are both 0.0s (of either sign), the value in the second source operand is returned. If a value in the second source operand is an SNaN, then SNaN is returned unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second source operand, either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN source operand (from either the first or second source) be returned, the action of MINSD can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\nThe second source operand can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The destination and first source operand are the same. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded version: Bits (127:64) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low quadword element of the destination operand is updated according to the writemask.\nSoftware should ensure VMINSD is encoded with VEX.L=0. Encoding VMINSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "MIN(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 < SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := MIN(SRC1[63:0], SRC2[63:0])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := MIN(SRC1[63:0], SRC2[63:0])\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := MIN(SRC1[63:0], SRC2[63:0])\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/minsd" + }, + "minss": { + "instruction": "MINSS", + "title": "MINSS\n\t\t— Return Minimum Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F 5D /r MINSS xmm1,xmm2/m32", + "description": "Compares the low single precision floating-point values in the first source operand and the second source operand and returns the minimum value to the low doubleword of the destination operand.\nIf the values being compared are both 0.0s (of either sign), the value in the second source operand is returned. If a value in the second operand is an SNaN, that SNaN is returned unchanged to the destination (that is, a QNaN version of the SNaN is not returned).\nIf only one value is a NaN (SNaN or QNaN) for this instruction, the second source operand, either a NaN or a valid floating-point value, is written to the result. If instead of this behavior, it is required that the NaN in either source operand be returned, the action of MINSD can be emulated using a sequence of instructions, such as, a comparison followed by AND, ANDN, and OR.\nThe second source operand can be an XMM register or a 32-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The destination and first source operand are the same. Bits (MAXVL:32) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded version: The first source operand is an xmm register encoded by (E)VEX.vvvv. Bits (127:32) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low doubleword element of the destination operand is updated according to the writemask.\nSoftware should ensure VMINSS is encoded with VEX.L=0. Encoding VMINSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "MIN(SRC1, SRC2)\n{\n IF ((SRC1 = 0.0) and (SRC2 = 0.0)) THEN DEST := SRC2;\n ELSE IF (SRC1 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC2 = NaN) THEN DEST := SRC2; FI;\n ELSE IF (SRC1 < SRC2) THEN DEST := SRC1;\n ELSE DEST := SRC2;\n FI;\n}\n\n\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := MIN(SRC1[31:0], SRC2[31:0])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := MIN(SRC1[31:0], SRC2[31:0])\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := MIN(SRC1[31:0], SRC2[31:0])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/minss" + }, + "monitor": { + "instruction": "MONITOR", + "title": "MONITOR\n\t\t— Set Up Monitor Address", + "opcode": "0F 01 C8", + "description": "The MONITOR instruction arms address monitoring hardware using an address specified in EAX (the address range that the monitoring hardware checks for store operations can be determined by using CPUID). A store to an address within the specified address range triggers the monitoring hardware. The state of monitor hardware is used by MWAIT.\nThe address is specified in RAX/EAX/AX and the size is based on the effective address size of the encoded instruction. By default, the DS segment is used to create a linear address that is monitored. Segment overrides can be used.\nECX and EDX are also used. They communicate other information to MONITOR. ECX specifies optional extensions. EDX specifies optional hints; it does not change the architectural behavior of the instruction. For the Pentium 4 processor (family 15, model 3), no extensions or hints are defined. Undefined hints in EDX are ignored by the processor; undefined extensions in ECX raises a general protection fault.\nThe address range must use memory of the write-back type. Only write-back memory will correctly trigger the monitoring hardware. Additional information on determining what address range to use in order to prevent false wake-ups is described in Chapter 9, “Multiple-Processor Management‚” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nThe MONITOR instruction is ordered as a load operation with respect to other memory transactions. The instruction is subject to the permission checking and faults associated with a byte load. Like a load, MONITOR sets the A-bit but not the D-bit in page tables.\nCPUID.01H:ECX.MONITOR[bit 3] indicates the availability of MONITOR and MWAIT in the processor. When set, MONITOR may be executed only at privilege level 0 (use at any other privilege level results in an invalid-opcode exception). The operating system or system BIOS may disable this instruction by using the IA32_MISC_ENABLE MSR; disabling MONITOR clears the CPUID feature flag and causes execution to generate an invalid-opcode exception.\nThe instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "MONITOR sets up an address range for the monitor hardware using the content of EAX (RAX in 64-bit mode) as an effective address\nand puts the monitor hardware in armed state. Always use memory of the write-back caching type. A store to the specified address\nrange will trigger the monitor hardware. The content of ECX and EDX are used to communicate other information to the monitor\nhardware.\n", + "url": "https://www.felixcloutier.com/x86/monitor" + }, + "mov": { + "instruction": "MOV", + "title": "MOV\n\t\t— Move to/from Debug Registers", + "opcode": "0F 21/r MOV r32, DR0–DR7", + "description": "Moves the contents of a debug register (DR0, DR1, DR2, DR3, DR4, DR5, DR6, or DR7) to a general-purpose register or vice versa. The operand size for these instructions is always 32 bits in non-64-bit modes, regardless of the operand-size attribute. (See Section 18.2, “Debug Registers”, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for a detailed description of the flags and fields in the debug registers.)\nThe instructions must be executed at privilege level 0 or in real-address mode.\nWhen the debug extension (DE) flag in register CR4 is clear, these instructions operate on debug registers in a manner that is compatible with Intel386 and Intel486 processors. In this mode, references to DR4 and DR5 refer to DR6 and DR7, respectively. When the DE flag in CR4 is set, attempts to reference DR4 and DR5 result in an undefined opcode (#UD) exception. (The CR4 register was added to the IA-32 Architecture beginning with the Pentium processor.)\nAt the opcode level, the reg field within the ModR/M byte specifies which of the debug registers is loaded or read. The two bits in the mod field are ignored. The r/m field specifies the general-purpose register loaded or read.\nIn 64-bit mode, the instruction’s default operation size is 64 bits. Use of the REX.B prefix permits access to additional registers (R8–R15). Use of the REX.W or 66H prefix is ignored. Use of the REX.R prefix causes an invalid-opcode exception. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF ((DE = 1) and (SRC or DEST = DR4 or DR5))\n THEN\n #UD;\n ELSE\n DEST := SRC;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/mov-2" + }, + "movapd": { + "instruction": "MOVAPD", + "title": "MOVAPD\n\t\t— Move Aligned Packed Double Precision Floating-Point Values", + "opcode": "66 0F 28 /r MOVAPD xmm1, xmm2/m128", + "description": "Moves 2, 4 or 8 double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM, YMM or ZMM register from an 128-bit, 256-bit or 512-bit memory location, to store the contents of an XMM, YMM or ZMM register into a 128-bit, 256-bit or 512-bit memory location, or to move data between two XMM, two YMM or two ZMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 16-byte (128-bit versions), 32-byte (256-bit version) or 64-byte (EVEX.512 encoded version) boundary or a general-protection\nexception (#GP) will be generated. For EVEX encoded versions, the operand must be aligned to the size of the memory operand. To move double precision floating-point values to and from unaligned memory locations, use the VMOVUPD instruction.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX.512 encoded version:\nMoves 512 bits of packed double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a ZMM register from a 512-bit float64 memory location, to store the contents of a ZMM register into a 512-bit float64 memory location, or to move data between two ZMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 64-byte boundary or a general-protection exception (#GP) will be generated. To move single precision floating-point values to and from unaligned memory locations, use the VMOVUPD instruction.\nVEX.256 and EVEX.256 encoded versions:\nMoves 256 bits of packed double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 32-byte boundary or a general-protection exception (#GP) will be generated. To move double precision floating-point values to and from unaligned memory locations, use the VMOVUPD instruction.\n128-bit versions:\nMoves 128 bits of packed double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated. To move single precision floating-point values to and from unaligned memory locations, use the VMOVUPD instruction.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\n(E)VEX.128 encoded version: Bits (MAXVL-1:128) of the destination ZMM register destination are zeroed.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movapd" + }, + "movaps": { + "instruction": "MOVAPS", + "title": "MOVAPS\n\t\t— Move Aligned Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 28 /r MOVAPS xmm1, xmm2/m128", + "description": "Moves 4, 8 or 16 single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM, YMM or ZMM register from an 128-bit, 256-bit or 512-bit memory location, to store the contents of an XMM, YMM or ZMM register into a 128-bit, 256-bit or 512-bit memory location, or to move data between two XMM, two YMM or two ZMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (EVEX.512 encoded version) boundary or a general-protection exception (#GP) will be generated. For EVEX.512 encoded versions, the operand must be aligned to the size of the memory operand. To move single precision floating-point values to and from unaligned memory locations, use the VMOVUPS instruction.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX.512 encoded version:\nMoves 512 bits of packed single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a ZMM register from a 512-bit float32 memory location, to store the contents of a ZMM register into a float32 memory location, or to move data between two ZMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 64-byte boundary or a general-protection exception (#GP) will be generated. To move single precision floating-point values to and from unaligned memory locations, use the VMOVUPS instruction.\nVEX.256 and EVEX.256 encoded version:\nMoves 256 bits of packed single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 32-byte boundary or a general-protection exception (#GP) will be generated.\n128-bit versions:\nMoves 128 bits of packed single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated. To move single precision floating-point values to and from unaligned memory locations, use the VMOVUPS instruction.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\n(E)VEX.128 encoded version: Bits (MAXVL-1:128) of the destination ZMM register are zeroed.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movaps" + }, + "movbe": { + "instruction": "MOVBE", + "title": "MOVBE\n\t\t— Move Data After Swapping Bytes", + "opcode": "0F 38 F0 /r MOVBE r16, m16", + "description": "Performs a byte swap operation on the data copied from the second operand (source operand) and store the result in the first operand (destination operand). The source operand can be a general-purpose register, or memory location; the destination register can be a general-purpose register, or a memory location; however, both operands can not be registers, and only one operand can be a memory location. Both operands must be the same size, which can be a word, a doubleword or quadword.\nThe MOVBE instruction is provided for swapping the bytes on a read from memory or on a write to memory; thus providing support for converting little-endian values to big-endian format and vice versa.\nIn 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "TEMP := SRC\nIF ( OperandSize = 16)\n THEN\n DEST[7:0] := TEMP[15:8];\n DEST[15:8] := TEMP[7:0];\n ELES IF ( OperandSize = 32)\n DEST[7:0] := TEMP[31:24];\n DEST[15:8] := TEMP[23:16];\n DEST[23:16] := TEMP[15:8];\n DEST[31:23] := TEMP[7:0];\n ELSE IF ( OperandSize = 64)\n DEST[7:0] := TEMP[63:56];\n DEST[15:8] := TEMP[55:48];\n DEST[23:16] := TEMP[47:40];\n DEST[31:24] := TEMP[39:32];\n DEST[39:32] := TEMP[31:24];\n DEST[47:40] := TEMP[23:16];\n DEST[55:48] := TEMP[15:8];\n DEST[63:56] := TEMP[7:0];\nFI;\n", + "url": "https://www.felixcloutier.com/x86/movbe" + }, + "movd": { + "instruction": "MOVD", + "title": "MOVD/MOVQ\n\t\t— Move Doubleword/Move Quadword", + "opcode": "NP 0F 6E /r MOVD mm, r/m32", + "description": "Copies a doubleword from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be general-purpose registers, MMX technology registers, XMM registers, or 32-bit memory locations. This instruction can be used to move a doubleword to and from the low doubleword of an MMX technology register and a general-purpose register or a 32-bit memory location, or to and from the low doubleword of an XMM register and a general-purpose register or a 32-bit memory location. The instruction cannot be used to transfer data between MMX technology registers, between XMM registers, between general-purpose registers, or between memory locations.\nWhen the destination operand is an MMX technology register, the source operand is written to the low doubleword of the register, and the register is zero-extended to 64 bits. When the destination operand is an XMM register, the source operand is written to the low doubleword of the register, and the register is zero-extended to 128 bits.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.\nMOVD/Q with XMM destination:\nMoves a dword/qword integer from the source operand and stores it in the low 32/64-bits of the destination XMM register. The upper bits of the destination are zeroed. The source operand can be a 32/64-bit register or 32/64-bit memory location.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. Qword operation requires the use of REX.W=1.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. Qword operation requires the use of VEX.W=1.\nEVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. Qword operation requires the use of EVEX.W=1.\nMOVD/Q with 32/64 reg/mem destination:\nStores the low dword/qword of the source XMM register to 32/64-bit memory location or general-purpose register. Qword operation requires the use of REX.W=1, VEX.W=1, or EVEX.W=1.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nIf VMOVD or VMOVQ is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "DEST[31:0] := SRC;\nDEST[63:32] := 00000000H;\n\n\nDEST[31:0] := SRC;\nDEST[127:32] := 000000000000000000000000H;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST := SRC[31:0];\n\n\nDEST[31:0] := SRC[31:0]\nDEST[MAXVL-1:32] := 0\n\n\nDEST[63:0] := SRC[63:0];\nDEST[127:64] := 0000000000000000H;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC[63:0];\n\n\nDEST := SRC[63:0];\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[31:0] := SRC[31:0]\nDEST[MAXVL-1:32] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n", + "url": "https://www.felixcloutier.com/x86/movd:movq" + }, + "movddup": { + "instruction": "MOVDDUP", + "title": "MOVDDUP\n\t\t— Replicate Double Precision Floating-Point Values", + "opcode": "F2 0F 12 /r MOVDDUP xmm1, xmm2/m64", + "description": "For 256-bit or higher versions: Duplicates even-indexed double precision floating-point values from the source operand (the second operand) and into adjacent pair and store to the destination operand (the first operand).\nFor 128-bit versions: Duplicates the low double precision floating-point value from the source operand (the second operand) and store to the destination operand (the first operand).\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register are unchanged. The source operand is XMM register or a 64-bit memory location.\nVEX.128 and EVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. The source operand is XMM register or a 64-bit memory location. The destination is updated conditionally under the writemask for EVEX version.\nVEX.256 and EVEX.256 encoded version: Bits (MAXVL-1:256) of the destination register are zeroed. The source operand is YMM register or a 256-bit memory location. The destination is updated conditionally under the write-mask for EVEX version.\nEVEX.512 encoded version: The destination is updated according to the writemask. The source operand is ZMM register or a 512-bit memory location.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_SRC[63:0] := SRC[63:0]\nTMP_SRC[127:64] := SRC[63:0]\nIF VL >= 256\n TMP_SRC[191:128] := SRC[191:128]\n TMP_SRC[255:192] := SRC[191:128]\nFI;\nIF VL >= 512\n TMP_SRC[319:256] := SRC[319:256]\n TMP_SRC[383:320] := SRC[319:256]\n TMP_SRC[477:384] := SRC[477:384]\n TMP_SRC[511:484] := SRC[477:384]\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+63:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[127:64] := SRC[63:0]\nDEST[191:128] := SRC[191:128]\nDEST[255:192] := SRC[191:128]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[127:64] := SRC[63:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[127:64] := SRC[63:0]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/movddup" + }, + "movdir64b": { + "instruction": "MOVDIR64B", + "title": "MOVDIR64B\n\t\t— Move 64 Bytes as Direct Store", + "opcode": "66 0F 38 F8 /r MOVDIR64B r16/r32/r64, m512", + "description": "Moves 64-bytes as direct-store with 64-byte write atomicity from source memory address to destination memory address. The source operand is a normal memory operand. The destination operand is a memory location specified in a general-purpose register. The register content is interpreted as an offset into ES segment without any segment override. In 64-bit mode, the register operand width is 64-bits (32-bits with 67H prefix). Outside of 64-bit mode, the register width is 32-bits when CS.D=1 (16-bits with 67H prefix), and 16-bits when CS.D=0 (32-bits with 67H prefix). MOVDIR64B requires the destination address to be 64-byte aligned. No alignment restriction is enforced for source operand.\nMOVDIR64B first reads 64-bytes from the source memory address. It then performs a 64-byte direct-store operation to the destination address. The load operation follows normal read ordering based on source address memory-type. The direct-store is implemented by using the write combining (WC) memory type protocol for writing data. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. If the destination address is cached, the line is written-back (if modified) and invalidated from the cache, before the direct-store.\nUnlike stores with non-temporal hint which allow UC/WP memory-type for destination to override the non-temporal hint, direct-stores always follow WC memory type protocol irrespective of destination address memory type (including UC/WP types). Unlike WC stores and stores with non-temporal hint, direct-stores are eligible for immediate eviction from the write-combining buffer, and thus not combined with younger stores (including direct-stores) to the same address. Older WC and non-temporal stores held in the write-combing buffer may be combined with younger direct stores to the same address. Direct stores are weakly ordered relative to other stores. Software that desires stronger ordering should use a fencing instruction (MFENCE or SFENCE) before or after a direct store to enforce the ordering desired.\nThere is no atomicity guarantee provided for the 64-byte load operation from source address, and processor implementations may use multiple load operations to read the 64-bytes. The 64-byte direct-store issued by MOVDIR64B guarantees 64-byte write-completion atomicity. This means that the data arrives at the destination in a single undivided 64-byte write transaction.\nAvailability of the MOVDIR64B instruction is indicated by the presence of the CPUID feature flag MOVDIR64B (bit 28 of the ECX register in leaf 07H, see “CPUID—CPU Identification” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A).", + "operation": "DEST := SRC;\n", + "url": "https://www.felixcloutier.com/x86/movdir64b" + }, + "movdiri": { + "instruction": "MOVDIRI", + "title": "MOVDIRI\n\t\t— Move Doubleword as Direct Store", + "opcode": "NP 0F 38 F9 /r MOVDIRI m32, r32", + "description": "Moves the doubleword integer in the source operand (second operand) to the destination operand (first operand) using a direct-store operation. The source operand is a general purpose register. The destination operand is a 32-bit memory location. In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See summary chart at the beginning of this section for encoding data and limits.\nThe direct-store is implemented by using write combining (WC) memory type protocol for writing data. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. If the destination address is cached, the line is written-back (if modified) and invalidated from the cache, before the direct-store. Unlike stores with non-temporal hint that allow uncached (UC) and write-protected (WP) memory-type for the destination to override the non-temporal hint, direct-stores always follow WC memory type protocol irrespective of the destination address memory type (including UC and WP types).\nUnlike WC stores and stores with non-temporal hint, direct-stores are eligible for immediate eviction from the write-combining buffer, and thus not combined with younger stores (including direct-stores) to the same address. Older WC and non-temporal stores held in the write-combing buffer may be combined with younger direct stores to the same address. Direct stores are weakly ordered relative to other stores. Software that desires stronger ordering should use a fencing instruction (MFENCE or SFENCE) before or after a direct store to enforce the ordering desired.\nDirect-stores issued by MOVDIRI to a destination aligned to a 4-byte boundary (8-byte boundary if used with REX.W prefix) guarantee 4-byte (8-byte with REX.W prefix) write-completion atomicity. This means that the data arrives at the destination in a single undivided 4-byte (or 8-byte) write transaction. If the destination is not aligned for the write size, the direct-stores issued by MOVDIRI are split and arrive at the destination in two parts. Each part of such split direct-store will not merge with younger stores but can arrive at the destination in either order. Availability of the MOVDIRI instruction is indicated by the presence of the CPUID feature flag MOVDIRI (bit 27 of the ECX register in leaf 07H, see “CPUID—CPU Identification” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A).", + "operation": "DEST := SRC;\n", + "url": "https://www.felixcloutier.com/x86/movdiri" + }, + "movdq2q": { + "instruction": "MOVDQ2Q", + "title": "MOVDQ2Q\n\t\t— Move Quadword from XMM to MMX Technology Register", + "opcode": "F2 0F D6 /r", + "description": "Moves the low quadword from the source operand (second operand) to the destination operand (first operand). The source operand is an XMM register and the destination operand is an MMX technology register.\nThis instruction causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the MOVDQ2Q instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST := SRC[63:0];\n", + "url": "https://www.felixcloutier.com/x86/movdq2q" + }, + "movdqa": { + "instruction": "MOVDQA", + "title": "MOVDQA/VMOVDQA32/VMOVDQA64\n\t\t— Move Aligned Packed Integer Values", + "opcode": "66 0F 6F /r MOVDQA xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed doubleword/quadword integer values from the source operand (the second operand) to the destination operand (the first operand). This instruction can be used to load a vector register from an int32/int64 memory location, to store the contents of a vector register into an int32/int64 memory location, or to move data between two ZMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16 (EVEX.128)/32(EVEX.256)/64(EVEX.512)-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction.\nThe destination operand is updated at 32-bit (VMOVDQA32) or 64-bit (VMOVDQA64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 32-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction. Bits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqa:vmovdqa32:vmovdqa64" + }, + "movdqu": { + "instruction": "MOVDQU", + "title": "MOVDQU/VMOVDQU8/VMOVDQU16/VMOVDQU32/VMOVDQU64\n\t\t— Move Unaligned Packed Integer Values", + "opcode": "F3 0F 6F /r MOVDQU xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed byte/word/doubleword/quadword integer values from the source operand (the second operand) to the destination operand (first operand). This instruction can be used to load a vector register from a memory location, to store the contents of a vector register into a memory location, or to move data between two vector registers.\nThe destination operand is updated at 8-bit (VMOVDQU8), 16-bit (VMOVDQU16), 32-bit (VMOVDQU32), or 64-bit (VMOVDQU64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nBits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned to any alignment without causing a general-protection exception (#GP) to be generated\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] :=\n SRC[i+7:i]\n ELSE *DEST[i+7:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] :=\n SRC[i+15:i]\n ELSE *DEST[i+15:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\nVMOVDQU (VEX.128 encoded version)\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqu:vmovdqu8:vmovdqu16:vmovdqu32:vmovdqu64" + }, + "movhlps": { + "instruction": "MOVHLPS", + "title": "MOVHLPS\n\t\t— Move Packed Single Precision Floating-Point Values High to Low", + "opcode": "NP 0F 12 /r MOVHLPS xmm1, xmm2", + "description": "This instruction cannot be used for memory to register moves.\n128-bit two-argument form:\nMoves two packed single precision floating-point values from the high quadword of the second XMM argument (second operand) to the low quadword of the first XMM register (first argument). The quadword at bits 127:64 of the destination operand is left unchanged. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\n128-bit and EVEX three-argument form:\nMoves two packed single precision floating-point values from the high quadword of the third XMM argument (third operand) to the low quadword of the destination (first operand). Copies the high quadword from the second XMM argument (second operand) to the high quadword of the destination (first operand). Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nIf VMOVHLPS is encoded with VEX.L or EVEX.L’L= 1, an attempt to execute the instruction encoded with VEX.L or EVEX.L’L= 1 will cause an #UD exception.", + "operation": "DEST[63:0] := SRC[127:64]\nDEST[MAXVL-1:64] (Unmodified)\n\n\nDEST[63:0] := SRC2[127:64]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/movhlps" + }, + "movhpd": { + "instruction": "MOVHPD", + "title": "MOVHPD\n\t\t— Move High Packed Double Precision Floating-Point Value", + "opcode": "66 0F 16 /r MOVHPD xmm1, m64", + "description": "This instruction cannot be used for register to register or memory to memory moves.\n128-bit Legacy SSE load:\nMoves a double precision floating-point value from the source 64-bit memory operand and stores it in the high 64-bits of the destination XMM register. The lower 64bits of the XMM register are preserved. Bits (MAXVL-1:128) of the corresponding destination register are preserved.\nVEX.128 & EVEX encoded load:\nLoads a double precision floating-point value from the source 64-bit memory operand (the third operand) and stores it in the upper 64-bits of the destination XMM register (first operand). The low 64-bits from the first source operand (second operand) are copied to the low 64-bits of the destination. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\n128-bit store:\nStores a double precision floating-point value from the high 64-bits of the XMM register source (second operand) to the 64-bit memory location (first operand).\nNote: VMOVHPD (store) (VEX.128.66.0F 17 /r) is legal and has the same behavior as the existing 66 0F 17 store. For VMOVHPD (store) VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instruction will #UD.\nIf VMOVHPD is encoded with VEX.L or EVEX.L’L= 1, an attempt to execute the instruction encoded with VEX.L or EVEX.L’L= 1 will cause an #UD exception.", + "operation": "DEST[63:0] (Unmodified)\nDEST[127:64] := SRC[63:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[127:64]\n", + "url": "https://www.felixcloutier.com/x86/movhpd" + }, + "movhps": { + "instruction": "MOVHPS", + "title": "MOVHPS\n\t\t— Move High Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 16 /r MOVHPS xmm1, m64", + "description": "This instruction cannot be used for register to register or memory to memory moves.\n128-bit Legacy SSE load:\nMoves two packed single precision floating-point values from the source 64-bit memory operand and stores them in the high 64-bits of the destination XMM register. The lower 64bits of the XMM register are preserved. Bits (MAXVL-1:128) of the corresponding destination register are preserved.\nVEX.128 & EVEX encoded load:\nLoads two single precision floating-point values from the source 64-bit memory operand (the third operand) and stores it in the upper 64-bits of the destination XMM register (first operand). The low 64-bits from the first source operand (the second operand) are copied to the lower 64-bits of the destination. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\n128-bit store:\nStores two packed single precision floating-point values from the high 64-bits of the XMM register source (second operand) to the 64-bit memory location (first operand).\nNote: VMOVHPS (store) (VEX.128.0F 17 /r) is legal and has the same behavior as the existing 0F 17 store. For VMOVHPS (store) VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instruction will #UD.\nIf VMOVHPS is encoded with VEX.L or EVEX.L’L= 1, an attempt to execute the instruction encoded with VEX.L or EVEX.L’L= 1 will cause an #UD exception.", + "operation": "DEST[63:0] (Unmodified)\nDEST[127:64] := SRC[63:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[127:64]\n", + "url": "https://www.felixcloutier.com/x86/movhps" + }, + "movlhps": { + "instruction": "MOVLHPS", + "title": "MOVLHPS\n\t\t— Move Packed Single Precision Floating-Point Values Low to High", + "opcode": "NP 0F 16 /r MOVLHPS xmm1, xmm2", + "description": "This instruction cannot be used for memory to register moves.\n128-bit two-argument form:\nMoves two packed single precision floating-point values from the low quadword of the second XMM argument (second operand) to the high quadword of the first XMM register (first argument). The low quadword of the destination operand is left unchanged. Bits (MAXVL-1:128) of the corresponding destination register are unmodified.\n128-bit three-argument forms:\nMoves two packed single precision floating-point values from the low quadword of the third XMM argument (third operand) to the high quadword of the destination (first operand). Copies the low quadword from the second XMM argument (second operand) to the low quadword of the destination (first operand). Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nIf VMOVLHPS is encoded with VEX.L or EVEX.L’L= 1, an attempt to execute the instruction encoded with VEX.L or EVEX.L’L= 1 will cause an #UD exception.", + "operation": "DEST[63:0] (Unmodified)\nDEST[127:64] := SRC[63:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/movlhps" + }, + "movlpd": { + "instruction": "MOVLPD", + "title": "MOVLPD\n\t\t— Move Low Packed Double Precision Floating-Point Value", + "opcode": "66 0F 12 /r MOVLPD xmm1, m64", + "description": "This instruction cannot be used for register to register or memory to memory moves.\n128-bit Legacy SSE load:\nMoves a double precision floating-point value from the source 64-bit memory operand and stores it in the low 64-bits of the destination XMM register. The upper 64bits of the XMM register are preserved. Bits (MAXVL-1:128) of the corresponding destination register are preserved.\nVEX.128 & EVEX encoded load:\nLoads a double precision floating-point value from the source 64-bit memory operand (third operand), merges it with the upper 64-bits of the first source XMM register (second operand), and stores it in the low 128-bits of the destination XMM register (first operand). Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\n128-bit store:\nStores a double precision floating-point value from the low 64-bits of the XMM register source (second operand) to the 64-bit memory location (first operand).\nNote: VMOVLPD (store) (VEX.128.66.0F 13 /r) is legal and has the same behavior as the existing 66 0F 13 store. For VMOVLPD (store) VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instruction will #UD.\nIf VMOVLPD is encoded with VEX.L or EVEX.L’L= 1, an attempt to execute the instruction encoded with VEX.L or EVEX.L’L= 1 will cause an #UD exception.", + "operation": "DEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n\n\nDEST[63:0] := SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[63:0]\n", + "url": "https://www.felixcloutier.com/x86/movlpd" + }, + "movlps": { + "instruction": "MOVLPS", + "title": "MOVLPS\n\t\t— Move Low Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 12 /r MOVLPS xmm1, m64", + "description": "This instruction cannot be used for register to register or memory to memory moves.\n128-bit Legacy SSE load:\nMoves two packed single precision floating-point values from the source 64-bit memory operand and stores them in the low 64-bits of the destination XMM register. The upper 64bits of the XMM register are preserved. Bits (MAXVL-1:128) of the corresponding destination register are preserved.\nVEX.128 & EVEX encoded load:\nLoads two packed single precision floating-point values from the source 64-bit memory operand (the third operand), merges them with the upper 64-bits of the first source operand (the second operand), and stores them in the low 128-bits of the destination register (the first operand). Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\n128-bit store:\nLoads two packed single precision floating-point values from the low 64-bits of the XMM register source (second operand) to the 64-bit memory location (first operand).\nNote: VMOVLPS (store) (VEX.128.0F 13 /r) is legal and has the same behavior as the existing 0F 13 store. For VMOVLPS (store) VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instruction will #UD.\nIf VMOVLPS is encoded with VEX.L or EVEX.L’L= 1, an attempt to execute the instruction encoded with VEX.L or EVEX.L’L= 1 will cause an #UD exception.", + "operation": "DEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n\n\nDEST[63:0] := SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[63:0]\n", + "url": "https://www.felixcloutier.com/x86/movlps" + }, + "movmskpd": { + "instruction": "MOVMSKPD", + "title": "MOVMSKPD\n\t\t— Extract Packed Double Precision Floating-Point Sign Mask", + "opcode": "66 0F 50 /r MOVMSKPD reg, xmm", + "description": "Extracts the sign bits from the packed double precision floating-point values in the source operand (second operand), formats them into a 2-bit mask, and stores the mask in the destination operand (first operand). The source operand is an XMM register, and the destination operand is a general-purpose register. The mask is stored in the 2 low-order bits of the destination operand. Zero-extend the upper bits of the destination.\nIn 64-bit mode, the instruction can access additional registers (XMM8-XMM15, R8-R15) when used with a REX.R prefix. The default operand size is 64-bit in 64-bit mode.\n128-bit versions: The source operand is a YMM register. The destination operand is a general purpose register.\nVEX.256 encoded version: The source operand is a YMM register. The destination operand is a general purpose register.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "DEST[0] := SRC[63]\nDEST[1] := SRC[127]\nIF DEST = r32\n THEN DEST[31:2] := 0;\n ELSE DEST[63:2] := 0;\nFI\n\n\nDEST[0] := SRC[63]\nDEST[1] := SRC[127]\nDEST[2] := SRC[191]\nDEST[3] := SRC[255]\nIF DEST = r32\n THEN DEST[31:4] := 0;\n ELSE DEST[63:4] := 0;\nFI\n", + "url": "https://www.felixcloutier.com/x86/movmskpd" + }, + "movmskps": { + "instruction": "MOVMSKPS", + "title": "MOVMSKPS\n\t\t— Extract Packed Single Precision Floating-Point Sign Mask", + "opcode": "NP 0F 50 /r MOVMSKPS reg, xmm", + "description": "Extracts the sign bits from the packed single precision floating-point values in the source operand (second operand), formats them into a 4- or 8-bit mask, and stores the mask in the destination operand (first operand). The source operand is an XMM or YMM register, and the destination operand is a general-purpose register. The mask is stored in the 4 or 8 low-order bits of the destination operand. The upper bits of the destination operand beyond the mask are filled with zeros.\nIn 64-bit mode, the instruction can access additional registers (XMM8-XMM15, R8-R15) when used with a REX.R prefix. The default operand size is 64-bit in 64-bit mode.\n128-bit versions: The source operand is a YMM register. The destination operand is a general purpose register.\nVEX.256 encoded version: The source operand is a YMM register. The destination operand is a general purpose register.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "DEST[0] := SRC[31];\nDEST[1] := SRC[63];\nDEST[2] := SRC[95];\nDEST[3] := SRC[127];\nIF DEST = r32\n THEN DEST[31:4] := ZeroExtend;\n ELSE DEST[63:4] := ZeroExtend;\nFI;\n\n\nDEST[0] := SRC[31]\nDEST[1] := SRC[63]\nDEST[2] := SRC[95]\nDEST[3] := SRC[127]\nIF DEST = r32\n THEN DEST[31:4] := 0;\n ELSE DEST[63:4] := 0;\nFI\n\n\nDEST[0] := SRC[31]\nDEST[1] := SRC[63]\nDEST[2] := SRC[95]\nDEST[3] := SRC[127]\nDEST[4] := SRC[159]\nDEST[5] := SRC[191]\nDEST[6] := SRC[223]\nDEST[7] := SRC[255]\nIF DEST = r32\n THEN DEST[31:8] := 0;\n ELSE DEST[63:8] := 0;\nFI\n", + "url": "https://www.felixcloutier.com/x86/movmskps" + }, + "movntdq": { + "instruction": "MOVNTDQ", + "title": "MOVNTDQ\n\t\t— Store Packed Integers Using Non-Temporal Hint", + "opcode": "66 0F E7 /r MOVNTDQ m128, xmm1", + "description": "Moves the packed integers in the source operand (second operand) to the destination operand (first operand) using a non-temporal hint to prevent caching of the data during the write to memory. The source operand is an XMM register, YMM register or ZMM register, which is assumed to contain integer data (packed bytes, words, double-words, or quadwords). The destination operand is a 128-bit, 256-bit or 512-bit memory location. The memory operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (512-bit version) boundary otherwise a general-protection exception (#GP) will be generated.\nThe non-temporal hint is implemented by using a write combining (WC) memory type protocol when writing the data to memory. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. The memory type of the region being written to can override the non-temporal hint, if the memory address specified for the non-temporal store is in an uncacheable (UC) or write protected (WP) memory region. For more information on non-temporal stores, see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10 in the IA-32 Intel Architecture Software Developer’s Manual, Volume 1.\nBecause the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with VMOVNTDQ instructions if multiple processors might use different memory types to read/write the destination memory locations.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, VEX.L must be 0; otherwise instructions will #UD.", + "operation": "VL = 128, 256, 512\nDEST[VL-1:0] := SRC[VL-1:0]\nDEST[MAXVL-1:VL] := 0\n\n\nDEST := SRC\n", + "url": "https://www.felixcloutier.com/x86/movntdq" + }, + "movntdqa": { + "instruction": "MOVNTDQA", + "title": "MOVNTDQA\n\t\t— Load Double Quadword Non-Temporal Aligned Hint", + "opcode": "66 0F 38 2A /r MOVNTDQA xmm1, m128", + "description": "MOVNTDQA loads a double quadword from the source operand (second operand) to the destination operand (first operand) using a non-temporal hint if the memory source is WC (write combining) memory type. For WC memory type, the nontemporal hint may be implemented by loading a temporary internal buffer with the equivalent of an aligned cache line without filling this data to the cache. Any memory-type aliased lines in the cache will be snooped and flushed. Subsequent MOVNTDQA reads to unread portions of the WC cache line will receive data from the temporary internal buffer if data is available. The temporary internal buffer may be flushed by the processor at any time for any reason, for example:\na mis-speculation condition, and various fault conditions\nThe non-temporal hint is implemented by using a write combining (WC) memory type protocol when reading the data from memory. Using this protocol, the processor does not read the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. The memory type of the region being read can override the non-temporal hint, if the memory address specified for the non-temporal read is not a WC memory region. Information on non-temporal reads and writes can be found in “Caching of Temporal vs. NonTemporal Data” in Chapter 10 in the Intel® 64 and IA-32 Architecture Software Developer’s Manual, Volume 3A.\nBecause the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with a MFENCE instruction should be used in conjunction with MOVNTDQA instructions if multiple processors might use different memory types for the referenced memory locations or to synchronize reads of a processor with writes by other agents in the system. A processor’s implementation of the streaming load hint does not override the effective memory type, but the implementation of the hint is processor dependent. For example, a processor implementa-\ntion may choose to ignore the hint and process the instruction as a normal MOVDQA for any memory type. Alternatively, another implementation may optimize cache reads generated by MOVNTDQA on WB memory type to reduce cache evictions.\nThe 128-bit (V)MOVNTDQA addresses must be 16-byte aligned or the instruction will cause a #GP.\nThe 256-bit VMOVNTDQA addresses must be 32-byte aligned or the instruction will cause a #GP.\nThe 512-bit VMOVNTDQA addresses must be 64-byte aligned or the instruction will cause a #GP.", + "operation": "DEST := SRC\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST := SRC\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[511:0] := SRC[511:0]\nDEST[MAXVL-1:512] := 0\n", + "url": "https://www.felixcloutier.com/x86/movntdqa" + }, + "movnti": { + "instruction": "MOVNTI", + "title": "MOVNTI\n\t\t— Store Doubleword Using Non-Temporal Hint", + "opcode": "NP 0F C3 /r MOVNTI m32, r32", + "description": "Moves the doubleword integer in the source operand (second operand) to the destination operand (first operand) using a non-temporal hint to minimize cache pollution during the write to memory. The source operand is a general-purpose register. The destination operand is a 32-bit memory location.\nThe non-temporal hint is implemented by using a write combining (WC) memory type protocol when writing the data to memory. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. The memory type of the region being written to can override the non-temporal hint, if the memory address specified for the non-temporal store is in an uncacheable (UC) or write protected (WP) memory region. For more information on non-temporal stores, see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nBecause the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with MOVNTI instructions if multiple processors might use different memory types to read/write the destination memory locations.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := SRC;\n", + "url": "https://www.felixcloutier.com/x86/movnti" + }, + "movntpd": { + "instruction": "MOVNTPD", + "title": "MOVNTPD\n\t\t— Store Packed Double Precision Floating-Point Values Using Non-Temporal Hint", + "opcode": "66 0F 2B /r MOVNTPD m128, xmm1", + "description": "Moves the packed double precision floating-point values in the source operand (second operand) to the destination operand (first operand) using a non-temporal hint to prevent caching of the data during the write to memory. The source operand is an XMM register, YMM register or ZMM register, which is assumed to contain packed double precision, floating-pointing data. The destination operand is a 128-bit, 256-bit or 512-bit memory location. The memory operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (EVEX.512 encoded version) boundary otherwise a general-protection exception (#GP) will be generated.\nThe non-temporal hint is implemented by using a write combining (WC) memory type protocol when writing the data to memory. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. The memory type of the region being written to can override the non-temporal hint, if the memory address specified for the non-temporal store is in an uncacheable (UC) or write protected (WP) memory region. For more information on non-temporal stores, see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10 in the IA-32 Intel Architecture Software Developer’s Manual, Volume 1.\nBecause the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with MOVNTPD instructions if multiple processors might use different memory types to read/write the destination memory locations.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, VEX.L must be 0; otherwise instructions will #UD.", + "operation": "VL = 128, 256, 512\nDEST[VL-1:0] := SRC[VL-1:0]\nDEST[MAXVL-1:VL] := 0\n\n\nDEST := SRC\n", + "url": "https://www.felixcloutier.com/x86/movntpd" + }, + "movntps": { + "instruction": "MOVNTPS", + "title": "MOVNTPS\n\t\t— Store Packed Single Precision Floating-Point Values Using Non-Temporal Hint", + "opcode": "NP 0F 2B /r MOVNTPS m128, xmm1", + "description": "Moves the packed single precision floating-point values in the source operand (second operand) to the destination operand (first operand) using a non-temporal hint to prevent caching of the data during the write to memory. The source operand is an XMM register, YMM register or ZMM register, which is assumed to contain packed single precision, floating-pointing. The destination operand is a 128-bit, 256-bit or 512-bit memory location. The memory operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (EVEX.512 encoded version) boundary otherwise a general-protection exception (#GP) will be generated.\nThe non-temporal hint is implemented by using a write combining (WC) memory type protocol when writing the data to memory. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. The memory type of the region being written to can override the non-temporal hint, if the memory address specified for the non-temporal store is in an uncacheable (UC) or write protected (WP) memory region. For more information on non-temporal stores, see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10 in the IA-32 Intel Architecture Software Developer’s Manual, Volume 1.\nBecause the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with MOVNTPS instructions if multiple processors might use different memory types to read/write the destination memory locations.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "VL = 128, 256, 512\nDEST[VL-1:0] := SRC[VL-1:0]\nDEST[MAXVL-1:VL] := 0\n\n\nDEST := SRC\n", + "url": "https://www.felixcloutier.com/x86/movntps" + }, + "movntq": { + "instruction": "MOVNTQ", + "title": "MOVNTQ\n\t\t— Store of Quadword Using Non-Temporal Hint", + "opcode": "NP 0F E7 /r", + "description": "Moves the quadword in the source operand (second operand) to the destination operand (first operand) using a non-temporal hint to minimize cache pollution during the write to memory. The source operand is an MMX technology register, which is assumed to contain packed integer data (packed bytes, words, or doublewords). The destination operand is a 64-bit memory location.\nThe non-temporal hint is implemented by using a write combining (WC) memory type protocol when writing the data to memory. Using this protocol, the processor does not write the data into the cache hierarchy, nor does it fetch the corresponding cache line from memory into the cache hierarchy. The memory type of the region being written to can override the non-temporal hint, if the memory address specified for the non-temporal store is in an uncacheable (UC) or write protected (WP) memory region. For more information on non-temporal stores, see “Caching of Temporal vs. Non-Temporal Data” in Chapter 10 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nBecause the WC protocol uses a weakly-ordered memory consistency model, a fencing operation implemented with the SFENCE or MFENCE instruction should be used in conjunction with MOVNTQ instructions if multiple processors might use different memory types to read/write the destination memory locations.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "DEST := SRC;\n", + "url": "https://www.felixcloutier.com/x86/movntq" + }, + "movq": { + "instruction": "MOVQ", + "title": "MOVQ\n\t\t— Move Quadword", + "opcode": "NP 0F 6F /r MOVQ mm, mm/m64", + "description": "Copies a quadword from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be MMX technology registers, XMM registers, or 64-bit memory locations. This instruction can be used to move a quadword between two MMX technology registers or between an MMX technology register and a 64-bit memory location, or to move data between two XMM registers or between an XMM register and a 64-bit memory location. The instruction cannot be used to transfer data between memory locations.\nWhen the source operand is an XMM register, the low quadword is moved; when the destination operand is an XMM register, the quadword is stored to the low quadword of the register, and the high quadword is cleared to all 0s.\nIn 64-bit mode and if not encoded using VEX/EVEX, use of the REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nIf VMOVQ is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "DEST := SRC;\n\n\nDEST[63:0] := SRC[63:0];\nDEST[127:64] := 0000000000000000H;\n\n\noperand is memory location:\n DEST := SRC[63:0];\n\n\noperand is XMM register:\n DEST[63:0] := SRC;\n DEST[127:64] := 0000000000000000H;\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[:MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC2[63:0]\n", + "url": "https://www.felixcloutier.com/x86/movq" + }, + "movq2dq": { + "instruction": "MOVQ2DQ", + "title": "MOVQ2DQ\n\t\t— Move Quadword from MMX Technology to XMM Register", + "opcode": "F3 0F D6 /r MOVQ2DQ xmm, mm", + "description": "Moves the quadword from the source operand (second operand) to the low quadword of the destination operand (first operand). The source operand is an MMX technology register and the destination operand is an XMM register.\nThis instruction causes a transition from x87 FPU to MMX technology operation (that is, the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid]). If this instruction is executed while an x87 FPU floating-point exception is pending, the exception is handled before the MOVQ2DQ instruction is executed.\nIn 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[63:0] := SRC[63:0];\nDEST[127:64] := 00000000000000000H;\n", + "url": "https://www.felixcloutier.com/x86/movq2dq" + }, + "movs": { + "instruction": "MOVS", + "title": "MOVS/MOVSB/MOVSW/MOVSD/MOVSQ\n\t\t— Move Data From String to String", + "opcode": "A4", + "description": "Moves the byte, word, or doubleword specified with the second operand (source operand) to the location specified with the first operand (destination operand). Both the source and destination operands are located in memory. The address of the source operand is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The address of the destination operand is read from the ES:EDI or the ES:DI registers (again depending on the address-size attribute of the instruction). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the MOVS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source and destination operands should be symbols that indicate the size and location of the source value and the destination, respectively. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source and destination operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords), but they do not have to specify the correct location. The locations of the source and destination operands are always specified by the DS:(E)SI and ES:(E)DI registers, which must be loaded correctly before the move string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the MOVS instructions. Here also DS:(E)SI and ES:(E)DI are assumed to be the source and destination operands, respectively. The size of the source and destination operands is selected with the mnemonic: MOVSB (byte move), MOVSW (word move), or MOVSD (doubleword move).\nAfter the move operation, the (E)SI and (E)DI registers are incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI and (E)DI register are incre-\nmented; if the DF flag is 1, the (E)SI and (E)DI registers are decremented.) The registers are incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.", + "operation": "DEST := SRC;\nNon-64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n FI;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n FI;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\nFI;\n64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 2;\n (R|E)DI := (R|E)DI + 2;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 2;\n (R|E)DI := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 4;\n (R|E)DI := (R|E)DI + 4;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 4;\n (R|E)DI := (R|E)DI – 4;\n FI;\n ELSE IF (Quadword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq" + }, + "movsb": { + "instruction": "MOVSB", + "title": "MOVS/MOVSB/MOVSW/MOVSD/MOVSQ\n\t\t— Move Data From String to String", + "opcode": "A4", + "description": "Moves the byte, word, or doubleword specified with the second operand (source operand) to the location specified with the first operand (destination operand). Both the source and destination operands are located in memory. The address of the source operand is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The address of the destination operand is read from the ES:EDI or the ES:DI registers (again depending on the address-size attribute of the instruction). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the MOVS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source and destination operands should be symbols that indicate the size and location of the source value and the destination, respectively. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source and destination operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords), but they do not have to specify the correct location. The locations of the source and destination operands are always specified by the DS:(E)SI and ES:(E)DI registers, which must be loaded correctly before the move string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the MOVS instructions. Here also DS:(E)SI and ES:(E)DI are assumed to be the source and destination operands, respectively. The size of the source and destination operands is selected with the mnemonic: MOVSB (byte move), MOVSW (word move), or MOVSD (doubleword move).\nAfter the move operation, the (E)SI and (E)DI registers are incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI and (E)DI register are incre-\nmented; if the DF flag is 1, the (E)SI and (E)DI registers are decremented.) The registers are incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.", + "operation": "DEST := SRC;\nNon-64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n FI;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n FI;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\nFI;\n64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 2;\n (R|E)DI := (R|E)DI + 2;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 2;\n (R|E)DI := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 4;\n (R|E)DI := (R|E)DI + 4;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 4;\n (R|E)DI := (R|E)DI – 4;\n FI;\n ELSE IF (Quadword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq" + }, + "movsd": { + "instruction": "MOVSD", + "title": "MOVSD\n\t\t— Move or Merge Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 10 /r MOVSD xmm1, xmm2", + "description": "Moves a scalar double precision floating-point value from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be XMM registers or 64-bit memory locations. This instruction can be used to move a double precision floating-point value to and from the low quadword of an XMM register and a 64-bit memory location, or to move a double precision floating-point value between the low quadwords of two XMM registers. The instruction cannot be used to transfer data between memory locations.\nLegacy version: When the source and destination operands are XMM registers, bits MAXVL:64 of the destination operand remains unchanged. When the source operand is a memory location and destination operand is an XMM\nregisters, the quadword at bits 127:64 of the destination operand is cleared to all 0s, bits MAXVL:128 of the destination operand remains unchanged.\nVEX and EVEX encoded register-register syntax: Moves a scalar double precision floating-point value from the second source operand (the third operand) to the low quadword element of the destination operand (the first operand). Bits 127:64 of the destination operand are copied from the first source operand (the second operand). Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX and EVEX encoded memory store syntax: When the source operand is a memory location and destination operand is an XMM registers, bits MAXVL:64 of the destination operand is cleared to all 0s.\nEVEX encoded versions: The low quadword of the destination is updated according to the writemask.\nNote: For VMOVSD (memory store and load forms), VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instruction will #UD.", + "operation": "IF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[MAXVL-1:64] := 0\n\n\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC[63:0]\n ELSE *DEST[63:0] remains unchanged* ; merging-masking\nFI;\n\n\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC2[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n\n\nDEST[63:0] := SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC[63:0]\nDEST[MAXVL-1:64] := 0\n\n\nDEST[63:0] := SRC[63:0]\n\n\nDEST[63:0] := SRC[63:0]\nDEST[127:64] := 0\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/movsd" + }, + "movshdup": { + "instruction": "MOVSHDUP", + "title": "MOVSHDUP\n\t\t— Replicate Single Precision Floating-Point Values", + "opcode": "F3 0F 16 /r MOVSHDUP xmm1, xmm2/m128", + "description": "Duplicates odd-indexed single precision floating-point values from the source operand (the second operand) to adjacent element pair in the destination operand (the first operand). See Figure 4-3. The source operand is an XMM, YMM or ZMM register or 128, 256 or 512-bit memory location and the destination operand is an XMM, YMM or ZMM register.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.\nVEX.256 encoded version: Bits (MAXVL-1:256) of the destination register are zeroed.\nEVEX encoded version: The destination operand is updated at 32-bit granularity according to the writemask.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nTMP_SRC[31:0] := SRC[63:32]\nTMP_SRC[63:32] := SRC[63:32]\nTMP_SRC[95:64] := SRC[127:96]\nTMP_SRC[127:96] := SRC[127:96]\nIF VL >= 256\n TMP_SRC[159:128] := SRC[191:160]\n TMP_SRC[191:160] := SRC[191:160]\n TMP_SRC[223:192] := SRC[255:224]\n TMP_SRC[255:224] := SRC[255:224]\nFI;\nIF VL >= 512\n TMP_SRC[287:256] := SRC[319:288]\n TMP_SRC[319:288] := SRC[319:288]\n TMP_SRC[351:320] := SRC[383:352]\n TMP_SRC[383:352] := SRC[383:352]\n TMP_SRC[415:384] := SRC[447:416]\n TMP_SRC[447:416] := SRC[447:416]\n TMP_SRC[479:448] := SRC[511:480]\n TMP_SRC[511:480] := SRC[511:480]\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_SRC[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC[63:32]\nDEST[63:32] := SRC[63:32]\nDEST[95:64] := SRC[127:96]\nDEST[127:96] := SRC[127:96]\nDEST[159:128] := SRC[191:160]\nDEST[191:160] := SRC[191:160]\nDEST[223:192] := SRC[255:224]\nDEST[255:224] := SRC[255:224]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC[63:32]\nDEST[63:32] := SRC[63:32]\nDEST[95:64] := SRC[127:96]\nDEST[127:96] := SRC[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC[63:32]\nDEST[63:32] := SRC[63:32]\nDEST[95:64] := SRC[127:96]\nDEST[127:96] := SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/movshdup" + }, + "movsldup": { + "instruction": "MOVSLDUP", + "title": "MOVSLDUP\n\t\t— Replicate Single Precision Floating-Point Values", + "opcode": "F3 0F 12 /r MOVSLDUP xmm1, xmm2/m128", + "description": "Duplicates even-indexed single precision floating-point values from the source operand (the second operand). See Figure 4-4. The source operand is an XMM, YMM or ZMM register or 128, 256 or 512-bit memory location and the destination operand is an XMM, YMM or ZMM register.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.\nVEX.256 encoded version: Bits (MAXVL-1:256) of the destination register are zeroed.\nEVEX encoded version: The destination operand is updated at 32-bit granularity according to the writemask.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nTMP_SRC[31:0] := SRC[31:0]\nTMP_SRC[63:32] := SRC[31:0]\nTMP_SRC[95:64] := SRC[95:64]\nTMP_SRC[127:96] := SRC[95:64]\nIF VL >= 256\n TMP_SRC[159:128] := SRC[159:128]\n TMP_SRC[191:160] := SRC[159:128]\n TMP_SRC[223:192] := SRC[223:192]\n TMP_SRC[255:224] := SRC[223:192]\nFI;\nIF VL >= 512\n TMP_SRC[287:256] := SRC[287:256]\n TMP_SRC[319:288] := SRC[287:256]\n TMP_SRC[351:320] := SRC[351:320]\n TMP_SRC[383:352] := SRC[351:320]\n TMP_SRC[415:384] := SRC[415:384]\n TMP_SRC[447:416] := SRC[415:384]\n TMP_SRC[479:448] := SRC[479:448]\n TMP_SRC[511:480] := SRC[479:448]\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC[31:0]\nDEST[63:32] := SRC[31:0]\nDEST[95:64] := SRC[95:64]\nDEST[127:96] := SRC[95:64]\nDEST[159:128] := SRC[159:128]\nDEST[191:160] := SRC[159:128]\nDEST[223:192] := SRC[223:192]\nDEST[255:224] := SRC[223:192]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC[31:0]\nDEST[63:32] := SRC[31:0]\nDEST[95:64] := SRC[95:64]\nDEST[127:96] := SRC[95:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC[31:0]\nDEST[63:32] := SRC[31:0]\nDEST[95:64] := SRC[95:64]\nDEST[127:96] := SRC[95:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/movsldup" + }, + "movsq": { + "instruction": "MOVSQ", + "title": "MOVS/MOVSB/MOVSW/MOVSD/MOVSQ\n\t\t— Move Data From String to String", + "opcode": "REX.W + A5", + "description": "Moves the byte, word, or doubleword specified with the second operand (source operand) to the location specified with the first operand (destination operand). Both the source and destination operands are located in memory. The address of the source operand is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The address of the destination operand is read from the ES:EDI or the ES:DI registers (again depending on the address-size attribute of the instruction). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the MOVS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source and destination operands should be symbols that indicate the size and location of the source value and the destination, respectively. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source and destination operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords), but they do not have to specify the correct location. The locations of the source and destination operands are always specified by the DS:(E)SI and ES:(E)DI registers, which must be loaded correctly before the move string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the MOVS instructions. Here also DS:(E)SI and ES:(E)DI are assumed to be the source and destination operands, respectively. The size of the source and destination operands is selected with the mnemonic: MOVSB (byte move), MOVSW (word move), or MOVSD (doubleword move).\nAfter the move operation, the (E)SI and (E)DI registers are incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI and (E)DI register are incre-\nmented; if the DF flag is 1, the (E)SI and (E)DI registers are decremented.) The registers are incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.", + "operation": "DEST := SRC;\nNon-64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n FI;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n FI;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\nFI;\n64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 2;\n (R|E)DI := (R|E)DI + 2;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 2;\n (R|E)DI := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 4;\n (R|E)DI := (R|E)DI + 4;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 4;\n (R|E)DI := (R|E)DI – 4;\n FI;\n ELSE IF (Quadword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq" + }, + "movss": { + "instruction": "MOVSS", + "title": "MOVSS\n\t\t— Move or Merge Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F 10 /r MOVSS xmm1, xmm2", + "description": "Moves a scalar single precision floating-point value from the source operand (second operand) to the destination operand (first operand). The source and destination operands can be XMM registers or 32-bit memory locations. This instruction can be used to move a single precision floating-point value to and from the low doubleword of an XMM register and a 32-bit memory location, or to move a single precision floating-point value between the low doublewords of two XMM registers. The instruction cannot be used to transfer data between memory locations.\nLegacy version: When the source and destination operands are XMM registers, bits (MAXVL-1:32) of the corresponding destination register are unmodified. When the source operand is a memory location and destination\noperand is an XMM registers, Bits (127:32) of the destination operand is cleared to all 0s, bits MAXVL:128 of the destination operand remains unchanged.\nVEX and EVEX encoded register-register syntax: Moves a scalar single precision floating-point value from the second source operand (the third operand) to the low doubleword element of the destination operand (the first operand). Bits 127:32 of the destination operand are copied from the first source operand (the second operand). Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX and EVEX encoded memory load syntax: When the source operand is a memory location and destination operand is an XMM registers, bits MAXVL:32 of the destination operand is cleared to all 0s.\nEVEX encoded versions: The low doubleword of the destination is updated according to the writemask.\nNote: For memory store form instruction “VMOVSS m32, xmm1”, VEX.vvvv is reserved and must be 1111b otherwise instruction will #UD. For memory store form instruction “VMOVSS mv {k1}, xmm1”, EVEX.vvvv is reserved and must be 1111b otherwise instruction will #UD.\nSoftware should ensure VMOVSS is encoded with VEX.L=0. Encoding VMOVSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[MAXVL-1:32] := 0\n\n\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC[31:0]\n ELSE *DEST[31:0] remains unchanged* ; merging-masking\nFI;\n\n\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC2[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC[31:0]\nDEST[MAXVL-1:32] (Unmodified)\n\n\nDEST[31:0] := SRC2[31:0]\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC2[31:0]\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC[31:0]\nDEST[MAXVL-1:32] := 0\n\n\nDEST[31:0] := SRC[31:0]\n\n\nDEST[31:0] := SRC[31:0]\nDEST[127:32] := 0\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/movss" + }, + "movsw": { + "instruction": "MOVSW", + "title": "MOVS/MOVSB/MOVSW/MOVSD/MOVSQ\n\t\t— Move Data From String to String", + "opcode": "A5", + "description": "Moves the byte, word, or doubleword specified with the second operand (source operand) to the location specified with the first operand (destination operand). Both the source and destination operands are located in memory. The address of the source operand is read from the DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). The address of the destination operand is read from the ES:EDI or the ES:DI registers (again depending on the address-size attribute of the instruction). The DS segment may be overridden with a segment override prefix, but the ES segment cannot be overridden.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the MOVS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source and destination operands should be symbols that indicate the size and location of the source value and the destination, respectively. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source and destination operand symbols must specify the correct type (size) of the operands (bytes, words, or doublewords), but they do not have to specify the correct location. The locations of the source and destination operands are always specified by the DS:(E)SI and ES:(E)DI registers, which must be loaded correctly before the move string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the MOVS instructions. Here also DS:(E)SI and ES:(E)DI are assumed to be the source and destination operands, respectively. The size of the source and destination operands is selected with the mnemonic: MOVSB (byte move), MOVSW (word move), or MOVSD (doubleword move).\nAfter the move operation, the (E)SI and (E)DI registers are incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI and (E)DI register are incre-\nmented; if the DF flag is 1, the (E)SI and (E)DI registers are decremented.) The registers are incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.", + "operation": "DEST := SRC;\nNon-64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (E)SI := (E)SI + 1;\n (E)DI := (E)DI + 1;\n ELSE\n (E)SI := (E)SI – 1;\n (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (E)SI := (E)SI + 2;\n (E)DI := (E)DI + 2;\n FI;\n ELSE\n (E)SI := (E)SI – 2;\n (E)DI := (E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (E)SI := (E)SI + 4;\n (E)DI := (E)DI + 4;\n FI;\n ELSE\n (E)SI := (E)SI – 4;\n (E)DI := (E)DI – 4;\n FI;\nFI;\n64-bit Mode:\nIF (Byte move)\n THEN IF DF = 0\n THEN\n (R|E)SI := (R|E)SI + 1;\n (R|E)DI := (R|E)DI + 1;\n ELSE\n (R|E)SI := (R|E)SI – 1;\n (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 2;\n (R|E)DI := (R|E)DI + 2;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 2;\n (R|E)DI := (R|E)DI – 2;\n FI;\n ELSE IF (Doubleword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 4;\n (R|E)DI := (R|E)DI + 4;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 4;\n (R|E)DI := (R|E)DI – 4;\n FI;\n ELSE IF (Quadword move)\n THEN IF DF = 0\n (R|E)SI := (R|E)SI + 8;\n (R|E)DI := (R|E)DI + 8;\n FI;\n ELSE\n (R|E)SI := (R|E)SI – 8;\n (R|E)DI := (R|E)DI – 8;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq" + }, + "movsx": { + "instruction": "MOVSX", + "title": "MOVSX/MOVSXD\n\t\t— Move With Sign-Extension", + "opcode": "0F BE /r", + "description": "Copies the contents of the source operand (register or memory location) to the destination operand (register) and sign extends the value to 16 or 32 bits (see Figure 7-6 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). The size of the converted value depends on the operand-size attribute.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := SignExtend(SRC);\n", + "url": "https://www.felixcloutier.com/x86/movsx:movsxd" + }, + "movsxd": { + "instruction": "MOVSXD", + "title": "MOVSX/MOVSXD\n\t\t— Move With Sign-Extension", + "opcode": "63 /r1", + "description": "Copies the contents of the source operand (register or memory location) to the destination operand (register) and sign extends the value to 16 or 32 bits (see Figure 7-6 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1). The size of the converted value depends on the operand-size attribute.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := SignExtend(SRC);\n", + "url": "https://www.felixcloutier.com/x86/movsx:movsxd" + }, + "movupd": { + "instruction": "MOVUPD", + "title": "MOVUPD\n\t\t— Move Unaligned Packed Double Precision Floating-Point Values", + "opcode": "66 0F 10 /r MOVUPD xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.\nEVEX.512 encoded version:\nMoves 512 bits of packed double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a ZMM register from a float64 memory location, to store the contents of a ZMM register into a memory. The destination operand is updated according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers. Bits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed double precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned on a 16-byte boundary without causing a general-protection exception (#GP) to be generated\nVEX.128 and EVEX.128 encoded versions: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movupd" + }, + "movups": { + "instruction": "MOVUPS", + "title": "MOVUPS\n\t\t— Move Unaligned Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 10 /r MOVUPS xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.\nEVEX.512 encoded version:\nMoves 512 bits of packed single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a ZMM register from a 512-bit float32 memory location, to store the contents of a ZMM register into memory. The destination operand is updated according to the writemask.\nVEX.256 and EVEX.256 encoded versions:\nMoves 256 bits of packed single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers. Bits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed single precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned without causing a general-protection exception (#GP) to be generated.\nVEX.128 and EVEX.128 encoded versions: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movups" + }, + "movzx": { + "instruction": "MOVZX", + "title": "MOVZX\n\t\t— Move With Zero-Extend", + "opcode": "0F B6 /r", + "description": "Copies the contents of the source operand (register or memory location) to the destination operand (register) and zero extends the value. The size of the converted value depends on the operand-size attribute.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bit operands. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := ZeroExtend(SRC);\n", + "url": "https://www.felixcloutier.com/x86/movzx" + }, + "mpsadbw": { + "instruction": "MPSADBW", + "title": "MPSADBW\n\t\t— Compute Multiple Packed Sums of Absolute Difference", + "opcode": "66 0F 3A 42 /r ib MPSADBW xmm1, xmm2/m128, imm8", + "description": "(V)MPSADBW calculates packed word results of sum-absolute-difference (SAD) of unsigned bytes from two blocks of 32-bit dword elements, using two select fields in the immediate byte to select the offsets of the two blocks within the first source operand and the second operand. Packed SAD word results are calculated within each 128-bit lane. Each SAD word result is calculated between a stationary block_2 (whose offset within the second source operand is selected by a two bit select control, multiplied by 32 bits) and a sliding block_1 at consecutive byte-granular position within the first source operand. The offset of the first 32-bit block of block_1 is selectable using a one bit select control, multiplied by 32 bits.\n128-bit Legacy SSE version: Imm8[1:0]*32 specifies the bit offset of block_2 within the second source operand. Imm[2]*32 specifies the initial bit offset of the block_1 within the first source operand. The first source operand and destination operand are the same. The first source and destination operands are XMM registers. The second source operand is either an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. Bits 7:3 of the immediate byte are ignored.\nVEX.128 encoded version: Imm8[1:0]*32 specifies the bit offset of block_2 within the second source operand. Imm[2]*32 specifies the initial bit offset of the block_1 within the first source operand. The first source and destination operands are XMM registers. The second source operand is either an XMM register or a 128-bit memory location. Bits (127:128) of the corresponding YMM register are zeroed. Bits 7:3 of the immediate byte are ignored.\nVEX.256 encoded version: The sum-absolute-difference (SAD) operation is repeated 8 times for MPSADW between the same block_2 (fixed offset within the second source operand) and a variable block_1 (offset is shifted by 8 bits for each SAD operation) in the first source operand. Each 16-bit result of eight SAD operations between block_2 and block_1 is written to the respective word in the lower 128 bits of the destination operand.\nAdditionally, VMPSADBW performs another eight SAD operations on block_4 of the second source operand and block_3 of the first source operand. (Imm8[4:3]*32 + 128) specifies the bit offset of block_4 within the second source operand. (Imm[5]*32+128) specifies the initial bit offset of the block_3 within the first source operand. Each 16-bit result of eight SAD operations between block_4 and block_3 is written to the respective word in the upper 128 bits of the destination operand.\nThe first source operand is a YMM register. The second source register can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. Bits 7:6 of the immediate byte are ignored.\nNote: If VMPSADBW is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an #UD exception.", + "operation": "BLK2_OFFSET := imm8[1:0]*32\nBLK1_OFFSET := imm8[2]*32\nSRC1_BYTE0 := SRC1[BLK1_OFFSET+7:BLK1_OFFSET]\nSRC1_BYTE1 := SRC1[BLK1_OFFSET+15:BLK1_OFFSET+8]\nSRC1_BYTE2 := SRC1[BLK1_OFFSET+23:BLK1_OFFSET+16]\nSRC1_BYTE3 := SRC1[BLK1_OFFSET+31:BLK1_OFFSET+24]\nSRC1_BYTE4 := SRC1[BLK1_OFFSET+39:BLK1_OFFSET+32]\nSRC1_BYTE5 := SRC1[BLK1_OFFSET+47:BLK1_OFFSET+40]\nSRC1_BYTE6 := SRC1[BLK1_OFFSET+55:BLK1_OFFSET+48]\nSRC1_BYTE7 := SRC1[BLK1_OFFSET+63:BLK1_OFFSET+56]\nSRC1_BYTE8 := SRC1[BLK1_OFFSET+71:BLK1_OFFSET+64]\nSRC1_BYTE9 := SRC1[BLK1_OFFSET+79:BLK1_OFFSET+72]\nSRC1_BYTE10 := SRC1[BLK1_OFFSET+87:BLK1_OFFSET+80]\nSRC2_BYTE0 := SRC2[BLK2_OFFSET+7:BLK2_OFFSET]\nSRC2_BYTE1 := SRC2[BLK2_OFFSET+15:BLK2_OFFSET+8]\nSRC2_BYTE2 := SRC2[BLK2_OFFSET+23:BLK2_OFFSET+16]\nSRC2_BYTE3 := SRC2[BLK2_OFFSET+31:BLK2_OFFSET+24]\nTEMP0 := ABS(SRC1_BYTE0 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE1 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE2 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE3 - SRC2_BYTE3)\nDEST[15:0] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE1 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE2 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE3 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE4 - SRC2_BYTE3)\nDEST[31:16] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE2 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE3 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE4 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE5 - SRC2_BYTE3)\nDEST[47:32] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE3 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE4 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE5 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE6 - SRC2_BYTE3)\nDEST[63:48] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE4 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE5 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE6 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE7 - SRC2_BYTE3)\nDEST[79:64] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE5 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE6 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE7 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE8 - SRC2_BYTE3)\nDEST[95:80] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE6 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE7 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE8 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE9 - SRC2_BYTE3)\nDEST[111:96] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE7 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE8 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE9 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE10 - SRC2_BYTE3)\nDEST[127:112] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nBLK2_OFFSET := imm8[4:3]*32 + 128\nBLK1_OFFSET := imm8[5]*32 + 128\nSRC1_BYTE0 := SRC1[BLK1_OFFSET+7:BLK1_OFFSET]\nSRC1_BYTE1 := SRC1[BLK1_OFFSET+15:BLK1_OFFSET+8]\nSRC1_BYTE2 := SRC1[BLK1_OFFSET+23:BLK1_OFFSET+16]\nSRC1_BYTE3 := SRC1[BLK1_OFFSET+31:BLK1_OFFSET+24]\nSRC1_BYTE4 := SRC1[BLK1_OFFSET+39:BLK1_OFFSET+32]\nSRC1_BYTE5 := SRC1[BLK1_OFFSET+47:BLK1_OFFSET+40]\nSRC1_BYTE6 := SRC1[BLK1_OFFSET+55:BLK1_OFFSET+48]\nSRC1_BYTE7 := SRC1[BLK1_OFFSET+63:BLK1_OFFSET+56]\nSRC1_BYTE8 := SRC1[BLK1_OFFSET+71:BLK1_OFFSET+64]\nSRC1_BYTE9 := SRC1[BLK1_OFFSET+79:BLK1_OFFSET+72]\nSRC1_BYTE10 := SRC1[BLK1_OFFSET+87:BLK1_OFFSET+80]\nSRC2_BYTE0 := SRC2[BLK2_OFFSET+7:BLK2_OFFSET]\nSRC2_BYTE1 := SRC2[BLK2_OFFSET+15:BLK2_OFFSET+8]\nSRC2_BYTE2 := SRC2[BLK2_OFFSET+23:BLK2_OFFSET+16]\nSRC2_BYTE3 := SRC2[BLK2_OFFSET+31:BLK2_OFFSET+24]\nTEMP0 := ABS(SRC1_BYTE0 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE1 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE2 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE3 - SRC2_BYTE3)\nDEST[143:128] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE1 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE2 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE3 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE4 - SRC2_BYTE3)\nDEST[159:144] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE2 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE3 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE4 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE5 - SRC2_BYTE3)\nDEST[175:160] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE3 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE4 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE5 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE6 - SRC2_BYTE3)\nDEST[191:176] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE4 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE5 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE6 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE7 - SRC2_BYTE3)\nDEST[207:192] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE5 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE6 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE7 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE8 - SRC2_BYTE3)\nDEST[223:208] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE6 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE7 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE8 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE9 - SRC2_BYTE3)\nDEST[239:224] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE7 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE8 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE9 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE10 - SRC2_BYTE3)\nDEST[255:240] := TEMP0 + TEMP1 + TEMP2 + TEMP3\n\n\nBLK2_OFFSET := imm8[1:0]*32\nBLK1_OFFSET := imm8[2]*32\nSRC1_BYTE0 := SRC1[BLK1_OFFSET+7:BLK1_OFFSET]\nSRC1_BYTE1 := SRC1[BLK1_OFFSET+15:BLK1_OFFSET+8]\nSRC1_BYTE2 := SRC1[BLK1_OFFSET+23:BLK1_OFFSET+16]\nSRC1_BYTE3 := SRC1[BLK1_OFFSET+31:BLK1_OFFSET+24]\nSRC1_BYTE4 := SRC1[BLK1_OFFSET+39:BLK1_OFFSET+32]\nSRC1_BYTE5 := SRC1[BLK1_OFFSET+47:BLK1_OFFSET+40]\nSRC1_BYTE6 := SRC1[BLK1_OFFSET+55:BLK1_OFFSET+48]\nSRC1_BYTE7 := SRC1[BLK1_OFFSET+63:BLK1_OFFSET+56]\nSRC1_BYTE8 := SRC1[BLK1_OFFSET+71:BLK1_OFFSET+64]\nSRC1_BYTE9 := SRC1[BLK1_OFFSET+79:BLK1_OFFSET+72]\nSRC1_BYTE10 := SRC1[BLK1_OFFSET+87:BLK1_OFFSET+80]\nSRC2_BYTE0 := SRC2[BLK2_OFFSET+7:BLK2_OFFSET]\nSRC2_BYTE1 := SRC2[BLK2_OFFSET+15:BLK2_OFFSET+8]\nSRC2_BYTE2 := SRC2[BLK2_OFFSET+23:BLK2_OFFSET+16]\nSRC2_BYTE3 := SRC2[BLK2_OFFSET+31:BLK2_OFFSET+24]\nTEMP0 := ABS(SRC1_BYTE0 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE1 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE2 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE3 - SRC2_BYTE3)\nDEST[15:0] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE1 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE2 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE3 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE4 - SRC2_BYTE3)\nDEST[31:16] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE2 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE3 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE4 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE5 - SRC2_BYTE3)\nDEST[47:32] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE3 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE4 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE5 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE6 - SRC2_BYTE3)\nDEST[63:48] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE4 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE5 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE6 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE7 - SRC2_BYTE3)\nDEST[79:64] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE5 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE6 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE7 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE8 - SRC2_BYTE3)\nDEST[95:80] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE6 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE7 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE8 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE9 - SRC2_BYTE3)\nDEST[111:96] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS(SRC1_BYTE7 - SRC2_BYTE0)\nTEMP1 := ABS(SRC1_BYTE8 - SRC2_BYTE1)\nTEMP2 := ABS(SRC1_BYTE9 - SRC2_BYTE2)\nTEMP3 := ABS(SRC1_BYTE10 - SRC2_BYTE3)\nDEST[127:112] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nDEST[MAXVL-1:128] := 0\n\n\nSRC_OFFSET := imm8[1:0]*32\nDEST_OFFSET := imm8[2]*32\nDEST_BYTE0 := DEST[DEST_OFFSET+7:DEST_OFFSET]\nDEST_BYTE1 := DEST[DEST_OFFSET+15:DEST_OFFSET+8]\nDEST_BYTE2 := DEST[DEST_OFFSET+23:DEST_OFFSET+16]\nDEST_BYTE3 := DEST[DEST_OFFSET+31:DEST_OFFSET+24]\nDEST_BYTE4 := DEST[DEST_OFFSET+39:DEST_OFFSET+32]\nDEST_BYTE5 := DEST[DEST_OFFSET+47:DEST_OFFSET+40]\nDEST_BYTE6 := DEST[DEST_OFFSET+55:DEST_OFFSET+48]\nDEST_BYTE7 := DEST[DEST_OFFSET+63:DEST_OFFSET+56]\nDEST_BYTE8 := DEST[DEST_OFFSET+71:DEST_OFFSET+64]\nDEST_BYTE9 := DEST[DEST_OFFSET+79:DEST_OFFSET+72]\nDEST_BYTE10 := DEST[DEST_OFFSET+87:DEST_OFFSET+80]\nSRC_BYTE0 := SRC[SRC_OFFSET+7:SRC_OFFSET]\nSRC_BYTE1 := SRC[SRC_OFFSET+15:SRC_OFFSET+8]\nSRC_BYTE2 := SRC[SRC_OFFSET+23:SRC_OFFSET+16]\nSRC_BYTE3 := SRC[SRC_OFFSET+31:SRC_OFFSET+24]\nTEMP0 := ABS( DEST_BYTE0 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE1 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE2 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE3 - SRC_BYTE3)\nDEST[15:0] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE1 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE2 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE3 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE4 - SRC_BYTE3)\nDEST[31:16] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE2 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE3 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE4 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE5 - SRC_BYTE3)\nDEST[47:32] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE3 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE4 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE5 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE6 - SRC_BYTE3)\nDEST[63:48] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE4 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE5 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE6 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE7 - SRC_BYTE3)\nDEST[79:64] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE5 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE6 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE7 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE8 - SRC_BYTE3)\nDEST[95:80] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE6 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE7 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE8 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE9 - SRC_BYTE3)\nDEST[111:96] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nTEMP0 := ABS( DEST_BYTE7 - SRC_BYTE0)\nTEMP1 := ABS( DEST_BYTE8 - SRC_BYTE1)\nTEMP2 := ABS( DEST_BYTE9 - SRC_BYTE2)\nTEMP3 := ABS( DEST_BYTE10 - SRC_BYTE3)\nDEST[127:112] := TEMP0 + TEMP1 + TEMP2 + TEMP3\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/mpsadbw" + }, + "mul": { + "instruction": "MUL", + "title": "MUL\n\t\t— Unsigned Multiply", + "opcode": "F6 /4", + "description": "Performs an unsigned multiplication of the first operand (destination operand) and the second operand (source operand) and stores the result in the destination operand. The destination operand is an implied operand located in register AL, AX or EAX (depending on the size of the operand); the source operand is located in a general-purpose register or a memory location. The action of this instruction and the location of the result depends on the opcode and the operand size as shown in Table 4-9.\nThe result is stored in register AX, register pair DX:AX, or register pair EDX:EAX (depending on the operand size), with the high-order bits of the product contained in register AH, DX, or EDX, respectively. If the high-order bits of the product are 0, the CF and OF flags are cleared; otherwise, the flags are set.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits.\nSee the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (Byte operation)\n THEN\n AX := AL ∗ SRC;\n ELSE (* Word or doubleword operation *)\n IF OperandSize = 16\n THEN\n DX:AX := AX ∗ SRC;\n ELSE IF OperandSize = 32\n THEN EDX:EAX := EAX ∗ SRC; FI;\n ELSE (* OperandSize = 64 *)\n RDX:RAX := RAX ∗ SRC;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/mul" + }, + "mulpd": { + "instruction": "MULPD", + "title": "MULPD\n\t\t— Multiply Packed Double Precision Floating-Point Values", + "opcode": "66 0F 59 /r MULPD xmm1, xmm2/m128", + "description": "Multiply packed double precision floating-point values from the first source operand with corresponding values in the second source operand, and stores the packed double precision floating-point results in the destination operand.\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. Bits (MAXVL-1:256) of the corresponding destination ZMM register are zeroed.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the destination YMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := SRC1[i+63:i] * SRC2[63:0]\n ELSE\n DEST[i+63:i] := SRC1[i+63:i] * SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0] * SRC2[63:0]\nDEST[127:64] := SRC1[127:64] * SRC2[127:64]\nDEST[191:128] := SRC1[191:128] * SRC2[191:128]\nDEST[255:192] := SRC1[255:192] * SRC2[255:192]\nDEST[MAXVL-1:256] := 0;\n.\n\n\nDEST[63:0] := SRC1[63:0] * SRC2[63:0]\nDEST[127:64] := SRC1[127:64] * SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] * SRC[63:0]\nDEST[127:64] := DEST[127:64] * SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/mulpd" + }, + "mulps": { + "instruction": "MULPS", + "title": "MULPS\n\t\t— Multiply Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 59 /r MULPS xmm1, xmm2/m128", + "description": "Multiply the packed single precision floating-point values from the first source operand with the corresponding values in the second source operand, and stores the packed double precision floating-point results in the destination operand.\nEVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. Bits (MAXVL-1:256) of the corresponding destination ZMM register are zeroed.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the destination YMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+31:i] := SRC1[i+31:i] * SRC2[31:0]\n ELSE\n DEST[i+31:i] := SRC1[i+31:i] * SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[31:0] * SRC2[31:0]\nDEST[63:32] := SRC1[63:32] * SRC2[63:32]\nDEST[95:64] := SRC1[95:64] * SRC2[95:64]\nDEST[127:96] := SRC1[127:96] * SRC2[127:96]\nDEST[159:128] := SRC1[159:128] * SRC2[159:128]\nDEST[191:160] := SRC1[191:160] * SRC2[191:160]\nDEST[223:192] := SRC1[223:192] * SRC2[223:192]\nDEST[255:224] := SRC1[255:224] * SRC2[255:224].\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[31:0] := SRC1[31:0] * SRC2[31:0]\nDEST[63:32] := SRC1[63:32] * SRC2[63:32]\nDEST[95:64] := SRC1[95:64] * SRC2[95:64]\nDEST[127:96] := SRC1[127:96] * SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] * SRC2[31:0]\nDEST[63:32] := SRC1[63:32] * SRC2[63:32]\nDEST[95:64] := SRC1[95:64] * SRC2[95:64]\nDEST[127:96] := SRC1[127:96] * SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/mulps" + }, + "mulsd": { + "instruction": "MULSD", + "title": "MULSD\n\t\t— Multiply Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 59 /r MULSD xmm1,xmm2/m64", + "description": "Multiplies the low double precision floating-point value in the second source operand by the low double precision floating-point value in the first source operand, and stores the double precision floating-point result in the destination operand. The second source operand can be an XMM register or a 64-bit memory location. The first source operand and the destination operands are XMM registers.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded version: The quadword at bits 127:64 of the destination operand is copied from the same bits of the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low quadword element of the destination operand is updated according to the write-mask.\nSoftware should ensure VMULSD is encoded with VEX.L=0. Encoding VMULSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC1[63:0] * SRC2[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI\n FI;\nENDFOR\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0] * SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] * SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/mulsd" + }, + "mulss": { + "instruction": "MULSS", + "title": "MULSS\n\t\t— Multiply Scalar Single Precision Floating-Point Values", + "opcode": "F3 0F 59 /r MULSS xmm1,xmm2/m32", + "description": "Multiplies the low single precision floating-point value from the second source operand by the low single precision floating-point value in the first source operand, and stores the single precision floating-point result in the destination operand. The second source operand can be an XMM register or a 32-bit memory location. The first source operand and the destination operands are XMM registers.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged.\nVEX.128 and EVEX encoded version: The first source operand is an xmm register encoded by VEX.vvvv. The three high-order doublewords of the destination operand are copied from the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low doubleword element of the destination operand is updated according to the write-mask.\nSoftware should ensure VMULSS is encoded with VEX.L=0. Encoding VMULSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND SRC2 *is a register*\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC1[31:0] * SRC2[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI\n FI;\nENDFOR\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] * SRC2[31:0]\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0] * SRC[31:0]\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/mulss" + }, + "mulx": { + "instruction": "MULX", + "title": "MULX\n\t\t— Unsigned Multiply Without Affecting Flags", + "opcode": "VEX.LZ.F2.0F38.W0 F6 /r MULX r32a, r32b, r/m32", + "description": "Performs an unsigned multiplication of the implicit source operand (EDX/RDX) and the specified source operand (the third operand) and stores the low half of the result in the second destination (second operand), the high half of the result in the first destination operand (first operand), without reading or writing the arithmetic flags. This enables efficient programming where the software can interleave add with carry operations and multiplications.\nIf the first and second operand are identical, it will contain the high half of the multiplication result.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "// DEST1: ModRM:reg\n// DEST2: VEX.vvvv\nIF (OperandSize = 32)\n SRC1 := EDX;\n DEST2 := (SRC1*SRC2)[31:0];\n DEST1 := (SRC1*SRC2)[63:32];\nELSE IF (OperandSize = 64)\n SRC1 := RDX;\n DEST2 := (SRC1*SRC2)[63:0];\n DEST1 := (SRC1*SRC2)[127:64];\nFI\n", + "url": "https://www.felixcloutier.com/x86/mulx" + }, + "mwait": { + "instruction": "MWAIT", + "title": "MWAIT\n\t\t— Monitor Wait", + "opcode": "0F 01 C9", + "description": "MWAIT instruction provides hints to allow the processor to enter an implementation-dependent optimized state. There are two principal targeted usages: address-range monitor and advanced power management. Both usages of MWAIT require the use of the MONITOR instruction.\nCPUID.01H:ECX.MONITOR[bit 3] indicates the availability of MONITOR and MWAIT in the processor. When set, MWAIT may be executed only at privilege level 0 (use at any other privilege level results in an invalid-opcode exception). The operating system or system BIOS may disable this instruction by using the IA32_MISC_ENABLE MSR; disabling MWAIT clears the CPUID feature flag and causes execution to generate an invalid-opcode exception.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.\nECX specifies optional extensions for the MWAIT instruction. EAX may contain hints such as the preferred optimized state the processor should enter. The first processors to implement MWAIT supported only the zero value for EAX and ECX. Later processors allowed setting ECX[0] to enable masked interrupts as break events for MWAIT (see below). Software can use the CPUID instruction to determine the extensions and hints supported by the processor.", + "operation": "(* MWAIT takes the argument in EAX as a hint extension and is architected to take the argument in ECX as an instruction extension\nMWAIT EAX, ECX *)\n{\nWHILE ( (“Monitor Hardware is in armed state”)) {\n implementation_dependent_optimized_state(EAX, ECX); }\nSet the state of Monitor Hardware as triggered;\n}\n", + "url": "https://www.felixcloutier.com/x86/mwait" + }, + "neg": { + "instruction": "NEG", + "title": "NEG\n\t\t— Two's Complement Negation", + "opcode": "F6 /3", + "description": "Replaces the value of operand (the destination operand) with its two's complement. (This operation is equivalent to subtracting the operand from 0.) The destination operand is located in a general-purpose register or a memory location.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF DEST = 0\n THEN CF := 0;\n ELSE CF := 1;\nFI;\nDEST := [– (DEST)]\n", + "url": "https://www.felixcloutier.com/x86/neg" + }, + "nop": { + "instruction": "NOP", + "title": "NOP\n\t\t— No Operation", + "opcode": "NP 90", + "description": "This instruction performs no operation. It is a one-byte or multi-byte NOP that takes up space in the instruction stream but does not impact machine context, except for the EIP register.\nThe multi-byte form of NOP is available on processors with model encoding:\nThe multi-byte NOP instruction does not alter the content of a register and will not issue a memory operation. The instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "The one-byte NOP instruction is an alias mnemonic for the XCHG (E)AX, (E)AX instruction.\nThe multi-byte NOP instruction performs no operation on supported processors and generates undefined opcode\nexception on processors that do not support the multi-byte NOP instruction.\nThe memory operand form of the instruction allows software to create a byte sequence of “no operation” as one\ninstruction. For situations where multiple-byte NOPs are needed, the recommended operations (32-bit mode and\n64-bit mode) are:\n", + "url": "https://www.felixcloutier.com/x86/nop" + }, + "not": { + "instruction": "NOT", + "title": "NOT\n\t\t— One's Complement Negation", + "opcode": "F6 /2", + "description": "Performs a bitwise NOT operation (each 1 is set to 0, and each 0 is set to 1) on the destination operand and stores the result in the destination operand location. The destination operand can be a register or a memory location.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := NOT DEST;\n", + "url": "https://www.felixcloutier.com/x86/not" + }, + "or": { + "instruction": "OR", + "title": "OR\n\t\t— Logical Inclusive OR", + "opcode": "0C ib", + "description": "Performs a bitwise inclusive OR operation between the destination (first) and source (second) operands and stores the result in the destination operand location. The source operand can be an immediate, a register, or a memory location; the destination operand can be a register or a memory location. (However, two memory operands cannot be used in one instruction.) Each bit of the result of the OR instruction is set to 0 if both corresponding bits of the first and second operands are 0; otherwise, each bit is set to 1.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := DEST OR SRC;\n", + "url": "https://www.felixcloutier.com/x86/or" + }, + "orpd": { + "instruction": "ORPD", + "title": "ORPD\n\t\t— Bitwise Logical OR of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 56/r ORPD xmm1, xmm2/m128", + "description": "Performs a bitwise logical OR of the two, four or eight packed double precision floating-point values from the first source operand and the second source operand, and stores the result in the destination operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with write-mask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+63:i] := SRC1[i+63:i] BITWISE OR SRC2[63:0]\n ELSE\n DEST[i+63:i] := SRC1[i+63:i] BITWISE OR SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]\nDEST[127:64] := SRC1[127:64] BITWISE OR SRC2[127:64]\nDEST[191:128] := SRC1[191:128] BITWISE OR SRC2[191:128]\nDEST[255:192] := SRC1[255:192] BITWISE OR SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]\nDEST[127:64] := SRC1[127:64] BITWISE OR SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] BITWISE OR SRC[63:0]\nDEST[127:64] := DEST[127:64] BITWISE OR SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/orpd" + }, + "orps": { + "instruction": "ORPS", + "title": "ORPS\n\t\t— Bitwise Logical OR of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 56 /r ORPS xmm1, xmm2/m128", + "description": "Performs a bitwise logical OR of the four, eight or sixteen packed single precision floating-point values from the first source operand and the second source operand, and stores the result in the destination operand\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with write-mask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n DEST[i+31:i] := SRC1[i+31:i] BITWISE OR SRC2[31:0]\n ELSE\n DEST[i+31:i] := SRC1[i+31:i] BITWISE OR SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[63:32] := SRC1[63:32] BITWISE OR SRC2[63:32]\nDEST[95:64] := SRC1[95:64] BITWISE OR SRC2[95:64]\nDEST[127:96] := SRC1[127:96] BITWISE OR SRC2[127:96]\nDEST[159:128] := SRC1[159:128] BITWISE OR SRC2[159:128]\nDEST[191:160] := SRC1[191:160] BITWISE OR SRC2[191:160]\nDEST[223:192] := SRC1[223:192] BITWISE OR SRC2[223:192]\nDEST[255:224] := SRC1[255:224] BITWISE OR SRC2[255:224].\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[63:32] := SRC1[63:32] BITWISE OR SRC2[63:32]\nDEST[95:64] := SRC1[95:64] BITWISE OR SRC2[95:64]\nDEST[127:96] := SRC1[127:96] BITWISE OR SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]\nDEST[63:32] := SRC1[63:32] BITWISE OR SRC2[63:32]\nDEST[95:64] := SRC1[95:64] BITWISE OR SRC2[95:64]\nDEST[127:96] := SRC1[127:96] BITWISE OR SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/orps" + }, + "out": { + "instruction": "OUT", + "title": "OUT\n\t\t— Output to Port", + "opcode": "E6 ib", + "description": "Copies the value from the second operand (source operand) to the I/O port specified with the destination operand (first operand). The source operand can be register AL, AX, or EAX, depending on the size of the port being accessed (8, 16, or 32 bits, respectively); the destination operand can be a byte-immediate or the DX register. Using a byte immediate allows I/O port addresses 0 to 255 to be accessed; using the DX register as a source operand allows I/O ports from 0 to 65,535 to be accessed.\nThe size of the I/O port being accessed is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the machine code level, I/O instructions are shorter when accessing 8-bit I/O ports. Here, the upper eight bits of the port address will be 0.\nThis instruction is only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE ( * I/O operation is allowed *)\n DEST := SRC; (* Writes to selected I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode with CPL ≤ IOPL *)\n DEST := SRC; (* Writes to selected I/O port *)\nFI;\n", + "url": "https://www.felixcloutier.com/x86/out" + }, + "outs": { + "instruction": "OUTS", + "title": "OUTS/OUTSB/OUTSW/OUTSD\n\t\t— Output String to Port", + "opcode": "6E", + "description": "Copies data from the source operand (second operand) to the I/O port specified with the destination operand (first operand). The source operand is a memory location, the address of which is read from either the DS:SI, DS:ESI or the RSI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The DS segment may be overridden with a segment override prefix.) The destination operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the OUTS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand should be a symbol that indicates the size of the I/O port and the source address, and the destination operand must be DX. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI or RSI registers, which must be loaded correctly before the OUTS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the OUTS instructions. Here also DS:(E)SI is assumed to be the source operand and DX is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: OUTSB (byte), OUTSW (word), or OUTSD (doubleword).\nAfter the byte, word, or doubleword is transferred from the memory location to the I/O port, the SI/ESI/RSI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the SI/ESI/RSI register is decremented.) The SI/ESI/RSI register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nThe OUTS, OUTSB, OUTSW, and OUTSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a\ndescription of the REP prefix. This instruction is only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, the default operand size is 32 bits; operand size is not promoted by the use of REX.W. In 64-bit mode, the default address size is 64 bits, and 64-bit address is specified using RSI by default. 32-bit address using ESI is support using the prefix 67H, but 16-bit address is not supported in 64-bit mode.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Writes to I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode or 64-Bit Mode with CPL ≤ IOPL *)\n DEST := SRC; (* Writes to I/O port *)\nFI;\nByte transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 1;\n ELSE RSI := RSI or – 1;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 1;\n ELSE ESI := ESI – 1;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\n FI;\nWord transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 2;\n ELSE RSI := RSI or – 2;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 2;\n ELSE ESI := ESI – 2;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n FI;\n FI;\nDoubleword transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 4;\n ELSE RSI := RSI or – 4;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 4;\n ELSE ESI := ESI – 4;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\n", + "url": "https://www.felixcloutier.com/x86/outs:outsb:outsw:outsd" + }, + "outsb": { + "instruction": "OUTSB", + "title": "OUTS/OUTSB/OUTSW/OUTSD\n\t\t— Output String to Port", + "opcode": "6E", + "description": "Copies data from the source operand (second operand) to the I/O port specified with the destination operand (first operand). The source operand is a memory location, the address of which is read from either the DS:SI, DS:ESI or the RSI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The DS segment may be overridden with a segment override prefix.) The destination operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the OUTS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand should be a symbol that indicates the size of the I/O port and the source address, and the destination operand must be DX. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI or RSI registers, which must be loaded correctly before the OUTS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the OUTS instructions. Here also DS:(E)SI is assumed to be the source operand and DX is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: OUTSB (byte), OUTSW (word), or OUTSD (doubleword).\nAfter the byte, word, or doubleword is transferred from the memory location to the I/O port, the SI/ESI/RSI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the SI/ESI/RSI register is decremented.) The SI/ESI/RSI register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nThe OUTS, OUTSB, OUTSW, and OUTSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a\ndescription of the REP prefix. This instruction is only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, the default operand size is 32 bits; operand size is not promoted by the use of REX.W. In 64-bit mode, the default address size is 64 bits, and 64-bit address is specified using RSI by default. 32-bit address using ESI is support using the prefix 67H, but 16-bit address is not supported in 64-bit mode.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Writes to I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode or 64-Bit Mode with CPL ≤ IOPL *)\n DEST := SRC; (* Writes to I/O port *)\nFI;\nByte transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 1;\n ELSE RSI := RSI or – 1;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 1;\n ELSE ESI := ESI – 1;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\n FI;\nWord transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 2;\n ELSE RSI := RSI or – 2;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 2;\n ELSE ESI := ESI – 2;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n FI;\n FI;\nDoubleword transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 4;\n ELSE RSI := RSI or – 4;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 4;\n ELSE ESI := ESI – 4;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\n", + "url": "https://www.felixcloutier.com/x86/outs:outsb:outsw:outsd" + }, + "outsd": { + "instruction": "OUTSD", + "title": "OUTS/OUTSB/OUTSW/OUTSD\n\t\t— Output String to Port", + "opcode": "6F", + "description": "Copies data from the source operand (second operand) to the I/O port specified with the destination operand (first operand). The source operand is a memory location, the address of which is read from either the DS:SI, DS:ESI or the RSI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The DS segment may be overridden with a segment override prefix.) The destination operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the OUTS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand should be a symbol that indicates the size of the I/O port and the source address, and the destination operand must be DX. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI or RSI registers, which must be loaded correctly before the OUTS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the OUTS instructions. Here also DS:(E)SI is assumed to be the source operand and DX is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: OUTSB (byte), OUTSW (word), or OUTSD (doubleword).\nAfter the byte, word, or doubleword is transferred from the memory location to the I/O port, the SI/ESI/RSI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the SI/ESI/RSI register is decremented.) The SI/ESI/RSI register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nThe OUTS, OUTSB, OUTSW, and OUTSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a\ndescription of the REP prefix. This instruction is only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, the default operand size is 32 bits; operand size is not promoted by the use of REX.W. In 64-bit mode, the default address size is 64 bits, and 64-bit address is specified using RSI by default. 32-bit address using ESI is support using the prefix 67H, but 16-bit address is not supported in 64-bit mode.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Writes to I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode or 64-Bit Mode with CPL ≤ IOPL *)\n DEST := SRC; (* Writes to I/O port *)\nFI;\nByte transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 1;\n ELSE RSI := RSI or – 1;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 1;\n ELSE ESI := ESI – 1;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\n FI;\nWord transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 2;\n ELSE RSI := RSI or – 2;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 2;\n ELSE ESI := ESI – 2;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n FI;\n FI;\nDoubleword transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 4;\n ELSE RSI := RSI or – 4;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 4;\n ELSE ESI := ESI – 4;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\n", + "url": "https://www.felixcloutier.com/x86/outs:outsb:outsw:outsd" + }, + "outsw": { + "instruction": "OUTSW", + "title": "OUTS/OUTSB/OUTSW/OUTSD\n\t\t— Output String to Port", + "opcode": "6F", + "description": "Copies data from the source operand (second operand) to the I/O port specified with the destination operand (first operand). The source operand is a memory location, the address of which is read from either the DS:SI, DS:ESI or the RSI registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The DS segment may be overridden with a segment override prefix.) The destination operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port.\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the OUTS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand should be a symbol that indicates the size of the I/O port and the source address, and the destination operand must be DX. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the source operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the DS:(E)SI or RSI registers, which must be loaded correctly before the OUTS instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, and doubleword versions of the OUTS instructions. Here also DS:(E)SI is assumed to be the source operand and DX is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: OUTSB (byte), OUTSW (word), or OUTSD (doubleword).\nAfter the byte, word, or doubleword is transferred from the memory location to the I/O port, the SI/ESI/RSI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the SI/ESI/RSI register is decremented.) The SI/ESI/RSI register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nThe OUTS, OUTSB, OUTSW, and OUTSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a\ndescription of the REP prefix. This instruction is only useful for accessing I/O ports located in the processor’s I/O address space. See Chapter 19, “Input/Output,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on accessing I/O ports in the I/O address space.\nIn 64-bit mode, the default operand size is 32 bits; operand size is not promoted by the use of REX.W. In 64-bit mode, the default address size is 64 bits, and 64-bit address is specified using RSI by default. 32-bit address using ESI is support using the prefix 67H, but 16-bit address is not supported in 64-bit mode.", + "operation": "IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))\n THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)\n IF (Any I/O Permission Bit for I/O port being accessed = 1)\n THEN (* I/O operation is not allowed *)\n #GP(0);\n ELSE (* I/O operation is allowed *)\n DEST := SRC; (* Writes to I/O port *)\n FI;\n ELSE (Real Mode or Protected Mode or 64-Bit Mode with CPL ≤ IOPL *)\n DEST := SRC; (* Writes to I/O port *)\nFI;\nByte transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 1;\n ELSE RSI := RSI or – 1;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 1;\n ELSE ESI := ESI – 1;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 1;\n ELSE (E)SI := (E)SI – 1;\n FI;\n FI;\nWord transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 2;\n ELSE RSI := RSI or – 2;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 2;\n ELSE ESI := ESI – 2;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 2;\n ELSE (E)SI := (E)SI – 2;\n FI;\n FI;\nDoubleword transfer:\n IF 64-bit mode\n Then\n IF 64-Bit Address Size\n THEN\n IF DF = 0\n THEN RSI := RSI RSI + 4;\n ELSE RSI := RSI or – 4;\n FI;\n ELSE (* 32-Bit Address Size *)\n IF DF = 0\n THEN ESI := ESI + 4;\n ELSE ESI := ESI – 4;\n FI;\n FI;\n ELSE\n IF DF = 0\n THEN (E)SI := (E)SI + 4;\n ELSE (E)SI := (E)SI – 4;\n FI;\n FI;\n", + "url": "https://www.felixcloutier.com/x86/outs:outsb:outsw:outsd" + }, + "pabsb": { + "instruction": "PABSB", + "title": "PABSB/PABSW/PABSD/PABSQ\n\t\t— Packed Absolute Value", + "opcode": "NP 0F 38 1C /r1 PABSB mm1, mm2/m64", + "description": "PABSB/W/D computes the absolute value of each data element of the source operand (the second operand) and stores the UNSIGNED results in the destination operand (the first operand). PABSB operates on signed bytes, PABSW operates on signed 16-bit words, and PABSD operates on signed 32-bit integers.\nEVEX encoded VPABSD/Q: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nEVEX encoded VPABSB/W: The source operand is a ZMM/YMM/XMM register, or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded versions: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding register destination are zeroed.\nVEX.128 encoded versions: The source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The source operand can be an XMM register or an 128-bit memory location. The destination is an XMM register. The upper bits (VL_MAX-1:128) of the corresponding register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "Unsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 31st bytes\nUnsigned DEST[255:248] := ABS(SRC[255:248])\n\n\n (KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+7:i] := ABS(SRC[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 15th 16-bit words\nUnsigned DEST[255:240] := ABS(SRC[255:240])\n\n\n (KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+15:i] := ABS(SRC[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 7th 32-bit double words\nUnsigned DEST[255:224] := ABS(SRC[255:224])\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+31:i] := ABS(SRC[31:0])\n ELSE\n Unsigned DEST[i+31:i] := ABS(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+63:i] := ABS(SRC[63:0])\n ELSE\n Unsigned DEST[i+63:i] := ABS(SRC[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pabsb:pabsw:pabsd:pabsq" + }, + "pabsd": { + "instruction": "PABSD", + "title": "PABSB/PABSW/PABSD/PABSQ\n\t\t— Packed Absolute Value", + "opcode": "NP 0F 38 1C /r1 PABSB mm1, mm2/m64", + "description": "PABSB/W/D computes the absolute value of each data element of the source operand (the second operand) and stores the UNSIGNED results in the destination operand (the first operand). PABSB operates on signed bytes, PABSW operates on signed 16-bit words, and PABSD operates on signed 32-bit integers.\nEVEX encoded VPABSD/Q: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nEVEX encoded VPABSB/W: The source operand is a ZMM/YMM/XMM register, or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded versions: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding register destination are zeroed.\nVEX.128 encoded versions: The source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The source operand can be an XMM register or an 128-bit memory location. The destination is an XMM register. The upper bits (VL_MAX-1:128) of the corresponding register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "Unsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 31st bytes\nUnsigned DEST[255:248] := ABS(SRC[255:248])\n\n\n (KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+7:i] := ABS(SRC[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 15th 16-bit words\nUnsigned DEST[255:240] := ABS(SRC[255:240])\n\n\n (KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+15:i] := ABS(SRC[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 7th 32-bit double words\nUnsigned DEST[255:224] := ABS(SRC[255:224])\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+31:i] := ABS(SRC[31:0])\n ELSE\n Unsigned DEST[i+31:i] := ABS(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+63:i] := ABS(SRC[63:0])\n ELSE\n Unsigned DEST[i+63:i] := ABS(SRC[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pabsb:pabsw:pabsd:pabsq" + }, + "pabsq": { + "instruction": "PABSQ", + "title": "PABSB/PABSW/PABSD/PABSQ\n\t\t— Packed Absolute Value", + "opcode": "NP 0F 38 1C /r1 PABSB mm1, mm2/m64", + "description": "PABSB/W/D computes the absolute value of each data element of the source operand (the second operand) and stores the UNSIGNED results in the destination operand (the first operand). PABSB operates on signed bytes, PABSW operates on signed 16-bit words, and PABSD operates on signed 32-bit integers.\nEVEX encoded VPABSD/Q: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nEVEX encoded VPABSB/W: The source operand is a ZMM/YMM/XMM register, or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded versions: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding register destination are zeroed.\nVEX.128 encoded versions: The source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The source operand can be an XMM register or an 128-bit memory location. The destination is an XMM register. The upper bits (VL_MAX-1:128) of the corresponding register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "Unsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 31st bytes\nUnsigned DEST[255:248] := ABS(SRC[255:248])\n\n\n (KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+7:i] := ABS(SRC[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 15th 16-bit words\nUnsigned DEST[255:240] := ABS(SRC[255:240])\n\n\n (KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+15:i] := ABS(SRC[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 7th 32-bit double words\nUnsigned DEST[255:224] := ABS(SRC[255:224])\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+31:i] := ABS(SRC[31:0])\n ELSE\n Unsigned DEST[i+31:i] := ABS(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+63:i] := ABS(SRC[63:0])\n ELSE\n Unsigned DEST[i+63:i] := ABS(SRC[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pabsb:pabsw:pabsd:pabsq" + }, + "pabsw": { + "instruction": "PABSW", + "title": "PABSB/PABSW/PABSD/PABSQ\n\t\t— Packed Absolute Value", + "opcode": "NP 0F 38 1C /r1 PABSB mm1, mm2/m64", + "description": "PABSB/W/D computes the absolute value of each data element of the source operand (the second operand) and stores the UNSIGNED results in the destination operand (the first operand). PABSB operates on signed bytes, PABSW operates on signed 16-bit words, and PABSD operates on signed 32-bit integers.\nEVEX encoded VPABSD/Q: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nEVEX encoded VPABSB/W: The source operand is a ZMM/YMM/XMM register, or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded versions: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding register destination are zeroed.\nVEX.128 encoded versions: The source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The source operand can be an XMM register or an 128-bit memory location. The destination is an XMM register. The upper bits (VL_MAX-1:128) of the corresponding register destination are unmodified.\nVEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "Unsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 15th bytes\nUnsigned DEST[127:120] := ABS(SRC[127:120])\n\n\nUnsigned DEST[7:0] := ABS(SRC[7: 0])\nRepeat operation for 2nd through 31st bytes\nUnsigned DEST[255:248] := ABS(SRC[255:248])\n\n\n (KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+7:i] := ABS(SRC[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 7th 16-bit words\nUnsigned DEST[127:112] := ABS(SRC[127:112])\n\n\nUnsigned DEST[15:0] := ABS(SRC[15:0])\nRepeat operation for 2nd through 15th 16-bit words\nUnsigned DEST[255:240] := ABS(SRC[255:240])\n\n\n (KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n Unsigned DEST[i+15:i] := ABS(SRC[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 3rd 32-bit double words\nUnsigned DEST[127:96] := ABS(SRC[127:96])\n\n\nUnsigned DEST[31:0] := ABS(SRC[31:0])\nRepeat operation for 2nd through 7th 32-bit double words\nUnsigned DEST[255:224] := ABS(SRC[255:224])\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+31:i] := ABS(SRC[31:0])\n ELSE\n Unsigned DEST[i+31:i] := ABS(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN\n Unsigned DEST[i+63:i] := ABS(SRC[63:0])\n ELSE\n Unsigned DEST[i+63:i] := ABS(SRC[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pabsb:pabsw:pabsd:pabsq" + }, + "packssdw": { + "instruction": "PACKSSDW", + "title": "PACKSSWB/PACKSSDW\n\t\t— Pack With Signed Saturation", + "opcode": "NP 0F 63 /r1 PACKSSWB mm1, mm2/m64", + "description": "Converts packed signed word integers into packed signed byte integers (PACKSSWB) or converts packed signed doubleword integers into packed signed word integers (PACKSSDW), using saturation to handle overflow conditions. See Figure 4-6 for an example of the packing operation.\nPACKSSWB converts packed signed word integers in the first and second source operands into packed signed byte integers using signed saturation to handle overflow conditions beyond the range of signed byte integers. If the signed word value is beyond the range of a signed byte value (i.e., greater than 7FH or less than 80H), the saturated signed byte integer value of 7FH or 80H, respectively, is stored in the destination. PACKSSDW converts packed signed doubleword integers in the first and second source operands into packed signed word integers using signed saturation to handle overflow conditions beyond 7FFFH and 8000H.\nEVEX encoded PACKSSWB: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register, updated conditional under the writemask k1.\nEVEX encoded PACKSSDW: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-\nbit memory location. The destination operand is a ZMM/YMM/XMM register, updated conditional under the write-mask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM destination register destination are unmodified.", + "operation": "DEST[7:0] := SaturateSignedWordToSignedByte (DEST[15:0]);\nDEST[15:8] := SaturateSignedWordToSignedByte (DEST[31:16]);\nDEST[23:16] := SaturateSignedWordToSignedByte (DEST[47:32]);\nDEST[31:24] := SaturateSignedWordToSignedByte (DEST[63:48]);\nDEST[39:32] := SaturateSignedWordToSignedByte (DEST[79:64]);\nDEST[47:40] := SaturateSignedWordToSignedByte (DEST[95:80]);\nDEST[55:48] := SaturateSignedWordToSignedByte (DEST[111:96]);\nDEST[63:56] := SaturateSignedWordToSignedByte (DEST[127:112]);\nDEST[71:64] := SaturateSignedWordToSignedByte (SRC[15:0]);\nDEST[79:72] := SaturateSignedWordToSignedByte (SRC[31:16]);\nDEST[87:80] := SaturateSignedWordToSignedByte (SRC[47:32]);\nDEST[95:88] := SaturateSignedWordToSignedByte (SRC[63:48]);\nDEST[103:96] := SaturateSignedWordToSignedByte (SRC[79:64]);\nDEST[111:104] := SaturateSignedWordToSignedByte (SRC[95:80]);\nDEST[119:112] := SaturateSignedWordToSignedByte (SRC[111:96]);\nDEST[127:120] := SaturateSignedWordToSignedByte (SRC[127:112]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SaturateSignedDwordToSignedWord (DEST[31:0]);\nDEST[31:16] := SaturateSignedDwordToSignedWord (DEST[63:32]);\nDEST[47:32] := SaturateSignedDwordToSignedWord (DEST[95:64]);\nDEST[63:48] := SaturateSignedDwordToSignedWord (DEST[127:96]);\nDEST[79:64] := SaturateSignedDwordToSignedWord (SRC[31:0]);\nDEST[95:80] := SaturateSignedDwordToSignedWord (SRC[63:32]);\nDEST[111:96] := SaturateSignedDwordToSignedWord (SRC[95:64]);\nDEST[127:112] := SaturateSignedDwordToSignedWord (SRC[127:96]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[7:0] := SaturateSignedWordToSignedByte (SRC1[15:0]);\nDEST[15:8] := SaturateSignedWordToSignedByte (SRC1[31:16]);\nDEST[23:16] := SaturateSignedWordToSignedByte (SRC1[47:32]);\nDEST[31:24] := SaturateSignedWordToSignedByte (SRC1[63:48]);\nDEST[39:32] := SaturateSignedWordToSignedByte (SRC1[79:64]);\nDEST[47:40] := SaturateSignedWordToSignedByte (SRC1[95:80]);\nDEST[55:48] := SaturateSignedWordToSignedByte (SRC1[111:96]);\nDEST[63:56] := SaturateSignedWordToSignedByte (SRC1[127:112]);\nDEST[71:64] := SaturateSignedWordToSignedByte (SRC2[15:0]);\nDEST[79:72] := SaturateSignedWordToSignedByte (SRC2[31:16]);\nDEST[87:80] := SaturateSignedWordToSignedByte (SRC2[47:32]);\nDEST[95:88] := SaturateSignedWordToSignedByte (SRC2[63:48]);\nDEST[103:96] := SaturateSignedWordToSignedByte (SRC2[79:64]);\nDEST[111:104] := SaturateSignedWordToSignedByte (SRC2[95:80]);\nDEST[119:112] := SaturateSignedWordToSignedByte (SRC2[111:96]);\nDEST[127:120] := SaturateSignedWordToSignedByte (SRC2[127:112]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SaturateSignedDwordToSignedWord (SRC1[31:0]);\nDEST[31:16] := SaturateSignedDwordToSignedWord (SRC1[63:32]);\nDEST[47:32] := SaturateSignedDwordToSignedWord (SRC1[95:64]);\nDEST[63:48] := SaturateSignedDwordToSignedWord (SRC1[127:96]);\nDEST[79:64] := SaturateSignedDwordToSignedWord (SRC2[31:0]);\nDEST[95:80] := SaturateSignedDwordToSignedWord (SRC2[63:32]);\nDEST[111:96] := SaturateSignedDwordToSignedWord (SRC2[95:64]);\nDEST[127:112] := SaturateSignedDwordToSignedWord (SRC2[127:96]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SaturateSignedWordToSignedByte (SRC1[15:0]);\nDEST[15:8] := SaturateSignedWordToSignedByte (SRC1[31:16]);\nDEST[23:16] := SaturateSignedWordToSignedByte (SRC1[47:32]);\nDEST[31:24] := SaturateSignedWordToSignedByte (SRC1[63:48]);\nDEST[39:32] := SaturateSignedWordToSignedByte (SRC1[79:64]);\nDEST[47:40] := SaturateSignedWordToSignedByte (SRC1[95:80]);\nDEST[55:48] := SaturateSignedWordToSignedByte (SRC1[111:96]);\nDEST[63:56] := SaturateSignedWordToSignedByte (SRC1[127:112]);\nDEST[71:64] := SaturateSignedWordToSignedByte (SRC2[15:0]);\nDEST[79:72] := SaturateSignedWordToSignedByte (SRC2[31:16]);\nDEST[87:80] := SaturateSignedWordToSignedByte (SRC2[47:32]);\nDEST[95:88] := SaturateSignedWordToSignedByte (SRC2[63:48]);\nDEST[103:96] := SaturateSignedWordToSignedByte (SRC2[79:64]);\nDEST[111:104] := SaturateSignedWordToSignedByte (SRC2[95:80]);\nDEST[119:112] := SaturateSignedWordToSignedByte (SRC2[111:96]);\nDEST[127:120] := SaturateSignedWordToSignedByte (SRC2[127:112]);\nDEST[135:128] := SaturateSignedWordToSignedByte (SRC1[143:128]);\nDEST[143:136] := SaturateSignedWordToSignedByte (SRC1[159:144]);\nDEST[151:144] := SaturateSignedWordToSignedByte (SRC1[175:160]);\nDEST[159:152] := SaturateSignedWordToSignedByte (SRC1[191:176]);\nDEST[167:160] := SaturateSignedWordToSignedByte (SRC1[207:192]);\nDEST[175:168] := SaturateSignedWordToSignedByte (SRC1[223:208]);\nDEST[183:176] := SaturateSignedWordToSignedByte (SRC1[239:224]);\nDEST[191:184] := SaturateSignedWordToSignedByte (SRC1[255:240]);\nDEST[199:192] := SaturateSignedWordToSignedByte (SRC2[143:128]);\nDEST[207:200] := SaturateSignedWordToSignedByte (SRC2[159:144]);\nDEST[215:208] := SaturateSignedWordToSignedByte (SRC2[175:160]);\nDEST[223:216] := SaturateSignedWordToSignedByte (SRC2[191:176]);\nDEST[231:224] := SaturateSignedWordToSignedByte (SRC2[207:192]);\nDEST[239:232] := SaturateSignedWordToSignedByte (SRC2[223:208]);\nDEST[247:240] := SaturateSignedWordToSignedByte (SRC2[239:224]);\nDEST[255:248] := SaturateSignedWordToSignedByte (SRC2[255:240]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[15:0] := SaturateSignedDwordToSignedWord (SRC1[31:0]);\nDEST[31:16] := SaturateSignedDwordToSignedWord (SRC1[63:32]);\nDEST[47:32] := SaturateSignedDwordToSignedWord (SRC1[95:64]);\nDEST[63:48] := SaturateSignedDwordToSignedWord (SRC1[127:96]);\nDEST[79:64] := SaturateSignedDwordToSignedWord (SRC2[31:0]);\nDEST[95:80] := SaturateSignedDwordToSignedWord (SRC2[63:32]);\nDEST[111:96] := SaturateSignedDwordToSignedWord (SRC2[95:64]);\nDEST[127:112] := SaturateSignedDwordToSignedWord (SRC2[127:96]);\nDEST[143:128] := SaturateSignedDwordToSignedWord (SRC1[159:128]);\nDEST[159:144] := SaturateSignedDwordToSignedWord (SRC1[191:160]);\nDEST[175:160] := SaturateSignedDwordToSignedWord (SRC1[223:192]);\nDEST[191:176] := SaturateSignedDwordToSignedWord (SRC1[255:224]);\nDEST[207:192] := SaturateSignedDwordToSignedWord (SRC2[159:128]);\nDEST[223:208] := SaturateSignedDwordToSignedWord (SRC2[191:160]);\nDEST[239:224] := SaturateSignedDwordToSignedWord (SRC2[223:192]);\nDEST[255:240] := SaturateSignedDwordToSignedWord (SRC2[255:224]);\nDEST[MAXVL-1:256] := 0;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nTMP_DEST[7:0] := SaturateSignedWordToSignedByte (SRC1[15:0]);\nTMP_DEST[15:8] := SaturateSignedWordToSignedByte (SRC1[31:16]);\nTMP_DEST[23:16] := SaturateSignedWordToSignedByte (SRC1[47:32]);\nTMP_DEST[31:24] := SaturateSignedWordToSignedByte (SRC1[63:48]);\nTMP_DEST[39:32] := SaturateSignedWordToSignedByte (SRC1[79:64]);\nTMP_DEST[47:40] := SaturateSignedWordToSignedByte (SRC1[95:80]);\nTMP_DEST[55:48] := SaturateSignedWordToSignedByte (SRC1[111:96]);\nTMP_DEST[63:56] := SaturateSignedWordToSignedByte (SRC1[127:112]);\nTMP_DEST[71:64] := SaturateSignedWordToSignedByte (SRC2[15:0]);\nTMP_DEST[79:72] := SaturateSignedWordToSignedByte (SRC2[31:16]);\nTMP_DEST[87:80] := SaturateSignedWordToSignedByte (SRC2[47:32]);\nTMP_DEST[95:88] := SaturateSignedWordToSignedByte (SRC2[63:48]);\nTMP_DEST[103:96] := SaturateSignedWordToSignedByte (SRC2[79:64]);\nTMP_DEST[111:104] := SaturateSignedWordToSignedByte (SRC2[95:80]);\nTMP_DEST[119:112] := SaturateSignedWordToSignedByte (SRC2[111:96]);\nTMP_DEST[127:120] := SaturateSignedWordToSignedByte (SRC2[127:112]);\nIF VL >= 256\n TMP_DEST[135:128] := SaturateSignedWordToSignedByte (SRC1[143:128]);\n TMP_DEST[143:136] := SaturateSignedWordToSignedByte (SRC1[159:144]);\n TMP_DEST[151:144] := SaturateSignedWordToSignedByte (SRC1[175:160]);\n TMP_DEST[159:152] := SaturateSignedWordToSignedByte (SRC1[191:176]);\n TMP_DEST[167:160] := SaturateSignedWordToSignedByte (SRC1[207:192]);\n TMP_DEST[175:168] := SaturateSignedWordToSignedByte (SRC1[223:208]);\n TMP_DEST[183:176] := SaturateSignedWordToSignedByte (SRC1[239:224]);\n TMP_DEST[191:184] := SaturateSignedWordToSignedByte (SRC1[255:240]);\n TMP_DEST[199:192] := SaturateSignedWordToSignedByte (SRC2[143:128]);\n TMP_DEST[207:200] := SaturateSignedWordToSignedByte (SRC2[159:144]);\n TMP_DEST[215:208] := SaturateSignedWordToSignedByte (SRC2[175:160]);\n TMP_DEST[223:216] := SaturateSignedWordToSignedByte (SRC2[191:176]);\n TMP_DEST[231:224] := SaturateSignedWordToSignedByte (SRC2[207:192]);\n TMP_DEST[239:232] := SaturateSignedWordToSignedByte (SRC2[223:208]);\n TMP_DEST[247:240] := SaturateSignedWordToSignedByte (SRC2[239:224]);\n TMP_DEST[255:248] := SaturateSignedWordToSignedByte (SRC2[255:240]);\nFI;\nIF VL >= 512\n TMP_DEST[263:256] := SaturateSignedWordToSignedByte (SRC1[271:256]);\n TMP_DEST[271:264] := SaturateSignedWordToSignedByte (SRC1[287:272]);\n TMP_DEST[279:272] := SaturateSignedWordToSignedByte (SRC1[303:288]);\n TMP_DEST[287:280] := SaturateSignedWordToSignedByte (SRC1[319:304]);\n TMP_DEST[295:288] := SaturateSignedWordToSignedByte (SRC1[335:320]);\n TMP_DEST[303:296] := SaturateSignedWordToSignedByte (SRC1[351:336]);\n TMP_DEST[311:304] := SaturateSignedWordToSignedByte (SRC1[367:352]);\n TMP_DEST[319:312] := SaturateSignedWordToSignedByte (SRC1[383:368]);\n TMP_DEST[327:320] := SaturateSignedWordToSignedByte (SRC2[271:256]);\n TMP_DEST[335:328] := SaturateSignedWordToSignedByte (SRC2[287:272]);\n TMP_DEST[343:336] := SaturateSignedWordToSignedByte (SRC2[303:288]);\n TMP_DEST[351:344] := SaturateSignedWordToSignedByte (SRC2[319:304]);\n TMP_DEST[359:352] := SaturateSignedWordToSignedByte (SRC2[335:320]);\n TMP_DEST[367:360] := SaturateSignedWordToSignedByte (SRC2[351:336]);\n TMP_DEST[375:368] := SaturateSignedWordToSignedByte (SRC2[367:352]);\n TMP_DEST[383:376] := SaturateSignedWordToSignedByte (SRC2[383:368]);\n TMP_DEST[391:384] := SaturateSignedWordToSignedByte (SRC1[399:384]);\n TMP_DEST[399:392] := SaturateSignedWordToSignedByte (SRC1[415:400]);\n TMP_DEST[407:400] := SaturateSignedWordToSignedByte (SRC1[431:416]);\n TMP_DEST[415:408] := SaturateSignedWordToSignedByte (SRC1[447:432]);\n TMP_DEST[423:416] := SaturateSignedWordToSignedByte (SRC1[463:448]);\n TMP_DEST[431:424] := SaturateSignedWordToSignedByte (SRC1[479:464]);\n TMP_DEST[439:432] := SaturateSignedWordToSignedByte (SRC1[495:480]);\n TMP_DEST[447:440] := SaturateSignedWordToSignedByte (SRC1[511:496]);\n TMP_DEST[455:448] := SaturateSignedWordToSignedByte (SRC2[399:384]);\n TMP_DEST[463:456] := SaturateSignedWordToSignedByte (SRC2[415:400]);\n TMP_DEST[471:464] := SaturateSignedWordToSignedByte (SRC2[431:416]);\n TMP_DEST[479:472] := SaturateSignedWordToSignedByte (SRC2[447:432]);\n TMP_DEST[487:480] := SaturateSignedWordToSignedByte (SRC2[463:448]);\n TMP_DEST[495:488] := SaturateSignedWordToSignedByte (SRC2[479:464]);\n TMP_DEST[503:496] := SaturateSignedWordToSignedByte (SRC2[495:480]);\n TMP_DEST[511:504] := SaturateSignedWordToSignedByte (SRC2[511:496]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO ((KL/2) - 1)\n i := j * 32\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE\n TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nTMP_DEST[15:0] := SaturateSignedDwordToSignedWord (SRC1[31:0]);\nTMP_DEST[31:16] := SaturateSignedDwordToSignedWord (SRC1[63:32]);\nTMP_DEST[47:32] := SaturateSignedDwordToSignedWord (SRC1[95:64]);\nTMP_DEST[63:48] := SaturateSignedDwordToSignedWord (SRC1[127:96]);\nTMP_DEST[79:64] := SaturateSignedDwordToSignedWord (TMP_SRC2[31:0]);\nTMP_DEST[95:80] := SaturateSignedDwordToSignedWord (TMP_SRC2[63:32]);\nTMP_DEST[111:96] := SaturateSignedDwordToSignedWord (TMP_SRC2[95:64]);\nTMP_DEST[127:112] := SaturateSignedDwordToSignedWord (TMP_SRC2[127:96]);\nIF VL >= 256\n TMP_DEST[143:128] := SaturateSignedDwordToSignedWord (SRC1[159:128]);\n TMP_DEST[159:144] := SaturateSignedDwordToSignedWord (SRC1[191:160]);\n TMP_DEST[175:160] := SaturateSignedDwordToSignedWord (SRC1[223:192]);\n TMP_DEST[191:176] := SaturateSignedDwordToSignedWord (SRC1[255:224]);\n TMP_DEST[207:192] := SaturateSignedDwordToSignedWord (TMP_SRC2[159:128]);\n TMP_DEST[223:208] := SaturateSignedDwordToSignedWord (TMP_SRC2[191:160]);\n TMP_DEST[239:224] := SaturateSignedDwordToSignedWord (TMP_SRC2[223:192]);\n TMP_DEST[255:240] := SaturateSignedDwordToSignedWord (TMP_SRC2[255:224]);\nFI;\nIF VL >= 512\n TMP_DEST[271:256] := SaturateSignedDwordToSignedWord (SRC1[287:256]);\n TMP_DEST[287:272] := SaturateSignedDwordToSignedWord (SRC1[319:288]);\n TMP_DEST[303:288] := SaturateSignedDwordToSignedWord (SRC1[351:320]);\n TMP_DEST[319:304] := SaturateSignedDwordToSignedWord (SRC1[383:352]);\n TMP_DEST[335:320] := SaturateSignedDwordToSignedWord (TMP_SRC2[287:256]);\n TMP_DEST[351:336] := SaturateSignedDwordToSignedWord (TMP_SRC2[319:288]);\n TMP_DEST[367:352] := SaturateSignedDwordToSignedWord (TMP_SRC2[351:320]);\n TMP_DEST[383:368] := SaturateSignedDwordToSignedWord (TMP_SRC2[383:352]);\n TMP_DEST[399:384] := SaturateSignedDwordToSignedWord (SRC1[415:384]);\n TMP_DEST[415:400] := SaturateSignedDwordToSignedWord (SRC1[447:416]);\n TMP_DEST[431:416] := SaturateSignedDwordToSignedWord (SRC1[479:448]);\n TMP_DEST[447:432] := SaturateSignedDwordToSignedWord (SRC1[511:480]);\n TMP_DEST[463:448] := SaturateSignedDwordToSignedWord (TMP_SRC2[415:384]);\n TMP_DEST[479:464] := SaturateSignedDwordToSignedWord (TMP_SRC2[447:416]);\n TMP_DEST[495:480] := SaturateSignedDwordToSignedWord (TMP_SRC2[479:448]);\n TMP_DEST[511:496] := SaturateSignedDwordToSignedWord (TMP_SRC2[511:480]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/packsswb:packssdw" + }, + "packsswb": { + "instruction": "PACKSSWB", + "title": "PACKSSWB/PACKSSDW\n\t\t— Pack With Signed Saturation", + "opcode": "NP 0F 63 /r1 PACKSSWB mm1, mm2/m64", + "description": "Converts packed signed word integers into packed signed byte integers (PACKSSWB) or converts packed signed doubleword integers into packed signed word integers (PACKSSDW), using saturation to handle overflow conditions. See Figure 4-6 for an example of the packing operation.\nPACKSSWB converts packed signed word integers in the first and second source operands into packed signed byte integers using signed saturation to handle overflow conditions beyond the range of signed byte integers. If the signed word value is beyond the range of a signed byte value (i.e., greater than 7FH or less than 80H), the saturated signed byte integer value of 7FH or 80H, respectively, is stored in the destination. PACKSSDW converts packed signed doubleword integers in the first and second source operands into packed signed word integers using signed saturation to handle overflow conditions beyond 7FFFH and 8000H.\nEVEX encoded PACKSSWB: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register, updated conditional under the writemask k1.\nEVEX encoded PACKSSDW: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-\nbit memory location. The destination operand is a ZMM/YMM/XMM register, updated conditional under the write-mask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM destination register destination are unmodified.", + "operation": "DEST[7:0] := SaturateSignedWordToSignedByte (DEST[15:0]);\nDEST[15:8] := SaturateSignedWordToSignedByte (DEST[31:16]);\nDEST[23:16] := SaturateSignedWordToSignedByte (DEST[47:32]);\nDEST[31:24] := SaturateSignedWordToSignedByte (DEST[63:48]);\nDEST[39:32] := SaturateSignedWordToSignedByte (DEST[79:64]);\nDEST[47:40] := SaturateSignedWordToSignedByte (DEST[95:80]);\nDEST[55:48] := SaturateSignedWordToSignedByte (DEST[111:96]);\nDEST[63:56] := SaturateSignedWordToSignedByte (DEST[127:112]);\nDEST[71:64] := SaturateSignedWordToSignedByte (SRC[15:0]);\nDEST[79:72] := SaturateSignedWordToSignedByte (SRC[31:16]);\nDEST[87:80] := SaturateSignedWordToSignedByte (SRC[47:32]);\nDEST[95:88] := SaturateSignedWordToSignedByte (SRC[63:48]);\nDEST[103:96] := SaturateSignedWordToSignedByte (SRC[79:64]);\nDEST[111:104] := SaturateSignedWordToSignedByte (SRC[95:80]);\nDEST[119:112] := SaturateSignedWordToSignedByte (SRC[111:96]);\nDEST[127:120] := SaturateSignedWordToSignedByte (SRC[127:112]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SaturateSignedDwordToSignedWord (DEST[31:0]);\nDEST[31:16] := SaturateSignedDwordToSignedWord (DEST[63:32]);\nDEST[47:32] := SaturateSignedDwordToSignedWord (DEST[95:64]);\nDEST[63:48] := SaturateSignedDwordToSignedWord (DEST[127:96]);\nDEST[79:64] := SaturateSignedDwordToSignedWord (SRC[31:0]);\nDEST[95:80] := SaturateSignedDwordToSignedWord (SRC[63:32]);\nDEST[111:96] := SaturateSignedDwordToSignedWord (SRC[95:64]);\nDEST[127:112] := SaturateSignedDwordToSignedWord (SRC[127:96]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[7:0] := SaturateSignedWordToSignedByte (SRC1[15:0]);\nDEST[15:8] := SaturateSignedWordToSignedByte (SRC1[31:16]);\nDEST[23:16] := SaturateSignedWordToSignedByte (SRC1[47:32]);\nDEST[31:24] := SaturateSignedWordToSignedByte (SRC1[63:48]);\nDEST[39:32] := SaturateSignedWordToSignedByte (SRC1[79:64]);\nDEST[47:40] := SaturateSignedWordToSignedByte (SRC1[95:80]);\nDEST[55:48] := SaturateSignedWordToSignedByte (SRC1[111:96]);\nDEST[63:56] := SaturateSignedWordToSignedByte (SRC1[127:112]);\nDEST[71:64] := SaturateSignedWordToSignedByte (SRC2[15:0]);\nDEST[79:72] := SaturateSignedWordToSignedByte (SRC2[31:16]);\nDEST[87:80] := SaturateSignedWordToSignedByte (SRC2[47:32]);\nDEST[95:88] := SaturateSignedWordToSignedByte (SRC2[63:48]);\nDEST[103:96] := SaturateSignedWordToSignedByte (SRC2[79:64]);\nDEST[111:104] := SaturateSignedWordToSignedByte (SRC2[95:80]);\nDEST[119:112] := SaturateSignedWordToSignedByte (SRC2[111:96]);\nDEST[127:120] := SaturateSignedWordToSignedByte (SRC2[127:112]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SaturateSignedDwordToSignedWord (SRC1[31:0]);\nDEST[31:16] := SaturateSignedDwordToSignedWord (SRC1[63:32]);\nDEST[47:32] := SaturateSignedDwordToSignedWord (SRC1[95:64]);\nDEST[63:48] := SaturateSignedDwordToSignedWord (SRC1[127:96]);\nDEST[79:64] := SaturateSignedDwordToSignedWord (SRC2[31:0]);\nDEST[95:80] := SaturateSignedDwordToSignedWord (SRC2[63:32]);\nDEST[111:96] := SaturateSignedDwordToSignedWord (SRC2[95:64]);\nDEST[127:112] := SaturateSignedDwordToSignedWord (SRC2[127:96]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SaturateSignedWordToSignedByte (SRC1[15:0]);\nDEST[15:8] := SaturateSignedWordToSignedByte (SRC1[31:16]);\nDEST[23:16] := SaturateSignedWordToSignedByte (SRC1[47:32]);\nDEST[31:24] := SaturateSignedWordToSignedByte (SRC1[63:48]);\nDEST[39:32] := SaturateSignedWordToSignedByte (SRC1[79:64]);\nDEST[47:40] := SaturateSignedWordToSignedByte (SRC1[95:80]);\nDEST[55:48] := SaturateSignedWordToSignedByte (SRC1[111:96]);\nDEST[63:56] := SaturateSignedWordToSignedByte (SRC1[127:112]);\nDEST[71:64] := SaturateSignedWordToSignedByte (SRC2[15:0]);\nDEST[79:72] := SaturateSignedWordToSignedByte (SRC2[31:16]);\nDEST[87:80] := SaturateSignedWordToSignedByte (SRC2[47:32]);\nDEST[95:88] := SaturateSignedWordToSignedByte (SRC2[63:48]);\nDEST[103:96] := SaturateSignedWordToSignedByte (SRC2[79:64]);\nDEST[111:104] := SaturateSignedWordToSignedByte (SRC2[95:80]);\nDEST[119:112] := SaturateSignedWordToSignedByte (SRC2[111:96]);\nDEST[127:120] := SaturateSignedWordToSignedByte (SRC2[127:112]);\nDEST[135:128] := SaturateSignedWordToSignedByte (SRC1[143:128]);\nDEST[143:136] := SaturateSignedWordToSignedByte (SRC1[159:144]);\nDEST[151:144] := SaturateSignedWordToSignedByte (SRC1[175:160]);\nDEST[159:152] := SaturateSignedWordToSignedByte (SRC1[191:176]);\nDEST[167:160] := SaturateSignedWordToSignedByte (SRC1[207:192]);\nDEST[175:168] := SaturateSignedWordToSignedByte (SRC1[223:208]);\nDEST[183:176] := SaturateSignedWordToSignedByte (SRC1[239:224]);\nDEST[191:184] := SaturateSignedWordToSignedByte (SRC1[255:240]);\nDEST[199:192] := SaturateSignedWordToSignedByte (SRC2[143:128]);\nDEST[207:200] := SaturateSignedWordToSignedByte (SRC2[159:144]);\nDEST[215:208] := SaturateSignedWordToSignedByte (SRC2[175:160]);\nDEST[223:216] := SaturateSignedWordToSignedByte (SRC2[191:176]);\nDEST[231:224] := SaturateSignedWordToSignedByte (SRC2[207:192]);\nDEST[239:232] := SaturateSignedWordToSignedByte (SRC2[223:208]);\nDEST[247:240] := SaturateSignedWordToSignedByte (SRC2[239:224]);\nDEST[255:248] := SaturateSignedWordToSignedByte (SRC2[255:240]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[15:0] := SaturateSignedDwordToSignedWord (SRC1[31:0]);\nDEST[31:16] := SaturateSignedDwordToSignedWord (SRC1[63:32]);\nDEST[47:32] := SaturateSignedDwordToSignedWord (SRC1[95:64]);\nDEST[63:48] := SaturateSignedDwordToSignedWord (SRC1[127:96]);\nDEST[79:64] := SaturateSignedDwordToSignedWord (SRC2[31:0]);\nDEST[95:80] := SaturateSignedDwordToSignedWord (SRC2[63:32]);\nDEST[111:96] := SaturateSignedDwordToSignedWord (SRC2[95:64]);\nDEST[127:112] := SaturateSignedDwordToSignedWord (SRC2[127:96]);\nDEST[143:128] := SaturateSignedDwordToSignedWord (SRC1[159:128]);\nDEST[159:144] := SaturateSignedDwordToSignedWord (SRC1[191:160]);\nDEST[175:160] := SaturateSignedDwordToSignedWord (SRC1[223:192]);\nDEST[191:176] := SaturateSignedDwordToSignedWord (SRC1[255:224]);\nDEST[207:192] := SaturateSignedDwordToSignedWord (SRC2[159:128]);\nDEST[223:208] := SaturateSignedDwordToSignedWord (SRC2[191:160]);\nDEST[239:224] := SaturateSignedDwordToSignedWord (SRC2[223:192]);\nDEST[255:240] := SaturateSignedDwordToSignedWord (SRC2[255:224]);\nDEST[MAXVL-1:256] := 0;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nTMP_DEST[7:0] := SaturateSignedWordToSignedByte (SRC1[15:0]);\nTMP_DEST[15:8] := SaturateSignedWordToSignedByte (SRC1[31:16]);\nTMP_DEST[23:16] := SaturateSignedWordToSignedByte (SRC1[47:32]);\nTMP_DEST[31:24] := SaturateSignedWordToSignedByte (SRC1[63:48]);\nTMP_DEST[39:32] := SaturateSignedWordToSignedByte (SRC1[79:64]);\nTMP_DEST[47:40] := SaturateSignedWordToSignedByte (SRC1[95:80]);\nTMP_DEST[55:48] := SaturateSignedWordToSignedByte (SRC1[111:96]);\nTMP_DEST[63:56] := SaturateSignedWordToSignedByte (SRC1[127:112]);\nTMP_DEST[71:64] := SaturateSignedWordToSignedByte (SRC2[15:0]);\nTMP_DEST[79:72] := SaturateSignedWordToSignedByte (SRC2[31:16]);\nTMP_DEST[87:80] := SaturateSignedWordToSignedByte (SRC2[47:32]);\nTMP_DEST[95:88] := SaturateSignedWordToSignedByte (SRC2[63:48]);\nTMP_DEST[103:96] := SaturateSignedWordToSignedByte (SRC2[79:64]);\nTMP_DEST[111:104] := SaturateSignedWordToSignedByte (SRC2[95:80]);\nTMP_DEST[119:112] := SaturateSignedWordToSignedByte (SRC2[111:96]);\nTMP_DEST[127:120] := SaturateSignedWordToSignedByte (SRC2[127:112]);\nIF VL >= 256\n TMP_DEST[135:128] := SaturateSignedWordToSignedByte (SRC1[143:128]);\n TMP_DEST[143:136] := SaturateSignedWordToSignedByte (SRC1[159:144]);\n TMP_DEST[151:144] := SaturateSignedWordToSignedByte (SRC1[175:160]);\n TMP_DEST[159:152] := SaturateSignedWordToSignedByte (SRC1[191:176]);\n TMP_DEST[167:160] := SaturateSignedWordToSignedByte (SRC1[207:192]);\n TMP_DEST[175:168] := SaturateSignedWordToSignedByte (SRC1[223:208]);\n TMP_DEST[183:176] := SaturateSignedWordToSignedByte (SRC1[239:224]);\n TMP_DEST[191:184] := SaturateSignedWordToSignedByte (SRC1[255:240]);\n TMP_DEST[199:192] := SaturateSignedWordToSignedByte (SRC2[143:128]);\n TMP_DEST[207:200] := SaturateSignedWordToSignedByte (SRC2[159:144]);\n TMP_DEST[215:208] := SaturateSignedWordToSignedByte (SRC2[175:160]);\n TMP_DEST[223:216] := SaturateSignedWordToSignedByte (SRC2[191:176]);\n TMP_DEST[231:224] := SaturateSignedWordToSignedByte (SRC2[207:192]);\n TMP_DEST[239:232] := SaturateSignedWordToSignedByte (SRC2[223:208]);\n TMP_DEST[247:240] := SaturateSignedWordToSignedByte (SRC2[239:224]);\n TMP_DEST[255:248] := SaturateSignedWordToSignedByte (SRC2[255:240]);\nFI;\nIF VL >= 512\n TMP_DEST[263:256] := SaturateSignedWordToSignedByte (SRC1[271:256]);\n TMP_DEST[271:264] := SaturateSignedWordToSignedByte (SRC1[287:272]);\n TMP_DEST[279:272] := SaturateSignedWordToSignedByte (SRC1[303:288]);\n TMP_DEST[287:280] := SaturateSignedWordToSignedByte (SRC1[319:304]);\n TMP_DEST[295:288] := SaturateSignedWordToSignedByte (SRC1[335:320]);\n TMP_DEST[303:296] := SaturateSignedWordToSignedByte (SRC1[351:336]);\n TMP_DEST[311:304] := SaturateSignedWordToSignedByte (SRC1[367:352]);\n TMP_DEST[319:312] := SaturateSignedWordToSignedByte (SRC1[383:368]);\n TMP_DEST[327:320] := SaturateSignedWordToSignedByte (SRC2[271:256]);\n TMP_DEST[335:328] := SaturateSignedWordToSignedByte (SRC2[287:272]);\n TMP_DEST[343:336] := SaturateSignedWordToSignedByte (SRC2[303:288]);\n TMP_DEST[351:344] := SaturateSignedWordToSignedByte (SRC2[319:304]);\n TMP_DEST[359:352] := SaturateSignedWordToSignedByte (SRC2[335:320]);\n TMP_DEST[367:360] := SaturateSignedWordToSignedByte (SRC2[351:336]);\n TMP_DEST[375:368] := SaturateSignedWordToSignedByte (SRC2[367:352]);\n TMP_DEST[383:376] := SaturateSignedWordToSignedByte (SRC2[383:368]);\n TMP_DEST[391:384] := SaturateSignedWordToSignedByte (SRC1[399:384]);\n TMP_DEST[399:392] := SaturateSignedWordToSignedByte (SRC1[415:400]);\n TMP_DEST[407:400] := SaturateSignedWordToSignedByte (SRC1[431:416]);\n TMP_DEST[415:408] := SaturateSignedWordToSignedByte (SRC1[447:432]);\n TMP_DEST[423:416] := SaturateSignedWordToSignedByte (SRC1[463:448]);\n TMP_DEST[431:424] := SaturateSignedWordToSignedByte (SRC1[479:464]);\n TMP_DEST[439:432] := SaturateSignedWordToSignedByte (SRC1[495:480]);\n TMP_DEST[447:440] := SaturateSignedWordToSignedByte (SRC1[511:496]);\n TMP_DEST[455:448] := SaturateSignedWordToSignedByte (SRC2[399:384]);\n TMP_DEST[463:456] := SaturateSignedWordToSignedByte (SRC2[415:400]);\n TMP_DEST[471:464] := SaturateSignedWordToSignedByte (SRC2[431:416]);\n TMP_DEST[479:472] := SaturateSignedWordToSignedByte (SRC2[447:432]);\n TMP_DEST[487:480] := SaturateSignedWordToSignedByte (SRC2[463:448]);\n TMP_DEST[495:488] := SaturateSignedWordToSignedByte (SRC2[479:464]);\n TMP_DEST[503:496] := SaturateSignedWordToSignedByte (SRC2[495:480]);\n TMP_DEST[511:504] := SaturateSignedWordToSignedByte (SRC2[511:496]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO ((KL/2) - 1)\n i := j * 32\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE\n TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nTMP_DEST[15:0] := SaturateSignedDwordToSignedWord (SRC1[31:0]);\nTMP_DEST[31:16] := SaturateSignedDwordToSignedWord (SRC1[63:32]);\nTMP_DEST[47:32] := SaturateSignedDwordToSignedWord (SRC1[95:64]);\nTMP_DEST[63:48] := SaturateSignedDwordToSignedWord (SRC1[127:96]);\nTMP_DEST[79:64] := SaturateSignedDwordToSignedWord (TMP_SRC2[31:0]);\nTMP_DEST[95:80] := SaturateSignedDwordToSignedWord (TMP_SRC2[63:32]);\nTMP_DEST[111:96] := SaturateSignedDwordToSignedWord (TMP_SRC2[95:64]);\nTMP_DEST[127:112] := SaturateSignedDwordToSignedWord (TMP_SRC2[127:96]);\nIF VL >= 256\n TMP_DEST[143:128] := SaturateSignedDwordToSignedWord (SRC1[159:128]);\n TMP_DEST[159:144] := SaturateSignedDwordToSignedWord (SRC1[191:160]);\n TMP_DEST[175:160] := SaturateSignedDwordToSignedWord (SRC1[223:192]);\n TMP_DEST[191:176] := SaturateSignedDwordToSignedWord (SRC1[255:224]);\n TMP_DEST[207:192] := SaturateSignedDwordToSignedWord (TMP_SRC2[159:128]);\n TMP_DEST[223:208] := SaturateSignedDwordToSignedWord (TMP_SRC2[191:160]);\n TMP_DEST[239:224] := SaturateSignedDwordToSignedWord (TMP_SRC2[223:192]);\n TMP_DEST[255:240] := SaturateSignedDwordToSignedWord (TMP_SRC2[255:224]);\nFI;\nIF VL >= 512\n TMP_DEST[271:256] := SaturateSignedDwordToSignedWord (SRC1[287:256]);\n TMP_DEST[287:272] := SaturateSignedDwordToSignedWord (SRC1[319:288]);\n TMP_DEST[303:288] := SaturateSignedDwordToSignedWord (SRC1[351:320]);\n TMP_DEST[319:304] := SaturateSignedDwordToSignedWord (SRC1[383:352]);\n TMP_DEST[335:320] := SaturateSignedDwordToSignedWord (TMP_SRC2[287:256]);\n TMP_DEST[351:336] := SaturateSignedDwordToSignedWord (TMP_SRC2[319:288]);\n TMP_DEST[367:352] := SaturateSignedDwordToSignedWord (TMP_SRC2[351:320]);\n TMP_DEST[383:368] := SaturateSignedDwordToSignedWord (TMP_SRC2[383:352]);\n TMP_DEST[399:384] := SaturateSignedDwordToSignedWord (SRC1[415:384]);\n TMP_DEST[415:400] := SaturateSignedDwordToSignedWord (SRC1[447:416]);\n TMP_DEST[431:416] := SaturateSignedDwordToSignedWord (SRC1[479:448]);\n TMP_DEST[447:432] := SaturateSignedDwordToSignedWord (SRC1[511:480]);\n TMP_DEST[463:448] := SaturateSignedDwordToSignedWord (TMP_SRC2[415:384]);\n TMP_DEST[479:464] := SaturateSignedDwordToSignedWord (TMP_SRC2[447:416]);\n TMP_DEST[495:480] := SaturateSignedDwordToSignedWord (TMP_SRC2[479:448]);\n TMP_DEST[511:496] := SaturateSignedDwordToSignedWord (TMP_SRC2[511:480]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/packsswb:packssdw" + }, + "packusdw": { + "instruction": "PACKUSDW", + "title": "PACKUSDW\n\t\t— Pack With Unsigned Saturation", + "opcode": "66 0F 38 2B /r PACKUSDW xmm1, xmm2/m128", + "description": "Converts packed signed doubleword integers in the first and second source operands into packed unsigned word integers using unsigned saturation to handle overflow conditions. If the signed doubleword value is beyond the range of an unsigned word (that is, greater than FFFFH or less than 0000H), the saturated unsigned word integer value of FFFFH or 0000H, respectively, is stored in the destination.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM register, updated conditionally under the writemask k1.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding destination register destination are unmodified.", + "operation": "TMP[15:0] := (DEST[31:0] < 0) ? 0 : DEST[15:0];\nDEST[15:0] := (DEST[31:0] > FFFFH) ? FFFFH : TMP[15:0] ;\nTMP[31:16] := (DEST[63:32] < 0) ? 0 : DEST[47:32];\nDEST[31:16] := (DEST[63:32] > FFFFH) ? FFFFH : TMP[31:16] ;\nTMP[47:32] := (DEST[95:64] < 0) ? 0 : DEST[79:64];\nDEST[47:32] := (DEST[95:64] > FFFFH) ? FFFFH : TMP[47:32] ;\nTMP[63:48] := (DEST[127:96] < 0) ? 0 : DEST[111:96];\nDEST[63:48] := (DEST[127:96] > FFFFH) ? FFFFH : TMP[63:48] ;\nTMP[79:64] := (SRC[31:0] < 0) ? 0 : SRC[15:0];\nDEST[79:64] := (SRC[31:0] > FFFFH) ? FFFFH : TMP[79:64] ;\nTMP[95:80] := (SRC[63:32] < 0) ? 0 : SRC[47:32];\nDEST[95:80] := (SRC[63:32] > FFFFH) ? FFFFH : TMP[95:80] ;\nTMP[111:96] := (SRC[95:64] < 0) ? 0 : SRC[79:64];\nDEST[111:96] := (SRC[95:64] > FFFFH) ? FFFFH : TMP[111:96] ;\nTMP[127:112] := (SRC[127:96] < 0) ? 0 : SRC[111:96];\nDEST[127:112] := (SRC[127:96] > FFFFH) ? FFFFH : TMP[127:112] ;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nTMP[15:0] := (SRC1[31:0] < 0) ? 0 : SRC1[15:0];\nDEST[15:0] := (SRC1[31:0] > FFFFH) ? FFFFH : TMP[15:0] ;\nTMP[31:16] := (SRC1[63:32] < 0) ? 0 : SRC1[47:32];\nDEST[31:16] := (SRC1[63:32] > FFFFH) ? FFFFH : TMP[31:16] ;\nTMP[47:32] := (SRC1[95:64] < 0) ? 0 : SRC1[79:64];\nDEST[47:32] := (SRC1[95:64] > FFFFH) ? FFFFH : TMP[47:32] ;\nTMP[63:48] := (SRC1[127:96] < 0) ? 0 : SRC1[111:96];\nDEST[63:48] := (SRC1[127:96] > FFFFH) ? FFFFH : TMP[63:48] ;\nTMP[79:64] := (SRC2[31:0] < 0) ? 0 : SRC2[15:0];\nDEST[79:64] := (SRC2[31:0] > FFFFH) ? FFFFH : TMP[79:64] ;\nTMP[95:80] := (SRC2[63:32] < 0) ? 0 : SRC2[47:32];\nDEST[95:80] := (SRC2[63:32] > FFFFH) ? FFFFH : TMP[95:80] ;\nTMP[111:96] := (SRC2[95:64] < 0) ? 0 : SRC2[79:64];\nDEST[111:96] := (SRC2[95:64] > FFFFH) ? FFFFH : TMP[111:96] ;\nTMP[127:112] := (SRC2[127:96] < 0) ? 0 : SRC2[111:96];\nDEST[127:112] := (SRC2[127:96] > FFFFH) ? FFFFH : TMP[127:112];\nDEST[MAXVL-1:128] := 0;\n\n\nTMP[15:0] := (SRC1[31:0] < 0) ? 0 : SRC1[15:0];\nDEST[15:0] := (SRC1[31:0] > FFFFH) ? FFFFH : TMP[15:0] ;\nTMP[31:16] := (SRC1[63:32] < 0) ? 0 : SRC1[47:32];\nDEST[31:16] := (SRC1[63:32] > FFFFH) ? FFFFH : TMP[31:16] ;\nTMP[47:32] := (SRC1[95:64] < 0) ? 0 : SRC1[79:64];\nDEST[47:32] := (SRC1[95:64] > FFFFH) ? FFFFH : TMP[47:32] ;\nTMP[63:48] := (SRC1[127:96] < 0) ? 0 : SRC1[111:96];\nDEST[63:48] := (SRC1[127:96] > FFFFH) ? FFFFH : TMP[63:48] ;\nTMP[79:64] := (SRC2[31:0] < 0) ? 0 : SRC2[15:0];\nDEST[79:64] := (SRC2[31:0] > FFFFH) ? FFFFH : TMP[79:64] ;\nTMP[95:80] := (SRC2[63:32] < 0) ? 0 : SRC2[47:32];\nDEST[95:80] := (SRC2[63:32] > FFFFH) ? FFFFH : TMP[95:80] ;\nTMP[111:96] := (SRC2[95:64] < 0) ? 0 : SRC2[79:64];\nDEST[111:96] := (SRC2[95:64] > FFFFH) ? FFFFH : TMP[111:96] ;\nTMP[127:112] := (SRC2[127:96] < 0) ? 0 : SRC2[111:96];\nDEST[127:112] := (SRC2[127:96] > FFFFH) ? FFFFH : TMP[127:112] ;\nTMP[143:128] := (SRC1[159:128] < 0) ? 0 : SRC1[143:128];\nDEST[143:128] := (SRC1[159:128] > FFFFH) ? FFFFH : TMP[143:128] ;\nTMP[159:144] := (SRC1[191:160] < 0) ? 0 : SRC1[175:160];\nDEST[159:144] := (SRC1[191:160] > FFFFH) ? FFFFH : TMP[159:144] ;\nTMP[175:160] := (SRC1[223:192] < 0) ? 0 : SRC1[207:192];\nDEST[175:160] := (SRC1[223:192] > FFFFH) ? FFFFH : TMP[175:160] ;\nTMP[191:176] := (SRC1[255:224] < 0) ? 0 : SRC1[239:224];\nDEST[191:176] := (SRC1[255:224] > FFFFH) ? FFFFH : TMP[191:176] ;\nTMP[207:192] := (SRC2[159:128] < 0) ? 0 : SRC2[143:128];\nDEST[207:192] := (SRC2[159:128] > FFFFH) ? FFFFH : TMP[207:192] ;\nTMP[223:208] := (SRC2[191:160] < 0) ? 0 : SRC2[175:160];\nDEST[223:208] := (SRC2[191:160] > FFFFH) ? FFFFH : TMP[223:208] ;\nTMP[239:224] := (SRC2[223:192] < 0) ? 0 : SRC2[207:192];\nDEST[239:224] := (SRC2[223:192] > FFFFH) ? FFFFH : TMP[239:224] ;\nTMP[255:240] := (SRC2[255:224] < 0) ? 0 : SRC2[239:224];\nDEST[255:240] := (SRC2[255:224] > FFFFH) ? FFFFH : TMP[255:240] ;\nDEST[MAXVL-1:256] := 0;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO ((KL/2) - 1)\n i := j * 32\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN\n TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE\n TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nTMP[15:0] := (SRC1[31:0] < 0) ? 0 : SRC1[15:0];\nDEST[15:0] := (SRC1[31:0] > FFFFH) ? FFFFH : TMP[15:0] ;\nTMP[31:16] := (SRC1[63:32] < 0) ? 0 : SRC1[47:32];\nDEST[31:16] := (SRC1[63:32] > FFFFH) ? FFFFH : TMP[31:16] ;\nTMP[47:32] := (SRC1[95:64] < 0) ? 0 : SRC1[79:64];\nDEST[47:32] := (SRC1[95:64] > FFFFH) ? FFFFH : TMP[47:32] ;\nTMP[63:48] := (SRC1[127:96] < 0) ? 0 : SRC1[111:96];\nDEST[63:48] := (SRC1[127:96] > FFFFH) ? FFFFH : TMP[63:48] ;\nTMP[79:64] := (TMP_SRC2[31:0] < 0) ? 0 : TMP_SRC2[15:0];\nDEST[79:64] := (TMP_SRC2[31:0] > FFFFH) ? FFFFH : TMP[79:64] ;\nTMP[95:80] := (TMP_SRC2[63:32] < 0) ? 0 : TMP_SRC2[47:32];\nDEST[95:80] := (TMP_SRC2[63:32] > FFFFH) ? FFFFH : TMP[95:80] ;\nTMP[111:96] := (TMP_SRC2[95:64] < 0) ? 0 : TMP_SRC2[79:64];\nDEST[111:96] := (TMP_SRC2[95:64] > FFFFH) ? FFFFH : TMP[111:96] ;\nTMP[127:112] := (TMP_SRC2[127:96] < 0) ? 0 : TMP_SRC2[111:96];\nDEST[127:112] := (TMP_SRC2[127:96] > FFFFH) ? FFFFH : TMP[127:112] ;\nIF VL >= 256\n TMP[143:128] := (SRC1[159:128] < 0) ? 0 : SRC1[143:128];\n DEST[143:128] := (SRC1[159:128] > FFFFH) ? FFFFH : TMP[143:128] ;\n TMP[159:144] := (SRC1[191:160] < 0) ? 0 : SRC1[175:160];\n DEST[159:144] := (SRC1[191:160] > FFFFH) ? FFFFH : TMP[159:144] ;\n TMP[175:160] := (SRC1[223:192] < 0) ? 0 : SRC1[207:192];\n DEST[175:160] := (SRC1[223:192] > FFFFH) ? FFFFH : TMP[175:160] ;\n TMP[191:176] := (SRC1[255:224] < 0) ? 0 : SRC1[239:224];\n DEST[191:176] := (SRC1[255:224] > FFFFH) ? FFFFH : TMP[191:176] ;\n TMP[207:192] := (TMP_SRC2[159:128] < 0) ? 0 : TMP_SRC2[143:128];\n DEST[207:192] := (TMP_SRC2[159:128] > FFFFH) ? FFFFH : TMP[207:192] ;\n TMP[223:208] := (TMP_SRC2[191:160] < 0) ? 0 : TMP_SRC2[175:160];\n DEST[223:208] := (TMP_SRC2[191:160] > FFFFH) ? FFFFH : TMP[223:208] ;\n TMP[239:224] := (TMP_SRC2[223:192] < 0) ? 0 : TMP_SRC2[207:192];\n DEST[239:224] := (TMP_SRC2[223:192] > FFFFH) ? FFFFH : TMP[239:224] ;\n TMP[255:240] := (TMP_SRC2[255:224] < 0) ? 0 : TMP_SRC2[239:224];\n DEST[255:240] := (TMP_SRC2[255:224] > FFFFH) ? FFFFH : TMP[255:240] ;\nFI;\nIF VL >= 512\n TMP[271:256] := (SRC1[287:256] < 0) ? 0 : SRC1[271:256];\n DEST[271:256] := (SRC1[287:256] > FFFFH) ? FFFFH : TMP[271:256] ;\n TMP[287:272] := (SRC1[319:288] < 0) ? 0 : SRC1[303:288];\n DEST[287:272] := (SRC1[319:288] > FFFFH) ? FFFFH : TMP[287:272] ;\n TMP[303:288] := (SRC1[351:320] < 0) ? 0 : SRC1[335:320];\n DEST[303:288] := (SRC1[351:320] > FFFFH) ? FFFFH : TMP[303:288] ;\n TMP[319:304] := (SRC1[383:352] < 0) ? 0 : SRC1[367:352];\n DEST[319:304] := (SRC1[383:352] > FFFFH) ? FFFFH : TMP[319:304] ;\n TMP[335:320] := (TMP_SRC2[287:256] < 0) ? 0 : TMP_SRC2[271:256];\n DEST[335:304] := (TMP_SRC2[287:256] > FFFFH) ? FFFFH : TMP[79:64] ;\n TMP[351:336] := (TMP_SRC2[319:288] < 0) ? 0 : TMP_SRC2[303:288];\n DEST[351:336] := (TMP_SRC2[319:288] > FFFFH) ? FFFFH : TMP[351:336] ;\n TMP[367:352] := (TMP_SRC2[351:320] < 0) ? 0 : TMP_SRC2[315:320];\n DEST[367:352] := (TMP_SRC2[351:320] > FFFFH) ? FFFFH : TMP[367:352] ;\n TMP[383:368] := (TMP_SRC2[383:352] < 0) ? 0 : TMP_SRC2[367:352];\n DEST[383:368] := (TMP_SRC2[383:352] > FFFFH) ? FFFFH : TMP[383:368] ;\n TMP[399:384] := (SRC1[415:384] < 0) ? 0 : SRC1[399:384];\n DEST[399:384] := (SRC1[415:384] > FFFFH) ? FFFFH : TMP[399:384] ;\n TMP[415:400] := (SRC1[447:416] < 0) ? 0 : SRC1[431:416];\n DEST[415:400] := (SRC1[447:416] > FFFFH) ? FFFFH : TMP[415:400] ;\n TMP[431:416] := (SRC1[479:448] < 0) ? 0 : SRC1[463:448];\n DEST[431:416] := (SRC1[479:448] > FFFFH) ? FFFFH : TMP[431:416] ;\n TMP[447:432] := (SRC1[511:480] < 0) ? 0 : SRC1[495:480];\n DEST[447:432] := (SRC1[511:480] > FFFFH) ? FFFFH : TMP[447:432] ;\n TMP[463:448] := (TMP_SRC2[415:384] < 0) ? 0 : TMP_SRC2[399:384];\n DEST[463:448] := (TMP_SRC2[415:384] > FFFFH) ? FFFFH : TMP[463:448] ;\n TMP[475:464] := (TMP_SRC2[447:416] < 0) ? 0 : TMP_SRC2[431:416];\n DEST[475:464] := (TMP_SRC2[447:416] > FFFFH) ? FFFFH : TMP[475:464] ;\n TMP[491:476] := (TMP_SRC2[479:448] < 0) ? 0 : TMP_SRC2[463:448];\n DEST[491:476] := (TMP_SRC2[479:448] > FFFFH) ? FFFFH : TMP[491:476] ;\n TMP[511:492] := (TMP_SRC2[511:480] < 0) ? 0 : TMP_SRC2[495:480];\n DEST[511:492] := (TMP_SRC2[511:480] > FFFFH) ? FFFFH : TMP[511:492] ;\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/packusdw" + }, + "packuswb": { + "instruction": "PACKUSWB", + "title": "PACKUSWB\n\t\t— Pack With Unsigned Saturation", + "opcode": "NP 0F 67 /r1 PACKUSWB mm, mm/m64", + "description": "Converts 4, 8, 16, or 32 signed word integers from the destination operand (first operand) and 4, 8, 16, or 32 signed word integers from the source operand (second operand) into 8, 16, 32 or 64 unsigned byte integers and stores the result in the destination operand. (See Figure 4-6 for an example of the packing operation.) If a signed word integer value is beyond the range of an unsigned byte integer (that is, greater than FFH or less than 00H), the saturated unsigned byte integer value of FFH or 00H, respectively, is stored in the destination.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register or a 512-bit memory location. The destination operand is a ZMM register.\nVEX.256 and EVEX.256 encoded versions: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 and EVEX.128 encoded versions: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "DEST[7:0] := SaturateSignedWordToUnsignedByte DEST[15:0];\nDEST[15:8] := SaturateSignedWordToUnsignedByte DEST[31:16];\nDEST[23:16] := SaturateSignedWordToUnsignedByte DEST[47:32];\nDEST[31:24] := SaturateSignedWordToUnsignedByte DEST[63:48];\nDEST[39:32] := SaturateSignedWordToUnsignedByte SRC[15:0];\nDEST[47:40] := SaturateSignedWordToUnsignedByte SRC[31:16];\nDEST[55:48] := SaturateSignedWordToUnsignedByte SRC[47:32];\nDEST[63:56] := SaturateSignedWordToUnsignedByte SRC[63:48];\n\n\nDEST[7:0] := SaturateSignedWordToUnsignedByte (DEST[15:0]);\nDEST[15:8] := SaturateSignedWordToUnsignedByte (DEST[31:16]);\nDEST[23:16] := SaturateSignedWordToUnsignedByte (DEST[47:32]);\nDEST[31:24] := SaturateSignedWordToUnsignedByte (DEST[63:48]);\nDEST[39:32] := SaturateSignedWordToUnsignedByte (DEST[79:64]);\nDEST[47:40] := SaturateSignedWordToUnsignedByte (DEST[95:80]);\nDEST[55:48] := SaturateSignedWordToUnsignedByte (DEST[111:96]);\nDEST[63:56] := SaturateSignedWordToUnsignedByte (DEST[127:112]);\nDEST[71:64] := SaturateSignedWordToUnsignedByte (SRC[15:0]);\nDEST[79:72] := SaturateSignedWordToUnsignedByte (SRC[31:16]);\nDEST[87:80] := SaturateSignedWordToUnsignedByte (SRC[47:32]);\nDEST[95:88] := SaturateSignedWordToUnsignedByte (SRC[63:48]);\nDEST[103:96] := SaturateSignedWordToUnsignedByte (SRC[79:64]);\nDEST[111:104] := SaturateSignedWordToUnsignedByte (SRC[95:80]);\nDEST[119:112] := SaturateSignedWordToUnsignedByte (SRC[111:96]);\nDEST[127:120] := SaturateSignedWordToUnsignedByte (SRC[127:112]);\n\n\nDEST[7:0] := SaturateSignedWordToUnsignedByte (SRC1[15:0]);\nDEST[15:8] := SaturateSignedWordToUnsignedByte (SRC1[31:16]);\nDEST[23:16] := SaturateSignedWordToUnsignedByte (SRC1[47:32]);\nDEST[31:24] := SaturateSignedWordToUnsignedByte (SRC1[63:48]);\nDEST[39:32] := SaturateSignedWordToUnsignedByte (SRC1[79:64]);\nDEST[47:40] := SaturateSignedWordToUnsignedByte (SRC1[95:80]);\nDEST[55:48] := SaturateSignedWordToUnsignedByte (SRC1[111:96]);\nDEST[63:56] := SaturateSignedWordToUnsignedByte (SRC1[127:112]);\nDEST[71:64] := SaturateSignedWordToUnsignedByte (SRC2[15:0]);\nDEST[79:72] := SaturateSignedWordToUnsignedByte (SRC2[31:16]);\nDEST[87:80] := SaturateSignedWordToUnsignedByte (SRC2[47:32]);\nDEST[95:88] := SaturateSignedWordToUnsignedByte (SRC2[63:48]);\nDEST[103:96] := SaturateSignedWordToUnsignedByte (SRC2[79:64]);\nDEST[111:104] := SaturateSignedWordToUnsignedByte (SRC2[95:80]);\nDEST[119:112] := SaturateSignedWordToUnsignedByte (SRC2[111:96]);\nDEST[127:120] := SaturateSignedWordToUnsignedByte (SRC2[127:112]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SaturateSignedWordToUnsignedByte (SRC1[15:0]);\nDEST[15:8] := SaturateSignedWordToUnsignedByte (SRC1[31:16]);\nDEST[23:16] := SaturateSignedWordToUnsignedByte (SRC1[47:32]);\nDEST[31:24] := SaturateSignedWordToUnsignedByte (SRC1[63:48]);\nDEST[39:32] := SaturateSignedWordToUnsignedByte (SRC1[79:64]);\nDEST[47:40] := SaturateSignedWordToUnsignedByte (SRC1[95:80]);\nDEST[55:48] := SaturateSignedWordToUnsignedByte (SRC1[111:96]);\nDEST[63:56] := SaturateSignedWordToUnsignedByte (SRC1[127:112]);\nDEST[71:64] := SaturateSignedWordToUnsignedByte (SRC2[15:0]);\nDEST[79:72] := SaturateSignedWordToUnsignedByte (SRC2[31:16]);\nDEST[87:80] := SaturateSignedWordToUnsignedByte (SRC2[47:32]);\nDEST[95:88] := SaturateSignedWordToUnsignedByte (SRC2[63:48]);\nDEST[103:96] := SaturateSignedWordToUnsignedByte (SRC2[79:64]);\nDEST[111:104] := SaturateSignedWordToUnsignedByte (SRC2[95:80]);\nDEST[119:112] := SaturateSignedWordToUnsignedByte (SRC2[111:96]);\nDEST[127:120] := SaturateSignedWordToUnsignedByte (SRC2[127:112]);\nDEST[135:128] := SaturateSignedWordToUnsignedByte (SRC1[143:128]);\nDEST[143:136] := SaturateSignedWordToUnsignedByte (SRC1[159:144]);\nDEST[151:144] := SaturateSignedWordToUnsignedByte (SRC1[175:160]);\nDEST[159:152] := SaturateSignedWordToUnsignedByte (SRC1[191:176]);\nDEST[167:160] := SaturateSignedWordToUnsignedByte (SRC1[207:192]);\nDEST[175:168] := SaturateSignedWordToUnsignedByte (SRC1[223:208]);\nDEST[183:176] := SaturateSignedWordToUnsignedByte (SRC1[239:224]);\nDEST[191:184] := SaturateSignedWordToUnsignedByte (SRC1[255:240]);\nDEST[199:192] := SaturateSignedWordToUnsignedByte (SRC2[143:128]);\nDEST[207:200] := SaturateSignedWordToUnsignedByte (SRC2[159:144]);\nDEST[215:208] := SaturateSignedWordToUnsignedByte (SRC2[175:160]);\nDEST[223:216] := SaturateSignedWordToUnsignedByte (SRC2[191:176]);\nDEST[231:224] := SaturateSignedWordToUnsignedByte (SRC2[207:192]);\nDEST[239:232] := SaturateSignedWordToUnsignedByte (SRC2[223:208]);\nDEST[247:240] := SaturateSignedWordToUnsignedByte (SRC2[239:224]);\nDEST[255:248] := SaturateSignedWordToUnsignedByte (SRC2[255:240]);\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nTMP_DEST[7:0] := SaturateSignedWordToUnsignedByte (SRC1[15:0]);\nTMP_DEST[15:8] := SaturateSignedWordToUnsignedByte (SRC1[31:16]);\nTMP_DEST[23:16] := SaturateSignedWordToUnsignedByte (SRC1[47:32]);\nTMP_DEST[31:24] := SaturateSignedWordToUnsignedByte (SRC1[63:48]);\nTMP_DEST[39:32] := SaturateSignedWordToUnsignedByte (SRC1[79:64]);\nTMP_DEST[47:40] := SaturateSignedWordToUnsignedByte (SRC1[95:80]);\nTMP_DEST[55:48] := SaturateSignedWordToUnsignedByte (SRC1[111:96]);\nTMP_DEST[63:56] := SaturateSignedWordToUnsignedByte (SRC1[127:112]);\nTMP_DEST[71:64] := SaturateSignedWordToUnsignedByte (SRC2[15:0]);\nTMP_DEST[79:72] := SaturateSignedWordToUnsignedByte (SRC2[31:16]);\nTMP_DEST[87:80] := SaturateSignedWordToUnsignedByte (SRC2[47:32]);\nTMP_DEST[95:88] := SaturateSignedWordToUnsignedByte (SRC2[63:48]);\nTMP_DEST[103:96] := SaturateSignedWordToUnsignedByte (SRC2[79:64]);\nTMP_DEST[111:104] := SaturateSignedWordToUnsignedByte (SRC2[95:80]);\nTMP_DEST[119:112] := SaturateSignedWordToUnsignedByte (SRC2[111:96]);\nTMP_DEST[127:120] := SaturateSignedWordToUnsignedByte (SRC2[127:112]);\nIF VL >= 256\n TMP_DEST[135:128] := SaturateSignedWordToUnsignedByte (SRC1[143:128]);\n TMP_DEST[143:136] := SaturateSignedWordToUnsignedByte (SRC1[159:144]);\n TMP_DEST[151:144] := SaturateSignedWordToUnsignedByte (SRC1[175:160]);\n TMP_DEST[159:152] := SaturateSignedWordToUnsignedByte (SRC1[191:176]);\n TMP_DEST[167:160] := SaturateSignedWordToUnsignedByte (SRC1[207:192]);\n TMP_DEST[175:168] := SaturateSignedWordToUnsignedByte (SRC1[223:208]);\n TMP_DEST[183:176] := SaturateSignedWordToUnsignedByte (SRC1[239:224]);\n TMP_DEST[191:184] := SaturateSignedWordToUnsignedByte (SRC1[255:240]);\n TMP_DEST[199:192] := SaturateSignedWordToUnsignedByte (SRC2[143:128]);\n TMP_DEST[207:200] := SaturateSignedWordToUnsignedByte (SRC2[159:144]);\n TMP_DEST[215:208] := SaturateSignedWordToUnsignedByte (SRC2[175:160]);\n TMP_DEST[223:216] := SaturateSignedWordToUnsignedByte (SRC2[191:176]);\n TMP_DEST[231:224] := SaturateSignedWordToUnsignedByte (SRC2[207:192]);\n TMP_DEST[239:232] := SaturateSignedWordToUnsignedByte (SRC2[223:208]);\n TMP_DEST[247:240] := SaturateSignedWordToUnsignedByte (SRC2[239:224]);\n TMP_DEST[255:248] := SaturateSignedWordToUnsignedByte (SRC2[255:240]);\nFI;\nIF VL >= 512\n TMP_DEST[263:256] := SaturateSignedWordToUnsignedByte (SRC1[271:256]);\n TMP_DEST[271:264] := SaturateSignedWordToUnsignedByte (SRC1[287:272]);\n TMP_DEST[279:272] := SaturateSignedWordToUnsignedByte (SRC1[303:288]);\n TMP_DEST[287:280] := SaturateSignedWordToUnsignedByte (SRC1[319:304]);\n TMP_DEST[295:288] := SaturateSignedWordToUnsignedByte (SRC1[335:320]);\n TMP_DEST[303:296] := SaturateSignedWordToUnsignedByte (SRC1[351:336]);\n TMP_DEST[311:304] := SaturateSignedWordToUnsignedByte (SRC1[367:352]);\n TMP_DEST[319:312] := SaturateSignedWordToUnsignedByte (SRC1[383:368]);\n TMP_DEST[327:320] := SaturateSignedWordToUnsignedByte (SRC2[271:256]);\n TMP_DEST[335:328] := SaturateSignedWordToUnsignedByte (SRC2[287:272]);\n TMP_DEST[343:336] := SaturateSignedWordToUnsignedByte (SRC2[303:288]);\n TMP_DEST[351:344] := SaturateSignedWordToUnsignedByte (SRC2[319:304]);\n TMP_DEST[359:352] := SaturateSignedWordToUnsignedByte (SRC2[335:320]);\n TMP_DEST[367:360] := SaturateSignedWordToUnsignedByte (SRC2[351:336]);\n TMP_DEST[375:368] := SaturateSignedWordToUnsignedByte (SRC2[367:352]);\n TMP_DEST[383:376] := SaturateSignedWordToUnsignedByte (SRC2[383:368]);\n TMP_DEST[391:384] := SaturateSignedWordToUnsignedByte (SRC1[399:384]);\n TMP_DEST[399:392] := SaturateSignedWordToUnsignedByte (SRC1[415:400]);\n TMP_DEST[407:400] := SaturateSignedWordToUnsignedByte (SRC1[431:416]);\n TMP_DEST[415:408] := SaturateSignedWordToUnsignedByte (SRC1[447:432]);\n TMP_DEST[423:416] := SaturateSignedWordToUnsignedByte (SRC1[463:448]);\n TMP_DEST[431:424] := SaturateSignedWordToUnsignedByte (SRC1[479:464]);\n TMP_DEST[439:432] := SaturateSignedWordToUnsignedByte (SRC1[495:480]);\n TMP_DEST[447:440] := SaturateSignedWordToUnsignedByte (SRC1[511:496]);\n TMP_DEST[455:448] := SaturateSignedWordToUnsignedByte (SRC2[399:384]);\n TMP_DEST[463:456] := SaturateSignedWordToUnsignedByte (SRC2[415:400]);\n TMP_DEST[471:464] := SaturateSignedWordToUnsignedByte (SRC2[431:416]);\n TMP_DEST[479:472] := SaturateSignedWordToUnsignedByte (SRC2[447:432]);\n TMP_DEST[487:480] := SaturateSignedWordToUnsignedByte (SRC2[463:448]);\n TMP_DEST[495:488] := SaturateSignedWordToUnsignedByte (SRC2[479:464]);\n TMP_DEST[503:496] := SaturateSignedWordToUnsignedByte (SRC2[495:480]);\n TMP_DEST[511:504] := SaturateSignedWordToUnsignedByte (SRC2[511:496]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN\n DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/packuswb" + }, + "paddb": { + "instruction": "PADDB", + "title": "PADDB/PADDW/PADDD/PADDQ\n\t\t— Add Packed Integers", + "opcode": "NP 0F FC /r1 PADDB mm, mm/m64", + "description": "Performs a SIMD add of the packed integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe PADDB and VPADDB instructions add packed byte integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 8 bits (overflow), the result is wrapped around and the low 8 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDW and VPADDW instructions add packed word integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to\nbe represented in 16 bits (overflow), the result is wrapped around and the low 16 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDD and VPADDD instructions add packed doubleword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 32 bits (overflow), the result is wrapped around and the low 32 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDQ and VPADDQ instructions add packed quadword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around and the low 64 bits are written to the destination operand (that is, the carry is ignored).\nNote that the (V)PADDB, (V)PADDW, (V)PADDD and (V)PADDQ instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values operated on.\nEVEX encoded VPADDD/Q: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the write-mask.\nEVEX encoded VPADDB/W: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. the upper bits (MAXVL-1:256) of the destination are cleared.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "DEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] + SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd and 3th word *)\nDEST[63:48] := DEST[63:48] + SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\nDEST[63:32] := DEST[63:32] + SRC[63:32];\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\n\n\nDEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := DEST[127:120] + SRC[127:120];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := DEST[127:112] + SRC[127:112];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := DEST[127:96] + SRC[127:96];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\nDEST[127:64] := DEST[127:64] + SRC[127:64];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := SRC1[127:120] + SRC2[127:120];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := SRC1[127:112] + SRC2[127:112];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := SRC1[127:96] + SRC2[127:96];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 31th byte *)\nDEST[255:248] := SRC1[255:248] + SRC2[255:248];\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 15th word *)\nDEST[255:240] := SRC1[255:240] + SRC2[255:240];\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 7th doubleword *)\nDEST[255:224] := SRC1[255:224] + SRC2[255:224];\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[191:128] := SRC1[191:128] + SRC2[191:128];\nDEST[255:192] := SRC1[255:192] + SRC2[255:192];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] + SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] + SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] + SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] + SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] + SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] + SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddb:paddw:paddd:paddq" + }, + "paddd": { + "instruction": "PADDD", + "title": "PADDB/PADDW/PADDD/PADDQ\n\t\t— Add Packed Integers", + "opcode": "NP 0F FC /r1 PADDB mm, mm/m64", + "description": "Performs a SIMD add of the packed integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe PADDB and VPADDB instructions add packed byte integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 8 bits (overflow), the result is wrapped around and the low 8 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDW and VPADDW instructions add packed word integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to\nbe represented in 16 bits (overflow), the result is wrapped around and the low 16 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDD and VPADDD instructions add packed doubleword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 32 bits (overflow), the result is wrapped around and the low 32 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDQ and VPADDQ instructions add packed quadword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around and the low 64 bits are written to the destination operand (that is, the carry is ignored).\nNote that the (V)PADDB, (V)PADDW, (V)PADDD and (V)PADDQ instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values operated on.\nEVEX encoded VPADDD/Q: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the write-mask.\nEVEX encoded VPADDB/W: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. the upper bits (MAXVL-1:256) of the destination are cleared.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "DEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] + SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd and 3th word *)\nDEST[63:48] := DEST[63:48] + SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\nDEST[63:32] := DEST[63:32] + SRC[63:32];\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\n\n\nDEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := DEST[127:120] + SRC[127:120];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := DEST[127:112] + SRC[127:112];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := DEST[127:96] + SRC[127:96];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\nDEST[127:64] := DEST[127:64] + SRC[127:64];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := SRC1[127:120] + SRC2[127:120];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := SRC1[127:112] + SRC2[127:112];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := SRC1[127:96] + SRC2[127:96];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 31th byte *)\nDEST[255:248] := SRC1[255:248] + SRC2[255:248];\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 15th word *)\nDEST[255:240] := SRC1[255:240] + SRC2[255:240];\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 7th doubleword *)\nDEST[255:224] := SRC1[255:224] + SRC2[255:224];\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[191:128] := SRC1[191:128] + SRC2[191:128];\nDEST[255:192] := SRC1[255:192] + SRC2[255:192];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] + SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] + SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] + SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] + SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] + SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] + SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddb:paddw:paddd:paddq" + }, + "paddq": { + "instruction": "PADDQ", + "title": "PADDB/PADDW/PADDD/PADDQ\n\t\t— Add Packed Integers", + "opcode": "NP 0F FC /r1 PADDB mm, mm/m64", + "description": "Performs a SIMD add of the packed integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe PADDB and VPADDB instructions add packed byte integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 8 bits (overflow), the result is wrapped around and the low 8 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDW and VPADDW instructions add packed word integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to\nbe represented in 16 bits (overflow), the result is wrapped around and the low 16 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDD and VPADDD instructions add packed doubleword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 32 bits (overflow), the result is wrapped around and the low 32 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDQ and VPADDQ instructions add packed quadword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around and the low 64 bits are written to the destination operand (that is, the carry is ignored).\nNote that the (V)PADDB, (V)PADDW, (V)PADDD and (V)PADDQ instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values operated on.\nEVEX encoded VPADDD/Q: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the write-mask.\nEVEX encoded VPADDB/W: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. the upper bits (MAXVL-1:256) of the destination are cleared.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "DEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] + SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd and 3th word *)\nDEST[63:48] := DEST[63:48] + SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\nDEST[63:32] := DEST[63:32] + SRC[63:32];\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\n\n\nDEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := DEST[127:120] + SRC[127:120];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := DEST[127:112] + SRC[127:112];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := DEST[127:96] + SRC[127:96];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\nDEST[127:64] := DEST[127:64] + SRC[127:64];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := SRC1[127:120] + SRC2[127:120];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := SRC1[127:112] + SRC2[127:112];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := SRC1[127:96] + SRC2[127:96];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 31th byte *)\nDEST[255:248] := SRC1[255:248] + SRC2[255:248];\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 15th word *)\nDEST[255:240] := SRC1[255:240] + SRC2[255:240];\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 7th doubleword *)\nDEST[255:224] := SRC1[255:224] + SRC2[255:224];\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[191:128] := SRC1[191:128] + SRC2[191:128];\nDEST[255:192] := SRC1[255:192] + SRC2[255:192];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] + SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] + SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] + SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] + SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] + SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] + SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddb:paddw:paddd:paddq" + }, + "paddsb": { + "instruction": "PADDSB", + "title": "PADDSB/PADDSW\n\t\t— Add Packed Signed Integers with Signed Saturation", + "opcode": "NP 0F EC /r1 PADDSB mm, mm/m64", + "description": "Performs a SIMD add of the packed signed integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with signed saturation, as described in the following paragraphs.\n(V)PADDSB performs a SIMD add of the packed signed integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual byte result is beyond the range of a signed byte integer (that is, greater than 7FH or less than 80H), the saturated value of 7FH or 80H, respectively, is written to the destination operand.\n(V)PADDSW performs a SIMD add of the packed signed word integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual word result is beyond the range of a signed word integer (that is, greater than 7FFFH or less than 8000H), the saturated value of 7FFFH or 8000H, respectively, is written to the destination operand.\nEVEX encoded versions: The first source operand is an ZMM/YMM/XMM register. The second source operand is an ZMM/YMM/XMM register or a memory location. The destination operand is an ZMM/YMM/XMM register.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "DEST[7:0] := SaturateToSignedByte(DEST[7:0] + SRC (7:0]);\n(* Repeat add operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToSignedByte(DEST[63:56] + SRC[63:56] );\n\n\nDEST[7:0] := SaturateToSignedByte (DEST[7:0] + SRC[7:0]);\n(* Repeat add operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (DEST[111:120] + SRC[127:120]);\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (SRC1[111:120] + SRC2[127:120]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat add operation for 2nd through 31st bytes *)\nDEST[255:248] := SaturateToSignedByte (SRC1[255:248] + SRC2[255:248]);\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToSignedByte (SRC1[i+7:i] + SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\nPADDSW (with 64-bit operands)\n DEST[15:0] := SaturateToSignedWord(DEST[15:0] + SRC[15:0] );\n (* Repeat add operation for 2nd and 7th words *)\n DEST[63:48] := SaturateToSignedWord(DEST[63:48] + SRC[63:48] );\nPADDSW (with 128-bit operands)\n DEST[15:0] := SaturateToSignedWord (DEST[15:0] + SRC[15:0]);\n (* Repeat add operation for 2nd through 7th words *)\n DEST[127:112] := SaturateToSignedWord (DEST[127:112] + SRC[127:112]);\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToSignedWord (SRC1[127:112] + SRC2[127:112]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat add operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToSignedWord (SRC1[255:240] + SRC2[255:240])\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToSignedWord (SRC1[i+15:i] + SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddsb:paddsw" + }, + "paddsw": { + "instruction": "PADDSW", + "title": "PADDSB/PADDSW\n\t\t— Add Packed Signed Integers with Signed Saturation", + "opcode": "NP 0F EC /r1 PADDSB mm, mm/m64", + "description": "Performs a SIMD add of the packed signed integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with signed saturation, as described in the following paragraphs.\n(V)PADDSB performs a SIMD add of the packed signed integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual byte result is beyond the range of a signed byte integer (that is, greater than 7FH or less than 80H), the saturated value of 7FH or 80H, respectively, is written to the destination operand.\n(V)PADDSW performs a SIMD add of the packed signed word integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual word result is beyond the range of a signed word integer (that is, greater than 7FFFH or less than 8000H), the saturated value of 7FFFH or 8000H, respectively, is written to the destination operand.\nEVEX encoded versions: The first source operand is an ZMM/YMM/XMM register. The second source operand is an ZMM/YMM/XMM register or a memory location. The destination operand is an ZMM/YMM/XMM register.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "DEST[7:0] := SaturateToSignedByte(DEST[7:0] + SRC (7:0]);\n(* Repeat add operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToSignedByte(DEST[63:56] + SRC[63:56] );\n\n\nDEST[7:0] := SaturateToSignedByte (DEST[7:0] + SRC[7:0]);\n(* Repeat add operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (DEST[111:120] + SRC[127:120]);\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (SRC1[111:120] + SRC2[127:120]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat add operation for 2nd through 31st bytes *)\nDEST[255:248] := SaturateToSignedByte (SRC1[255:248] + SRC2[255:248]);\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToSignedByte (SRC1[i+7:i] + SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\nPADDSW (with 64-bit operands)\n DEST[15:0] := SaturateToSignedWord(DEST[15:0] + SRC[15:0] );\n (* Repeat add operation for 2nd and 7th words *)\n DEST[63:48] := SaturateToSignedWord(DEST[63:48] + SRC[63:48] );\nPADDSW (with 128-bit operands)\n DEST[15:0] := SaturateToSignedWord (DEST[15:0] + SRC[15:0]);\n (* Repeat add operation for 2nd through 7th words *)\n DEST[127:112] := SaturateToSignedWord (DEST[127:112] + SRC[127:112]);\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToSignedWord (SRC1[127:112] + SRC2[127:112]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat add operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToSignedWord (SRC1[255:240] + SRC2[255:240])\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToSignedWord (SRC1[i+15:i] + SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddsb:paddsw" + }, + "paddusb": { + "instruction": "PADDUSB", + "title": "PADDUSB/PADDUSW\n\t\t— Add Packed Unsigned Integers With Unsigned Saturation", + "opcode": "NP 0F DC /r1 PADDUSB mm, mm/m64", + "description": "Performs a SIMD add of the packed unsigned integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with unsigned saturation, as described in the following paragraphs.\n(V)PADDUSB performs a SIMD add of the packed unsigned integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual byte result is beyond the range of an unsigned byte integer (that is, greater than FFH), the saturated value of FFH is written to the destination operand.\n(V)PADDUSW performs a SIMD add of the packed unsigned word integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual word result is beyond the range of an unsigned word integer (that is, greater than FFFFH), the saturated value of FFFFH is written to the destination operand.\nEVEX encoded versions: The first source operand is an ZMM/YMM/XMM register. The second source operand is an ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination is an ZMM/YMM/XMM register.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding destination register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "DEST[7:0] := SaturateToUnsignedByte(DEST[7:0] + SRC (7:0] );\n(* Repeat add operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToUnsignedByte(DEST[63:56] + SRC[63:56]\n\n\nDEST[7:0] := SaturateToUnsignedByte (DEST[7:0] + SRC[7:0]);\n(* Repeat add operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnSignedByte (DEST[127:120] + SRC[127:120]);\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnsignedByte (SRC1[111:120] + SRC2[127:120]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat add operation for 2nd through 31st bytes *)\nDEST[255:248] := SaturateToUnsignedByte (SRC1[255:248] + SRC2[255:248]);\n\n\nDEST[15:0] := SaturateToUnsignedWord(DEST[15:0] + SRC[15:0] );\n(* Repeat add operation for 2nd and 3rd words *)\nDEST[63:48] := SaturateToUnsignedWord(DEST[63:48] + SRC[63:48] );\n\n\nDEST[15:0] := SaturateToUnsignedWord (DEST[15:0] + SRC[15:0]);\n(* Repeat add operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnSignedWord (DEST[127:112] + SRC[127:112]);\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnsignedWord (SRC1[127:112] + SRC2[127:112]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat add operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToUnsignedWord (SRC1[255:240] + SRC2[255:240])\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToUnsignedByte (SRC1[i+7:i] + SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToUnsignedWord (SRC1[i+15:i] + SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddusb:paddusw" + }, + "paddusw": { + "instruction": "PADDUSW", + "title": "PADDUSB/PADDUSW\n\t\t— Add Packed Unsigned Integers With Unsigned Saturation", + "opcode": "NP 0F DC /r1 PADDUSB mm, mm/m64", + "description": "Performs a SIMD add of the packed unsigned integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with unsigned saturation, as described in the following paragraphs.\n(V)PADDUSB performs a SIMD add of the packed unsigned integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual byte result is beyond the range of an unsigned byte integer (that is, greater than FFH), the saturated value of FFH is written to the destination operand.\n(V)PADDUSW performs a SIMD add of the packed unsigned word integers with saturation from the first source operand and second source operand and stores the packed integer results in the destination operand. When an individual word result is beyond the range of an unsigned word integer (that is, greater than FFFFH), the saturated value of FFFFH is written to the destination operand.\nEVEX encoded versions: The first source operand is an ZMM/YMM/XMM register. The second source operand is an ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination is an ZMM/YMM/XMM register.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding destination register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "DEST[7:0] := SaturateToUnsignedByte(DEST[7:0] + SRC (7:0] );\n(* Repeat add operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToUnsignedByte(DEST[63:56] + SRC[63:56]\n\n\nDEST[7:0] := SaturateToUnsignedByte (DEST[7:0] + SRC[7:0]);\n(* Repeat add operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnSignedByte (DEST[127:120] + SRC[127:120]);\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnsignedByte (SRC1[111:120] + SRC2[127:120]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] + SRC2[7:0]);\n(* Repeat add operation for 2nd through 31st bytes *)\nDEST[255:248] := SaturateToUnsignedByte (SRC1[255:248] + SRC2[255:248]);\n\n\nDEST[15:0] := SaturateToUnsignedWord(DEST[15:0] + SRC[15:0] );\n(* Repeat add operation for 2nd and 3rd words *)\nDEST[63:48] := SaturateToUnsignedWord(DEST[63:48] + SRC[63:48] );\n\n\nDEST[15:0] := SaturateToUnsignedWord (DEST[15:0] + SRC[15:0]);\n(* Repeat add operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnSignedWord (DEST[127:112] + SRC[127:112]);\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnsignedWord (SRC1[127:112] + SRC2[127:112]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] + SRC2[15:0]);\n(* Repeat add operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToUnsignedWord (SRC1[255:240] + SRC2[255:240])\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToUnsignedByte (SRC1[i+7:i] + SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToUnsignedWord (SRC1[i+15:i] + SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddusb:paddusw" + }, + "paddw": { + "instruction": "PADDW", + "title": "PADDB/PADDW/PADDD/PADDQ\n\t\t— Add Packed Integers", + "opcode": "NP 0F FC /r1 PADDB mm, mm/m64", + "description": "Performs a SIMD add of the packed integers from the source operand (second operand) and the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe PADDB and VPADDB instructions add packed byte integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 8 bits (overflow), the result is wrapped around and the low 8 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDW and VPADDW instructions add packed word integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to\nbe represented in 16 bits (overflow), the result is wrapped around and the low 16 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDD and VPADDD instructions add packed doubleword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When an individual result is too large to be represented in 32 bits (overflow), the result is wrapped around and the low 32 bits are written to the destination operand (that is, the carry is ignored).\nThe PADDQ and VPADDQ instructions add packed quadword integers from the first source operand and second source operand and store the packed integer results in the destination operand. When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around and the low 64 bits are written to the destination operand (that is, the carry is ignored).\nNote that the (V)PADDB, (V)PADDW, (V)PADDD and (V)PADDQ instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values operated on.\nEVEX encoded VPADDD/Q: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the write-mask.\nEVEX encoded VPADDB/W: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. the upper bits (MAXVL-1:256) of the destination are cleared.\nVEX.128 encoded version: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.", + "operation": "DEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] + SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd and 3th word *)\nDEST[63:48] := DEST[63:48] + SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\nDEST[63:32] := DEST[63:32] + SRC[63:32];\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\n\n\nDEST[7:0] := DEST[7:0] + SRC[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := DEST[127:120] + SRC[127:120];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := DEST[15:0] + SRC[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := DEST[127:112] + SRC[127:112];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := DEST[31:0] + SRC[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := DEST[127:96] + SRC[127:96];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := DEST[63:0] + SRC[63:0];\nDEST[127:64] := DEST[127:64] + SRC[127:64];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 15th byte *)\nDEST[127:120] := SRC1[127:120] + SRC2[127:120];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 7th word *)\nDEST[127:112] := SRC1[127:112] + SRC2[127:112];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 3th doubleword *)\nDEST[127:96] := SRC1[127:96] + SRC2[127:96];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SRC1[7:0] + SRC2[7:0];\n(* Repeat add operation for 2nd through 31th byte *)\nDEST[255:248] := SRC1[255:248] + SRC2[255:248];\n\n\nDEST[15:0] := SRC1[15:0] + SRC2[15:0];\n(* Repeat add operation for 2nd through 15th word *)\nDEST[255:240] := SRC1[255:240] + SRC2[255:240];\n\n\nDEST[31:0] := SRC1[31:0] + SRC2[31:0];\n(* Repeat add operation for 2nd and 7th doubleword *)\nDEST[255:224] := SRC1[255:224] + SRC2[255:224];\n\n\nDEST[63:0] := SRC1[63:0] + SRC2[63:0];\nDEST[127:64] := SRC1[127:64] + SRC2[127:64];\nDEST[191:128] := SRC1[191:128] + SRC2[191:128];\nDEST[255:192] := SRC1[255:192] + SRC2[255:192];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] + SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] + SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] + SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] + SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] + SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] + SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/paddb:paddw:paddd:paddq" + }, + "palignr": { + "instruction": "PALIGNR", + "title": "PALIGNR\n\t\t— Packed Align Right", + "opcode": "NP 0F 3A 0F /r ib1 PALIGNR mm1, mm2/m64, imm8", + "description": "(V)PALIGNR concatenates the destination operand (the first operand) and the source operand (the second operand) into an intermediate composite, shifts the composite at byte granularity to the right by a constant immediate, and extracts the right-aligned result into the destination. The first and the second operands can be an MMX, XMM or a YMM register. The immediate value is considered unsigned. Immediate shift counts larger than the 2L (i.e., 32 for 128-bit operands, or 16 for 64-bit operands) produce a zero result. Both operands can be MMX registers, XMM registers or YMM registers. When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nIn 64-bit mode and not encoded by VEX/EVEX prefix, use the REX prefix to access additional registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nEVEX.512 encoded version: The first source operand is a ZMM register and contains four 16-byte blocks. The second source operand is a ZMM register or a 512-bit memory location containing four 16-byte block. The destination operand is a ZMM register and contain four 16-byte results. The imm8[7:0] is the common shift count\nused for each of the four successive 16-byte block sources. The low 16-byte block of the two source operands produce the low 16-byte result of the destination operand, the high 16-byte block of the two source operands produce the high 16-byte result of the destination operand and so on for the blocks in the middle.\nVEX.256 and EVEX.256 encoded versions: The first source operand is a YMM register and contains two 16-byte blocks. The second source operand is a YMM register or a 256-bit memory location containing two 16-byte block. The destination operand is a YMM register and contain two 16-byte results. The imm8[7:0] is the common shift count used for the two lower 16-byte block sources and the two upper 16-byte block sources. The low 16-byte block of the two source operands produce the low 16-byte result of the destination operand, the high 16-byte block of the two source operands produce the high 16-byte result of the destination operand. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 and EVEX.128 encoded versions: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nConcatenation is done with 128-bit data in the first and second source operand for both 128-bit and 256-bit instructions. The high 128-bits of the intermediate composite 256-bit result came from the 128-bit data from the first source operand; the low 128-bits of the intermediate result came from the 128-bit data of the second source operand.\n0 127 0 127", + "operation": "temp1[127:0] = CONCATENATE(DEST,SRC)>>(imm8*8)\nDEST[63:0] = temp1[63:0]\n\n\ntemp1[255:0] := ((DEST[127:0] << 128) OR SRC[127:0])>>(imm8*8);\nDEST[127:0] := temp1[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\ntemp1[255:0] := ((SRC1[127:0] << 128) OR SRC2[127:0])>>(imm8*8);\nDEST[127:0] := temp1[127:0]\nDEST[MAXVL-1:128] := 0\n\n\ntemp1[255:0] := ((SRC1[127:0] << 128) OR SRC2[127:0])>>(imm8[7:0]*8);\nDEST[127:0] := temp1[127:0]\ntemp1[255:0] := ((SRC1[255:128] << 128) OR SRC2[255:128])>>(imm8[7:0]*8);\nDEST[MAXVL-1:128] := temp1[127:0]\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR l := 0 TO VL-1 with increments of 128\n temp1[255:0] := ((SRC1[l+127:l] << 128) OR SRC2[l+127:l])>>(imm8[7:0]*8);\n TMP_DEST[l+127:l] := temp1[127:0]\nENDFOR;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/palignr" + }, + "pand": { + "instruction": "PAND", + "title": "PAND\n\t\t— Logical AND", + "opcode": "NP 0F DB /r1 PAND mm, mm/m64", + "description": "Performs a bitwise logical AND operation on the first source operand and second source operand and stores the result in the destination operand. Each bit of the result is set to 1 if the corresponding bits of the first and second operands are 1, otherwise it is set to 0.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with write-mask k1 at 32/64-bit granularity.\nVEX.256 encoded versions: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded versions: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.", + "operation": "DEST := DEST AND SRC\n\n\nDEST := DEST AND SRC\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST := SRC1 AND SRC2\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := (SRC1[255:0] AND SRC2[255:0])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] BITWISE AND SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] BITWISE AND SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] BITWISE AND SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] BITWISE AND SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pand" + }, + "pandn": { + "instruction": "PANDN", + "title": "PANDN\n\t\t— Logical AND NOT", + "opcode": "NP 0F DF /r1 PANDN mm, mm/m64", + "description": "Performs a bitwise logical NOT operation on the first source operand, then performs bitwise AND with second source operand and stores the result in the destination operand. Each bit of the result is set to 1 if the corresponding bit in the first operand is 0 and the corresponding bit in the second operand is 1, otherwise it is set to 0.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with write-mask k1 at 32/64-bit granularity.\nVEX.256 encoded versions: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded versions: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.", + "operation": "DEST := NOT(DEST) AND SRC\n\n\nDEST := NOT(DEST) AND SRC\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST := NOT(SRC1) AND SRC2\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := ((NOT SRC1[255:0]) AND SRC2[255:0])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := ((NOT SRC1[i+31:i]) AND SRC2[31:0])\n ELSE DEST[i+31:i] := ((NOT SRC1[i+31:i]) AND SRC2[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := ((NOT SRC1[i+63:i]) AND SRC2[63:0])\n ELSE DEST[i+63:i] := ((NOT SRC1[i+63:i]) AND SRC2[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pandn" + }, + "parameters": { + "instruction": "PARAMETERS", + "title": "GETSEC[PARAMETERS]\n\t\t— Report the SMX Parameters", + "opcode": "NP 0F 37 (EAX=6)", + "description": "The GETSEC[PARAMETERS] instruction returns specific parameter information for SMX features supported by the processor. Parameter information is returned in EAX, EBX, and ECX, with the input parameter selected using EBX.\nSoftware retrieves parameter information by searching with an input index for EBX starting at 0, and then reading the returned results in EAX, EBX, and ECX. EAX[4:0] is designated to return a parameter type field indicating if a parameter is available and what type it is. If EAX[4:0] is returned with 0, this designates a null parameter and indicates no more parameters are available.\nTable 7-7 defines the parameter types supported in current and future implementations.\nSupported AC module versions (as defined by the AC module HeaderVersion field) can be determined for a particular SMX capable processor by the type 1 parameter. Using EBX to index through the available parameters reported by GETSEC[PARAMETERS] for each unique parameter set returned for type 1, software can determine the complete list of AC module version(s) supported.\nFor each parameter set, EBX returns the comparison mask and ECX returns the available HeaderVersion field values supported, after AND'ing the target HeaderVersion with the comparison mask. Software can then determine if a particular AC module version is supported by following the pseudo-code search routine given below:\nparameter_search_index= 0 do { EBX= parameter_search_index++ EAX= 6 GETSEC if (EAX[4:0] = 1) { if ((version_query & EBX) = ECX) { version_is_supported= 1 break } }\n} while (EAX[4:0] ≠ 0)\nIf only AC modules with a HeaderVersion of 0 are supported by the processor, then only one parameter set of type 1 will be returned, as follows: EAX = 00000001H,\nEBX = FFFFFFFFH and ECX = 00000000H.\nThe maximum capacity for an authenticated code execution area supported by the processor is reported with the parameter type of 2. The maximum supported size in bytes is determined by multiplying the returned size in EAX[31:5] by 32. Thus, for a maximum supported authenticated RAM size of 32KBytes, EAX returns with 00008002H.\nSupportable memory types for memory mapped outside of the authenticated code execution area are reported with the parameter type of 3. While is active, as initiated by the GETSEC functions SENTER and ENTERACCS and terminated by EXITAC, there are restrictions on what memory types are allowed for the rest of system memory. It is the responsibility of the system software to initialize the memory type range register (MTRR) MSRs and/or the page attribute table (PAT) to only map memory types consistent with the reporting of this parameter. The reporting of supportable memory types of external memory is indicated using a bit map returned in EAX[31:8]. These bit positions correspond to the memory type encodings defined for the MTRR MSR and PAT programming. See Table 7-9.\nThe parameter type of 4 is used for enumerating the availability of selective GETSEC[SENTER] function disable controls. If a 1 is reported in bits 14:8 of the returned parameter EAX, then this indicates a disable control capability exists with SENTER for a particular function. The enumerated field in bits 14:8 corresponds to use of the EDX input parameter bits 6:0 for SENTER. If an enumerated field bit is set to 1, then the corresponding EDX input parameter bit of EDX may be set to 1 to disable that designated function. If the enumerated field bit is 0 or this parameter is not reported, then no disable capability exists with the corresponding EDX input parameter for SENTER, and EDX bit(s) must be cleared to 0 to enable execution of SENTER. If no selective disable capability for SENTER exists as enumerated, then the corresponding bits in the IA32_FEATURE_CONTROL MSR bits 14:8 must also be programmed to 1 if the SENTER global enable bit 15 of the MSR is set. This is required to enable future extensibility of SENTER selective disable capability with respect to potentially separate software initialization of the MSR.\nIf the GETSEC[PARAMETERS] leaf or specific parameter is not present for a given SMX capable processor, then default parameter values should be assumed. These are defined in Table 7-10.", + "operation": "(* example of a processor supporting only a 0.0 HeaderVersion, 32K ACRAM size, memory types UC and WC *)\nIF (CR4.SMXE=0)\n THEN #UD;\nELSE IF (in VMX non-root operation)\n THEN VM Exit (reason=”GETSEC instruction”);\nELSE IF (GETSEC leaf unsupported)\n THEN #UD;\n (* example of a processor supporting a 0.0 HeaderVersion *)\nIF (EBX=0) THEN\n EAX := 00000001h;\n EBX := FFFFFFFFh;\n ECX := 00000000h;\nELSE IF (EBX=1)\n (* example of a processor supporting a 32K ACRAM size *)\n THEN EAX := 00008002h;\nESE IF (EBX= 2)\n (* example of a processor supporting external memory types of UC and WC *)\n THEN EAX := 00000303h;\nESE IF (EBX= other value(s) less than unsupported index value)\n (* EAX value varies. Consult Table 7-7 and Table *)\nELSE (* unsupported index*)\n EAX := 00000000h;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/parameters" + }, + "pause": { + "instruction": "PAUSE", + "title": "PAUSE\n\t\t— Spin Loop Hint", + "opcode": "F3 90", + "description": "Improves the performance of spin-wait loops. When executing a “spin-wait loop,” processors will suffer a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The processor uses this hint to avoid the memory order violation in most situations, which greatly improves processor performance. For this reason, it is recommended that a PAUSE instruction be placed in all spin-wait loops.\nAn additional function of the PAUSE instruction is to reduce the power consumed by a processor while executing a spin loop. A processor can execute a spin-wait loop extremely quickly, causing the processor to consume a lot of power while it waits for the resource it is spinning on to become available. Inserting a pause instruction in a spin-wait loop greatly reduces the processor’s power consumption.\nThis instruction was introduced in the Pentium 4 processors, but is backward compatible with all IA-32 processors. In earlier IA-32 processors, the PAUSE instruction operates like a NOP instruction. The Pentium 4 and Intel Xeon processors implement the PAUSE instruction as a delay. The delay is finite and can be zero for some processors. This instruction does not change the architectural state of the processor (that is, it performs essentially a delaying no-op operation).\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "Execute_Next_Instruction(DELAY);\n", + "url": "https://www.felixcloutier.com/x86/pause" + }, + "pavgb": { + "instruction": "PAVGB", + "title": "PAVGB/PAVGW\n\t\t— Average Packed Integers", + "opcode": "NP 0F E0 /r1 PAVGB mm1, mm2/m64", + "description": "Performs a SIMD average of the packed unsigned integers from the source operand (second operand) and the destination operand (first operand), and stores the results in the destination operand. For each corresponding pair of data elements in the first and second operands, the elements are added together, a 1 is added to the temporary sum, and that result is shifted right one bit position.\nThe (V)PAVGB instruction operates on packed unsigned bytes and the (V)PAVGW instruction operates on packed unsigned words.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register or a 512-bit memory location. The destination operand is a ZMM register.\nVEX.256 and EVEX.256 encoded versions: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 and EVEX.128 encoded versions: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.", + "operation": "DEST[7:0] := (SRC[7:0] + DEST[7:0] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n(* Repeat operation performed for bytes 2 through 6 *)\nDEST[63:56] := (SRC[63:56] + DEST[63:56] + 1) >> 1;\n\n\nDEST[15:0] := (SRC[15:0] + DEST[15:0] + 1) >> 1; (* Temp sum before shifting is 17 bits *)\n(* Repeat operation performed for words 2 and 3 *)\nDEST[63:48] := (SRC[63:48] + DEST[63:48] + 1) >> 1;\n\n\nDEST[7:0] := (SRC[7:0] + DEST[7:0] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n(* Repeat operation performed for bytes 2 through 14 *)\nDEST[127:120] := (SRC[127:120] + DEST[127:120] + 1) >> 1;\n\n\nDEST[15:0] := (SRC[15:0] + DEST[15:0] + 1) >> 1; (* Temp sum before shifting is 17 bits *)\n(* Repeat operation performed for words 2 through 6 *)\nDEST[127:112] := (SRC[127:112] + DEST[127:112] + 1) >> 1;\n\n\nDEST[7:0] := (SRC1[7:0] + SRC2[7:0] + 1) >> 1;\n(* Repeat operation performed for bytes 2 through 15 *)\nDEST[127:120] := (SRC1[127:120] + SRC2[127:120] + 1) >> 1\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := (SRC1[15:0] + SRC2[15:0] + 1) >> 1;\n(* Repeat operation performed for 16-bit words 2 through 7 *)\nDEST[127:112] := (SRC1[127:112] + SRC2[127:112] + 1) >> 1\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := (SRC1[7:0] + SRC2[7:0] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n(* Repeat operation performed for bytes 2 through 31)\nDEST[255:248] := (SRC1[255:248] + SRC2[255:248] + 1) >> 1;\n\n\n DEST[15:0] := (SRC1[15:0] + SRC2[15:0] + 1) >> 1; (* Temp sum before shifting is 17 bits *)\n (* Repeat operation performed for words 2 through 15)\n DEST[255:14]) := (SRC1[255:240] + SRC2[255:240] + 1) >> 1;\nVPAVGB (EVEX encoded versions)\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := (SRC1[i+7:i] + SRC2[i+7:i] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := (SRC1[i+15:i] + SRC2[i+15:i] + 1) >> 1\n ; (* Temp sum before shifting is 17 bits *)\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pavgb:pavgw" + }, + "pavgw": { + "instruction": "PAVGW", + "title": "PAVGB/PAVGW\n\t\t— Average Packed Integers", + "opcode": "NP 0F E0 /r1 PAVGB mm1, mm2/m64", + "description": "Performs a SIMD average of the packed unsigned integers from the source operand (second operand) and the destination operand (first operand), and stores the results in the destination operand. For each corresponding pair of data elements in the first and second operands, the elements are added together, a 1 is added to the temporary sum, and that result is shifted right one bit position.\nThe (V)PAVGB instruction operates on packed unsigned bytes and the (V)PAVGW instruction operates on packed unsigned words.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source operand is an XMM register. The second operand can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding register destination are unmodified.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register or a 512-bit memory location. The destination operand is a ZMM register.\nVEX.256 and EVEX.256 encoded versions: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nVEX.128 and EVEX.128 encoded versions: The first source operand is an XMM register. The second source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding register destination are zeroed.", + "operation": "DEST[7:0] := (SRC[7:0] + DEST[7:0] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n(* Repeat operation performed for bytes 2 through 6 *)\nDEST[63:56] := (SRC[63:56] + DEST[63:56] + 1) >> 1;\n\n\nDEST[15:0] := (SRC[15:0] + DEST[15:0] + 1) >> 1; (* Temp sum before shifting is 17 bits *)\n(* Repeat operation performed for words 2 and 3 *)\nDEST[63:48] := (SRC[63:48] + DEST[63:48] + 1) >> 1;\n\n\nDEST[7:0] := (SRC[7:0] + DEST[7:0] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n(* Repeat operation performed for bytes 2 through 14 *)\nDEST[127:120] := (SRC[127:120] + DEST[127:120] + 1) >> 1;\n\n\nDEST[15:0] := (SRC[15:0] + DEST[15:0] + 1) >> 1; (* Temp sum before shifting is 17 bits *)\n(* Repeat operation performed for words 2 through 6 *)\nDEST[127:112] := (SRC[127:112] + DEST[127:112] + 1) >> 1;\n\n\nDEST[7:0] := (SRC1[7:0] + SRC2[7:0] + 1) >> 1;\n(* Repeat operation performed for bytes 2 through 15 *)\nDEST[127:120] := (SRC1[127:120] + SRC2[127:120] + 1) >> 1\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := (SRC1[15:0] + SRC2[15:0] + 1) >> 1;\n(* Repeat operation performed for 16-bit words 2 through 7 *)\nDEST[127:112] := (SRC1[127:112] + SRC2[127:112] + 1) >> 1\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := (SRC1[7:0] + SRC2[7:0] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n(* Repeat operation performed for bytes 2 through 31)\nDEST[255:248] := (SRC1[255:248] + SRC2[255:248] + 1) >> 1;\n\n\n DEST[15:0] := (SRC1[15:0] + SRC2[15:0] + 1) >> 1; (* Temp sum before shifting is 17 bits *)\n (* Repeat operation performed for words 2 through 15)\n DEST[255:14]) := (SRC1[255:240] + SRC2[255:240] + 1) >> 1;\nVPAVGB (EVEX encoded versions)\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := (SRC1[i+7:i] + SRC2[i+7:i] + 1) >> 1; (* Temp sum before shifting is 9 bits *)\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := (SRC1[i+15:i] + SRC2[i+15:i] + 1) >> 1\n ; (* Temp sum before shifting is 17 bits *)\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pavgb:pavgw" + }, + "pblendvb": { + "instruction": "PBLENDVB", + "title": "PBLENDVB\n\t\t— Variable Blend Packed Bytes", + "opcode": "66 0F 38 10 /r PBLENDVB xmm1, xmm2/m128, ", + "description": "Conditionally copies byte elements from the source operand (second operand) to the destination operand (first operand) depending on mask bits defined in the implicit third register argument, XMM0. The mask bits are the most significant bit in each byte element of the XMM0 register.\nIf a mask bit is “1\", then the corresponding byte element in the source operand is copied to the destination, else the byte element in the destination operand is left unchanged.\nThe register assignment of the implicit third operand is defined to be the architectural register XMM0.\n128-bit Legacy SSE version: The first source operand and the destination operand is the same. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The mask register operand is implicitly defined to be the architectural register XMM0. An attempt to execute PBLENDVB with a VEX prefix will cause #UD.\nVEX.128 encoded version: The first source operand and the destination operand are XMM registers. The second source operand is an XMM register or 128-bit memory location. The mask operand is the third source register, and encoded in bits[7:4] of the immediate byte(imm8). The bits[3:0] of imm8 are ignored. In 32-bit mode, imm8[7] is ignored. The upper bits (MAXVL-1:128) of the corresponding YMM register (destination register) are zeroed. VEX.L must be 0, otherwise the instruction will #UD. VEX.W must be 0, otherwise, the instruction will #UD.\nVEX.256 encoded version: The first source operand and the destination operand are YMM registers. The second source operand is an YMM register or 256-bit memory location. The third source register is an YMM register and encoded in bits[7:4] of the immediate byte(imm8). The bits[3:0] of imm8 are ignored. In 32-bit mode, imm8[7] is ignored.\nVPBLENDVB permits the mask to be any XMM or YMM register. In contrast, PBLENDVB treats XMM0 implicitly as the mask and do not support non-destructive destination operation. An attempt to execute PBLENDVB encoded with a VEX prefix will cause a #UD exception.", + "operation": "MASK := XMM0\nIF (MASK[7] = 1) THEN DEST[7:0] := SRC[7:0];\nELSE DEST[7:0] := DEST[7:0];\nIF (MASK[15] = 1) THEN DEST[15:8] := SRC[15:8];\nELSE DEST[15:8] := DEST[15:8];\nIF (MASK[23] = 1) THEN DEST[23:16] := SRC[23:16]\nELSE DEST[23:16] := DEST[23:16];\nIF (MASK[31] = 1) THEN DEST[31:24] := SRC[31:24]\nELSE DEST[31:24] := DEST[31:24];\nIF (MASK[39] = 1) THEN DEST[39:32] := SRC[39:32]\nELSE DEST[39:32] := DEST[39:32];\nIF (MASK[47] = 1) THEN DEST[47:40] := SRC[47:40]\nELSE DEST[47:40] := DEST[47:40];\nIF (MASK[55] = 1) THEN DEST[55:48] := SRC[55:48]\nELSE DEST[55:48] := DEST[55:48];\nIF (MASK[63] = 1) THEN DEST[63:56] := SRC[63:56]\nELSE DEST[63:56] := DEST[63:56];\nIF (MASK[71] = 1) THEN DEST[71:64] := SRC[71:64]\nELSE DEST[71:64] := DEST[71:64];\nIF (MASK[79] = 1) THEN DEST[79:72] := SRC[79:72]\nELSE DEST[79:72] := DEST[79:72];\nIF (MASK[87] = 1) THEN DEST[87:80] := SRC[87:80]\nELSE DEST[87:80] := DEST[87:80];\nIF (MASK[95] = 1) THEN DEST[95:88] := SRC[95:88]\nELSE DEST[95:88] := DEST[95:88];\nIF (MASK[103] = 1) THEN DEST[103:96] := SRC[103:96]\nELSE DEST[103:96] := DEST[103:96];\nIF (MASK[111] = 1) THEN DEST[111:104] := SRC[111:104]\nELSE DEST[111:104] := DEST[111:104];\nIF (MASK[119] = 1) THEN DEST[119:112] := SRC[119:112]\nELSE DEST[119:112] := DEST[119:112];\nIF (MASK[127] = 1) THEN DEST[127:120] := SRC[127:120]\nELSE DEST[127:120] := DEST[127:120])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nMASK := SRC3\nIF (MASK[7] = 1) THEN DEST[7:0] := SRC2[7:0];\nELSE DEST[7:0] := SRC1[7:0];\nIF (MASK[15] = 1) THEN DEST[15:8] := SRC2[15:8];\nELSE DEST[15:8] := SRC1[15:8];\nIF (MASK[23] = 1) THEN DEST[23:16] := SRC2[23:16]\nELSE DEST[23:16] := SRC1[23:16];\nIF (MASK[31] = 1) THEN DEST[31:24] := SRC2[31:24]\nELSE DEST[31:24] := SRC1[31:24];\nIF (MASK[39] = 1) THEN DEST[39:32] := SRC2[39:32]\nELSE DEST[39:32] := SRC1[39:32];\nIF (MASK[47] = 1) THEN DEST[47:40] := SRC2[47:40]\nELSE DEST[47:40] := SRC1[47:40];\nIF (MASK[55] = 1) THEN DEST[55:48] := SRC2[55:48]\nELSE DEST[55:48] := SRC1[55:48];\nIF (MASK[63] = 1) THEN DEST[63:56] := SRC2[63:56]\nELSE DEST[63:56] := SRC1[63:56];\nIF (MASK[71] = 1) THEN DEST[71:64] := SRC2[71:64]\nELSE DEST[71:64] := SRC1[71:64];\nIF (MASK[79] = 1) THEN DEST[79:72] := SRC2[79:72]\nELSE DEST[79:72] := SRC1[79:72];\nIF (MASK[87] = 1) THEN DEST[87:80] := SRC2[87:80]\nELSE DEST[87:80] := SRC1[87:80];\nIF (MASK[95] = 1) THEN DEST[95:88] := SRC2[95:88]\nELSE DEST[95:88] := SRC1[95:88];\nIF (MASK[103] = 1) THEN DEST[103:96] := SRC2[103:96]\nELSE DEST[103:96] := SRC1[103:96];\nIF (MASK[111] = 1) THEN DEST[111:104] := SRC2[111:104]\nELSE DEST[111:104] := SRC1[111:104];\nIF (MASK[119] = 1) THEN DEST[119:112] := SRC2[119:112]\nELSE DEST[119:112] := SRC1[119:112];\nIF (MASK[127] = 1) THEN DEST[127:120] := SRC2[127:120]\nELSE DEST[127:120] := SRC1[127:120])\nDEST[MAXVL-1:128] := 0\n\n\nMASK := SRC3\nIF (MASK[7] == 1) THEN DEST[7:0] := SRC2[7:0];\nELSE DEST[7:0] := SRC1[7:0];\nIF (MASK[15] == 1) THEN DEST[15:8] := SRC2[15:8];\nELSE DEST[15:8] := SRC1[15:8];\nIF (MASK[23] == 1) THEN DEST[23:16] := SRC2[23:16]\nELSE DEST[23:16] := SRC1[23:16];\nIF (MASK[31] == 1) THEN DEST[31:24] := SRC2[31:24]\nELSE DEST[31:24] := SRC1[31:24];\nIF (MASK[39] == 1) THEN DEST[39:32] := SRC2[39:32]\nELSE DEST[39:32] := SRC1[39:32];\nIF (MASK[47] == 1) THEN DEST[47:40] := SRC2[47:40]\nELSE DEST[47:40] := SRC1[47:40];\nIF (MASK[55] == 1) THEN DEST[55:48] := SRC2[55:48]\nELSE DEST[55:48] := SRC1[55:48];\nIF (MASK[63] == 1) THEN DEST[63:56] := SRC2[63:56]\nELSE DEST[63:56] := SRC1[63:56];\nIF (MASK[71] == 1) THEN DEST[71:64] := SRC2[71:64]\nELSE DEST[71:64] := SRC1[71:64];\nIF (MASK[79] == 1) THEN DEST[79:72] := SRC2[79:72]\nELSE DEST[79:72] := SRC1[79:72];\nIF (MASK[87] == 1) THEN DEST[87:80] := SRC2[87:80]\nELSE DEST[87:80] := SRC1[87:80];\nIF (MASK[95] == 1) THEN DEST[95:88] := SRC2[95:88]\nELSE DEST[95:88] := SRC1[95:88];\nIF (MASK[103] == 1) THEN DEST[103:96] := SRC2[103:96]\nELSE DEST[103:96] := SRC1[103:96];\nIF (MASK[111] == 1) THEN DEST[111:104] := SRC2[111:104]\nELSE DEST[111:104] := SRC1[111:104];\nIF (MASK[119] == 1) THEN DEST[119:112] := SRC2[119:112]\nELSE DEST[119:112] := SRC1[119:112];\nIF (MASK[127] == 1) THEN DEST[127:120] := SRC2[127:120]\nELSE DEST[127:120] := SRC1[127:120])\nIF (MASK[135] == 1) THEN DEST[135:128] := SRC2[135:128];\nELSE DEST[135:128] := SRC1[135:128];\nIF (MASK[143] == 1) THEN DEST[143:136] := SRC2[143:136];\nELSE DEST[[143:136] := SRC1[143:136];\nIF (MASK[151] == 1) THEN DEST[151:144] := SRC2[151:144]\nELSE DEST[151:144] := SRC1[151:144];\nIF (MASK[159] == 1) THEN DEST[159:152] := SRC2[159:152]\nELSE DEST[159:152] := SRC1[159:152];\nIF (MASK[167] == 1) THEN DEST[167:160] := SRC2[167:160]\nELSE DEST[167:160] := SRC1[167:160];\nIF (MASK[175] == 1) THEN DEST[175:168] := SRC2[175:168]\nELSE DEST[175:168] := SRC1[175:168];\nIF (MASK[183] == 1) THEN DEST[183:176] := SRC2[183:176]\nELSE DEST[183:176] := SRC1[183:176];\nIF (MASK[191] == 1) THEN DEST[191:184] := SRC2[191:184]\nELSE DEST[191:184] := SRC1[191:184];\nIF (MASK[199] == 1) THEN DEST[199:192] := SRC2[199:192]\nELSE DEST[199:192] := SRC1[199:192];\nIF (MASK[207] == 1) THEN DEST[207:200] := SRC2[207:200]\nELSE DEST[207:200] := SRC1[207:200]\nIF (MASK[215] == 1) THEN DEST[215:208] := SRC2[215:208]\nELSE DEST[215:208] := SRC1[215:208];\nIF (MASK[223] == 1) THEN DEST[223:216] := SRC2[223:216]\nELSE DEST[223:216] := SRC1[223:216];\nIF (MASK[231] == 1) THEN DEST[231:224] := SRC2[231:224]\nELSE DEST[231:224] := SRC1[231:224];\nIF (MASK[239] == 1) THEN DEST[239:232] := SRC2[239:232]\nELSE DEST[239:232] := SRC1[239:232];\nIF (MASK[247] == 1) THEN DEST[247:240] := SRC2[247:240]\nELSE DEST[247:240] := SRC1[247:240];\nIF (MASK[255] == 1) THEN DEST[255:248] := SRC2[255:248]\nELSE DEST[255:248] := SRC1[255:248]\n", + "url": "https://www.felixcloutier.com/x86/pblendvb" + }, + "pblendw": { + "instruction": "PBLENDW", + "title": "PBLENDW\n\t\t— Blend Packed Words", + "opcode": "66 0F 3A 0E /r ib PBLENDW xmm1, xmm2/m128, imm8", + "description": "Words from the source operand (second operand) are conditionally written to the destination operand (first operand) depending on bits in the immediate operand (third operand). The immediate bits (bits 7:0) form a mask that determines whether the corresponding word in the destination is copied from the source. If a bit in the mask, corresponding to a word, is “1\", then the word is copied, else the word element in the destination operand is unchanged.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "IF (imm8[0] = 1) THEN DEST[15:0] := SRC[15:0]\nELSE DEST[15:0] := DEST[15:0]\nIF (imm8[1] = 1) THEN DEST[31:16] := SRC[31:16]\nELSE DEST[31:16] := DEST[31:16]\nIF (imm8[2] = 1) THEN DEST[47:32] := SRC[47:32]\nELSE DEST[47:32] := DEST[47:32]\nIF (imm8[3] = 1) THEN DEST[63:48] := SRC[63:48]\nELSE DEST[63:48] := DEST[63:48]\nIF (imm8[4] = 1) THEN DEST[79:64] := SRC[79:64]\nELSE DEST[79:64] := DEST[79:64]\nIF (imm8[5] = 1) THEN DEST[95:80] := SRC[95:80]\nELSE DEST[95:80] := DEST[95:80]\nIF (imm8[6] = 1) THEN DEST[111:96] := SRC[111:96]\nELSE DEST[111:96] := DEST[111:96]\nIF (imm8[7] = 1) THEN DEST[127:112] := SRC[127:112]\nELSE DEST[127:112] := DEST[127:112]\n\n\nIF (imm8[0] = 1) THEN DEST[15:0] := SRC2[15:0]\nELSE DEST[15:0] := SRC1[15:0]\nIF (imm8[1] = 1) THEN DEST[31:16] := SRC2[31:16]\nELSE DEST[31:16] := SRC1[31:16]\nIF (imm8[2] = 1) THEN DEST[47:32] := SRC2[47:32]\nELSE DEST[47:32] := SRC1[47:32]\nIF (imm8[3] = 1) THEN DEST[63:48] := SRC2[63:48]\nELSE DEST[63:48] := SRC1[63:48]\nIF (imm8[4] = 1) THEN DEST[79:64] := SRC2[79:64]\nELSE DEST[79:64] := SRC1[79:64]\nIF (imm8[5] = 1) THEN DEST[95:80] := SRC2[95:80]\nELSE DEST[95:80] := SRC1[95:80]\nIF (imm8[6] = 1) THEN DEST[111:96] := SRC2[111:96]\nELSE DEST[111:96] := SRC1[111:96]\nIF (imm8[7] = 1) THEN DEST[127:112] := SRC2[127:112]\nELSE DEST[127:112] := SRC1[127:112]\nDEST[MAXVL-1:128] := 0\n\n\nIF (imm8[0] == 1) THEN DEST[15:0] := SRC2[15:0]\nELSE DEST[15:0] := SRC1[15:0]\nIF (imm8[1] == 1) THEN DEST[31:16] := SRC2[31:16]\nELSE DEST[31:16] := SRC1[31:16]\nIF (imm8[2] == 1) THEN DEST[47:32] := SRC2[47:32]\nELSE DEST[47:32] := SRC1[47:32]\nIF (imm8[3] == 1) THEN DEST[63:48] := SRC2[63:48]\nELSE DEST[63:48] := SRC1[63:48]\nIF (imm8[4] == 1) THEN DEST[79:64] := SRC2[79:64]\nELSE DEST[79:64] := SRC1[79:64]\nIF (imm8[5] == 1) THEN DEST[95:80] := SRC2[95:80]\nELSE DEST[95:80] := SRC1[95:80]\nIF (imm8[6] == 1) THEN DEST[111:96] := SRC2[111:96]\nELSE DEST[111:96] := SRC1[111:96]\nIF (imm8[7] == 1) THEN DEST[127:112]\nELSE DEST[127:112] := SRC1[127:112]\nIF (imm8[0] == 1) THEN DEST[143:128]\nELSE DEST[143:128] := SRC1[143:128]\nIF (imm8[1] == 1) THEN DEST[159:144]\nELSE DEST[159:144] := SRC1[159:144]\nIF (imm8[2] == 1) THEN DEST[175:160]\nELSE DEST[175:160] := SRC1[175:160]\nIF (imm8[3] == 1) THEN DEST[191:176]\nELSE DEST[191:176] := SRC1[191:176]\nIF (imm8[4] == 1) THEN DEST[207:192]\nELSE DEST[207:192] := SRC1[207:192]\nIF (imm8[5] == 1) THEN DEST[223:208]\nELSE DEST[223:208] := SRC1[223:208]\nIF (imm8[6] == 1) THEN DEST[239:224]\nELSE DEST[239:224] := SRC1[239:224]\nIF (imm8[7] == 1) THEN DEST[255:240]\nELSE DEST[255:240] := SRC1[255:240]\n", + "url": "https://www.felixcloutier.com/x86/pblendw" + }, + "pclmulqdq": { + "instruction": "PCLMULQDQ", + "title": "PCLMULQDQ\n\t\t— Carry-Less Multiplication Quadword", + "opcode": "66 0F 3A 44 /r ib PCLMULQDQ xmm1, xmm2/m128, imm8", + "description": "Performs a carry-less multiplication of two quadwords, selected from the first source and second source operand according to the value of the immediate byte. Bits 4 and 0 are used to select which 64-bit half of each operand to use according to Table 4-13, other bits of the immediate byte are ignored.\nThe EVEX encoded form of this instruction does not support memory fault suppression.\nThe first source operand and the destination operand are the same and must be a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register or a 512/256/128-bit memory location. Bits (VL_MAX-1:128) of the corresponding YMM destination register remain unchanged.\nCompilers and assemblers may implement the following pseudo-op syntax to simplify programming and emit the required encoding for imm8.", + "operation": "define PCLMUL128(X,Y): // helper function\n FOR i := 0 to 63:\n TMP [ i ] := X[ 0 ] and Y[ i ]\n FOR j := 1 to i:\n TMP [ i ] := TMP [ i ] xor (X[ j ] and Y[ i - j ])\n DEST[ i ] := TMP[ i ]\n FOR i := 64 to 126:\n TMP [ i ] := 0\n FOR j := i - 63 to 63:\n TMP [ i ] := TMP [ i ] xor (X[ j ] and Y[ i - j ])\n DEST[ i ] := TMP[ i ]\n DEST[127] := 0;\n RETURN DEST // 128b vector\n\n\nIF imm8[0] = 0:\n TEMP1 := SRC1.qword[0]\nELSE:\n TEMP1 := SRC1.qword[1]\nIF imm8[4] = 0:\n TEMP2 := SRC2.qword[0]\nELSE:\n TEMP2 := SRC2.qword[1]\nDEST[127:0] := PCLMUL128(TEMP1, TEMP2)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL,VL) = (1,128), (2,256)\nFOR i= 0 to KL-1:\n IF imm8[0] = 0:\n TEMP1 := SRC1.xmm[i].qword[0]\n ELSE:\n TEMP1 := SRC1.xmm[i].qword[1]\n IF imm8[4] = 0:\n TEMP2 := SRC2.xmm[i].qword[0]\n ELSE:\n TEMP2 := SRC2.xmm[i].qword[1]\n DEST.xmm[i] := PCLMUL128(TEMP1, TEMP2)\nDEST[MAXVL-1:VL] := 0\n\n\n(KL,VL) = (1,128), (2,256), (4,512)\nFOR i = 0 to KL-1:\n IF imm8[0] = 0:\n TEMP1 := SRC1.xmm[i].qword[0]\n ELSE:\n TEMP1 := SRC1.xmm[i].qword[1]\n IF imm8[4] = 0:\n TEMP2 := SRC2.xmm[i].qword[0]\n ELSE:\n TEMP2 := SRC2.xmm[i].qword[1]\n DEST.xmm[i] := PCLMUL128(TEMP1, TEMP2)\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pclmulqdq" + }, + "pcmpeqb": { + "instruction": "PCMPEQB", + "title": "PCMPEQB/PCMPEQW/PCMPEQD\n\t\t— Compare Packed Data for Equal", + "opcode": "NP 0F 74 /r1 PCMPEQB mm, mm/m64", + "description": "Performs a SIMD compare for equality of the packed bytes, words, or doublewords in the destination operand (first operand) and the source operand (second operand). If a pair of data elements is equal, the corresponding data element in the destination operand is set to all 1s; otherwise, it is set to all 0s.\nThe (V)PCMPEQB instruction compares the corresponding bytes in the destination and source operands; the (V)PCMPEQW instruction compares the corresponding words in the destination and source operands; and the (V)PCMPEQD instruction compares the corresponding doublewords in the destination and source operands.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPEQD: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.\nEVEX encoded VPCMPEQB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF DEST[7:0] = SRC[7:0]\n THEN DEST[7:0) := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)\nIF DEST[63:56] = SRC[63:56]\n THEN DEST[63:56] := FFH;\n ELSE DEST[63:56] := 0; FI;\n\n\n IF SRC1[7:0] = SRC2[7:0]\n THEN DEST[7:0] := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)\n IF SRC1[127:120] = SRC2[127:120]\n THEN DEST[127:120] := FFH;\n ELSE DEST[127:120] := 0; FI;\n\n\n IF SRC1[15:0] = SRC2[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)\n IF SRC1[127:112] = SRC2[127:112]\n THEN DEST[127:112] := FFFFH;\n ELSE DEST[127:112] := 0; FI;\n\n\n IF SRC1[31:0] = SRC2[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\n(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)\n IF SRC1[127:96] = SRC2[127:96]\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 0; FI;\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_BYTES_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+7:i] == SRC2[i+7:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[15:0] = SRC[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd and 3rd words in DEST and SRC *)\nIF DEST[63:48] = SRC[63:48]\n THEN DEST[63:48] := FFFFH;\n ELSE DEST[63:48] := 0; FI;\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_WORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+15:i] == SRC2[i+15:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[31:0] = SRC[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\nIF DEST[63:32] = SRC[63:32]\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 0; FI;\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_DWORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+31:i] = SRC2[31:0];\n ELSE CMP := SRC1[i+31:i] = SRC2[i+31:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking only\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpeqb:pcmpeqw:pcmpeqd" + }, + "pcmpeqd": { + "instruction": "PCMPEQD", + "title": "PCMPEQB/PCMPEQW/PCMPEQD\n\t\t— Compare Packed Data for Equal", + "opcode": "NP 0F 74 /r1 PCMPEQB mm, mm/m64", + "description": "Performs a SIMD compare for equality of the packed bytes, words, or doublewords in the destination operand (first operand) and the source operand (second operand). If a pair of data elements is equal, the corresponding data element in the destination operand is set to all 1s; otherwise, it is set to all 0s.\nThe (V)PCMPEQB instruction compares the corresponding bytes in the destination and source operands; the (V)PCMPEQW instruction compares the corresponding words in the destination and source operands; and the (V)PCMPEQD instruction compares the corresponding doublewords in the destination and source operands.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPEQD: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.\nEVEX encoded VPCMPEQB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF DEST[7:0] = SRC[7:0]\n THEN DEST[7:0) := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)\nIF DEST[63:56] = SRC[63:56]\n THEN DEST[63:56] := FFH;\n ELSE DEST[63:56] := 0; FI;\n\n\n IF SRC1[7:0] = SRC2[7:0]\n THEN DEST[7:0] := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)\n IF SRC1[127:120] = SRC2[127:120]\n THEN DEST[127:120] := FFH;\n ELSE DEST[127:120] := 0; FI;\n\n\n IF SRC1[15:0] = SRC2[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)\n IF SRC1[127:112] = SRC2[127:112]\n THEN DEST[127:112] := FFFFH;\n ELSE DEST[127:112] := 0; FI;\n\n\n IF SRC1[31:0] = SRC2[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\n(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)\n IF SRC1[127:96] = SRC2[127:96]\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 0; FI;\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_BYTES_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+7:i] == SRC2[i+7:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[15:0] = SRC[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd and 3rd words in DEST and SRC *)\nIF DEST[63:48] = SRC[63:48]\n THEN DEST[63:48] := FFFFH;\n ELSE DEST[63:48] := 0; FI;\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_WORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+15:i] == SRC2[i+15:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[31:0] = SRC[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\nIF DEST[63:32] = SRC[63:32]\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 0; FI;\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_DWORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+31:i] = SRC2[31:0];\n ELSE CMP := SRC1[i+31:i] = SRC2[i+31:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking only\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpeqb:pcmpeqw:pcmpeqd" + }, + "pcmpeqq": { + "instruction": "PCMPEQQ", + "title": "PCMPEQQ\n\t\t— Compare Packed Qword Data for Equal", + "opcode": "66 0F 38 29 /r PCMPEQQ xmm1, xmm2/m128", + "description": "Performs an SIMD compare for equality of the packed quadwords in the destination operand (first operand) and the source operand (second operand). If a pair of data elements is equal, the corresponding data element in the destination is set to all 1s; otherwise, it is set to 0s.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPEQQ: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF (DEST[63:0] = SRC[63:0])\n THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[63:0] := 0; FI;\nIF (DEST[127:64] = SRC[127:64])\n THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;\n ELSE DEST[127:64] := 0; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nIF SRC1[63:0] = SRC2[63:0]\nTHEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\nELSE DEST[63:0] := 0; FI;\nIF SRC1[127:64] = SRC2[127:64]\nTHEN DEST[127:64] := FFFFFFFFFFFFFFFFH;\nELSE DEST[127:64] := 0; FI;\n\n\nDEST[127:0] := COMPARE_QWORDS_EQUAL(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_QWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_QWORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k2[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+63:i] = SRC2[63:0];\n ELSE CMP := SRC1[i+63:i] = SRC2[i+63:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking only\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpeqq" + }, + "pcmpeqw": { + "instruction": "PCMPEQW", + "title": "PCMPEQB/PCMPEQW/PCMPEQD\n\t\t— Compare Packed Data for Equal", + "opcode": "NP 0F 74 /r1 PCMPEQB mm, mm/m64", + "description": "Performs a SIMD compare for equality of the packed bytes, words, or doublewords in the destination operand (first operand) and the source operand (second operand). If a pair of data elements is equal, the corresponding data element in the destination operand is set to all 1s; otherwise, it is set to all 0s.\nThe (V)PCMPEQB instruction compares the corresponding bytes in the destination and source operands; the (V)PCMPEQW instruction compares the corresponding words in the destination and source operands; and the (V)PCMPEQD instruction compares the corresponding doublewords in the destination and source operands.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPEQD: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.\nEVEX encoded VPCMPEQB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF DEST[7:0] = SRC[7:0]\n THEN DEST[7:0) := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)\nIF DEST[63:56] = SRC[63:56]\n THEN DEST[63:56] := FFH;\n ELSE DEST[63:56] := 0; FI;\n\n\n IF SRC1[7:0] = SRC2[7:0]\n THEN DEST[7:0] := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)\n IF SRC1[127:120] = SRC2[127:120]\n THEN DEST[127:120] := FFH;\n ELSE DEST[127:120] := 0; FI;\n\n\n IF SRC1[15:0] = SRC2[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)\n IF SRC1[127:112] = SRC2[127:112]\n THEN DEST[127:112] := FFFFH;\n ELSE DEST[127:112] := 0; FI;\n\n\n IF SRC1[31:0] = SRC2[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\n(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)\n IF SRC1[127:96] = SRC2[127:96]\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 0; FI;\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_BYTES_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+7:i] == SRC2[i+7:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[15:0] = SRC[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd and 3rd words in DEST and SRC *)\nIF DEST[63:48] = SRC[63:48]\n THEN DEST[63:48] := FFFFH;\n ELSE DEST[63:48] := 0; FI;\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_WORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+15:i] == SRC2[i+15:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[31:0] = SRC[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\nIF DEST[63:32] = SRC[63:32]\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 0; FI;\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_DWORDS_EQUAL(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+31:i] = SRC2[31:0];\n ELSE CMP := SRC1[i+31:i] = SRC2[i+31:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking only\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpeqb:pcmpeqw:pcmpeqd" + }, + "pcmpestri": { + "instruction": "PCMPESTRI", + "title": "PCMPESTRI\n\t\t— Packed Compare Explicit Length Strings, Return Index", + "opcode": "66 0F 3A 61 /r imm8 PCMPESTRI xmm1, xmm2/m128, imm8", + "description": "The instruction compares and processes data from two string fragments based on the encoded value in the imm8 control byte (see Section 4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”), and generates an index stored to the count register (ECX).\nEach string fragment is represented by two values. The first value is an xmm (or possibly m128 for the second operand) which contains the data elements of the string (byte or word data). The second value is stored in an input length register. The input length register is EAX/RAX (for xmm1) or EDX/RDX (for xmm2/m128). The length represents the number of bytes/words which are valid for the respective xmm/m128 data.\nThe length of each input is interpreted as being the absolute-value of the value in the length register. The absolute-value computation saturates to 16 (for bytes) and 8 (for words), based on the value of imm8[bit3] when the value in the length register is greater than 16 (8) or less than -16 (-8).\nThe comparison and aggregation operations are performed according to the encoded value of imm8 bit fields (see Section 4.1). The index of the first (or last, according to imm8[6]) set bit of IntRes2 (see Section 4.1.4) is returned in ECX. If no bits are set in IntRes2, ECX is set to 16 (8).\nNote that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant information:\nCFlag – Reset if IntRes2 is equal to zero, set otherwise\nZFlag – Set if absolute-value of EDX is < 16 (8), reset otherwise\nSFlag – Set if absolute-value of EAX is < 16 (8), reset otherwise\nOFlag – IntRes2[0]\nAFlag – Reset\nPFlag – Reset", + "operation": "", + "url": "https://www.felixcloutier.com/x86/pcmpestri" + }, + "pcmpestrm": { + "instruction": "PCMPESTRM", + "title": "PCMPESTRM\n\t\t— Packed Compare Explicit Length Strings, Return Mask", + "opcode": "66 0F 3A 60 /r imm8 PCMPESTRM xmm1, xmm2/m128, imm8", + "description": "The instruction compares data from two string fragments based on the encoded value in the imm8 contol byte (see Section 4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”), and generates a mask stored to XMM0.\nEach string fragment is represented by two values. The first value is an xmm (or possibly m128 for the second operand) which contains the data elements of the string (byte or word data). The second value is stored in an input length register. The input length register is EAX/RAX (for xmm1) or EDX/RDX (for xmm2/m128). The length represents the number of bytes/words which are valid for the respective xmm/m128 data.\nThe length of each input is interpreted as being the absolute-value of the value in the length register. The absolute-value computation saturates to 16 (for bytes) and 8 (for words), based on the value of imm8[bit3] when the value in the length register is greater than 16 (8) or less than -16 (-8).\nThe comparison and aggregation operations are performed according to the encoded value of imm8 bit fields (see Section 4.1). As defined by imm8[6], IntRes2 is then either stored to the least significant bits of XMM0 (zero extended to 128 bits) or expanded into a byte/word-mask and then stored to XMM0.\nNote that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant information:\nCFlag – Reset if IntRes2 is equal to zero, set otherwise\nZFlag – Set if absolute-value of EDX is < 16 (8), reset otherwise\nSFlag – Set if absolute-value of EAX is < 16 (8), reset otherwise\nOFlag –IntRes2[0]\nAFlag – Reset\nPFlag – Reset\nNote: In VEX.128 encoded versions, bits (MAXVL-1:128) of XMM0 are zeroed. VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/pcmpestrm" + }, + "pcmpgtb": { + "instruction": "PCMPGTB", + "title": "PCMPGTB/PCMPGTW/PCMPGTD\n\t\t— Compare Packed Signed Integers for Greater Than", + "opcode": "NP 0F 64 /r1 PCMPGTB mm, mm/m64", + "description": "Performs an SIMD signed compare for the greater value of the packed byte, word, or doubleword integers in the destination operand (first operand) and the source operand (second operand). If a data element in the destination operand is greater than the corresponding date element in the source operand, the corresponding data element in the destination operand is set to all 1s; otherwise, it is set to all 0s.\nThe PCMPGTB instruction compares the corresponding signed byte integers in the destination and source operands; the PCMPGTW instruction compares the corresponding signed word integers in the destination and source operands; and the PCMPGTD instruction compares the corresponding signed doubleword integers in the destination and source operands.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPGTD: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.\nEVEX encoded VPCMPGTB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF DEST[7:0] > SRC[7:0]\n THEN DEST[7:0) := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)\nIF DEST[63:56] > SRC[63:56]\n THEN DEST[63:56] := FFH;\n ELSE DEST[63:56] := 0; FI;\n\n\n IF SRC1[7:0] > SRC2[7:0]\n THEN DEST[7:0] := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)\n IF SRC1[127:120] > SRC2[127:120]\n THEN DEST[127:120] := FFH;\n ELSE DEST[127:120] := 0; FI;\n\n\n IF SRC1[15:0] > SRC2[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)\n IF SRC1[127:112] > SRC2[127:112]\n THEN DEST[127:112] := FFFFH;\n ELSE DEST[127:112] := 0; FI;\n\n\n IF SRC1[31:0] > SRC2[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\n(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)\n IF SRC1[127:96] > SRC2[127:96]\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 0; FI;\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_BYTES_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+7:i] > SRC2[i+7:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[15:0] > SRC[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd and 3rd words in DEST and SRC *)\nIF DEST[63:48] > SRC[63:48]\n THEN DEST[63:48] := FFFFH;\n ELSE DEST[63:48] := 0; FI;\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_WORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+15:i] > SRC2[i+15:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[31:0] > SRC[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\nIF DEST[63:32] > SRC[63:32]\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 0; FI;\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_DWORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+31:i] > SRC2[31:0];\n ELSE CMP := SRC1[i+31:i] > SRC2[i+31:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE\n DEST[j] := 0\n ; zeroing-masking only\n I\n ;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpgtb:pcmpgtw:pcmpgtd" + }, + "pcmpgtd": { + "instruction": "PCMPGTD", + "title": "PCMPGTB/PCMPGTW/PCMPGTD\n\t\t— Compare Packed Signed Integers for Greater Than", + "opcode": "NP 0F 64 /r1 PCMPGTB mm, mm/m64", + "description": "Performs an SIMD signed compare for the greater value of the packed byte, word, or doubleword integers in the destination operand (first operand) and the source operand (second operand). If a data element in the destination operand is greater than the corresponding date element in the source operand, the corresponding data element in the destination operand is set to all 1s; otherwise, it is set to all 0s.\nThe PCMPGTB instruction compares the corresponding signed byte integers in the destination and source operands; the PCMPGTW instruction compares the corresponding signed word integers in the destination and source operands; and the PCMPGTD instruction compares the corresponding signed doubleword integers in the destination and source operands.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPGTD: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.\nEVEX encoded VPCMPGTB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF DEST[7:0] > SRC[7:0]\n THEN DEST[7:0) := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)\nIF DEST[63:56] > SRC[63:56]\n THEN DEST[63:56] := FFH;\n ELSE DEST[63:56] := 0; FI;\n\n\n IF SRC1[7:0] > SRC2[7:0]\n THEN DEST[7:0] := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)\n IF SRC1[127:120] > SRC2[127:120]\n THEN DEST[127:120] := FFH;\n ELSE DEST[127:120] := 0; FI;\n\n\n IF SRC1[15:0] > SRC2[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)\n IF SRC1[127:112] > SRC2[127:112]\n THEN DEST[127:112] := FFFFH;\n ELSE DEST[127:112] := 0; FI;\n\n\n IF SRC1[31:0] > SRC2[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\n(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)\n IF SRC1[127:96] > SRC2[127:96]\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 0; FI;\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_BYTES_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+7:i] > SRC2[i+7:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[15:0] > SRC[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd and 3rd words in DEST and SRC *)\nIF DEST[63:48] > SRC[63:48]\n THEN DEST[63:48] := FFFFH;\n ELSE DEST[63:48] := 0; FI;\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_WORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+15:i] > SRC2[i+15:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[31:0] > SRC[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\nIF DEST[63:32] > SRC[63:32]\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 0; FI;\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_DWORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+31:i] > SRC2[31:0];\n ELSE CMP := SRC1[i+31:i] > SRC2[i+31:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE\n DEST[j] := 0\n ; zeroing-masking only\n I\n ;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpgtb:pcmpgtw:pcmpgtd" + }, + "pcmpgtq": { + "instruction": "PCMPGTQ", + "title": "PCMPGTQ\n\t\t— Compare Packed Data for Greater Than", + "opcode": "66 0F 38 37 /r PCMPGTQ xmm1,xmm2/m128", + "description": "Performs an SIMD signed compare for the packed quadwords in the destination operand (first operand) and the source operand (second operand). If the data element in the first (destination) operand is greater than the corresponding element in the second (source) operand, the corresponding data element in the destination is set to all 1s; otherwise, it is set to 0s.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPGTD/Q: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF SRC1[63:0] > SRC2[63:0]\nTHEN DEST[63:0] := FFFFFFFFFFFFFFFFH;\nELSE DEST[63:0] := 0; FI;\nIF SRC1[127:64] > SRC2[127:64]\nTHEN DEST[127:64] := FFFFFFFFFFFFFFFFH;\nELSE DEST[127:64] := 0; FI;\n\n\nDEST[127:0] := COMPARE_QWORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_QWORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_QWORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+63:i] > SRC2[63:0];\n ELSE CMP := SRC1[i+63:i] > SRC2[i+63:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking only\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpgtq" + }, + "pcmpgtw": { + "instruction": "PCMPGTW", + "title": "PCMPGTB/PCMPGTW/PCMPGTD\n\t\t— Compare Packed Signed Integers for Greater Than", + "opcode": "NP 0F 64 /r1 PCMPGTB mm, mm/m64", + "description": "Performs an SIMD signed compare for the greater value of the packed byte, word, or doubleword integers in the destination operand (first operand) and the source operand (second operand). If a data element in the destination operand is greater than the corresponding date element in the source operand, the corresponding data element in the destination operand is set to all 1s; otherwise, it is set to all 0s.\nThe PCMPGTB instruction compares the corresponding signed byte integers in the destination and source operands; the PCMPGTW instruction compares the corresponding signed word integers in the destination and source operands; and the PCMPGTD instruction compares the corresponding signed doubleword integers in the destination and source operands.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX encoded VPCMPGTD: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.\nEVEX encoded VPCMPGTB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand (first operand) is a mask register updated according to the writemask k2.", + "operation": "IF DEST[7:0] > SRC[7:0]\n THEN DEST[7:0) := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)\nIF DEST[63:56] > SRC[63:56]\n THEN DEST[63:56] := FFH;\n ELSE DEST[63:56] := 0; FI;\n\n\n IF SRC1[7:0] > SRC2[7:0]\n THEN DEST[7:0] := FFH;\n ELSE DEST[7:0] := 0; FI;\n(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)\n IF SRC1[127:120] > SRC2[127:120]\n THEN DEST[127:120] := FFH;\n ELSE DEST[127:120] := 0; FI;\n\n\n IF SRC1[15:0] > SRC2[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)\n IF SRC1[127:112] > SRC2[127:112]\n THEN DEST[127:112] := FFFFH;\n ELSE DEST[127:112] := 0; FI;\n\n\n IF SRC1[31:0] > SRC2[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\n(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)\n IF SRC1[127:96] > SRC2[127:96]\n THEN DEST[127:96] := FFFFFFFFH;\n ELSE DEST[127:96] := 0; FI;\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_BYTES_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_BYTES_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+7:i] > SRC2[i+7:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[15:0] > SRC[15:0]\n THEN DEST[15:0] := FFFFH;\n ELSE DEST[15:0] := 0; FI;\n(* Continue comparison of 2nd and 3rd words in DEST and SRC *)\nIF DEST[63:48] > SRC[63:48]\n THEN DEST[63:48] := FFFFH;\n ELSE DEST[63:48] := 0; FI;\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_WORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_WORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n CMP := SRC1[i+15:i] > SRC2[i+15:i];\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE DEST[j] := 0\n ; zeroing-masking onlyFI;\n FI;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n\n\nIF DEST[31:0] > SRC[31:0]\n THEN DEST[31:0] := FFFFFFFFH;\n ELSE DEST[31:0] := 0; FI;\nIF DEST[63:32] > SRC[63:32]\n THEN DEST[63:32] := FFFFFFFFH;\n ELSE DEST[63:32] := 0; FI;\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(DEST[127:0],SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(SRC1,SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := COMPARE_DWORDS_GREATER(SRC1[127:0],SRC2[127:0])\nDEST[255:128] := COMPARE_DWORDS_GREATER(SRC1[255:128],SRC2[255:128])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k2[j] OR *no writemask*\n THEN\n /* signed comparison */\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN CMP := SRC1[i+31:i] > SRC2[31:0];\n ELSE CMP := SRC1[i+31:i] > SRC2[i+31:i];\n FI;\n IF CMP = TRUE\n THEN DEST[j] := 1;\n ELSE DEST[j] := 0; FI;\n ELSE\n DEST[j] := 0\n ; zeroing-masking only\n I\n ;\nENDFOR\nDEST[MAX_KL-1:KL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pcmpgtb:pcmpgtw:pcmpgtd" + }, + "pcmpistri": { + "instruction": "PCMPISTRI", + "title": "PCMPISTRI\n\t\t— Packed Compare Implicit Length Strings, Return Index", + "opcode": "66 0F 3A 63 /r imm8 PCMPISTRI xmm1, xmm2/m128, imm8", + "description": "The instruction compares data from two strings based on the encoded value in the imm8 control byte (see Section 4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”), and generates an index stored to ECX.\nEach string is represented by a single value. The value is an xmm (or possibly m128 for the second operand) which contains the data elements of the string (byte or word data). Each input byte/word is augmented with a valid/invalid tag. A byte/word is considered valid only if it has a lower index than the least significant null byte/word. (The least significant null byte/word is also considered invalid.)\nThe comparison and aggregation operations are performed according to the encoded value of imm8 bit fields (see Section 4.1). The index of the first (or last, according to imm8[6]) set bit of IntRes2 is returned in ECX. If no bits are set in IntRes2, ECX is set to 16 (8).\nNote that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant information:\nCFlag – Reset if IntRes2 is equal to zero, set otherwise\nZFlag – Set if any byte/word of xmm2/mem128 is null, reset otherwise\nSFlag – Set if any byte/word of xmm1 is null, reset otherwise\nOFlag –IntRes2[0]\nAFlag – Reset\nPFlag – Reset\nNote: In VEX.128 encoded version, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/pcmpistri" + }, + "pcmpistrm": { + "instruction": "PCMPISTRM", + "title": "PCMPISTRM\n\t\t— Packed Compare Implicit Length Strings, Return Mask", + "opcode": "66 0F 3A 62 /r imm8 PCMPISTRM xmm1, xmm2/m128, imm8", + "description": "The instruction compares data from two strings based on the encoded value in the imm8 byte (see Section 4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”) generating a mask stored to XMM0.\nEach string is represented by a single value. The value is an xmm (or possibly m128 for the second operand) which contains the data elements of the string (byte or word data). Each input byte/word is augmented with a valid/invalid tag. A byte/word is considered valid only if it has a lower index than the least significant null byte/word. (The least significant null byte/word is also considered invalid.)\nThe comparison and aggregation operation are performed according to the encoded value of imm8 bit fields (see Section 4.1). As defined by imm8[6], IntRes2 is then either stored to the least significant bits of XMM0 (zero extended to 128 bits) or expanded into a byte/word-mask and then stored to XMM0.\nNote that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant information:\nCFlag – Reset if IntRes2 is equal to zero, set otherwise\nZFlag – Set if any byte/word of xmm2/mem128 is null, reset otherwise\nSFlag – Set if any byte/word of xmm1 is null, reset otherwise\nOFlag – IntRes2[0]\nAFlag – Reset\nPFlag – Reset\nNote: In VEX.128 encoded versions, bits (MAXVL-1:128) of XMM0 are zeroed. VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/pcmpistrm" + }, + "pconfig": { + "instruction": "PCONFIG", + "title": "PCONFIG\n\t\t— Platform Configuration", + "opcode": "NP 0F 01 C5 PCONFIG", + "description": "The PCONFIG instruction allows software to configure certain platform features. It supports these features with multiple leaf functions, selecting a leaf function using the value in EAX.\nDepending on the leaf function, the registers RBX, RCX, and RDX may be used to provide input information or for the instruction to report output information. Addresses and operands are 32 bits outside 64-bit mode and are 64 bits in 64-bit mode. The value of CS.D does not affect operand size or address size.\nExecutions of PCONFIG may fail for platform-specific reasons. An execution reports failure by setting the ZF flag and loading EAX with a non-zero failure reason; a successful execution clears ZF and EAX.\nEach PCONFIG leaf function applies to a specific hardware block called a PCONFIG target. The leaf function is supported only if the processor supports that target. Each target is associated with a numerical target identifier, and CPUID leaf 1BH (PCONFIG information) enumerates the identifiers of the supported targets. An attempt to execute an undefined leaf function, or a leaf function that applies to an unsupported target identifier, results in a general-protection exception (#GP).", + "operation": "(* #UD if PCONFIG is not enumerated or CPL > 0 *)\nIF CPUID.7.0:EDX[18] = 0 OR CPL > 0\n THEN #UD; FI;\n(* #GP(0) for an unsupported leaf function *)\nIF EAX != 0\n THEN #GP(0); FI;\nCASE (EAX) (* operation based on selected leaf function *)\n 0 (MKTME_KEY_PROGRAM):\n (* Confirm that TME-MK is properly enabled by the IA32_TME_ACTIVATE MSR *)\n (* The MSR must be locked, encryption enabled, and a non-zero number of KeyID bits specified *)\n IF IA32_TME_ACTIVATE[0] = 0 OR IA32_TME_ACTIVATE[1] = 0 OR IA32_TME_ACTIVATE[35:32] = 0\n THEN #GP(0); FI;\n IF DS:RBX is not 256-byte aligned\n THEN #GP(0); FI;\n Load TMP_KEY_PROGRAM_STRUCT from 192 bytes at linear address DS:RBX;\n IF TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL sets any reserved bits\n THEN #GP(0); FI;\n (* Check for a valid command *)\n IF TMP_KEY_PROGRAM_STRUCT. KEYID_CTRL.COMMAND > 3\n THEN #GP(0); FI;\n (* Check that the KEYID being operated upon is a valid KEYID *)\n IF TMP_KEY_PROGRAM_STRUCT.KEYID = 0 OR\n TMP_KEY_PROGRAM_STRUCT.KEYID > 2^IA32_TME_ACTIVATE.MK_TME_KEYID_BITS – 1 OR\n TMP_KEY_PROGRAM_STRUCT.KEYID > IA32_TME_CAPABILITY.MK_TME_MAX_KEYS\n THEN #GP(0); FI;\n (* Check that only one encryption algorithm is requested for the KeyID and it is one of the activated algorithms *)\n IF TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG does not set exactly one bit OR\n (TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG & IA32_TME_ACTIVATE[63:48]) = 0\n THEN #GP(0); FI:\n Attempt to acquire lock to gain exclusive access to platform key table;\n IF attempt is unsuccessful\n THEN (* PCONFIG failure *)\n RFLAGS.ZF := 1;\n RAX := DEVICE_BUSY;\n (* failure reason 5 *)\n GOTO EXIT;\n FI;\n CASE (TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.COMMAND) OF\n 0 (KEYID_SET_KEY_DIRECT):\n Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:\n Encrypt with the selected key\n Use the encryption algorithm selected by TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG\n (* The number of bytes used by the next two lines depends on selected encryption algorithm *)\n DATA_KEY is TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1\n TWEAK_KEY is TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2\n BREAK;\n 1 (KEYID_SET_KEY_RANDOM):\n Load TMP_RND_DATA_KEY with a random key using hardware RNG; (* key size depends on selected encryption algorithm *)\n IF there was insufficient entropy\n THEN (* PCONFIG failure *)\n RFLAGS.ZF := 1;\n RAX := ENTROPY_ERROR; (* failure reason 2 *)\n Release lock on platform key table;\n GOTO EXIT;\n FI;\n Load TMP_RND_TWEAK_KEY with a random key using hardware RNG; (* key size depends on selected encryption algorithm *)\n IF there was insufficient entropy\n THEN (* PCONFIG failure *)\n RFLAGS.ZF := 1;\n RAX := ENTROPY_ERROR; (* failure reason 2 *)\n Release lock on platform key table;\n GOTO EXIT;\n FI;\n (* Combine software-supplied entropy to the data key and tweak key *)\n (* The number of bytes used by the next two lines depends on selected encryption algorithm *)\n TMP_RND_DATA_KEY := TMP_RND_KEY XOR TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1;\n TMP_RND_TWEAK_KEY := TMP_RND_TWEAK_KEY XOR TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2;\n Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:\n Encrypt with the selected key\n Use the encryption algorithm selected by TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG\n (* The number of bytes used by the next two lines depends on selected encryption algorithm *)\n DATA_KEY is TMP_RND_DATA_KEY\n TWEAK_KEY is TMP_RND_TWEAK_KEY\n BREAK;\n 2 (KEYID_CLEAR_KEY):\n Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:\n Encrypt (or not) using the current configuration for TME\n The specified encryption algorithm and key values are not used.\n BREAK;\n 3 (KEYID_NO_ENCRYPT):\n Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:\n Do not encrypt\n The specified encryption algorithm and key values are not used.\n BREAK;\n ESAC;\n Release lock on platform key table;\nESAC;\nRAX := 0;\nRFLAGS.ZF := 0;\nEXIT:\nRFLAGS.CF := 0;\nRFLAGS.PF := 0;\nRFLAGS.AF := 0;\nRFLAGS.OF := 0;\nRFLAGS.SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/pconfig" + }, + "pdep": { + "instruction": "PDEP", + "title": "PDEP\n\t\t— Parallel Bits Deposit", + "opcode": "VEX.LZ.F2.0F38.W0 F5 /r PDEP r32a, r32b, r/m32", + "description": "PDEP uses a mask in the second source operand (the third operand) to transfer/scatter contiguous low order bits in the first source operand (the second operand) into the destination (the first operand). PDEP takes the low bits from the first source operand and deposit them in the destination operand at the corresponding bit locations that are set in the second source operand (mask). All other bits (bits not set in mask) in destination are set to zero.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "TEMP := SRC1;\nMASK := SRC2;\nDEST := 0 ;\nm := 0, k := 0;\nDO WHILE m < OperandSize\n IF MASK[ m] = 1 THEN\n DEST[ m] := TEMP[ k];\n k := k+ 1;\n FI\n m := m+ 1;\nOD\n", + "url": "https://www.felixcloutier.com/x86/pdep" + }, + "pext": { + "instruction": "PEXT", + "title": "PEXT\n\t\t— Parallel Bits Extract", + "opcode": "VEX.LZ.F3.0F38.W0 F5 /r PEXT r32a, r32b, r/m32", + "description": "PEXT uses a mask in the second source operand (the third operand) to transfer either contiguous or non-contiguous bits in the first source operand (the second operand) to contiguous low order bit positions in the destination (the first operand). For each bit set in the MASK, PEXT extracts the corresponding bits from the first source operand and writes them into contiguous lower bits of destination operand. The remaining upper bits of destination are zeroed.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "TEMP := SRC1;\nMASK := SRC2;\nDEST := 0 ;\nm := 0, k := 0;\nDO WHILE m < OperandSize\n IF MASK[ m] = 1 THEN\n DEST[ k] := TEMP[ m];\n k := k+ 1;\n FI\n m := m+ 1;\nOD\n", + "url": "https://www.felixcloutier.com/x86/pext" + }, + "pextrb": { + "instruction": "PEXTRB", + "title": "PEXTRB/PEXTRD/PEXTRQ\n\t\t— Extract Byte/Dword/Qword", + "opcode": "66 0F 3A 14 /r ib PEXTRB reg/m8, xmm2, imm8", + "description": "Extract a byte/dword/qword integer value from the source XMM register at a byte/dword/qword offset determined from imm8[3:0]. The destination can be a register or byte/dword/qword memory location. If the destination is a register, the upper bits of the register are zero extended.\nIn legacy non-VEX encoded version and if the destination operand is a register, the default operand size in 64-bit mode for PEXTRB/PEXTRD is 64 bits, the bits above the least significant byte/dword data are filled with zeros. PEXTRQ is not encodable in non-64-bit modes and requires REX.W in 64-bit mode.\nNote: In VEX.128 encoded versions, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD. In EVEX.128 encoded versions, EVEX.vvvv is reserved and must be 1111b, EVEX.L”L must be 0, otherwise the instruction will #UD. If the destination operand is a register, the default operand size in 64-bit mode for VPEXTRB/VPEXTRD is 64 bits, the bits above the least significant byte/word/dword data are filled with zeros.", + "operation": "CASE of\n PEXTRB: SEL := COUNT[3:0];\n TEMP := (Src >> SEL*8) AND FFH;\n IF (DEST = Mem8)\n THEN\n Mem8 := TEMP[7:0];\n ELSE IF (64-Bit Mode and 64-bit register selected)\n THEN\n R64[7:0] := TEMP[7:0];\n r64[63:8] := ZERO_FILL; };\n ELSE\n R32[7:0] := TEMP[7:0];\n r32[31:8] := ZERO_FILL; };\n FI;\n PEXTRD:SEL := COUNT[1:0];\n TEMP := (Src >> SEL*32) AND FFFF_FFFFH;\n DEST := TEMP;\n PEXTRQ: SEL := COUNT[0];\n TEMP := (Src >> SEL*64);\n DEST := TEMP;\nEASC:\n\n\nIF (64-Bit Mode and 64-bit dest operand)\nTHEN\n Src_Offset := imm8[0]\n r64/m64 := (Src >> Src_Offset * 64)\nELSE\n Src_Offset := imm8[1:0]\n r32/m32 := ((Src >> Src_Offset *32) AND 0FFFFFFFFh);\nFI\n\n\nSRC_Offset := imm8[3:0]\nMem8 := (Src >> Src_Offset*8)\n\n\nIF (64-Bit Mode )\nTHEN\n SRC_Offset := imm8[3:0]\n DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh)\n DEST[63:8] := ZERO_FILL;\nELSE\n SRC_Offset := imm8[3:0];\n DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh);\n DEST[31:8] := ZERO_FILL;\nFI\n", + "url": "https://www.felixcloutier.com/x86/pextrb:pextrd:pextrq" + }, + "pextrd": { + "instruction": "PEXTRD", + "title": "PEXTRB/PEXTRD/PEXTRQ\n\t\t— Extract Byte/Dword/Qword", + "opcode": "66 0F 3A 14 /r ib PEXTRB reg/m8, xmm2, imm8", + "description": "Extract a byte/dword/qword integer value from the source XMM register at a byte/dword/qword offset determined from imm8[3:0]. The destination can be a register or byte/dword/qword memory location. If the destination is a register, the upper bits of the register are zero extended.\nIn legacy non-VEX encoded version and if the destination operand is a register, the default operand size in 64-bit mode for PEXTRB/PEXTRD is 64 bits, the bits above the least significant byte/dword data are filled with zeros. PEXTRQ is not encodable in non-64-bit modes and requires REX.W in 64-bit mode.\nNote: In VEX.128 encoded versions, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD. In EVEX.128 encoded versions, EVEX.vvvv is reserved and must be 1111b, EVEX.L”L must be 0, otherwise the instruction will #UD. If the destination operand is a register, the default operand size in 64-bit mode for VPEXTRB/VPEXTRD is 64 bits, the bits above the least significant byte/word/dword data are filled with zeros.", + "operation": "CASE of\n PEXTRB: SEL := COUNT[3:0];\n TEMP := (Src >> SEL*8) AND FFH;\n IF (DEST = Mem8)\n THEN\n Mem8 := TEMP[7:0];\n ELSE IF (64-Bit Mode and 64-bit register selected)\n THEN\n R64[7:0] := TEMP[7:0];\n r64[63:8] := ZERO_FILL; };\n ELSE\n R32[7:0] := TEMP[7:0];\n r32[31:8] := ZERO_FILL; };\n FI;\n PEXTRD:SEL := COUNT[1:0];\n TEMP := (Src >> SEL*32) AND FFFF_FFFFH;\n DEST := TEMP;\n PEXTRQ: SEL := COUNT[0];\n TEMP := (Src >> SEL*64);\n DEST := TEMP;\nEASC:\n\n\nIF (64-Bit Mode and 64-bit dest operand)\nTHEN\n Src_Offset := imm8[0]\n r64/m64 := (Src >> Src_Offset * 64)\nELSE\n Src_Offset := imm8[1:0]\n r32/m32 := ((Src >> Src_Offset *32) AND 0FFFFFFFFh);\nFI\n\n\nSRC_Offset := imm8[3:0]\nMem8 := (Src >> Src_Offset*8)\n\n\nIF (64-Bit Mode )\nTHEN\n SRC_Offset := imm8[3:0]\n DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh)\n DEST[63:8] := ZERO_FILL;\nELSE\n SRC_Offset := imm8[3:0];\n DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh);\n DEST[31:8] := ZERO_FILL;\nFI\n", + "url": "https://www.felixcloutier.com/x86/pextrb:pextrd:pextrq" + }, + "pextrq": { + "instruction": "PEXTRQ", + "title": "PEXTRB/PEXTRD/PEXTRQ\n\t\t— Extract Byte/Dword/Qword", + "opcode": "66 0F 3A 14 /r ib PEXTRB reg/m8, xmm2, imm8", + "description": "Extract a byte/dword/qword integer value from the source XMM register at a byte/dword/qword offset determined from imm8[3:0]. The destination can be a register or byte/dword/qword memory location. If the destination is a register, the upper bits of the register are zero extended.\nIn legacy non-VEX encoded version and if the destination operand is a register, the default operand size in 64-bit mode for PEXTRB/PEXTRD is 64 bits, the bits above the least significant byte/dword data are filled with zeros. PEXTRQ is not encodable in non-64-bit modes and requires REX.W in 64-bit mode.\nNote: In VEX.128 encoded versions, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD. In EVEX.128 encoded versions, EVEX.vvvv is reserved and must be 1111b, EVEX.L”L must be 0, otherwise the instruction will #UD. If the destination operand is a register, the default operand size in 64-bit mode for VPEXTRB/VPEXTRD is 64 bits, the bits above the least significant byte/word/dword data are filled with zeros.", + "operation": "CASE of\n PEXTRB: SEL := COUNT[3:0];\n TEMP := (Src >> SEL*8) AND FFH;\n IF (DEST = Mem8)\n THEN\n Mem8 := TEMP[7:0];\n ELSE IF (64-Bit Mode and 64-bit register selected)\n THEN\n R64[7:0] := TEMP[7:0];\n r64[63:8] := ZERO_FILL; };\n ELSE\n R32[7:0] := TEMP[7:0];\n r32[31:8] := ZERO_FILL; };\n FI;\n PEXTRD:SEL := COUNT[1:0];\n TEMP := (Src >> SEL*32) AND FFFF_FFFFH;\n DEST := TEMP;\n PEXTRQ: SEL := COUNT[0];\n TEMP := (Src >> SEL*64);\n DEST := TEMP;\nEASC:\n\n\nIF (64-Bit Mode and 64-bit dest operand)\nTHEN\n Src_Offset := imm8[0]\n r64/m64 := (Src >> Src_Offset * 64)\nELSE\n Src_Offset := imm8[1:0]\n r32/m32 := ((Src >> Src_Offset *32) AND 0FFFFFFFFh);\nFI\n\n\nSRC_Offset := imm8[3:0]\nMem8 := (Src >> Src_Offset*8)\n\n\nIF (64-Bit Mode )\nTHEN\n SRC_Offset := imm8[3:0]\n DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh)\n DEST[63:8] := ZERO_FILL;\nELSE\n SRC_Offset := imm8[3:0];\n DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh);\n DEST[31:8] := ZERO_FILL;\nFI\n", + "url": "https://www.felixcloutier.com/x86/pextrb:pextrd:pextrq" + }, + "pextrw": { + "instruction": "PEXTRW", + "title": "PEXTRW\n\t\t— Extract Word", + "opcode": "NP 0F C5 /r ib1 PEXTRW reg, mm, imm8", + "description": "Copies the word in the source operand (second operand) specified by the count operand (third operand) to the destination operand (first operand). The source operand can be an MMX technology register or an XMM register. The destination operand can be the low word of a general-purpose register or a 16-bit memory address. The count operand is an 8-bit immediate. When specifying a word location in an MMX technology register, the 2 least-significant bits of the count operand specify the location; for an XMM register, the 3 least-significant bits specify the location. The content of the destination register above bit 16 is cleared (set to all 0s).\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15, R8-15). If the destination operand is a general-purpose register, the default operand size is 64-bits in 64-bit mode.\nNote: In VEX.128 encoded versions, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD. In EVEX.128 encoded versions, EVEX.vvvv is reserved and must be 1111b, EVEX.L must be 0, otherwise the instruction will #UD. If the destination operand is a register, the default operand size in 64-bit mode for VPEXTRW is 64 bits, the bits above the least significant byte/word/dword data are filled with zeros.", + "operation": "IF (DEST = Mem16)\nTHEN\n SEL := COUNT[2:0];\n TEMP := (Src >> SEL*16) AND FFFFH;\n Mem16 := TEMP[15:0];\nELSE IF (64-Bit Mode and destination is a general-purpose register)\n THEN\n FOR (PEXTRW instruction with 64-bit source operand)\n { SEL := COUNT[1:0];\n TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;\n r64[15:0] := TEMP[15:0];\n r64[63:16] := ZERO_FILL; };\n FOR (PEXTRW instruction with 128-bit source operand)\n { SEL := COUNT[2:0];\n TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;\n r64[15:0] := TEMP[15:0];\n r64[63:16] := ZERO_FILL; }\n ELSE\n FOR (PEXTRW instruction with 64-bit source operand)\n { SEL := COUNT[1:0];\n TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;\n r32[15:0] := TEMP[15:0];\n r32[31:16] := ZERO_FILL; };\n FOR (PEXTRW instruction with 128-bit source operand)\n { SEL := COUNT[2:0];\n TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;\n r32[15:0] := TEMP[15:0];\n r32[31:16] := ZERO_FILL; };\n FI;\nFI;\n\n\nSRC_Offset := imm8[2:0]\nMem16 := (Src >> Src_Offset*16)\n\n\nIF (64-Bit Mode )\nTHEN\n SRC_Offset := imm8[2:0]\n DEST[15:0] := ((Src >> Src_Offset*16) AND 0FFFFh)\n DEST[63:16] := ZERO_FILL;\nELSE\n SRC_Offset := imm8[2:0]\n DEST[15:0] := ((Src >> Src_Offset*16) AND 0FFFFh)\n DEST[31:16] := ZERO_FILL;\nFI\n", + "url": "https://www.felixcloutier.com/x86/pextrw" + }, + "phaddd": { + "instruction": "PHADDD", + "title": "PHADDW/PHADDD\n\t\t— Packed Horizontal Add", + "opcode": "NP 0F 38 01 /r1 PHADDW mm1, mm2/m64", + "description": "(V)PHADDW adds two adjacent 16-bit signed integers horizontally from the source and destination operands and packs the 16-bit signed results to the destination operand (first operand). (V)PHADDD adds two adjacent 32-bit signed integers horizontally from the source and destination operands and packs the 32-bit signed results to the destination operand (first operand). When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nNote that these instructions can operate on either unsigned or signed (two’s complement notation) integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of the values operated on.\nLegacy SSE instructions: Both operands can be MMX registers. The second source operand can be an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nIn 64-bit mode, use the REX prefix to access additional registers.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: Horizontal addition of two adjacent data elements of the low 16-bytes of the first and second source operands are packed into the low 16-bytes of the destination operand. Horizontal addition of two adjacent data elements of the high 16-bytes of the first and second source operands are packed into the high 16-bytes of the destination operand. The first source and destination operands are YMM registers. The second source operand can be an YMM register or a 256-bit memory location.\nS7 S3 S3 S4 S3 S2 S1 S0", + "operation": "mm1[15-0] = mm1[31-16] + mm1[15-0];\nmm1[31-16] = mm1[63-48] + mm1[47-32];\nmm1[47-32] = mm2/m64[31-16] + mm2/m64[15-0];\nmm1[63-48] = mm2/m64[63-48] + mm2/m64[47-32];\n\n\nxmm1[15-0] = xmm1[31-16] + xmm1[15-0];\nxmm1[31-16] = xmm1[63-48] + xmm1[47-32];\nxmm1[47-32] = xmm1[95-80] + xmm1[79-64];\nxmm1[63-48] = xmm1[127-112] + xmm1[111-96];\nxmm1[79-64] = xmm2/m128[31-16] + xmm2/m128[15-0];\nxmm1[95-80] = xmm2/m128[63-48] + xmm2/m128[47-32];\nxmm1[111-96] = xmm2/m128[95-80] + xmm2/m128[79-64];\nxmm1[127-112] = xmm2/m128[127-112] + xmm2/m128[111-96];\n\n\nDEST[15:0] := SRC1[31:16] + SRC1[15:0]\nDEST[31:16] := SRC1[63:48] + SRC1[47:32]\nDEST[47:32] := SRC1[95:80] + SRC1[79:64]\nDEST[63:48] := SRC1[127:112] + SRC1[111:96]\nDEST[79:64] := SRC2[31:16] + SRC2[15:0]\nDEST[95:80] := SRC2[63:48] + SRC2[47:32]\nDEST[111:96] := SRC2[95:80] + SRC2[79:64]\nDEST[127:112] := SRC2[127:112] + SRC2[111:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SRC1[31:16] + SRC1[15:0]\nDEST[31:16] := SRC1[63:48] + SRC1[47:32]\nDEST[47:32] := SRC1[95:80] + SRC1[79:64]\nDEST[63:48] := SRC1[127:112] + SRC1[111:96]\nDEST[79:64] := SRC2[31:16] + SRC2[15:0]\nDEST[95:80] := SRC2[63:48] + SRC2[47:32]\nDEST[111:96] := SRC2[95:80] + SRC2[79:64]\nDEST[127:112] := SRC2[127:112] + SRC2[111:96]\nDEST[143:128] := SRC1[159:144] + SRC1[143:128]\nDEST[159:144] := SRC1[191:176] + SRC1[175:160]\nDEST[175:160] := SRC1[223:208] + SRC1[207:192]\nDEST[191:176] := SRC1[255:240] + SRC1[239:224]\nDEST[207:192] := SRC2[127:112] + SRC2[143:128]\nDEST[223:208] := SRC2[159:144] + SRC2[175:160]\nDEST[239:224] := SRC2[191:176] + SRC2[207:192]\nDEST[255:240] := SRC2[223:208] + SRC2[239:224]\n\n\nmm1[31-0] = mm1[63-32] + mm1[31-0];\nmm1[63-32] = mm2/m64[63-32] + mm2/m64[31-0];\n\n\nxmm1[31-0] = xmm1[63-32] + xmm1[31-0];\nxmm1[63-32] = xmm1[127-96] + xmm1[95-64];\nxmm1[95-64] = xmm2/m128[63-32] + xmm2/m128[31-0];\nxmm1[127-96] = xmm2/m128[127-96] + xmm2/m128[95-64];\n\n\nDEST[31-0] := SRC1[63-32] + SRC1[31-0]\nDEST[63-32] := SRC1[127-96] + SRC1[95-64]\nDEST[95-64] := SRC2[63-32] + SRC2[31-0]\nDEST[127-96] := SRC2[127-96] + SRC2[95-64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31-0] := SRC1[63-32] + SRC1[31-0]\nDEST[63-32] := SRC1[127-96] + SRC1[95-64]\nDEST[95-64] := SRC2[63-32] + SRC2[31-0]\nDEST[127-96] := SRC2[127-96] + SRC2[95-64]\nDEST[159-128] := SRC1[191-160] + SRC1[159-128]\nDEST[191-160] := SRC1[255-224] + SRC1[223-192]\nDEST[223-192] := SRC2[191-160] + SRC2[159-128]\nDEST[255-224] := SRC2[255-224] + SRC2[223-192]\n", + "url": "https://www.felixcloutier.com/x86/phaddw:phaddd" + }, + "phaddsw": { + "instruction": "PHADDSW", + "title": "PHADDSW\n\t\t— Packed Horizontal Add and Saturate", + "opcode": "NP 0F 38 03 /r1 PHADDSW mm1, mm2/m64", + "description": "(V)PHADDSW adds two adjacent signed 16-bit integers horizontally from the source and destination operands and saturates the signed results; packs the signed, saturated 16-bit results to the destination operand (first operand) When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nLegacy SSE version: Both operands can be MMX registers. The second source operand can be an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nIn 64-bit mode, use the REX prefix to access additional registers.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand can be an YMM register or a 256-bit memory location.", + "operation": "mm1[15-0] = SaturateToSignedWord((mm1[31-16] + mm1[15-0]);\nmm1[31-16] = SaturateToSignedWord(mm1[63-48] + mm1[47-32]);\nmm1[47-32] = SaturateToSignedWord(mm2/m64[31-16] + mm2/m64[15-0]);\nmm1[63-48] = SaturateToSignedWord(mm2/m64[63-48] + mm2/m64[47-32]);\n\n\nxmm1[15-0]= SaturateToSignedWord(xmm1[31-16] + xmm1[15-0]);\nxmm1[31-16] = SaturateToSignedWord(xmm1[63-48] + xmm1[47-32]);\nxmm1[47-32] = SaturateToSignedWord(xmm1[95-80] + xmm1[79-64]);\nxmm1[63-48] = SaturateToSignedWord(xmm1[127-112] + xmm1[111-96]);\nxmm1[79-64] = SaturateToSignedWord(xmm2/m128[31-16] + xmm2/m128[15-0]);\nxmm1[95-80] = SaturateToSignedWord(xmm2/m128[63-48] + xmm2/m128[47-32]);\nxmm1[111-96] = SaturateToSignedWord(xmm2/m128[95-80] + xmm2/m128[79-64]);\nxmm1[127-112] = SaturateToSignedWord(xmm2/m128[127-112] + xmm2/m128[111-96]);\n\n\nDEST[15:0]= SaturateToSignedWord(SRC1[31:16] + SRC1[15:0])\nDEST[31:16] = SaturateToSignedWord(SRC1[63:48] + SRC1[47:32])\nDEST[47:32] = SaturateToSignedWord(SRC1[95:80] + SRC1[79:64])\nDEST[63:48] = SaturateToSignedWord(SRC1[127:112] + SRC1[111:96])\nDEST[79:64] = SaturateToSignedWord(SRC2[31:16] + SRC2[15:0])\nDEST[95:80] = SaturateToSignedWord(SRC2[63:48] + SRC2[47:32])\nDEST[111:96] = SaturateToSignedWord(SRC2[95:80] + SRC2[79:64])\nDEST[127:112] = SaturateToSignedWord(SRC2[127:112] + SRC2[111:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0]= SaturateToSignedWord(SRC1[31:16] + SRC1[15:0])\nDEST[31:16] = SaturateToSignedWord(SRC1[63:48] + SRC1[47:32])\nDEST[47:32] = SaturateToSignedWord(SRC1[95:80] + SRC1[79:64])\nDEST[63:48] = SaturateToSignedWord(SRC1[127:112] + SRC1[111:96])\nDEST[79:64] = SaturateToSignedWord(SRC2[31:16] + SRC2[15:0])\nDEST[95:80] = SaturateToSignedWord(SRC2[63:48] + SRC2[47:32])\nDEST[111:96] = SaturateToSignedWord(SRC2[95:80] + SRC2[79:64])\nDEST[127:112] = SaturateToSignedWord(SRC2[127:112] + SRC2[111:96])\nDEST[143:128]= SaturateToSignedWord(SRC1[159:144] + SRC1[143:128])\nDEST[159:144] = SaturateToSignedWord(SRC1[191:176] + SRC1[175:160])\nDEST[175:160] = SaturateToSignedWord( SRC1[223:208] + SRC1[207:192])\nDEST[191:176] = SaturateToSignedWord(SRC1[255:240] + SRC1[239:224])\nDEST[207:192] = SaturateToSignedWord(SRC2[127:112] + SRC2[143:128])\nDEST[223:208] = SaturateToSignedWord(SRC2[159:144] + SRC2[175:160])\nDEST[239:224] = SaturateToSignedWord(SRC2[191-160] + SRC2[159-128])\nDEST[255:240] = SaturateToSignedWord(SRC2[255:240] + SRC2[239:224])\n", + "url": "https://www.felixcloutier.com/x86/phaddsw" + }, + "phaddw": { + "instruction": "PHADDW", + "title": "PHADDW/PHADDD\n\t\t— Packed Horizontal Add", + "opcode": "NP 0F 38 01 /r1 PHADDW mm1, mm2/m64", + "description": "(V)PHADDW adds two adjacent 16-bit signed integers horizontally from the source and destination operands and packs the 16-bit signed results to the destination operand (first operand). (V)PHADDD adds two adjacent 32-bit signed integers horizontally from the source and destination operands and packs the 32-bit signed results to the destination operand (first operand). When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nNote that these instructions can operate on either unsigned or signed (two’s complement notation) integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of the values operated on.\nLegacy SSE instructions: Both operands can be MMX registers. The second source operand can be an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nIn 64-bit mode, use the REX prefix to access additional registers.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: Horizontal addition of two adjacent data elements of the low 16-bytes of the first and second source operands are packed into the low 16-bytes of the destination operand. Horizontal addition of two adjacent data elements of the high 16-bytes of the first and second source operands are packed into the high 16-bytes of the destination operand. The first source and destination operands are YMM registers. The second source operand can be an YMM register or a 256-bit memory location.\nS7 S3 S3 S4 S3 S2 S1 S0", + "operation": "mm1[15-0] = mm1[31-16] + mm1[15-0];\nmm1[31-16] = mm1[63-48] + mm1[47-32];\nmm1[47-32] = mm2/m64[31-16] + mm2/m64[15-0];\nmm1[63-48] = mm2/m64[63-48] + mm2/m64[47-32];\n\n\nxmm1[15-0] = xmm1[31-16] + xmm1[15-0];\nxmm1[31-16] = xmm1[63-48] + xmm1[47-32];\nxmm1[47-32] = xmm1[95-80] + xmm1[79-64];\nxmm1[63-48] = xmm1[127-112] + xmm1[111-96];\nxmm1[79-64] = xmm2/m128[31-16] + xmm2/m128[15-0];\nxmm1[95-80] = xmm2/m128[63-48] + xmm2/m128[47-32];\nxmm1[111-96] = xmm2/m128[95-80] + xmm2/m128[79-64];\nxmm1[127-112] = xmm2/m128[127-112] + xmm2/m128[111-96];\n\n\nDEST[15:0] := SRC1[31:16] + SRC1[15:0]\nDEST[31:16] := SRC1[63:48] + SRC1[47:32]\nDEST[47:32] := SRC1[95:80] + SRC1[79:64]\nDEST[63:48] := SRC1[127:112] + SRC1[111:96]\nDEST[79:64] := SRC2[31:16] + SRC2[15:0]\nDEST[95:80] := SRC2[63:48] + SRC2[47:32]\nDEST[111:96] := SRC2[95:80] + SRC2[79:64]\nDEST[127:112] := SRC2[127:112] + SRC2[111:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SRC1[31:16] + SRC1[15:0]\nDEST[31:16] := SRC1[63:48] + SRC1[47:32]\nDEST[47:32] := SRC1[95:80] + SRC1[79:64]\nDEST[63:48] := SRC1[127:112] + SRC1[111:96]\nDEST[79:64] := SRC2[31:16] + SRC2[15:0]\nDEST[95:80] := SRC2[63:48] + SRC2[47:32]\nDEST[111:96] := SRC2[95:80] + SRC2[79:64]\nDEST[127:112] := SRC2[127:112] + SRC2[111:96]\nDEST[143:128] := SRC1[159:144] + SRC1[143:128]\nDEST[159:144] := SRC1[191:176] + SRC1[175:160]\nDEST[175:160] := SRC1[223:208] + SRC1[207:192]\nDEST[191:176] := SRC1[255:240] + SRC1[239:224]\nDEST[207:192] := SRC2[127:112] + SRC2[143:128]\nDEST[223:208] := SRC2[159:144] + SRC2[175:160]\nDEST[239:224] := SRC2[191:176] + SRC2[207:192]\nDEST[255:240] := SRC2[223:208] + SRC2[239:224]\n\n\nmm1[31-0] = mm1[63-32] + mm1[31-0];\nmm1[63-32] = mm2/m64[63-32] + mm2/m64[31-0];\n\n\nxmm1[31-0] = xmm1[63-32] + xmm1[31-0];\nxmm1[63-32] = xmm1[127-96] + xmm1[95-64];\nxmm1[95-64] = xmm2/m128[63-32] + xmm2/m128[31-0];\nxmm1[127-96] = xmm2/m128[127-96] + xmm2/m128[95-64];\n\n\nDEST[31-0] := SRC1[63-32] + SRC1[31-0]\nDEST[63-32] := SRC1[127-96] + SRC1[95-64]\nDEST[95-64] := SRC2[63-32] + SRC2[31-0]\nDEST[127-96] := SRC2[127-96] + SRC2[95-64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31-0] := SRC1[63-32] + SRC1[31-0]\nDEST[63-32] := SRC1[127-96] + SRC1[95-64]\nDEST[95-64] := SRC2[63-32] + SRC2[31-0]\nDEST[127-96] := SRC2[127-96] + SRC2[95-64]\nDEST[159-128] := SRC1[191-160] + SRC1[159-128]\nDEST[191-160] := SRC1[255-224] + SRC1[223-192]\nDEST[223-192] := SRC2[191-160] + SRC2[159-128]\nDEST[255-224] := SRC2[255-224] + SRC2[223-192]\n", + "url": "https://www.felixcloutier.com/x86/phaddw:phaddd" + }, + "phminposuw": { + "instruction": "PHMINPOSUW", + "title": "PHMINPOSUW\n\t\t— Packed Horizontal Word Minimum", + "opcode": "66 0F 38 41 /r PHMINPOSUW xmm1, xmm2/m128", + "description": "Determine the minimum unsigned word value in the source operand (second operand) and place the unsigned word in the low word (bits 0-15) of the destination operand (first operand). The word index of the minimum value is stored in bits 16-18 of the destination operand. The remaining upper bits of the destination are set to zero.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding XMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination XMM register are zeroed. VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD.", + "operation": "INDEX := 0;\nMIN := SRC[15:0]\nIF (SRC[31:16] < MIN)\n THEN INDEX := 1; MIN := SRC[31:16]; FI;\nIF (SRC[47:32] < MIN)\n THEN INDEX := 2; MIN := SRC[47:32]; FI;\n* Repeat operation for words 3 through 6\nIF (SRC[127:112] < MIN)\n THEN INDEX := 7; MIN := SRC[127:112]; FI;\nDEST[15:0] := MIN;\nDEST[18:16] := INDEX;\nDEST[127:19] := 0000000000000000000000000000H;\n\n\nINDEX := 0\nMIN := SRC[15:0]\nIF (SRC[31:16] < MIN) THEN INDEX := 1; MIN := SRC[31:16]\nIF (SRC[47:32] < MIN) THEN INDEX := 2; MIN := SRC[47:32]\n* Repeat operation for words 3 through 6\nIF (SRC[127:112] < MIN) THEN INDEX := 7; MIN := SRC[127:112]\nDEST[15:0] := MIN\nDEST[18:16] := INDEX\nDEST[127:19] := 0000000000000000000000000000H\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/phminposuw" + }, + "phsubd": { + "instruction": "PHSUBD", + "title": "PHSUBW/PHSUBD\n\t\t— Packed Horizontal Subtract", + "opcode": "NP 0F 38 05 /r1 PHSUBW mm1, mm2/m64", + "description": "(V)PHSUBW performs horizontal subtraction on each adjacent pair of 16-bit signed integers by subtracting the most significant word from the least significant word of each pair in the source and destination operands, and packs the signed 16-bit results to the destination operand (first operand). (V)PHSUBD performs horizontal subtraction on each adjacent pair of 32-bit signed integers by subtracting the most significant doubleword from the least significant doubleword of each pair, and packs the signed 32-bit result to the destination operand. When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nLegacy SSE version: Both operands can be MMX registers. The second source operand can be an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nIn 64-bit mode, use the REX prefix to access additional registers.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand can be an YMM register or a 256-bit memory location.", + "operation": "mm1[15-0] = mm1[15-0] - mm1[31-16];\nmm1[31-16] = mm1[47-32] - mm1[63-48];\nmm1[47-32] = mm2/m64[15-0] - mm2/m64[31-16];\nmm1[63-48] = mm2/m64[47-32] - mm2/m64[63-48];\n\n\nxmm1[15-0] = xmm1[15-0] - xmm1[31-16];\nxmm1[31-16] = xmm1[47-32] - xmm1[63-48];\nxmm1[47-32] = xmm1[79-64] - xmm1[95-80];\nxmm1[63-48] = xmm1[111-96] - xmm1[127-112];\nxmm1[79-64] = xmm2/m128[15-0] - xmm2/m128[31-16];\nxmm1[95-80] = xmm2/m128[47-32] - xmm2/m128[63-48];\nxmm1[111-96] = xmm2/m128[79-64] - xmm2/m128[95-80];\nxmm1[127-112] = xmm2/m128[111-96] - xmm2/m128[127-112];\n\n\nDEST[15:0] := SRC1[15:0] - SRC1[31:16]\nDEST[31:16] := SRC1[47:32] - SRC1[63:48]\nDEST[47:32] := SRC1[79:64] - SRC1[95:80]\nDEST[63:48] := SRC1[111:96] - SRC1[127:112]\nDEST[79:64] := SRC2[15:0] - SRC2[31:16]\nDEST[95:80] := SRC2[47:32] - SRC2[63:48]\nDEST[111:96] := SRC2[79:64] - SRC2[95:80]\nDEST[127:112] := SRC2[111:96] - SRC2[127:112]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SRC1[15:0] - SRC1[31:16]\nDEST[31:16] := SRC1[47:32] - SRC1[63:48]\nDEST[47:32] := SRC1[79:64] - SRC1[95:80]\nDEST[63:48] := SRC1[111:96] - SRC1[127:112]\nDEST[79:64] := SRC2[15:0] - SRC2[31:16]\nDEST[95:80] := SRC2[47:32] - SRC2[63:48]\nDEST[111:96] := SRC2[79:64] - SRC2[95:80]\nDEST[127:112] := SRC2[111:96] - SRC2[127:112]\nDEST[143:128] := SRC1[143:128] - SRC1[159:144]\nDEST[159:144] := SRC1[175:160] - SRC1[191:176]\nDEST[175:160] := SRC1[207:192] - SRC1[223:208]\nDEST[191:176] := SRC1[239:224] - SRC1[255:240]\nDEST[207:192] := SRC2[143:128] - SRC2[159:144]\nDEST[223:208] := SRC2[175:160] - SRC2[191:176]\nDEST[239:224] := SRC2[207:192] - SRC2[223:208]\nDEST[255:240] := SRC2[239:224] - SRC2[255:240]\n\n\nmm1[31-0] = mm1[31-0] - mm1[63-32];\nmm1[63-32] = mm2/m64[31-0] - mm2/m64[63-32];\n\n\nxmm1[31-0] = xmm1[31-0] - xmm1[63-32];\nxmm1[63-32] = xmm1[95-64] - xmm1[127-96];\nxmm1[95-64] = xmm2/m128[31-0] - xmm2/m128[63-32];\nxmm1[127-96] = xmm2/m128[95-64] - xmm2/m128[127-96];\n\n\nDEST[31-0] := SRC1[31-0] - SRC1[63-32]\nDEST[63-32] := SRC1[95-64] - SRC1[127-96]\nDEST[95-64] := SRC2[31-0] - SRC2[63-32]\nDEST[127-96] := SRC2[95-64] - SRC2[127-96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC1[63:32]\nDEST[63:32] := SRC1[95:64] - SRC1[127:96]\nDEST[95:64] := SRC2[31:0] - SRC2[63:32]\nDEST[127:96] := SRC2[95:64] - SRC2[127:96]\nDEST[159:128] := SRC1[159:128] - SRC1[191:160]\nDEST[191:160] := SRC1[223:192] - SRC1[255:224]\nDEST[223:192] := SRC2[159:128] - SRC2[191:160]\nDEST[255:224] := SRC2[223:192] - SRC2[255:224]\n", + "url": "https://www.felixcloutier.com/x86/phsubw:phsubd" + }, + "phsubsw": { + "instruction": "PHSUBSW", + "title": "PHSUBSW\n\t\t— Packed Horizontal Subtract and Saturate", + "opcode": "NP 0F 38 07 /r1 PHSUBSW mm1, mm2/m64", + "description": "(V)PHSUBSW performs horizontal subtraction on each adjacent pair of 16-bit signed integers by subtracting the most significant word from the least significant word of each pair in the source and destination operands. The signed, saturated 16-bit results are packed to the destination operand (first operand). When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nLegacy SSE version: Both operands can be MMX registers. The second source operand can be an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nIn 64-bit mode, use the REX prefix to access additional registers.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand can be an YMM register or a 256-bit memory location.", + "operation": "mm1[15-0] = SaturateToSignedWord(mm1[15-0] - mm1[31-16]);\nmm1[31-16] = SaturateToSignedWord(mm1[47-32] - mm1[63-48]);\nmm1[47-32] = SaturateToSignedWord(mm2/m64[15-0] - mm2/m64[31-16]);\nmm1[63-48] = SaturateToSignedWord(mm2/m64[47-32] - mm2/m64[63-48]);\n\n\nxmm1[15-0] = SaturateToSignedWord(xmm1[15-0] - xmm1[31-16]);\nxmm1[31-16] = SaturateToSignedWord(xmm1[47-32] - xmm1[63-48]);\nxmm1[47-32] = SaturateToSignedWord(xmm1[79-64] - xmm1[95-80]);\nxmm1[63-48] = SaturateToSignedWord(xmm1[111-96] - xmm1[127-112]);\nxmm1[79-64] = SaturateToSignedWord(xmm2/m128[15-0] - xmm2/m128[31-16]);\nxmm1[95-80] =SaturateToSignedWord(xmm2/m128[47-32] - xmm2/m128[63-48]);\nxmm1[111-96] =SaturateToSignedWord(xmm2/m128[79-64] - xmm2/m128[95-80]);\nxmm1[127-112]= SaturateToSignedWord(xmm2/m128[111-96] - xmm2/m128[127-112]);\n\n\nDEST[15:0]= SaturateToSignedWord(SRC1[15:0] - SRC1[31:16])\nDEST[31:16] = SaturateToSignedWord(SRC1[47:32] - SRC1[63:48])\nDEST[47:32] = SaturateToSignedWord(SRC1[79:64] - SRC1[95:80])\nDEST[63:48] = SaturateToSignedWord(SRC1[111:96] - SRC1[127:112])\nDEST[79:64] = SaturateToSignedWord(SRC2[15:0] - SRC2[31:16])\nDEST[95:80] = SaturateToSignedWord(SRC2[47:32] - SRC2[63:48])\nDEST[111:96] = SaturateToSignedWord(SRC2[79:64] - SRC2[95:80])\nDEST[127:112] = SaturateToSignedWord(SRC2[111:96] - SRC2[127:112])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0]= SaturateToSignedWord(SRC1[15:0] - SRC1[31:16])\nDEST[31:16] = SaturateToSignedWord(SRC1[47:32] - SRC1[63:48])\nDEST[47:32] = SaturateToSignedWord(SRC1[79:64] - SRC1[95:80])\nDEST[63:48] = SaturateToSignedWord(SRC1[111:96] - SRC1[127:112])\nDEST[79:64] = SaturateToSignedWord(SRC2[15:0] - SRC2[31:16])\nDEST[95:80] = SaturateToSignedWord(SRC2[47:32] - SRC2[63:48])\nDEST[111:96] = SaturateToSignedWord(SRC2[79:64] - SRC2[95:80])\nDEST[127:112] = SaturateToSignedWord(SRC2[111:96] - SRC2[127:112])\nDEST[143:128]= SaturateToSignedWord(SRC1[143:128] - SRC1[159:144])\nDEST[159:144] = SaturateToSignedWord(SRC1[175:160] - SRC1[191:176])\nDEST[175:160] = SaturateToSignedWord(SRC1[207:192] - SRC1[223:208])\nDEST[191:176] = SaturateToSignedWord(SRC1[239:224] - SRC1[255:240])\nDEST[207:192] = SaturateToSignedWord(SRC2[143:128] - SRC2[159:144])\nDEST[223:208] = SaturateToSignedWord(SRC2[175:160] - SRC2[191:176])\nDEST[239:224] = SaturateToSignedWord(SRC2[207:192] - SRC2[223:208])\nDEST[255:240] = SaturateToSignedWord(SRC2[239:224] - SRC2[255:240])\n", + "url": "https://www.felixcloutier.com/x86/phsubsw" + }, + "phsubw": { + "instruction": "PHSUBW", + "title": "PHSUBW/PHSUBD\n\t\t— Packed Horizontal Subtract", + "opcode": "NP 0F 38 05 /r1 PHSUBW mm1, mm2/m64", + "description": "(V)PHSUBW performs horizontal subtraction on each adjacent pair of 16-bit signed integers by subtracting the most significant word from the least significant word of each pair in the source and destination operands, and packs the signed 16-bit results to the destination operand (first operand). (V)PHSUBD performs horizontal subtraction on each adjacent pair of 32-bit signed integers by subtracting the most significant doubleword from the least significant doubleword of each pair, and packs the signed 32-bit result to the destination operand. When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nLegacy SSE version: Both operands can be MMX registers. The second source operand can be an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nIn 64-bit mode, use the REX prefix to access additional registers.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand can be an YMM register or a 256-bit memory location.", + "operation": "mm1[15-0] = mm1[15-0] - mm1[31-16];\nmm1[31-16] = mm1[47-32] - mm1[63-48];\nmm1[47-32] = mm2/m64[15-0] - mm2/m64[31-16];\nmm1[63-48] = mm2/m64[47-32] - mm2/m64[63-48];\n\n\nxmm1[15-0] = xmm1[15-0] - xmm1[31-16];\nxmm1[31-16] = xmm1[47-32] - xmm1[63-48];\nxmm1[47-32] = xmm1[79-64] - xmm1[95-80];\nxmm1[63-48] = xmm1[111-96] - xmm1[127-112];\nxmm1[79-64] = xmm2/m128[15-0] - xmm2/m128[31-16];\nxmm1[95-80] = xmm2/m128[47-32] - xmm2/m128[63-48];\nxmm1[111-96] = xmm2/m128[79-64] - xmm2/m128[95-80];\nxmm1[127-112] = xmm2/m128[111-96] - xmm2/m128[127-112];\n\n\nDEST[15:0] := SRC1[15:0] - SRC1[31:16]\nDEST[31:16] := SRC1[47:32] - SRC1[63:48]\nDEST[47:32] := SRC1[79:64] - SRC1[95:80]\nDEST[63:48] := SRC1[111:96] - SRC1[127:112]\nDEST[79:64] := SRC2[15:0] - SRC2[31:16]\nDEST[95:80] := SRC2[47:32] - SRC2[63:48]\nDEST[111:96] := SRC2[79:64] - SRC2[95:80]\nDEST[127:112] := SRC2[111:96] - SRC2[127:112]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SRC1[15:0] - SRC1[31:16]\nDEST[31:16] := SRC1[47:32] - SRC1[63:48]\nDEST[47:32] := SRC1[79:64] - SRC1[95:80]\nDEST[63:48] := SRC1[111:96] - SRC1[127:112]\nDEST[79:64] := SRC2[15:0] - SRC2[31:16]\nDEST[95:80] := SRC2[47:32] - SRC2[63:48]\nDEST[111:96] := SRC2[79:64] - SRC2[95:80]\nDEST[127:112] := SRC2[111:96] - SRC2[127:112]\nDEST[143:128] := SRC1[143:128] - SRC1[159:144]\nDEST[159:144] := SRC1[175:160] - SRC1[191:176]\nDEST[175:160] := SRC1[207:192] - SRC1[223:208]\nDEST[191:176] := SRC1[239:224] - SRC1[255:240]\nDEST[207:192] := SRC2[143:128] - SRC2[159:144]\nDEST[223:208] := SRC2[175:160] - SRC2[191:176]\nDEST[239:224] := SRC2[207:192] - SRC2[223:208]\nDEST[255:240] := SRC2[239:224] - SRC2[255:240]\n\n\nmm1[31-0] = mm1[31-0] - mm1[63-32];\nmm1[63-32] = mm2/m64[31-0] - mm2/m64[63-32];\n\n\nxmm1[31-0] = xmm1[31-0] - xmm1[63-32];\nxmm1[63-32] = xmm1[95-64] - xmm1[127-96];\nxmm1[95-64] = xmm2/m128[31-0] - xmm2/m128[63-32];\nxmm1[127-96] = xmm2/m128[95-64] - xmm2/m128[127-96];\n\n\nDEST[31-0] := SRC1[31-0] - SRC1[63-32]\nDEST[63-32] := SRC1[95-64] - SRC1[127-96]\nDEST[95-64] := SRC2[31-0] - SRC2[63-32]\nDEST[127-96] := SRC2[95-64] - SRC2[127-96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC1[63:32]\nDEST[63:32] := SRC1[95:64] - SRC1[127:96]\nDEST[95:64] := SRC2[31:0] - SRC2[63:32]\nDEST[127:96] := SRC2[95:64] - SRC2[127:96]\nDEST[159:128] := SRC1[159:128] - SRC1[191:160]\nDEST[191:160] := SRC1[223:192] - SRC1[255:224]\nDEST[223:192] := SRC2[159:128] - SRC2[191:160]\nDEST[255:224] := SRC2[223:192] - SRC2[255:224]\n", + "url": "https://www.felixcloutier.com/x86/phsubw:phsubd" + }, + "pinsrb": { + "instruction": "PINSRB", + "title": "PINSRB/PINSRD/PINSRQ\n\t\t— Insert Byte/Dword/Qword", + "opcode": "66 0F 3A 20 /r ib PINSRB xmm1, r32/m8, imm8", + "description": "Copies a byte/dword/qword from the source operand (second operand) and inserts it in the destination operand (first operand) at the location specified with the count operand (third operand). (The other elements in the destination register are left untouched.) The source operand can be a general-purpose register or a memory location. (When the source operand is a general-purpose register, PINSRB copies the low byte of the register.) The destination operand is an XMM register. The count operand is an 8-bit immediate. When specifying a qword[dword, byte] location in an XMM register, the [2, 4] least-significant bit(s) of the count operand specify the location.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15, R8-15). Use of REX.W permits the use of 64 bit general purpose registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. VEX.L must be 0, otherwise the instruction will #UD. Attempt to execute VPINSRQ in non-64-bit mode will cause #UD.\nEVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. EVEX.L’L must be 0, otherwise the instruction will #UD.", + "operation": "CASE OF\n PINSRB: SEL:=COUNT[3:0];\n MASK := (0FFH << (SEL * 8));\n TEMP := (((SRC[7:0] << (SEL *8)) AND MASK);\n PINSRD: SEL := COUNT[1:0];\n MASK := (0FFFFFFFFH << (SEL * 32));\n TEMP := (((SRC << (SEL *32)) AND MASK) ;\n PINSRQ: SEL:=COUNT[0]\n MASK := (0FFFFFFFFFFFFFFFFH << (SEL * 64));\n TEMP := (((SRC << (SEL *64)) AND MASK) ;\nESAC;\n DEST := ((DEST AND NOT MASK) OR TEMP);\n\n\nSEL := imm8[3:0]\nDEST[127:0] := write_b_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n\n\nSEL := imm8[1:0]\nDEST[127:0] := write_d_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n\n\nSEL := imm8[0]\nDEST[127:0] := write_q_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/pinsrb:pinsrd:pinsrq" + }, + "pinsrd": { + "instruction": "PINSRD", + "title": "PINSRB/PINSRD/PINSRQ\n\t\t— Insert Byte/Dword/Qword", + "opcode": "66 0F 3A 20 /r ib PINSRB xmm1, r32/m8, imm8", + "description": "Copies a byte/dword/qword from the source operand (second operand) and inserts it in the destination operand (first operand) at the location specified with the count operand (third operand). (The other elements in the destination register are left untouched.) The source operand can be a general-purpose register or a memory location. (When the source operand is a general-purpose register, PINSRB copies the low byte of the register.) The destination operand is an XMM register. The count operand is an 8-bit immediate. When specifying a qword[dword, byte] location in an XMM register, the [2, 4] least-significant bit(s) of the count operand specify the location.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15, R8-15). Use of REX.W permits the use of 64 bit general purpose registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. VEX.L must be 0, otherwise the instruction will #UD. Attempt to execute VPINSRQ in non-64-bit mode will cause #UD.\nEVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. EVEX.L’L must be 0, otherwise the instruction will #UD.", + "operation": "CASE OF\n PINSRB: SEL:=COUNT[3:0];\n MASK := (0FFH << (SEL * 8));\n TEMP := (((SRC[7:0] << (SEL *8)) AND MASK);\n PINSRD: SEL := COUNT[1:0];\n MASK := (0FFFFFFFFH << (SEL * 32));\n TEMP := (((SRC << (SEL *32)) AND MASK) ;\n PINSRQ: SEL:=COUNT[0]\n MASK := (0FFFFFFFFFFFFFFFFH << (SEL * 64));\n TEMP := (((SRC << (SEL *64)) AND MASK) ;\nESAC;\n DEST := ((DEST AND NOT MASK) OR TEMP);\n\n\nSEL := imm8[3:0]\nDEST[127:0] := write_b_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n\n\nSEL := imm8[1:0]\nDEST[127:0] := write_d_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n\n\nSEL := imm8[0]\nDEST[127:0] := write_q_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/pinsrb:pinsrd:pinsrq" + }, + "pinsrq": { + "instruction": "PINSRQ", + "title": "PINSRB/PINSRD/PINSRQ\n\t\t— Insert Byte/Dword/Qword", + "opcode": "66 0F 3A 20 /r ib PINSRB xmm1, r32/m8, imm8", + "description": "Copies a byte/dword/qword from the source operand (second operand) and inserts it in the destination operand (first operand) at the location specified with the count operand (third operand). (The other elements in the destination register are left untouched.) The source operand can be a general-purpose register or a memory location. (When the source operand is a general-purpose register, PINSRB copies the low byte of the register.) The destination operand is an XMM register. The count operand is an 8-bit immediate. When specifying a qword[dword, byte] location in an XMM register, the [2, 4] least-significant bit(s) of the count operand specify the location.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15, R8-15). Use of REX.W permits the use of 64 bit general purpose registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. VEX.L must be 0, otherwise the instruction will #UD. Attempt to execute VPINSRQ in non-64-bit mode will cause #UD.\nEVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed. EVEX.L’L must be 0, otherwise the instruction will #UD.", + "operation": "CASE OF\n PINSRB: SEL:=COUNT[3:0];\n MASK := (0FFH << (SEL * 8));\n TEMP := (((SRC[7:0] << (SEL *8)) AND MASK);\n PINSRD: SEL := COUNT[1:0];\n MASK := (0FFFFFFFFH << (SEL * 32));\n TEMP := (((SRC << (SEL *32)) AND MASK) ;\n PINSRQ: SEL:=COUNT[0]\n MASK := (0FFFFFFFFFFFFFFFFH << (SEL * 64));\n TEMP := (((SRC << (SEL *64)) AND MASK) ;\nESAC;\n DEST := ((DEST AND NOT MASK) OR TEMP);\n\n\nSEL := imm8[3:0]\nDEST[127:0] := write_b_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n\n\nSEL := imm8[1:0]\nDEST[127:0] := write_d_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n\n\nSEL := imm8[0]\nDEST[127:0] := write_q_element(SEL, SRC2, SRC1)\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/pinsrb:pinsrd:pinsrq" + }, + "pinsrw": { + "instruction": "PINSRW", + "title": "PINSRW\n\t\t— Insert Word", + "opcode": "NP 0F C4 /r ib1 PINSRW mm, r32/m16, imm8", + "description": "Three operand MMX and SSE instructions:\nCopies a word from the source operand and inserts it in the destination operand at the location specified with the count operand. (The other words in the destination register are left untouched.) The source operand can be a general-purpose register or a 16-bit memory location. (When the source operand is a general-purpose register, the low word of the register is copied.) The destination operand can be an MMX technology register or an XMM register. The count operand is an 8-bit immediate. When specifying a word location in an MMX technology register, the 2 least-significant bits of the count operand specify the location; for an XMM register, the 3 least-significant bits specify the location.\nBits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nFour operand AVX and AVX-512 instructions:\nCombines a word from the first source operand with the second source operand, and inserts it in the destination operand at the location specified with the count operand. The second source operand can be a general-purpose register or a 16-bit memory location. (When the source operand is a general-purpose register, the low word of the register is copied.) The first source and destination operands are XMM registers. The count operand is an 8-bit immediate. When specifying a word location, the 3 least-significant bits specify the location.\nBits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L/EVEX.L’L must be 0, otherwise the instruction will #UD.", + "operation": "SEL := imm8[1:0]\nDEST.word[SEL] := src.word[0]\n\n\nSEL := imm8[2:0]\nDEST.word[SEL] := src.word[0]\n\n\nSEL := imm8[2:0]\nDEST := src1\nDEST.word[SEL] := src2.word[0]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/pinsrw" + }, + "pmaddubsw": { + "instruction": "PMADDUBSW", + "title": "PMADDUBSW\n\t\t— Multiply and Add Packed Signed and Unsigned Bytes", + "opcode": "NP 0F 38 04 /r1 PMADDUBSW mm1, mm2/m64", + "description": "(V)PMADDUBSW multiplies vertically each unsigned byte of the destination operand (first operand) with the corresponding signed byte of the source operand (second operand), producing intermediate signed 16-bit integers. Each adjacent pair of signed words is added and the saturated result is packed to the destination operand. For example, the lowest-order bytes (bits 7-0) in the source and destination operands are multiplied and the intermediate signed word result is added with the corresponding intermediate result from the 2nd lowest-order bytes (bits 15-8) of the operands; the sign-saturated result is stored in the lowest word of the destination register (15-0). The same operation is performed on the other pairs of adjacent bytes. Both operands can be MMX register or XMM registers. When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nIn 64-bit mode and not encoded with VEX/EVEX, use the REX prefix to access XMM8-XMM15.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX.128 encoded versions: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 and EVEX.256 encoded versions: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX.512 encoded version: The second source operand can be an ZMM register or a 512-bit memory location. The first source and destination operands are ZMM registers.", + "operation": "DEST[15-0] = SaturateToSignedWord(SRC[15-8]*DEST[15-8]+SRC[7-0]*DEST[7-0]);\nDEST[31-16] = SaturateToSignedWord(SRC[31-24]*DEST[31-24]+SRC[23-16]*DEST[23-16]);\nDEST[47-32] = SaturateToSignedWord(SRC[47-40]*DEST[47-40]+SRC[39-32]*DEST[39-32]);\nDEST[63-48] = SaturateToSignedWord(SRC[63-56]*DEST[63-56]+SRC[55-48]*DEST[55-48]);\n\n\nDEST[15-0] = SaturateToSignedWord(SRC[15-8]* DEST[15-8]+SRC[7-0]*DEST[7-0]);\n// Repeat operation for 2nd through 7th word\nSRC1/DEST[127-112] = SaturateToSignedWord(SRC[127-120]*DEST[127-120]+ SRC[119-112]* DEST[119-112]);\n\n\nDEST[15:0] := SaturateToSignedWord(SRC2[15:8]* SRC1[15:8]+SRC2[7:0]*SRC1[7:0])\n// Repeat operation for 2nd through 7th word\nDEST[127:112] := SaturateToSignedWord(SRC2[127:120]*SRC1[127:120]+ SRC2[119:112]* SRC1[119:112])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToSignedWord(SRC2[15:8]* SRC1[15:8]+SRC2[7:0]*SRC1[7:0])\n// Repeat operation for 2nd through 15th word\nDEST[255:240] := SaturateToSignedWord(SRC2[255:248]*SRC1[255:248]+ SRC2[247:240]* SRC1[247:240])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToSignedWord(SRC2[i+15:i+8]* SRC1[i+15:i+8] + SRC2[i+7:i]*SRC1[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaddubsw" + }, + "pmaddwd": { + "instruction": "PMADDWD", + "title": "PMADDWD\n\t\t— Multiply and Add Packed Integers", + "opcode": "NP 0F F5 /r1 PMADDWD mm, mm/m64", + "description": "Multiplies the individual signed words of the destination operand (first operand) by the corresponding signed words of the source operand (second operand), producing temporary signed, doubleword results. The adjacent double-word results are then summed and stored in the destination operand. For example, the corresponding low-order words (15-0) and (31-16) in the source and destination operands are multiplied by one another and the double-word results are added together and stored in the low doubleword of the destination register (31-0). The same operation is performed on the other pairs of adjacent words. (Figure 4-11 shows this operation when using 64-bit operands).\nThe (V)PMADDWD instruction wraps around only in one situation: when the 2 pairs of words being operated on in a group are all 8000H. In this case, the result wraps around to 80000000H.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version: The first source and destination operands are MMX registers. The second source operand is an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX.512 encoded version: The second source operand can be an ZMM register or a 512-bit memory location. The first source and destination operands are ZMM registers.", + "operation": "DEST[31:0] := (DEST[15:0] ∗ SRC[15:0]) + (DEST[31:16] ∗ SRC[31:16]);\nDEST[63:32] := (DEST[47:32] ∗ SRC[47:32]) + (DEST[63:48] ∗ SRC[63:48]);\n\n\nDEST[31:0] := (DEST[15:0] ∗ SRC[15:0]) + (DEST[31:16] ∗ SRC[31:16]);\nDEST[63:32] := (DEST[47:32] ∗ SRC[47:32]) + (DEST[63:48] ∗ SRC[63:48]);\nDEST[95:64] := (DEST[79:64] ∗ SRC[79:64]) + (DEST[95:80] ∗ SRC[95:80]);\nDEST[127:96] := (DEST[111:96] ∗ SRC[111:96]) + (DEST[127:112] ∗ SRC[127:112]);\n\n\nDEST[31:0] := (SRC1[15:0] * SRC2[15:0]) + (SRC1[31:16] * SRC2[31:16])\nDEST[63:32] := (SRC1[47:32] * SRC2[47:32]) + (SRC1[63:48] * SRC2[63:48])\nDEST[95:64] := (SRC1[79:64] * SRC2[79:64]) + (SRC1[95:80] * SRC2[95:80])\nDEST[127:96] := (SRC1[111:96] * SRC2[111:96]) + (SRC1[127:112] * SRC2[127:112])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := (SRC1[15:0] * SRC2[15:0]) + (SRC1[31:16] * SRC2[31:16])\nDEST[63:32] := (SRC1[47:32] * SRC2[47:32]) + (SRC1[63:48] * SRC2[63:48])\nDEST[95:64] := (SRC1[79:64] * SRC2[79:64]) + (SRC1[95:80] * SRC2[95:80])\nDEST[127:96] := (SRC1[111:96] * SRC2[111:96]) + (SRC1[127:112] * SRC2[127:112])\nDEST[159:128] := (SRC1[143:128] * SRC2[143:128]) + (SRC1[159:144] * SRC2[159:144])\nDEST[191:160] := (SRC1[175:160] * SRC2[175:160]) + (SRC1[191:176] * SRC2[191:176])\nDEST[223:192] := (SRC1[207:192] * SRC2[207:192]) + (SRC1[223:208] * SRC2[223:208])\nDEST[255:224] := (SRC1[239:224] * SRC2[239:224]) + (SRC1[255:240] * SRC2[255:240])\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := (SRC2[i+31:i+16]* SRC1[i+31:i+16]) + (SRC2[i+15:i]*SRC1[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaddwd" + }, + "pmaxsb": { + "instruction": "PMAXSB", + "title": "PMAXSB/PMAXSW/PMAXSD/PMAXSQ\n\t\t— Maximum of Packed Signed Integers", + "opcode": "NP 0F EE /r1 PMAXSW mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed signed byte, word, dword or qword integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\nLegacy SSE version PMAXSW: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded VPMAXSD/Q: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.\nEVEX encoded VPMAXSB/W: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[15:0] > SRC[15:0]) THEN\n DEST[15:0] := DEST[15:0];\nELSE\n DEST[15:0] := SRC[15:0]; FI;\n(* Repeat operation for 2nd and 3rd words in source and destination operands *)\nIF DEST[63:48] > SRC[63:48]) THEN\n DEST[63:48] := DEST[63:48];\nELSE\n DEST[63:48] := SRC[63:48]; FI;\n\n\n IF DEST[7:0] > SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[7:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] >SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] >SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] >SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] > SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] >SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] >SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] >SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] >SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] > SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[31:0] >SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] >SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] > SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] > SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] > SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] > SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] > SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n THEN DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxsb:pmaxsw:pmaxsd:pmaxsq" + }, + "pmaxsd": { + "instruction": "PMAXSD", + "title": "PMAXSB/PMAXSW/PMAXSD/PMAXSQ\n\t\t— Maximum of Packed Signed Integers", + "opcode": "NP 0F EE /r1 PMAXSW mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed signed byte, word, dword or qword integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\nLegacy SSE version PMAXSW: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded VPMAXSD/Q: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.\nEVEX encoded VPMAXSB/W: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[15:0] > SRC[15:0]) THEN\n DEST[15:0] := DEST[15:0];\nELSE\n DEST[15:0] := SRC[15:0]; FI;\n(* Repeat operation for 2nd and 3rd words in source and destination operands *)\nIF DEST[63:48] > SRC[63:48]) THEN\n DEST[63:48] := DEST[63:48];\nELSE\n DEST[63:48] := SRC[63:48]; FI;\n\n\n IF DEST[7:0] > SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[7:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] >SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] >SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] >SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] > SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] >SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] >SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] >SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] >SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] > SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[31:0] >SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] >SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] > SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] > SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] > SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] > SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] > SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n THEN DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxsb:pmaxsw:pmaxsd:pmaxsq" + }, + "pmaxsq": { + "instruction": "PMAXSQ", + "title": "PMAXSB/PMAXSW/PMAXSD/PMAXSQ\n\t\t— Maximum of Packed Signed Integers", + "opcode": "NP 0F EE /r1 PMAXSW mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed signed byte, word, dword or qword integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\nLegacy SSE version PMAXSW: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded VPMAXSD/Q: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.\nEVEX encoded VPMAXSB/W: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[15:0] > SRC[15:0]) THEN\n DEST[15:0] := DEST[15:0];\nELSE\n DEST[15:0] := SRC[15:0]; FI;\n(* Repeat operation for 2nd and 3rd words in source and destination operands *)\nIF DEST[63:48] > SRC[63:48]) THEN\n DEST[63:48] := DEST[63:48];\nELSE\n DEST[63:48] := SRC[63:48]; FI;\n\n\n IF DEST[7:0] > SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[7:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] >SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] >SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] >SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] > SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] >SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] >SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] >SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] >SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] > SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[31:0] >SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] >SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] > SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] > SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] > SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] > SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] > SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n THEN DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxsb:pmaxsw:pmaxsd:pmaxsq" + }, + "pmaxsw": { + "instruction": "PMAXSW", + "title": "PMAXSB/PMAXSW/PMAXSD/PMAXSQ\n\t\t— Maximum of Packed Signed Integers", + "opcode": "NP 0F EE /r1 PMAXSW mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed signed byte, word, dword or qword integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\nLegacy SSE version PMAXSW: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded VPMAXSD/Q: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.\nEVEX encoded VPMAXSB/W: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[15:0] > SRC[15:0]) THEN\n DEST[15:0] := DEST[15:0];\nELSE\n DEST[15:0] := SRC[15:0]; FI;\n(* Repeat operation for 2nd and 3rd words in source and destination operands *)\nIF DEST[63:48] > SRC[63:48]) THEN\n DEST[63:48] := DEST[63:48];\nELSE\n DEST[63:48] := SRC[63:48]; FI;\n\n\n IF DEST[7:0] > SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[7:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] >SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] >SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] > SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] >SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] > SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] >SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] >SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] >SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] >SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] > SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[31:0] >SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] >SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] > SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] > SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] > SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] > SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] > SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n THEN DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxsb:pmaxsw:pmaxsd:pmaxsq" + }, + "pmaxub": { + "instruction": "PMAXUB", + "title": "PMAXUB/PMAXUW\n\t\t— Maximum of Packed Unsigned Integers", + "opcode": "NP 0F DE /r1 PMAXUB mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed unsigned byte, word integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\nLegacy SSE version PMAXUB: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[7:0] > SRC[17:0]) THEN\n DEST[7:0] := DEST[7:0];\nELSE\n DEST[7:0] := SRC[7:0]; FI;\n(* Repeat operation for 2nd through 7th bytes in source and destination operands *)\nIF DEST[63:56] > SRC[63:56]) THEN\n DEST[63:56] := DEST[63:56];\nELSE\n DEST[63:56] := SRC[63:56]; FI;\n\n\n IF DEST[7:0] >SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[15:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] >SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] >SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] >SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] >SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[15:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] >SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] > SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] >SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] >SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] >SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] >SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] > SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxub:pmaxuw" + }, + "pmaxud": { + "instruction": "PMAXUD", + "title": "PMAXUD/PMAXUQ\n\t\t— Maximum of Packed Unsigned Integers", + "opcode": "66 0F 38 3F /r PMAXUD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed unsigned dword or qword integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register; The second source operand is a YMM register or 256-bit memory location. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": " IF DEST[31:0] >SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] >SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] > SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] > SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] > SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] > SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxud:pmaxuq" + }, + "pmaxuq": { + "instruction": "PMAXUQ", + "title": "PMAXUD/PMAXUQ\n\t\t— Maximum of Packed Unsigned Integers", + "opcode": "66 0F 38 3F /r PMAXUD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed unsigned dword or qword integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register; The second source operand is a YMM register or 256-bit memory location. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": " IF DEST[31:0] >SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] >SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] > SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] > SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] > SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] > SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] > SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+31:i] > SRC2[i+31:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxud:pmaxuq" + }, + "pmaxuw": { + "instruction": "PMAXUW", + "title": "PMAXUB/PMAXUW\n\t\t— Maximum of Packed Unsigned Integers", + "opcode": "NP 0F DE /r1 PMAXUB mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed unsigned byte, word integers in the second source operand and the first source operand and returns the maximum value for each pair of integers to the destination operand.\nLegacy SSE version PMAXUB: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[7:0] > SRC[17:0]) THEN\n DEST[7:0] := DEST[7:0];\nELSE\n DEST[7:0] := SRC[7:0]; FI;\n(* Repeat operation for 2nd through 7th bytes in source and destination operands *)\nIF DEST[63:56] > SRC[63:56]) THEN\n DEST[63:56] := DEST[63:56];\nELSE\n DEST[63:56] := SRC[63:56]; FI;\n\n\n IF DEST[7:0] >SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[15:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] >SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] >SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] >SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] >SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[15:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] >SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] > SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] >SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] >SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] >SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] > SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] >SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] > SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmaxub:pmaxuw" + }, + "pminsb": { + "instruction": "PMINSB", + "title": "PMINSB/PMINSW\n\t\t— Minimum of Packed Signed Integers", + "opcode": "NP 0F EA /r1 PMINSW mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed signed byte, word, or dword integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\nLegacy SSE version PMINSW: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[15:0] < SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\nELSE\n DEST[15:0] := SRC[15:0]; FI;\n(* Repeat operation for 2nd and 3rd words in source and destination operands *)\nIF DEST[63:48] < SRC[63:48] THEN\n DEST[63:48] := DEST[63:48];\nELSE\n DEST[63:48] := SRC[63:48]; FI;\n\n\n IF DEST[7:0] < SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[15:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] < SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] < SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[15:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] < SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] < SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] < SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] < SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] < SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] < SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] < SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminsb:pminsw" + }, + "pminsd": { + "instruction": "PMINSD", + "title": "PMINSD/PMINSQ\n\t\t— Minimum of Packed Signed Integers", + "opcode": "66 0F 38 39 /r PMINSD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed signed dword or qword integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": " IF DEST[31:0] < SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] < SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] < SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] < SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] < SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] < SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] < SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] < SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminsd:pminsq" + }, + "pminsq": { + "instruction": "PMINSQ", + "title": "PMINSD/PMINSQ\n\t\t— Minimum of Packed Signed Integers", + "opcode": "66 0F 38 39 /r PMINSD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed signed dword or qword integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": " IF DEST[31:0] < SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] < SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] < SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] < SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] < SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] < SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] < SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] < SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminsd:pminsq" + }, + "pminsw": { + "instruction": "PMINSW", + "title": "PMINSB/PMINSW\n\t\t— Minimum of Packed Signed Integers", + "opcode": "NP 0F EA /r1 PMINSW mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed signed byte, word, or dword integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\nLegacy SSE version PMINSW: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[15:0] < SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\nELSE\n DEST[15:0] := SRC[15:0]; FI;\n(* Repeat operation for 2nd and 3rd words in source and destination operands *)\nIF DEST[63:48] < SRC[63:48] THEN\n DEST[63:48] := DEST[63:48];\nELSE\n DEST[63:48] := SRC[63:48]; FI;\n\n\n IF DEST[7:0] < SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[15:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] < SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] < SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[15:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] < SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] < SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] < SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] < SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] < SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] < SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] < SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminsb:pminsw" + }, + "pminub": { + "instruction": "PMINUB", + "title": "PMINUB/PMINUW\n\t\t— Minimum of Packed Unsigned Integers", + "opcode": "NP 0F DA /r1 PMINUB mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed unsigned byte or word integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\nLegacy SSE version PMINUB: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[7:0] < SRC[17:0] THEN\n DEST[7:0] := DEST[7:0];\nELSE\n DEST[7:0] := SRC[7:0]; FI;\n(* Repeat operation for 2nd through 7th bytes in source and destination operands *)\nIF DEST[63:56] < SRC[63:56] THEN\n DEST[63:56] := DEST[63:56];\nELSE\n DEST[63:56] := SRC[63:56]; FI;\n\n\n IF DEST[7:0] < SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[15:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] < SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] < SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[15:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] < SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] < SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] < SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] < SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] < SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] < SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] < SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminub:pminuw" + }, + "pminud": { + "instruction": "PMINUD", + "title": "PMINUD/PMINUQ\n\t\t— Minimum of Packed Unsigned Integers", + "opcode": "66 0F 38 3B /r PMINUD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed unsigned dword/qword integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "PMINUD instruction for 128-bit operands:\n IF DEST[31:0] < SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] < SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nVPMINUD instruction for 128-bit operands:\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] < SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\nVPMINUD instruction for 128-bit operands:\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] < SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] < SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] < SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] < SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] < SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminud:pminuq" + }, + "pminuq": { + "instruction": "PMINUQ", + "title": "PMINUD/PMINUQ\n\t\t— Minimum of Packed Unsigned Integers", + "opcode": "66 0F 38 3B /r PMINUD xmm1, xmm2/m128", + "description": "Performs a SIMD compare of the packed unsigned dword/qword integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "PMINUD instruction for 128-bit operands:\n IF DEST[31:0] < SRC[31:0] THEN\n DEST[31:0] := DEST[31:0];\n ELSE\n DEST[31:0] := SRC[31:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:96] < SRC[127:96] THEN\n DEST[127:96] := DEST[127:96];\n ELSE\n DEST[127:96] := SRC[127:96]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\nVPMINUD instruction for 128-bit operands:\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 3rd dwords in source and destination operands *)\n IF SRC1[127:96] < SRC2[127:96] THEN\n DEST[127:96] := SRC1[127:96];\n ELSE\n DEST[127:96] := SRC2[127:96]; FI;\nDEST[MAXVL-1:128] := 0\n\n\nVPMINUD instruction for 128-bit operands:\n IF SRC1[31:0] < SRC2[31:0] THEN\n DEST[31:0] := SRC1[31:0];\n ELSE\n DEST[31:0] := SRC2[31:0]; FI;\n (* Repeat operation for 2nd through 7th dwords in source and destination operands *)\n IF SRC1[255:224] < SRC2[255:224] THEN\n DEST[255:224] := SRC1[255:224];\n ELSE\n DEST[255:224] := SRC2[255:224]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+31:i] < SRC2[31:0]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[31:0];\n FI;\n ELSE\n IF SRC1[i+31:i] < SRC2[i+31:i]\n THEN DEST[i+31:i] := SRC1[i+31:i];\n ELSE DEST[i+31:i] := SRC2[i+31:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN\n IF SRC1[i+63:i] < SRC2[63:0]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[63:0];\n FI;\n ELSE\n IF SRC1[i+63:i] < SRC2[i+63:i]\n THEN DEST[i+63:i] := SRC1[i+63:i];\n ELSE DEST[i+63:i] := SRC2[i+63:i];\n FI;\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminud:pminuq" + }, + "pminuw": { + "instruction": "PMINUW", + "title": "PMINUB/PMINUW\n\t\t— Minimum of Packed Unsigned Integers", + "opcode": "NP 0F DA /r1 PMINUB mm1, mm2/m64", + "description": "Performs a SIMD compare of the packed unsigned byte or word integers in the second source operand and the first source operand and returns the minimum value for each pair of integers to the destination operand.\nLegacy SSE version PMINUB: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand can be an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register; The second source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "IF DEST[7:0] < SRC[17:0] THEN\n DEST[7:0] := DEST[7:0];\nELSE\n DEST[7:0] := SRC[7:0]; FI;\n(* Repeat operation for 2nd through 7th bytes in source and destination operands *)\nIF DEST[63:56] < SRC[63:56] THEN\n DEST[63:56] := DEST[63:56];\nELSE\n DEST[63:56] := SRC[63:56]; FI;\n\n\n IF DEST[7:0] < SRC[7:0] THEN\n DEST[7:0] := DEST[7:0];\n ELSE\n DEST[15:0] := SRC[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF DEST[127:120] < SRC[127:120] THEN\n DEST[127:120] := DEST[127:120];\n ELSE\n DEST[127:120] := SRC[127:120]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[7:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 15th bytes in source and destination operands *)\n IF SRC1[127:120] < SRC2[127:120] THEN\n DEST[127:120] := SRC1[127:120];\n ELSE\n DEST[127:120] := SRC2[127:120]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[7:0] < SRC2[7:0] THEN\n DEST[7:0] := SRC1[7:0];\n ELSE\n DEST[15:0] := SRC2[7:0]; FI;\n (* Repeat operation for 2nd through 31st bytes in source and destination operands *)\n IF SRC1[255:248] < SRC2[255:248] THEN\n DEST[255:248] := SRC1[255:248];\n ELSE\n DEST[255:248] := SRC2[255:248]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+7:i] < SRC2[i+7:i]\n THEN DEST[i+7:i] := SRC1[i+7:i];\n ELSE DEST[i+7:i] := SRC2[i+7:i];\n FI;\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n IF DEST[15:0] < SRC[15:0] THEN\n DEST[15:0] := DEST[15:0];\n ELSE\n DEST[15:0] := SRC[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF DEST[127:112] < SRC[127:112] THEN\n DEST[127:112] := DEST[127:112];\n ELSE\n DEST[127:112] := SRC[127:112]; FI;\nDEST[MAXVL-1:128] (Unmodified)\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 7th words in source and destination operands *)\n IF SRC1[127:112] < SRC2[127:112] THEN\n DEST[127:112] := SRC1[127:112];\n ELSE\n DEST[127:112] := SRC2[127:112]; FI;\nDEST[MAXVL-1:128] := 0\n\n\n IF SRC1[15:0] < SRC2[15:0] THEN\n DEST[15:0] := SRC1[15:0];\n ELSE\n DEST[15:0] := SRC2[15:0]; FI;\n (* Repeat operation for 2nd through 15th words in source and destination operands *)\n IF SRC1[255:240] < SRC2[255:240] THEN\n DEST[255:240] := SRC1[255:240];\n ELSE\n DEST[255:240] := SRC2[255:240]; FI;\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask* THEN\n IF SRC1[i+15:i] < SRC2[i+15:i]\n THEN DEST[i+15:i] := SRC1[i+15:i];\n ELSE DEST[i+15:i] := SRC2[i+15:i];\n FI;\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pminub:pminuw" + }, + "pmovmskb": { + "instruction": "PMOVMSKB", + "title": "PMOVMSKB\n\t\t— Move Byte Mask", + "opcode": "NP 0F D7 /r1 PMOVMSKB reg, mm", + "description": "Creates a mask made up of the most significant bit of each byte of the source operand (second operand) and stores the result in the low byte or word of the destination operand (first operand).\nThe byte mask is 8 bits for 64-bit source operand, 16 bits for 128-bit source operand and 32 bits for 256-bit source operand. The destination operand is a general-purpose register.\nIn 64-bit mode, the instruction can access additional registers (XMM8-XMM15, R8-R15) when used with a REX.R prefix. The default operand size is 64-bit in 64-bit mode.\nLegacy SSE version: The source operand is an MMX technology register.\n128-bit Legacy SSE version: The source operand is an XMM register.\nVEX.128 encoded version: The source operand is an XMM register.\nVEX.256 encoded version: The source operand is a YMM register.\nNote: VEX.vvvv is reserved and must be 1111b.", + "operation": "r32[0] := SRC[7];\nr32[1] := SRC[15];\n(* Repeat operation for bytes 2 through 6 *)\nr32[7] := SRC[63];\nr32[31:8] := ZERO_FILL;\n\n\nr32[0] := SRC[7];\nr32[1] := SRC[15];\n(* Repeat operation for bytes 2 through 14 *)\nr32[15] := SRC[127];\nr32[31:16] := ZERO_FILL;\n\n\nr32[0] := SRC[7];\nr32[1] := SRC[15];\n(* Repeat operation for bytes 3rd through 31*)\nr32[31] := SRC[255];\n\n\nr64[0] := SRC[7];\nr64[1] := SRC[15];\n(* Repeat operation for bytes 2 through 6 *)\nr64[7] := SRC[63];\nr64[63:8] := ZERO_FILL;\n\n\nr64[0] := SRC[7];\nr64[1] := SRC[15];\n(* Repeat operation for bytes 2 through 14 *)\nr64[15] := SRC[127];\nr64[63:16] := ZERO_FILL;\n\n\nr64[0] := SRC[7];\nr64[1] := SRC[15];\n(* Repeat operation for bytes 2 through 31*)\nr64[31] := SRC[255];\nr64[63:32] := ZERO_FILL;\n", + "url": "https://www.felixcloutier.com/x86/pmovmskb" + }, + "pmovsx": { + "instruction": "PMOVSX", + "title": "PMOVSX\n\t\t— Packed Move With Sign Extend", + "opcode": "66 0f 38 20 /r PMOVSXBW xmm1, xmm2/m64", + "description": "Legacy and VEX encoded versions: Packed byte, word, or dword integers in the low bytes of the source operand (second operand) are sign extended to word, dword, or quadword integers and stored in packed signed bytes the destination operand.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX.128 encoded versions: Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 and EVEX.256 encoded versions: Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: Packed byte, word or dword integers starting from the low bytes of the source operand (second operand) are sign extended to word, dword or quadword integers and stored to the destination operand under the writemask. The destination register is XMM, YMM or ZMM Register.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "DEST[15:0] := SignExtend(SRC[7:0]);\nDEST[31:16] := SignExtend(SRC[15:8]);\nDEST[47:32] := SignExtend(SRC[23:16]);\nDEST[63:48] := SignExtend(SRC[31:24]);\nDEST[79:64] := SignExtend(SRC[39:32]);\nDEST[95:80] := SignExtend(SRC[47:40]);\nDEST[111:96] := SignExtend(SRC[55:48]);\nDEST[127:112] := SignExtend(SRC[63:56]);\n\n\nDEST[31:0] := SignExtend(SRC[7:0]);\nDEST[63:32] := SignExtend(SRC[15:8]);\nDEST[95:64] := SignExtend(SRC[23:16]);\nDEST[127:96] := SignExtend(SRC[31:24]);\n\n\nDEST[63:0] := SignExtend(SRC[7:0]);\nDEST[127:64] := SignExtend(SRC[15:8]);\n\n\nDEST[31:0] := SignExtend(SRC[15:0]);\nDEST[63:32] := SignExtend(SRC[31:16]);\nDEST[95:64] := SignExtend(SRC[47:32]);\nDEST[127:96] := SignExtend(SRC[63:48]);\n\n\nDEST[63:0] := SignExtend(SRC[15:0]);\nDEST[127:64] := SignExtend(SRC[31:16]);\n\n\nDEST[63:0] := SignExtend(SRC[31:0]);\nDEST[127:64] := SignExtend(SRC[63:32]);\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nPacked_Sign_Extend_BYTE_to_WORD(TMP_DEST[127:0], SRC[63:0])\nIF VL >= 256\n Packed_Sign_Extend_BYTE_to_WORD(TMP_DEST[255:128], SRC[127:64])\nFI;\nIF VL >= 512\n Packed_Sign_Extend_BYTE_to_WORD(TMP_DEST[383:256], SRC[191:128])\n Packed_Sign_Extend_BYTE_to_WORD(TMP_DEST[511:384], SRC[255:192])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TEMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nPacked_Sign_Extend_BYTE_to_DWORD(TMP_DEST[127:0], SRC[31:0])\nIF VL >= 256\n Packed_Sign_Extend_BYTE_to_DWORD(TMP_DEST[255:128], SRC[63:32])\nFI;\nIF VL >= 512\n Packed_Sign_Extend_BYTE_to_DWORD(TMP_DEST[383:256], SRC[95:64])\n Packed_Sign_Extend_BYTE_to_DWORD(TMP_DEST[511:384], SRC[127:96])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TEMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nPacked_Sign_Extend_BYTE_to_QWORD(TMP_DEST[127:0], SRC[15:0])\nIF VL >= 256\n Packed_Sign_Extend_BYTE_to_QWORD(TMP_DEST[255:128], SRC[31:16])\nFI;\nIF VL >= 512\n Packed_Sign_Extend_BYTE_to_QWORD(TMP_DEST[383:256], SRC[47:32])\n Packed_Sign_Extend_BYTE_to_QWORD(TMP_DEST[511:384], SRC[63:48])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TEMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nPacked_Sign_Extend_WORD_to_DWORD(TMP_DEST[127:0], SRC[63:0])\nIF VL >= 256\n Packed_Sign_Extend_WORD_to_DWORD(TMP_DEST[255:128], SRC[127:64])\nFI;\nIF VL >= 512\n Packed_Sign_Extend_WORD_to_DWORD(TMP_DEST[383:256], SRC[191:128])\n Packed_Sign_Extend_WORD_to_DWORD(TMP_DEST[511:384], SRC[256:192])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TEMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nPacked_Sign_Extend_WORD_to_QWORD(TMP_DEST[127:0], SRC[31:0])\nIF VL >= 256\n Packed_Sign_Extend_WORD_to_QWORD(TMP_DEST[255:128], SRC[63:32])\nFI;\nIF VL >= 512\n Packed_Sign_Extend_WORD_to_QWORD(TMP_DEST[383:256], SRC[95:64])\n Packed_Sign_Extend_WORD_to_QWORD(TMP_DEST[511:384], SRC[127:96])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TEMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nPacked_Sign_Extend_DWORD_to_QWORD(TEMP_DEST[127:0], SRC[63:0])\nIF VL >= 256\n Packed_Sign_Extend_DWORD_to_QWORD(TEMP_DEST[255:128], SRC[127:64])\nFI;\nIF VL >= 512\n Packed_Sign_Extend_DWORD_to_QWORD(TEMP_DEST[383:256], SRC[191:128])\n Packed_Sign_Extend_DWORD_to_QWORD(TEMP_DEST[511:384], SRC[255:192])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TEMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nPacked_Sign_Extend_BYTE_to_WORD(DEST[127:0], SRC[63:0])\nPacked_Sign_Extend_BYTE_to_WORD(DEST[255:128], SRC[127:64])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Sign_Extend_BYTE_to_DWORD(DEST[127:0], SRC[31:0])\nPacked_Sign_Extend_BYTE_to_DWORD(DEST[255:128], SRC[63:32])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Sign_Extend_BYTE_to_QWORD(DEST[127:0], SRC[15:0])\nPacked_Sign_Extend_BYTE_to_QWORD(DEST[255:128], SRC[31:16])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Sign_Extend_WORD_to_DWORD(DEST[127:0], SRC[63:0])\nPacked_Sign_Extend_WORD_to_DWORD(DEST[255:128], SRC[127:64])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Sign_Extend_WORD_to_QWORD(DEST[127:0], SRC[31:0])\nPacked_Sign_Extend_WORD_to_QWORD(DEST[255:128], SRC[63:32])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Sign_Extend_DWORD_to_QWORD(DEST[127:0], SRC[63:0])\nPacked_Sign_Extend_DWORD_to_QWORD(DEST[255:128], SRC[127:64])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Sign_Extend_BYTE_to_WORDDEST[127:0], SRC[127:0]()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Sign_Extend_BYTE_to_DWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Sign_Extend_BYTE_to_QWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Sign_Extend_WORD_to_DWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Sign_Extend_WORD_to_QWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Sign_Extend_DWORD_to_QWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Sign_Extend_BYTE_to_WORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Sign_Extend_BYTE_to_DWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Sign_Extend_BYTE_to_QWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Sign_Extend_WORD_to_DWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Sign_Extend_WORD_to_QWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Sign_Extend_DWORD_to_QWORD(DEST[127:0], SRC[127:0])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/pmovsx" + }, + "pmovzx": { + "instruction": "PMOVZX", + "title": "PMOVZX\n\t\t— Packed Move With Zero Extend", + "opcode": "66 0f 38 30 /r PMOVZXBW xmm1, xmm2/m64", + "description": "Legacy, VEX, and EVEX encoded versions: Packed byte, word, or dword integers starting from the low bytes of the source operand (second operand) are zero extended to word, dword, or quadword integers and stored in packed signed bytes the destination operand.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 encoded version: Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX encoded versions: Packed dword integers starting from the low bytes of the source operand (second operand) are zero extended to quadword integers and stored to the destination operand under the writemask.The destination register is XMM, YMM or ZMM Register.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "DEST[15:0] := ZeroExtend(SRC[7:0]);\nDEST[31:16] := ZeroExtend(SRC[15:8]);\nDEST[47:32] := ZeroExtend(SRC[23:16]);\nDEST[63:48] := ZeroExtend(SRC[31:24]);\nDEST[79:64] := ZeroExtend(SRC[39:32]);\nDEST[95:80] := ZeroExtend(SRC[47:40]);\nDEST[111:96] := ZeroExtend(SRC[55:48]);\nDEST[127:112] := ZeroExtend(SRC[63:56]);\n\n\nDEST[31:0] := ZeroExtend(SRC[7:0]);\nDEST[63:32] := ZeroExtend(SRC[15:8]);\nDEST[95:64] := ZeroExtend(SRC[23:16]);\nDEST[127:96] := ZeroExtend(SRC[31:24]);\n\n\nDEST[63:0] := ZeroExtend(SRC[7:0]);\nDEST[127:64] := ZeroExtend(SRC[15:8]);\n\n\nDEST[31:0] := ZeroExtend(SRC[15:0]);\nDEST[63:32] := ZeroExtend(SRC[31:16]);\nDEST[95:64] := ZeroExtend(SRC[47:32]);\nDEST[127:96] := ZeroExtend(SRC[63:48]);\n\n\nDEST[63:0] := ZeroExtend(SRC[15:0]);\nDEST[127:64] := ZeroExtend(SRC[31:16]);\n\n\nDEST[63:0] := ZeroExtend(SRC[31:0]);\nDEST[127:64] := ZeroExtend(SRC[63:32]);\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nPacked_Zero_Extend_BYTE_to_WORD(TMP_DEST[127:0], SRC[63:0])\nIF VL >= 256\n Packed_Zero_Extend_BYTE_to_WORD(TMP_DEST[255:128], SRC[127:64])\nFI;\nIF VL >= 512\n Packed_Zero_Extend_BYTE_to_WORD(TMP_DEST[383:256], SRC[191:128])\n Packed_Zero_Extend_BYTE_to_WORD(TMP_DEST[511:384], SRC[255:192])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TEMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nPacked_Zero_Extend_BYTE_to_DWORD(TMP_DEST[127:0], SRC[31:0])\nIF VL >= 256\n Packed_Zero_Extend_BYTE_to_DWORD(TMP_DEST[255:128], SRC[63:32])\nFI;\nIF VL >= 512\n Packed_Zero_Extend_BYTE_to_DWORD(TMP_DEST[383:256], SRC[95:64])\n Packed_Zero_Extend_BYTE_to_DWORD(TMP_DEST[511:384], SRC[127:96])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TEMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nPacked_Zero_Extend_BYTE_to_QWORD(TMP_DEST[127:0], SRC[15:0])\nIF VL >= 256\n Packed_Zero_Extend_BYTE_to_QWORD(TMP_DEST[255:128], SRC[31:16])\nFI;\nIF VL >= 512\n Packed_Zero_Extend_BYTE_to_QWORD(TMP_DEST[383:256], SRC[47:32])\n Packed_Zero_Extend_BYTE_to_QWORD(TMP_DEST[511:384], SRC[63:48])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TEMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nPacked_Zero_Extend_WORD_to_DWORD(TMP_DEST[127:0], SRC[63:0])\nIF VL >= 256\n Packed_Zero_Extend_WORD_to_DWORD(TMP_DEST[255:128], SRC[127:64])\nFI;\nIF VL >= 512\n Packed_Zero_Extend_WORD_to_DWORD(TMP_DEST[383:256], SRC[191:128])\n Packed_Zero_Extend_WORD_to_DWORD(TMP_DEST[511:384], SRC[256:192])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TEMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nPacked_Zero_Extend_WORD_to_QWORD(TMP_DEST[127:0], SRC[31:0])\nIF VL >= 256\n Packed_Zero_Extend_WORD_to_QWORD(TMP_DEST[255:128], SRC[63:32])\nFI;\nIF VL >= 512\n Packed_Zero_Extend_WORD_to_QWORD(TMP_DEST[383:256], SRC[95:64])\n Packed_Zero_Extend_WORD_to_QWORD(TMP_DEST[511:384], SRC[127:96])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TEMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nPacked_Zero_Extend_DWORD_to_QWORD(TEMP_DEST[127:0], SRC[63:0])\nIF VL >= 256\n Packed_Zero_Extend_DWORD_to_QWORD(TEMP_DEST[255:128], SRC[127:64])\nFI;\nIF VL >= 512\n Packed_Zero_Extend_DWORD_to_QWORD(TEMP_DEST[383:256], SRC[191:128])\n Packed_Zero_Extend_DWORD_to_QWORD(TEMP_DEST[511:384], SRC[255:192])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TEMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nPacked_Zero_Extend_BYTE_to_WORD(DEST[127:0], SRC[63:0])\nPacked_Zero_Extend_BYTE_to_WORD(DEST[255:128], SRC[127:64])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Zero_Extend_BYTE_to_DWORD(DEST[127:0], SRC[31:0])\nPacked_Zero_Extend_BYTE_to_DWORD(DEST[255:128], SRC[63:32])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Zero_Extend_BYTE_to_QWORD(DEST[127:0], SRC[15:0])\nPacked_Zero_Extend_BYTE_to_QWORD(DEST[255:128], SRC[31:16])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Zero_Extend_WORD_to_DWORD(DEST[127:0], SRC[63:0])\nPacked_Zero_Extend_WORD_to_DWORD(DEST[255:128], SRC[127:64])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Zero_Extend_WORD_to_QWORD(DEST[127:0], SRC[31:0])\nPacked_Zero_Extend_WORD_to_QWORD(DEST[255:128], SRC[63:32])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Zero_Extend_DWORD_to_QWORD(DEST[127:0], SRC[63:0])\nPacked_Zero_Extend_DWORD_to_QWORD(DEST[255:128], SRC[127:64])\nDEST[MAXVL-1:256] := 0\n\n\nPacked_Zero_Extend_BYTE_to_WORD()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Zero_Extend_BYTE_to_DWORD()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Zero_Extend_BYTE_to_QWORD()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Zero_Extend_WORD_to_DWORD()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Zero_Extend_WORD_to_QWORD()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Zero_Extend_DWORD_to_QWORD()\nDEST[MAXVL-1:128] := 0\n\n\nPacked_Zero_Extend_BYTE_to_WORD()\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Zero_Extend_BYTE_to_DWORD()\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Zero_Extend_BYTE_to_QWORD()\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Zero_Extend_WORD_to_DWORD()\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Zero_Extend_WORD_to_QWORD()\nDEST[MAXVL-1:128] (Unmodified)\n\n\nPacked_Zero_Extend_DWORD_to_QWORD()\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/pmovzx" + }, + "pmuldq": { + "instruction": "PMULDQ", + "title": "PMULDQ\n\t\t— Multiply Packed Doubleword Integers", + "opcode": "66 0F 38 28 /r PMULDQ xmm1, xmm2/m128", + "description": "", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SignExtend64( SRC1[i+31:i]) * SignExtend64( SRC2[31:0])\n ELSE DEST[i+63:i] := SignExtend64( SRC1[i+31:i]) * SignExtend64( SRC2[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SignExtend64( SRC1[31:0]) * SignExtend64( SRC2[31:0])\nDEST[127:64] := SignExtend64( SRC1[95:64]) * SignExtend64( SRC2[95:64])\nDEST[191:128] := SignExtend64( SRC1[159:128]) * SignExtend64( SRC2[159:128])\nDEST[255:192] := SignExtend64( SRC1[223:192]) * SignExtend64( SRC2[223:192])\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SignExtend64( SRC1[31:0]) * SignExtend64( SRC2[31:0])\nDEST[127:64] := SignExtend64( SRC1[95:64]) * SignExtend64( SRC2[95:64])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SignExtend64( DEST[31:0]) * SignExtend64( SRC[31:0])\nDEST[127:64] := SignExtend64( DEST[95:64]) * SignExtend64( SRC[95:64])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/pmuldq" + }, + "pmulhrsw": { + "instruction": "PMULHRSW", + "title": "PMULHRSW\n\t\t— Packed Multiply High With Round and Scale", + "opcode": "NP 0F 38 0B /r1 PMULHRSW mm1, mm2/m64", + "description": "PMULHRSW multiplies vertically each signed 16-bit integer from the destination operand (first operand) with the corresponding signed 16-bit integer of the source operand (second operand), producing intermediate, signed 32-bit integers. Each intermediate 32-bit integer is truncated to the 18 most significant bits. Rounding is always performed by adding 1 to the least significant bit of the 18-bit intermediate result. The final result is obtained by selecting the 16 bits immediately to the right of the most significant bit of each 18-bit intermediate result and packed to the destination operand.\nWhen the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nIn 64-bit mode and not encoded with VEX/EVEX, use the REX prefix to access XMM8-XMM15 registers.\nLegacy SSE version 64-bit operand: Both operands can be MMX registers. The second source operand is an MMX register or a 64-bit memory location.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.", + "operation": "temp0[31:0] = INT32 ((DEST[15:0] * SRC[15:0]) >>14) + 1;\ntemp1[31:0] = INT32 ((DEST[31:16] * SRC[31:16]) >>14) + 1;\ntemp2[31:0] = INT32 ((DEST[47:32] * SRC[47:32]) >> 14) + 1;\ntemp3[31:0] = INT32 ((DEST[63:48] * SRc[63:48]) >> 14) + 1;\nDEST[15:0] = temp0[16:1];\nDEST[31:16] = temp1[16:1];\nDEST[47:32] = temp2[16:1];\nDEST[63:48] = temp3[16:1];\n\n\ntemp0[31:0] = INT32 ((DEST[15:0] * SRC[15:0]) >>14) + 1;\ntemp1[31:0] = INT32 ((DEST[31:16] * SRC[31:16]) >>14) + 1;\ntemp2[31:0] = INT32 ((DEST[47:32] * SRC[47:32]) >>14) + 1;\ntemp3[31:0] = INT32 ((DEST[63:48] * SRC[63:48]) >>14) + 1;\ntemp4[31:0] = INT32 ((DEST[79:64] * SRC[79:64]) >>14) + 1;\ntemp5[31:0] = INT32 ((DEST[95:80] * SRC[95:80]) >>14) + 1;\ntemp6[31:0] = INT32 ((DEST[111:96] * SRC[111:96]) >>14) + 1;\ntemp7[31:0] = INT32 ((DEST[127:112] * SRC[127:112) >>14) + 1;\nDEST[15:0] = temp0[16:1];\nDEST[31:16] = temp1[16:1];\nDEST[47:32] = temp2[16:1];\nDEST[63:48] = temp3[16:1];\nDEST[79:64] = temp4[16:1];\nDEST[95:80] = temp5[16:1];\nDEST[111:96] = temp6[16:1];\nDEST[127:112] = temp7[16:1];\n\n\ntemp0[31:0] := INT32 ((SRC1[15:0] * SRC2[15:0]) >>14) + 1\ntemp1[31:0] := INT32 ((SRC1[31:16] * SRC2[31:16]) >>14) + 1\ntemp2[31:0] := INT32 ((SRC1[47:32] * SRC2[47:32]) >>14) + 1\ntemp3[31:0] := INT32 ((SRC1[63:48] * SRC2[63:48]) >>14) + 1\ntemp4[31:0] := INT32 ((SRC1[79:64] * SRC2[79:64]) >>14) + 1\ntemp5[31:0] := INT32 ((SRC1[95:80] * SRC2[95:80]) >>14) + 1\ntemp6[31:0] := INT32 ((SRC1[111:96] * SRC2[111:96]) >>14) + 1\ntemp7[31:0] := INT32 ((SRC1[127:112] * SRC2[127:112) >>14) + 1\nDEST[15:0] := temp0[16:1]\nDEST[31:16] := temp1[16:1]\nDEST[47:32] := temp2[16:1]\nDEST[63:48] := temp3[16:1]\nDEST[79:64] := temp4[16:1]\nDEST[95:80] := temp5[16:1]\nDEST[111:96] := temp6[16:1]\nDEST[127:112] := temp7[16:1]\nDEST[MAXVL-1:128] := 0\n\n\ntemp0[31:0] := INT32 ((SRC1[15:0] * SRC2[15:0]) >>14) + 1\ntemp1[31:0] := INT32 ((SRC1[31:16] * SRC2[31:16]) >>14) + 1\ntemp2[31:0] := INT32 ((SRC1[47:32] * SRC2[47:32]) >>14) + 1\ntemp3[31:0] := INT32 ((SRC1[63:48] * SRC2[63:48]) >>14) + 1\ntemp4[31:0] := INT32 ((SRC1[79:64] * SRC2[79:64]) >>14) + 1\ntemp5[31:0] := INT32 ((SRC1[95:80] * SRC2[95:80]) >>14) + 1\ntemp6[31:0] := INT32 ((SRC1[111:96] * SRC2[111:96]) >>14) + 1\ntemp7[31:0] := INT32 ((SRC1[127:112] * SRC2[127:112) >>14) + 1\ntemp8[31:0] := INT32 ((SRC1[143:128] * SRC2[143:128]) >>14) + 1\ntemp9[31:0] := INT32 ((SRC1[159:144] * SRC2[159:144]) >>14) + 1\ntemp10[31:0] := INT32 ((SRC1[75:160] * SRC2[175:160]) >>14) + 1\ntemp11[31:0] := INT32 ((SRC1[191:176] * SRC2[191:176]) >>14) + 1\ntemp12[31:0] := INT32 ((SRC1[207:192] * SRC2[207:192]) >>14) + 1\ntemp13[31:0] := INT32 ((SRC1[223:208] * SRC2[223:208]) >>14) + 1\ntemp14[31:0] := INT32 ((SRC1[239:224] * SRC2[239:224]) >>14) + 1\ntemp15[31:0] := INT32 ((SRC1[255:240] * SRC2[255:240) >>14) + 1\nDEST[15:0] := temp0[16:1]\nDEST[31:16] := temp1[16:1]\nDEST[47:32] := temp2[16:1]\nDEST[63:48] := temp3[16:1]\nDEST[79:64] := temp4[16:1]\nDEST[95:80] := temp5[16:1]\nDEST[111:96] := temp6[16:1]\nDEST[127:112] := temp7[16:1]\nDEST[143:128] := temp8[16:1]\nDEST[159:144] := temp9[16:1]\nDEST[175:160] := temp10[16:1]\nDEST[191:176] := temp11[16:1]\nDEST[207:192] := temp12[16:1]\nDEST[223:208] := temp13[16:1]\nDEST[239:224] := temp14[16:1]\nDEST[255:240] := temp15[16:1]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n temp[31:0] := ((SRC1[i+15:i] * SRC2[i+15:i]) >>14) + 1\n DEST[i+15:i] := tmp[16:1]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmulhrsw" + }, + "pmulhuw": { + "instruction": "PMULHUW", + "title": "PMULHUW\n\t\t— Multiply Packed Unsigned Integers and Store High Result", + "opcode": "NP 0F E4 /r1 PMULHUW mm1, mm2/m64", + "description": "Performs a SIMD unsigned multiply of the packed unsigned word integers in the destination operand (first operand) and the source operand (second operand), and stores the high 16 bits of each 32-bit intermediate results in the destination operand. (Figure 4-12 shows this operation when using 64-bit operands.)\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L must be 0, otherwise the instruction will #UD.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.", + "operation": "TEMP0[31:0] := DEST[15:0] ∗ SRC[15:0]; (* Unsigned multiplication *)\nTEMP1[31:0] := DEST[31:16] ∗ SRC[31:16];\nTEMP2[31:0] := DEST[47:32] ∗ SRC[47:32];\nTEMP3[31:0] := DEST[63:48] ∗ SRC[63:48];\nDEST[15:0] := TEMP0[31:16];\nDEST[31:16] := TEMP1[31:16];\nDEST[47:32] := TEMP2[31:16];\nDEST[63:48] := TEMP3[31:16];\n\n\nTEMP0[31:0] := DEST[15:0] ∗ SRC[15:0]; (* Unsigned multiplication *)\nTEMP1[31:0] := DEST[31:16] ∗ SRC[31:16];\nTEMP2[31:0] := DEST[47:32] ∗ SRC[47:32];\nTEMP3[31:0] := DEST[63:48] ∗ SRC[63:48];\nTEMP4[31:0] := DEST[79:64] ∗ SRC[79:64];\nTEMP5[31:0] := DEST[95:80] ∗ SRC[95:80];\nTEMP6[31:0] := DEST[111:96] ∗ SRC[111:96];\nTEMP7[31:0] := DEST[127:112] ∗ SRC[127:112];\nDEST[15:0] := TEMP0[31:16];\nDEST[31:16] := TEMP1[31:16];\nDEST[47:32] := TEMP2[31:16];\nDEST[63:48] := TEMP3[31:16];\nDEST[79:64] := TEMP4[31:16];\nDEST[95:80] := TEMP5[31:16];\nDEST[111:96] := TEMP6[31:16];\nDEST[127:112] := TEMP7[31:16];\n\n\nTEMP0[31:0] := SRC1[15:0] * SRC2[15:0]\nTEMP1[31:0] := SRC1[31:16] * SRC2[31:16]\nTEMP2[31:0] := SRC1[47:32] * SRC2[47:32]\nTEMP3[31:0] := SRC1[63:48] * SRC2[63:48]\nTEMP4[31:0] := SRC1[79:64] * SRC2[79:64]\nTEMP5[31:0] := SRC1[95:80] * SRC2[95:80]\nTEMP6[31:0] := SRC1[111:96] * SRC2[111:96]\nTEMP7[31:0] := SRC1[127:112] * SRC2[127:112]\nDEST[15:0] := TEMP0[31:16]\nDEST[31:16] := TEMP1[31:16]\nDEST[47:32] := TEMP2[31:16]\nDEST[63:48] := TEMP3[31:16]\nDEST[79:64] := TEMP4[31:16]\nDEST[95:80] := TEMP5[31:16]\nDEST[111:96] := TEMP6[31:16]\nDEST[127:112] := TEMP7[31:16]\nDEST[MAXVL-1:128] := 0\n\n\nTEMP0[31:0] := SRC1[15:0] * SRC2[15:0]\nTEMP1[31:0] := SRC1[31:16] * SRC2[31:16]\nTEMP2[31:0] := SRC1[47:32] * SRC2[47:32]\nTEMP3[31:0] := SRC1[63:48] * SRC2[63:48]\nTEMP4[31:0] := SRC1[79:64] * SRC2[79:64]\nTEMP5[31:0] := SRC1[95:80] * SRC2[95:80]\nTEMP6[31:0] := SRC1[111:96] * SRC2[111:96]\nTEMP7[31:0] := SRC1[127:112] * SRC2[127:112]\nTEMP8[31:0] := SRC1[143:128] * SRC2[143:128]\nTEMP9[31:0] := SRC1[159:144] * SRC2[159:144]\nTEMP10[31:0] := SRC1[175:160] * SRC2[175:160]\nTEMP11[31:0] := SRC1[191:176] * SRC2[191:176]\nTEMP12[31:0] := SRC1[207:192] * SRC2[207:192]\nTEMP13[31:0] := SRC1[223:208] * SRC2[223:208]\nTEMP14[31:0] := SRC1[239:224] * SRC2[239:224]\nTEMP15[31:0] := SRC1[255:240] * SRC2[255:240]\nDEST[15:0] := TEMP0[31:16]\nDEST[31:16] := TEMP1[31:16]\nDEST[47:32] := TEMP2[31:16]\nDEST[63:48] := TEMP3[31:16]\nDEST[79:64] := TEMP4[31:16]\nDEST[95:80] := TEMP5[31:16]\nDEST[111:96] := TEMP6[31:16]\nDEST[127:112] := TEMP7[31:16]\nDEST[143:128] := TEMP8[31:16]\nDEST[159:144] := TEMP9[31:16]\nDEST[175:160] := TEMP10[31:16]\nDEST[191:176] := TEMP11[31:16]\nDEST[207:192] := TEMP12[31:16]\nDEST[223:208] := TEMP13[31:16]\nDEST[239:224] := TEMP14[31:16]\nDEST[255:240] := TEMP15[31:16]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n temp[31:0] := SRC1[i+15:i] * SRC2[i+15:i]\n DEST[i+15:i] := tmp[31:16]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmulhuw" + }, + "pmulhw": { + "instruction": "PMULHW", + "title": "PMULHW\n\t\t— Multiply Packed Signed Integers and Store High Result", + "opcode": "NP 0F E5 /r1 PMULHW mm, mm/m64", + "description": "Performs a SIMD signed multiply of the packed signed word integers in the destination operand (first operand) and the source operand (second operand), and stores the high 16 bits of each intermediate 32-bit result in the destination operand. (Figure 4-12 shows this operation when using 64-bit operands.)\nn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L must be 0, otherwise the instruction will #UD.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.", + "operation": "TEMP0[31:0] := DEST[15:0] ∗ SRC[15:0]; (* Signed multiplication *)\nTEMP1[31:0] := DEST[31:16] ∗ SRC[31:16];\nTEMP2[31:0] := DEST[47:32] ∗ SRC[47:32];\nTEMP3[31:0] := DEST[63:48] ∗ SRC[63:48];\nDEST[15:0] := TEMP0[31:16];\nDEST[31:16] := TEMP1[31:16];\nDEST[47:32] := TEMP2[31:16];\nDEST[63:48] := TEMP3[31:16];\n\n\nTEMP0[31:0] := DEST[15:0] ∗ SRC[15:0]; (* Signed multiplication *)\nTEMP1[31:0] := DEST[31:16] ∗ SRC[31:16];\nTEMP2[31:0] := DEST[47:32] ∗ SRC[47:32];\nTEMP3[31:0] := DEST[63:48] ∗ SRC[63:48];\nTEMP4[31:0] := DEST[79:64] ∗ SRC[79:64];\nTEMP5[31:0] := DEST[95:80] ∗ SRC[95:80];\nTEMP6[31:0] := DEST[111:96] ∗ SRC[111:96];\nTEMP7[31:0] := DEST[127:112] ∗ SRC[127:112];\nDEST[15:0] := TEMP0[31:16];\nDEST[31:16] := TEMP1[31:16];\nDEST[47:32] := TEMP2[31:16];\nDEST[63:48] := TEMP3[31:16];\nDEST[79:64] := TEMP4[31:16];\nDEST[95:80] := TEMP5[31:16];\nDEST[111:96] := TEMP6[31:16];\nDEST[127:112] := TEMP7[31:16];\n\n\nTEMP0[31:0] := SRC1[15:0] * SRC2[15:0] (*Signed Multiplication*)\nTEMP1[31:0] := SRC1[31:16] * SRC2[31:16]\nTEMP2[31:0] := SRC1[47:32] * SRC2[47:32]\nTEMP3[31:0] := SRC1[63:48] * SRC2[63:48]\nTEMP4[31:0] := SRC1[79:64] * SRC2[79:64]\nTEMP5[31:0] := SRC1[95:80] * SRC2[95:80]\nTEMP6[31:0] := SRC1[111:96] * SRC2[111:96]\nTEMP7[31:0] := SRC1[127:112] * SRC2[127:112]\nDEST[15:0] := TEMP0[31:16]\nDEST[31:16] := TEMP1[31:16]\nDEST[47:32] := TEMP2[31:16]\nDEST[63:48] := TEMP3[31:16]\nDEST[79:64] := TEMP4[31:16]\nDEST[95:80] := TEMP5[31:16]\nDEST[111:96] := TEMP6[31:16]\nDEST[127:112] := TEMP7[31:16]\nDEST[MAXVL-1:128] := 0\n\n\nTEMP0[31:0] := SRC1[15:0] * SRC2[15:0] (*Signed Multiplication*)\nTEMP1[31:0] := SRC1[31:16] * SRC2[31:16]\nTEMP2[31:0] := SRC1[47:32] * SRC2[47:32]\nTEMP3[31:0] := SRC1[63:48] * SRC2[63:48]\nTEMP4[31:0] := SRC1[79:64] * SRC2[79:64]\nTEMP5[31:0] := SRC1[95:80] * SRC2[95:80]\nTEMP6[31:0] := SRC1[111:96] * SRC2[111:96]\nTEMP7[31:0] := SRC1[127:112] * SRC2[127:112]\nTEMP8[31:0] := SRC1[143:128] * SRC2[143:128]\nTEMP9[31:0] := SRC1[159:144] * SRC2[159:144]\nTEMP10[31:0] := SRC1[175:160] * SRC2[175:160]\nTEMP11[31:0] := SRC1[191:176] * SRC2[191:176]\nTEMP12[31:0] := SRC1[207:192] * SRC2[207:192]\nTEMP13[31:0] := SRC1[223:208] * SRC2[223:208]\nTEMP14[31:0] := SRC1[239:224] * SRC2[239:224]\nTEMP15[31:0] := SRC1[255:240] * SRC2[255:240]\nDEST[15:0] := TEMP0[31:16]\nDEST[31:16] := TEMP1[31:16]\nDEST[47:32] := TEMP2[31:16]\nDEST[63:48] := TEMP3[31:16]\nDEST[79:64] := TEMP4[31:16]\nDEST[95:80] := TEMP5[31:16]\nDEST[111:96] := TEMP6[31:16]\nDEST[127:112] := TEMP7[31:16]\nDEST[143:128] := TEMP8[31:16]\nDEST[159:144] := TEMP9[31:16]\nDEST[175:160] := TEMP10[31:16]\nDEST[191:176] := TEMP11[31:16]\nDEST[207:192] := TEMP12[31:16]\nDEST[223:208] := TEMP13[31:16]\nDEST[239:224] := TEMP14[31:16]\nDEST[255:240] := TEMP15[31:16]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n temp[31:0] := SRC1[i+15:i] * SRC2[i+15:i]\n DEST[i+15:i] := tmp[31:16]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmulhw" + }, + "pmulld": { + "instruction": "PMULLD", + "title": "PMULLD/PMULLQ\n\t\t— Multiply Packed Integers and Store Low Result", + "opcode": "66 0F 38 40 /r PMULLD xmm1, xmm2/m128", + "description": "Performs a SIMD signed multiply of the packed signed dword/qword integers from each element of the first source operand with the corresponding element in the second source operand. The low 32/64 bits of each 64/128-bit intermediate results are stored to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register; The second source operand is a YMM register or 256-bit memory location. Bits (MAXVL-1:256) of the corresponding destination ZMM register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN Temp[127:0] := SRC1[i+63:i] * SRC2[63:0]\n ELSE Temp[127:0] := SRC1[i+63:i] * SRC2[i+63:i]\n FI;\n DEST[i+63:i] := Temp[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN Temp[63:0] := SRC1[i+31:i] * SRC2[31:0]\n ELSE Temp[63:0] := SRC1[i+31:i] * SRC2[i+31:i]\n FI;\n DEST[i+31:i] := Temp[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nTemp0[63:0] := SRC1[31:0] * SRC2[31:0]\nTemp1[63:0] := SRC1[63:32] * SRC2[63:32]\nTemp2[63:0] := SRC1[95:64] * SRC2[95:64]\nTemp3[63:0] := SRC1[127:96] * SRC2[127:96]\nTemp4[63:0] := SRC1[159:128] * SRC2[159:128]\nTemp5[63:0] := SRC1[191:160] * SRC2[191:160]\nTemp6[63:0] := SRC1[223:192] * SRC2[223:192]\nTemp7[63:0] := SRC1[255:224] * SRC2[255:224]\nDEST[31:0] := Temp0[31:0]\nDEST[63:32] := Temp1[31:0]\nDEST[95:64] := Temp2[31:0]\nDEST[127:96] := Temp3[31:0]\nDEST[159:128] := Temp4[31:0]\nDEST[191:160] := Temp5[31:0]\nDEST[223:192] := Temp6[31:0]\nDEST[255:224] := Temp7[31:0]\nDEST[MAXVL-1:256] := 0\n\n\nTemp0[63:0] := SRC1[31:0] * SRC2[31:0]\nTemp1[63:0] := SRC1[63:32] * SRC2[63:32]\nTemp2[63:0] := SRC1[95:64] * SRC2[95:64]\nTemp3[63:0] := SRC1[127:96] * SRC2[127:96]\nDEST[31:0] := Temp0[31:0]\nDEST[63:32] := Temp1[31:0]\nDEST[95:64] := Temp2[31:0]\nDEST[127:96] := Temp3[31:0]\nDEST[MAXVL-1:128] := 0\n\n\nTemp0[63:0] := DEST[31:0] * SRC[31:0]\nTemp1[63:0] := DEST[63:32] * SRC[63:32]\nTemp2[63:0] := DEST[95:64] * SRC[95:64]\nTemp3[63:0] := DEST[127:96] * SRC[127:96]\nDEST[31:0] := Temp0[31:0]\nDEST[63:32] := Temp1[31:0]\nDEST[95:64] := Temp2[31:0]\nDEST[127:96] := Temp3[31:0]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/pmulld:pmullq" + }, + "pmullq": { + "instruction": "PMULLQ", + "title": "PMULLD/PMULLQ\n\t\t— Multiply Packed Integers and Store Low Result", + "opcode": "66 0F 38 40 /r PMULLD xmm1, xmm2/m128", + "description": "Performs a SIMD signed multiply of the packed signed dword/qword integers from each element of the first source operand with the corresponding element in the second source operand. The low 32/64 bits of each 64/128-bit intermediate results are stored to the destination operand.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register; The second source operand is a YMM register or 256-bit memory location. Bits (MAXVL-1:256) of the corresponding destination ZMM register are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b == 1) AND (SRC2 *is memory*)\n THEN Temp[127:0] := SRC1[i+63:i] * SRC2[63:0]\n ELSE Temp[127:0] := SRC1[i+63:i] * SRC2[i+63:i]\n FI;\n DEST[i+63:i] := Temp[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN Temp[63:0] := SRC1[i+31:i] * SRC2[31:0]\n ELSE Temp[63:0] := SRC1[i+31:i] * SRC2[i+31:i]\n FI;\n DEST[i+31:i] := Temp[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nTemp0[63:0] := SRC1[31:0] * SRC2[31:0]\nTemp1[63:0] := SRC1[63:32] * SRC2[63:32]\nTemp2[63:0] := SRC1[95:64] * SRC2[95:64]\nTemp3[63:0] := SRC1[127:96] * SRC2[127:96]\nTemp4[63:0] := SRC1[159:128] * SRC2[159:128]\nTemp5[63:0] := SRC1[191:160] * SRC2[191:160]\nTemp6[63:0] := SRC1[223:192] * SRC2[223:192]\nTemp7[63:0] := SRC1[255:224] * SRC2[255:224]\nDEST[31:0] := Temp0[31:0]\nDEST[63:32] := Temp1[31:0]\nDEST[95:64] := Temp2[31:0]\nDEST[127:96] := Temp3[31:0]\nDEST[159:128] := Temp4[31:0]\nDEST[191:160] := Temp5[31:0]\nDEST[223:192] := Temp6[31:0]\nDEST[255:224] := Temp7[31:0]\nDEST[MAXVL-1:256] := 0\n\n\nTemp0[63:0] := SRC1[31:0] * SRC2[31:0]\nTemp1[63:0] := SRC1[63:32] * SRC2[63:32]\nTemp2[63:0] := SRC1[95:64] * SRC2[95:64]\nTemp3[63:0] := SRC1[127:96] * SRC2[127:96]\nDEST[31:0] := Temp0[31:0]\nDEST[63:32] := Temp1[31:0]\nDEST[95:64] := Temp2[31:0]\nDEST[127:96] := Temp3[31:0]\nDEST[MAXVL-1:128] := 0\n\n\nTemp0[63:0] := DEST[31:0] * SRC[31:0]\nTemp1[63:0] := DEST[63:32] * SRC[63:32]\nTemp2[63:0] := DEST[95:64] * SRC[95:64]\nTemp3[63:0] := DEST[127:96] * SRC[127:96]\nDEST[31:0] := Temp0[31:0]\nDEST[63:32] := Temp1[31:0]\nDEST[95:64] := Temp2[31:0]\nDEST[127:96] := Temp3[31:0]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/pmulld:pmullq" + }, + "pmullw": { + "instruction": "PMULLW", + "title": "PMULLW\n\t\t— Multiply Packed Signed Integers and Store Low Result", + "opcode": "NP 0F D5 /r1 PMULLW mm, mm/m64", + "description": "Performs a SIMD signed multiply of the packed signed word integers in the destination operand (first operand) and the source operand (second operand), and stores the low 16 bits of each intermediate 32-bit result in the destination operand. (Figure 4-12 shows this operation when using 64-bit operands.)\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L must be 0, otherwise the instruction will #UD.\nVEX.256 encoded version: The second source operand can be an YMM register or a 256-bit memory location. The first source and destination operands are YMM registers.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand is conditionally updated based on writemask k1.", + "operation": "TEMP0[31:0] := DEST[15:0] ∗ SRC[15:0]; (* Signed multiplication *)\nTEMP1[31:0] := DEST[31:16] ∗ SRC[31:16];\nTEMP2[31:0] := DEST[47:32] ∗ SRC[47:32];\nTEMP3[31:0] := DEST[63:48] ∗ SRC[63:48];\nDEST[15:0] := TEMP0[15:0];\nDEST[31:16] := TEMP1[15:0];\nDEST[47:32] := TEMP2[15:0];\nDEST[63:48] := TEMP3[15:0];\n\n\n TEMP0[31:0] := DEST[15:0] ∗ SRC[15:0]; (* Signed multiplication *)\n TEMP1[31:0] := DEST[31:16] ∗ SRC[31:16];\n TEMP2[31:0] := DEST[47:32] ∗ SRC[47:32];\n TEMP3[31:0] := DEST[63:48] ∗ SRC[63:48];\n TEMP4[31:0] := DEST[79:64] ∗ SRC[79:64];\n TEMP5[31:0] := DEST[95:80] ∗ SRC[95:80];\n TEMP6[31:0] := DEST[111:96] ∗ SRC[111:96];\n TEMP7[31:0] := DEST[127:112] ∗ SRC[127:112];\n DEST[15:0] := TEMP0[15:0];\n DEST[31:16] := TEMP1[15:0];\n DEST[47:32] := TEMP2[15:0];\n DEST[63:48] := TEMP3[15:0];\n DEST[79:64] := TEMP4[15:0];\n DEST[95:80] := TEMP5[15:0];\n DEST[111:96] := TEMP6[15:0];\n DEST[127:112] := TEMP7[15:0];\nDEST[MAXVL-1:256] := 0\n\n\nTemp0[31:0] := SRC1[15:0] * SRC2[15:0]\nTemp1[31:0] := SRC1[31:16] * SRC2[31:16]\nTemp2[31:0] := SRC1[47:32] * SRC2[47:32]\nTemp3[31:0] := SRC1[63:48] * SRC2[63:48]\nTemp4[31:0] := SRC1[79:64] * SRC2[79:64]\nTemp5[31:0] := SRC1[95:80] * SRC2[95:80]\nTemp6[31:0] := SRC1[111:96] * SRC2[111:96]\nTemp7[31:0] := SRC1[127:112] * SRC2[127:112]\nDEST[15:0] := Temp0[15:0]\nDEST[31:16] := Temp1[15:0]\nDEST[47:32] := Temp2[15:0]\nDEST[63:48] := Temp3[15:0]\nDEST[79:64] := Temp4[15:0]\nDEST[95:80] := Temp5[15:0]\nDEST[111:96] := Temp6[15:0]\nDEST[127:112] := Temp7[15:0]\nDEST[MAXVL-1:128] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN\n temp[31:0] := SRC1[i+15:i] * SRC2[i+15:i]\n DEST[i+15:i] := temp[15:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmullw" + }, + "pmuludq": { + "instruction": "PMULUDQ", + "title": "PMULUDQ\n\t\t— Multiply Packed Unsigned Doubleword Integers", + "opcode": "NP 0F F4 /r1 PMULUDQ mm1, mm2/m64", + "description": "Multiplies the first operand (destination operand) by the second operand (source operand) and stores the result in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The source operand can be an unsigned doubleword integer stored in the low doubleword of an MMX technology register or a 64-bit memory location. The destination operand can be an unsigned doubleword integer stored in the low doubleword an MMX technology register. The result is an unsigned\nquadword integer stored in the destination an MMX technology register. When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around and the low 64 bits are written to the destination element (that is, the carry is ignored).\nFor 64-bit memory operands, 64 bits are fetched from memory, but only the low doubleword is used in the computation.\n128-bit Legacy SSE version: The second source operand is two packed unsigned doubleword integers stored in the first (low) and third doublewords of an XMM register or a 128-bit memory location. For 128-bit memory operands, 128 bits are fetched from memory, but only the first and third doublewords are used in the computation. The first source operand is two packed unsigned doubleword integers stored in the first and third doublewords of an XMM register. The destination contains two packed unsigned quadword integers stored in an XMM register. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is two packed unsigned doubleword integers stored in the first (low) and third doublewords of an XMM register or a 128-bit memory location. For 128-bit memory operands, 128 bits are fetched from memory, but only the first and third doublewords are used in the computation. The first source operand is two packed unsigned doubleword integers stored in the first and third doublewords of an XMM register. The destination contains two packed unsigned quadword integers stored in an XMM register. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is four packed unsigned doubleword integers stored in the first (low), third, fifth, and seventh doublewords of a YMM register or a 256-bit memory location. For 256-bit memory operands, 256 bits are fetched from memory, but only the first, third, fifth, and seventh doublewords are used in the computation. The first source operand is four packed unsigned doubleword integers stored in the first, third, fifth, and seventh doublewords of an YMM register. The destination contains four packed unaligned quadword integers stored in an YMM register.\nEVEX encoded version: The input unsigned doubleword integers are taken from the even-numbered elements of the source operands. The first source operand is a ZMM/YMM/XMM registers. The second source operand can be an ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination is a ZMM/YMM/XMM register, and updated according to the writemask at 64-bit granularity.", + "operation": "DEST[63:0] := DEST[31:0] ∗ SRC[31:0];\n\n\nDEST[63:0] := DEST[31:0] ∗ SRC[31:0];\nDEST[127:64] := DEST[95:64] ∗ SRC[95:64];\n\n\nDEST[63:0] := SRC1[31:0] * SRC2[31:0]\nDEST[127:64] := SRC1[95:64] * SRC2[95:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[31:0] * SRC2[31:0]\nDEST[127:64] := SRC1[95:64] * SRC2[95:64\nDEST[191:128] := SRC1[159:128] * SRC2[159:128]\nDEST[255:192] := SRC1[223:192] * SRC2[223:192]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := ZeroExtend64( SRC1[i+31:i]) * ZeroExtend64( SRC2[31:0] )\n ELSE DEST[i+63:i] := ZeroExtend64( SRC1[i+31:i]) * ZeroExtend64( SRC2[i+31:i] )\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pmuludq" + }, + "pop": { + "instruction": "POP", + "title": "POP\n\t\t— Pop a Value From the Stack", + "opcode": "8F /0", + "description": "Loads the value from the top of the stack to the location specified with the destination operand (or explicit opcode) and then increments the stack pointer. The destination operand can be a general-purpose register, memory location, or segment register.\nAddress and operand sizes are determined and used as follows:\nThe address size is used only when writing to a destination operand in memory.\nThe operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is incremented (2, 4 or 8).\nThe stack-address size determines the width of the stack pointer when reading from the stack in memory and when incrementing the stack pointer. (As stated above, the amount by which the stack pointer is incremented is determined by the operand size.)\nIf the destination operand is one of the segment registers DS, ES, FS, GS, or SS, the value loaded into the register must be a valid segment selector. In protected mode, popping a segment selector into a segment register automat-\nically causes the descriptor information associated with that segment selector to be loaded into the hidden (shadow) part of the segment register and causes the selector and the descriptor information to be validated (see the “Operation” section below).\nA NULL value (0000-0003) may be popped into the DS, ES, FS, or GS register without causing a general protection fault. However, any subsequent attempt to reference a segment whose corresponding segment register is loaded with a NULL value causes a general protection exception (#GP). In this situation, no memory reference occurs and the saved value of the segment register is NULL.\nThe POP instruction cannot pop a value into the CS register. To load the CS register from the stack, use the RET instruction.\nIf the ESP register is used as a base register for addressing a destination operand in memory, the POP instruction computes the effective address of the operand after it increments the ESP register. For the case of a 16-bit stack where ESP wraps to 0H as a result of the POP instruction, the resulting location of the memory write is processor-family-specific.\nThe POP ESP instruction increments the stack pointer (ESP) before data at the old top of stack is written into the destination.\nLoading the SS register with a POP instruction suppresses or inhibits some debug exceptions and inhibits interrupts on the following instruction boundary. (The inhibition ends after delivery of an exception or the execution of the next instruction.) This behavior allows a stack pointer to be loaded into the ESP register with the next instruction (POP ESP) before an event can be delivered. See Section 6.8.3, “Masking Exceptions and Interrupts When Switching Stacks,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A. Intel recommends that software use the LSS instruction to load the SS register and ESP together.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). When in 64-bit mode, POPs using 32-bit operands are not encodable and POPs to DS, ES, SS are not valid. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF StackAddrSize = 32\n THEN\n IF OperandSize = 32\n THEN\n DEST := SS:ESP; (* Copy a doubleword *)\n ESP := ESP + 4;\n ELSE (* OperandSize = 16*)\n DEST := SS:ESP; (* Copy a word *)\n ESP := ESP + 2;\n FI;\n ELSE IF StackAddrSize = 64\n THEN\n IF OperandSize = 64\n THEN\n DEST := SS:RSP; (* Copy quadword *)\n RSP := RSP + 8;\n ELSE (* OperandSize = 16*)\n DEST := SS:RSP; (* Copy a word *)\n RSP := RSP + 2;\n FI;\n FI;\n ELSE StackAddrSize = 16\n THEN\n IF OperandSize = 16\n THEN\n DEST := SS:SP; (* Copy a word *)\n SP := SP + 2;\n ELSE (* OperandSize = 32 *)\n DEST := SS:SP; (* Copy a doubleword *)\n SP := SP + 4;\n FI;\nFI;\nLoading a segment register while in protected mode results in special actions, as described in the following listing.\nThese checks are performed on the segment selector and the segment descriptor it points to.\n64-BIT_MODE\nIF FS, or GS is loaded with non-NULL selector;\n THEN\n IF segment selector index is outside descriptor table limits\n OR segment is not a data or readable code segment\n OR ((segment is a data or nonconforming code segment)\n AND ((RPL > DPL) or (CPL > DPL))\n THEN #GP(selector);\n IF segment not marked present\n THEN #NP(selector);\n ELSE\n SegmentRegister := segment selector;\n SegmentRegister := segment descriptor;\n FI;\nFI;\nIF FS, or GS is loaded with a NULL selector;\n THEN\n SegmentRegister := segment selector;\n SegmentRegister := segment descriptor;\nFI;\nPREOTECTED MODE OR COMPATIBILITY MODE;\nIF SS is loaded;\n THEN\n IF segment selector is NULL\n THEN #GP(0);\n FI;\n IF segment selector index is outside descriptor table limits\n or segment selector's RPL ≠ CPL\n or segment is not a writable data segment\n or DPL ≠ CPL\n THEN #GP(selector);\n FI;\n IF segment not marked present\n THEN #SS(selector);\n ELSE\n SS := segment selector;\n SS := segment descriptor;\n FI;\nFI;\nIF DS, ES, FS, or GS is loaded with non-NULL selector;\n THEN\n IF segment selector index is outside descriptor table limits\n or segment is not a data or readable code segment\n or ((segment is a data or nonconforming code segment)\n and ((RPL > DPL) or (CPL > DPL))\n THEN #GP(selector);\n FI;\n IF segment not marked present\n THEN #NP(selector);\n ELSE\n SegmentRegister := segment selector;\n SegmentRegister := segment descriptor;\n FI;\nFI;\nIF DS, ES, FS, or GS is loaded with a NULL selector\n THEN\n SegmentRegister := segment selector;\n SegmentRegister := segment descriptor;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/pop" + }, + "popa": { + "instruction": "POPA", + "title": "POPA/POPAD\n\t\t— Pop All General-Purpose Registers", + "opcode": "61", + "description": "Pops doublewords (POPAD) or words (POPA) from the stack into the general-purpose registers. The registers are loaded in the following order: EDI, ESI, EBP, EBX, EDX, ECX, and EAX (if the operand-size attribute is 32) and DI, SI, BP, BX, DX, CX, and AX (if the operand-size attribute is 16). (These instructions reverse the operation of the PUSHA/PUSHAD instructions.) The value on the stack for the ESP or SP register is ignored. Instead, the ESP or SP register is incremented after each register is loaded.\nThe POPA (pop all) and POPAD (pop all double) mnemonics reference the same opcode. The POPA instruction is intended for use when the operand-size attribute is 16 and the POPAD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when POPA is used and to 32 when POPAD is used (using the operand-size override prefix [66H] if necessary). Others may treat these mnemonics as synonyms (POPA/POPAD) and use the current setting of the operand-size attribute to determine the size of values to be popped from the stack, regardless of the mnemonic used. (The D flag in the current code segment’s segment descriptor determines the operand-size attribute.)\nThis instruction executes as described in non-64-bit modes. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\nELSE\n IF OperandSize = 32 (* Instruction = POPAD *)\n THEN\n EDI := Pop();\n ESI := Pop();\n EBP := Pop();\n Increment ESP by 4; (* Skip next 4 bytes of stack *)\n EBX := Pop();\n EDX := Pop();\n ECX := Pop();\n EAX := Pop();\n ELSE (* OperandSize = 16, instruction = POPA *)\n DI := Pop();\n SI := Pop();\n BP := Pop();\n Increment ESP by 2; (* Skip next 2 bytes of stack *)\n BX := Pop();\n DX := Pop();\n CX := Pop();\n AX := Pop();\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/popa:popad" + }, + "popad": { + "instruction": "POPAD", + "title": "POPA/POPAD\n\t\t— Pop All General-Purpose Registers", + "opcode": "61", + "description": "Pops doublewords (POPAD) or words (POPA) from the stack into the general-purpose registers. The registers are loaded in the following order: EDI, ESI, EBP, EBX, EDX, ECX, and EAX (if the operand-size attribute is 32) and DI, SI, BP, BX, DX, CX, and AX (if the operand-size attribute is 16). (These instructions reverse the operation of the PUSHA/PUSHAD instructions.) The value on the stack for the ESP or SP register is ignored. Instead, the ESP or SP register is incremented after each register is loaded.\nThe POPA (pop all) and POPAD (pop all double) mnemonics reference the same opcode. The POPA instruction is intended for use when the operand-size attribute is 16 and the POPAD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when POPA is used and to 32 when POPAD is used (using the operand-size override prefix [66H] if necessary). Others may treat these mnemonics as synonyms (POPA/POPAD) and use the current setting of the operand-size attribute to determine the size of values to be popped from the stack, regardless of the mnemonic used. (The D flag in the current code segment’s segment descriptor determines the operand-size attribute.)\nThis instruction executes as described in non-64-bit modes. It is not valid in 64-bit mode.", + "operation": "IF 64-Bit Mode\n THEN\n #UD;\nELSE\n IF OperandSize = 32 (* Instruction = POPAD *)\n THEN\n EDI := Pop();\n ESI := Pop();\n EBP := Pop();\n Increment ESP by 4; (* Skip next 4 bytes of stack *)\n EBX := Pop();\n EDX := Pop();\n ECX := Pop();\n EAX := Pop();\n ELSE (* OperandSize = 16, instruction = POPA *)\n DI := Pop();\n SI := Pop();\n BP := Pop();\n Increment ESP by 2; (* Skip next 2 bytes of stack *)\n BX := Pop();\n DX := Pop();\n CX := Pop();\n AX := Pop();\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/popa:popad" + }, + "popcnt": { + "instruction": "POPCNT", + "title": "POPCNT\n\t\t— Return the Count of Number of Bits Set to 1", + "opcode": "F3 0F B8 /r", + "description": "This instruction calculates the number of bits set to 1 in the second operand (source) and returns the count in the first operand (a destination register).", + "operation": "Count = 0;\nFor (i=0; i < OperandSize; i++)\n{ IF (SRC[ i] = 1) // i’th bit\n THEN Count++; FI;\n}\nDEST := Count;\n", + "url": "https://www.felixcloutier.com/x86/popcnt" + }, + "popf": { + "instruction": "POPF", + "title": "POPF/POPFD/POPFQ\n\t\t— Pop Stack Into EFLAGS Register", + "opcode": "9D", + "description": "Pops a doubleword (POPFD) from the top of the stack (if the current operand-size attribute is 32) and stores the value in the EFLAGS register, or pops a word from the top of the stack (if the operand-size attribute is 16) and stores it in the lower 16 bits of the EFLAGS register (that is, the FLAGS register). These instructions reverse the operation of the PUSHF/PUSHFD/PUSHFQ instructions.\nThe POPF (pop flags) and POPFD (pop flags double) mnemonics reference the same opcode. The POPF instruction is intended for use when the operand-size attribute is 16; the POPFD instruction is intended for use when the operand-size attribute is 32. Some assemblers may force the operand size to 16 for POPF and to 32 for POPFD. Others may treat the mnemonics as synonyms (POPF/POPFD) and use the setting of the operand-size attribute to determine the size of values to pop from the stack.\nThe effect of POPF/POPFD on the EFLAGS register changes, depending on the mode of operation. See Table 4-16 and the key below for details.\nWhen operating in protected, compatibility, or 64-bit mode at privilege level 0 (or in real-address mode, the equivalent to privilege level 0), all non-reserved flags in the EFLAGS register except RF1, VIP, VIF, and VM may be modified. VIP, VIF, and VM remain unaffected.\nWhen operating in protected, compatibility, or 64-bit mode with a privilege level greater than 0, but less than or equal to IOPL, all flags can be modified except the IOPL field and RF, IF, VIP, VIF, and VM; these remain unaffected. The AC and ID flags can only be modified if the operand-size attribute is 32. The interrupt flag (IF) is altered only when executing at a level at least as privileged as the IOPL. If a POPF/POPFD instruction is executed with insufficient privilege, an exception does not occur but privileged bits do not change.\nWhen operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the POPF/POPFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), POPF (but not POPFD) can be executed in virtual-8086 mode with IOPL < 3.\n(The protected-mode virtual-interrupt feature — enabled by setting CR4.PVI — affects the CLI and STI instructions in the same manner as the virtual-8086 mode extensions. POPF, however, is not affected by CR4.PVI.)\nIn 64-bit mode, the mnemonic assigned is POPFQ (note that the 32-bit operand is not encodable). POPFQ pops 64 bits from the stack. Reserved bits of RFLAGS (including the upper 32 bits of RFLAGS) are not affected.\nSee Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS registers.", + "operation": "IF EFLAGS.VM = 0 (* Not in Virtual-8086 Mode *)\n THEN IF CPL = 0 OR CR0.PE = 0\n THEN\n IF OperandSize = 32;\n THEN\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;\n VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)\n ELSE IF (Operandsize = 64)\n RFLAGS = Pop(); (* 64-bit pop *)\n (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;\n VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)\n ELSE (* OperandSize = 16 *)\n EFLAGS[15:0] := Pop(); (* 16-bit pop *)\n (* All non-reserved flags can be modified. *)\n FI;\n ELSE (* CPL > 0 *)\n IF OperandSize = 32\n THEN\n IF CPL > IOPL\n THEN\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;\n IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n ELSE\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n FI;\n ELSE IF (Operandsize = 64)\n IF CPL > IOPL\n THEN\n RFLAGS := Pop(); (* 64-bit pop *)\n (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;\n IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n ELSE\n RFLAGS := Pop(); (* 64-bit pop *)\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n FI;\n ELSE (* OperandSize = 16 *)\n EFLAGS[15:0] := Pop(); (* 16-bit pop *)\n (* All non-reserved bits except IOPL can be modified; IOPL and all\n reserved bits are unaffected. *)\n FI;\n FI;\n ELSE (* In virtual-8086 mode *)\n IF IOPL = 3\n THEN\n IF OperandSize = 32\n THEN\n EFLAGS := Pop();\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n VIP, VIF, VM, IOPL, and all reserved bits are unaffected. RF is cleared. *)\n ELSE\n EFLAGS[15:0] := Pop(); FI;\n (* All non-reserved bits except IOPL can be modified; IOPL and all reserved bits are unaffected. *)\n FI;\n ELSE (* IOPL < 3 *)\n IF (Operandsize = 32) OR (CR4.VME = 0)\n THEN #GP(0); (* Trap to virtual-8086 monitor. *)\n ELSE (* Operandsize = 16 and CR4.VME = 1 *)\n tempFLAGS := Pop();\n IF (EFLAGS.VIP = 1 AND tempFLAGS[9] = 1) OR tempFLAGS[8] = 1\n THEN #GP(0);\n ELSE\n EFLAGS.VIF := tempFLAGS[9];\n EFLAGS[15:0] := tempFLAGS;\n (* All non-reserved bits except IOPL and IF can be modified;\n IOPL, IF, and all reserved bits are unaffected. *)\n FI;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/popf:popfd:popfq" + }, + "popfd": { + "instruction": "POPFD", + "title": "POPF/POPFD/POPFQ\n\t\t— Pop Stack Into EFLAGS Register", + "opcode": "9D", + "description": "Pops a doubleword (POPFD) from the top of the stack (if the current operand-size attribute is 32) and stores the value in the EFLAGS register, or pops a word from the top of the stack (if the operand-size attribute is 16) and stores it in the lower 16 bits of the EFLAGS register (that is, the FLAGS register). These instructions reverse the operation of the PUSHF/PUSHFD/PUSHFQ instructions.\nThe POPF (pop flags) and POPFD (pop flags double) mnemonics reference the same opcode. The POPF instruction is intended for use when the operand-size attribute is 16; the POPFD instruction is intended for use when the operand-size attribute is 32. Some assemblers may force the operand size to 16 for POPF and to 32 for POPFD. Others may treat the mnemonics as synonyms (POPF/POPFD) and use the setting of the operand-size attribute to determine the size of values to pop from the stack.\nThe effect of POPF/POPFD on the EFLAGS register changes, depending on the mode of operation. See Table 4-16 and the key below for details.\nWhen operating in protected, compatibility, or 64-bit mode at privilege level 0 (or in real-address mode, the equivalent to privilege level 0), all non-reserved flags in the EFLAGS register except RF1, VIP, VIF, and VM may be modified. VIP, VIF, and VM remain unaffected.\nWhen operating in protected, compatibility, or 64-bit mode with a privilege level greater than 0, but less than or equal to IOPL, all flags can be modified except the IOPL field and RF, IF, VIP, VIF, and VM; these remain unaffected. The AC and ID flags can only be modified if the operand-size attribute is 32. The interrupt flag (IF) is altered only when executing at a level at least as privileged as the IOPL. If a POPF/POPFD instruction is executed with insufficient privilege, an exception does not occur but privileged bits do not change.\nWhen operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the POPF/POPFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), POPF (but not POPFD) can be executed in virtual-8086 mode with IOPL < 3.\n(The protected-mode virtual-interrupt feature — enabled by setting CR4.PVI — affects the CLI and STI instructions in the same manner as the virtual-8086 mode extensions. POPF, however, is not affected by CR4.PVI.)\nIn 64-bit mode, the mnemonic assigned is POPFQ (note that the 32-bit operand is not encodable). POPFQ pops 64 bits from the stack. Reserved bits of RFLAGS (including the upper 32 bits of RFLAGS) are not affected.\nSee Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS registers.", + "operation": "IF EFLAGS.VM = 0 (* Not in Virtual-8086 Mode *)\n THEN IF CPL = 0 OR CR0.PE = 0\n THEN\n IF OperandSize = 32;\n THEN\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;\n VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)\n ELSE IF (Operandsize = 64)\n RFLAGS = Pop(); (* 64-bit pop *)\n (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;\n VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)\n ELSE (* OperandSize = 16 *)\n EFLAGS[15:0] := Pop(); (* 16-bit pop *)\n (* All non-reserved flags can be modified. *)\n FI;\n ELSE (* CPL > 0 *)\n IF OperandSize = 32\n THEN\n IF CPL > IOPL\n THEN\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;\n IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n ELSE\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n FI;\n ELSE IF (Operandsize = 64)\n IF CPL > IOPL\n THEN\n RFLAGS := Pop(); (* 64-bit pop *)\n (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;\n IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n ELSE\n RFLAGS := Pop(); (* 64-bit pop *)\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n FI;\n ELSE (* OperandSize = 16 *)\n EFLAGS[15:0] := Pop(); (* 16-bit pop *)\n (* All non-reserved bits except IOPL can be modified; IOPL and all\n reserved bits are unaffected. *)\n FI;\n FI;\n ELSE (* In virtual-8086 mode *)\n IF IOPL = 3\n THEN\n IF OperandSize = 32\n THEN\n EFLAGS := Pop();\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n VIP, VIF, VM, IOPL, and all reserved bits are unaffected. RF is cleared. *)\n ELSE\n EFLAGS[15:0] := Pop(); FI;\n (* All non-reserved bits except IOPL can be modified; IOPL and all reserved bits are unaffected. *)\n FI;\n ELSE (* IOPL < 3 *)\n IF (Operandsize = 32) OR (CR4.VME = 0)\n THEN #GP(0); (* Trap to virtual-8086 monitor. *)\n ELSE (* Operandsize = 16 and CR4.VME = 1 *)\n tempFLAGS := Pop();\n IF (EFLAGS.VIP = 1 AND tempFLAGS[9] = 1) OR tempFLAGS[8] = 1\n THEN #GP(0);\n ELSE\n EFLAGS.VIF := tempFLAGS[9];\n EFLAGS[15:0] := tempFLAGS;\n (* All non-reserved bits except IOPL and IF can be modified;\n IOPL, IF, and all reserved bits are unaffected. *)\n FI;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/popf:popfd:popfq" + }, + "popfq": { + "instruction": "POPFQ", + "title": "POPF/POPFD/POPFQ\n\t\t— Pop Stack Into EFLAGS Register", + "opcode": "9D", + "description": "Pops a doubleword (POPFD) from the top of the stack (if the current operand-size attribute is 32) and stores the value in the EFLAGS register, or pops a word from the top of the stack (if the operand-size attribute is 16) and stores it in the lower 16 bits of the EFLAGS register (that is, the FLAGS register). These instructions reverse the operation of the PUSHF/PUSHFD/PUSHFQ instructions.\nThe POPF (pop flags) and POPFD (pop flags double) mnemonics reference the same opcode. The POPF instruction is intended for use when the operand-size attribute is 16; the POPFD instruction is intended for use when the operand-size attribute is 32. Some assemblers may force the operand size to 16 for POPF and to 32 for POPFD. Others may treat the mnemonics as synonyms (POPF/POPFD) and use the setting of the operand-size attribute to determine the size of values to pop from the stack.\nThe effect of POPF/POPFD on the EFLAGS register changes, depending on the mode of operation. See Table 4-16 and the key below for details.\nWhen operating in protected, compatibility, or 64-bit mode at privilege level 0 (or in real-address mode, the equivalent to privilege level 0), all non-reserved flags in the EFLAGS register except RF1, VIP, VIF, and VM may be modified. VIP, VIF, and VM remain unaffected.\nWhen operating in protected, compatibility, or 64-bit mode with a privilege level greater than 0, but less than or equal to IOPL, all flags can be modified except the IOPL field and RF, IF, VIP, VIF, and VM; these remain unaffected. The AC and ID flags can only be modified if the operand-size attribute is 32. The interrupt flag (IF) is altered only when executing at a level at least as privileged as the IOPL. If a POPF/POPFD instruction is executed with insufficient privilege, an exception does not occur but privileged bits do not change.\nWhen operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the POPF/POPFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), POPF (but not POPFD) can be executed in virtual-8086 mode with IOPL < 3.\n(The protected-mode virtual-interrupt feature — enabled by setting CR4.PVI — affects the CLI and STI instructions in the same manner as the virtual-8086 mode extensions. POPF, however, is not affected by CR4.PVI.)\nIn 64-bit mode, the mnemonic assigned is POPFQ (note that the 32-bit operand is not encodable). POPFQ pops 64 bits from the stack. Reserved bits of RFLAGS (including the upper 32 bits of RFLAGS) are not affected.\nSee Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS registers.", + "operation": "IF EFLAGS.VM = 0 (* Not in Virtual-8086 Mode *)\n THEN IF CPL = 0 OR CR0.PE = 0\n THEN\n IF OperandSize = 32;\n THEN\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;\n VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)\n ELSE IF (Operandsize = 64)\n RFLAGS = Pop(); (* 64-bit pop *)\n (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;\n VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)\n ELSE (* OperandSize = 16 *)\n EFLAGS[15:0] := Pop(); (* 16-bit pop *)\n (* All non-reserved flags can be modified. *)\n FI;\n ELSE (* CPL > 0 *)\n IF OperandSize = 32\n THEN\n IF CPL > IOPL\n THEN\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;\n IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n ELSE\n EFLAGS := Pop(); (* 32-bit pop *)\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n FI;\n ELSE IF (Operandsize = 64)\n IF CPL > IOPL\n THEN\n RFLAGS := Pop(); (* 64-bit pop *)\n (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;\n IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n ELSE\n RFLAGS := Pop(); (* 64-bit pop *)\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)\n FI;\n ELSE (* OperandSize = 16 *)\n EFLAGS[15:0] := Pop(); (* 16-bit pop *)\n (* All non-reserved bits except IOPL can be modified; IOPL and all\n reserved bits are unaffected. *)\n FI;\n FI;\n ELSE (* In virtual-8086 mode *)\n IF IOPL = 3\n THEN\n IF OperandSize = 32\n THEN\n EFLAGS := Pop();\n (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;\n VIP, VIF, VM, IOPL, and all reserved bits are unaffected. RF is cleared. *)\n ELSE\n EFLAGS[15:0] := Pop(); FI;\n (* All non-reserved bits except IOPL can be modified; IOPL and all reserved bits are unaffected. *)\n FI;\n ELSE (* IOPL < 3 *)\n IF (Operandsize = 32) OR (CR4.VME = 0)\n THEN #GP(0); (* Trap to virtual-8086 monitor. *)\n ELSE (* Operandsize = 16 and CR4.VME = 1 *)\n tempFLAGS := Pop();\n IF (EFLAGS.VIP = 1 AND tempFLAGS[9] = 1) OR tempFLAGS[8] = 1\n THEN #GP(0);\n ELSE\n EFLAGS.VIF := tempFLAGS[9];\n EFLAGS[15:0] := tempFLAGS;\n (* All non-reserved bits except IOPL and IF can be modified;\n IOPL, IF, and all reserved bits are unaffected. *)\n FI;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/popf:popfd:popfq" + }, + "por": { + "instruction": "POR", + "title": "POR\n\t\t— Bitwise Logical OR", + "opcode": "NP 0F EB /r1 POR mm, mm/m64", + "description": "Performs a bitwise logical OR operation on the source operand (second operand) and the destination operand (first operand) and stores the result in the destination operand. Each bit of the result is set to 1 if either or both of the corresponding bits of the first and second operands are 1; otherwise, it is set to 0.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source and destination operands can be XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source and destination operands can be XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or a 256-bit memory location. The first source and destination operands can be YMM registers.\nEVEX encoded version: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with write-mask k1 at 32/64-bit granularity.", + "operation": "DEST := DEST OR SRC\n\n\nDEST := DEST OR SRC\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST := SRC1 OR SRC2\nDEST[MAXVL-1:128] := 0\n\n\nDEST := SRC1 OR SRC2\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] BITWISE OR SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] BITWISE OR SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n *DEST[i+31:i] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI;\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/por" + }, + "prefetchh": { + "instruction": "PREFETCHH", + "title": "PREFETCHh\n\t\t— Prefetch Data Into Caches", + "opcode": "0F 18 /1", + "description": "Fetches the line of data from memory that contains the byte specified with the source operand to a location in the cache hierarchy specified by a locality hint:\nThe source operand is a byte memory location. (The locality hints are encoded into the machine level instruction using bits 3 through 5 of the ModR/M byte.)\nIf the line selected is already present in the cache hierarchy at a level closer to the processor, no data movement occurs. Prefetches from uncacheable or WC memory are ignored.\nThe PREFETCHh instruction is merely a hint and does not affect program behavior. If executed, this instruction moves data closer to the processor in anticipation of future use.\nThe implementation of prefetch locality hints is implementation-dependent, and can be overloaded or ignored by a processor implementation. The amount of data prefetched is also processor implementation-dependent. It will, however, be a minimum of 32 bytes. Additional details of the implementation-dependent locality hints are described in Section 7.4 of Intel® 64 and IA-32 Architectures Optimization Reference Manual.\nIt should be noted that processors are free to speculatively fetch and cache data from system memory regions that are assigned a memory-type that permits speculative reads (that is, the WB, WC, and WT memory types). A PREFETCHh instruction is considered a hint to this speculative behavior. Because this speculative fetching can occur at any time and is not tied to instruction execution, a PREFETCHh instruction is not ordered with respect to the fence instructions (MFENCE, SFENCE, and LFENCE) or locked memory references. A PREFETCHh instruction is also unordered with respect to CLFLUSH and CLFLUSHOPT instructions, other PREFETCHh instructions, or any other general instruction. It is ordered with respect to serializing instructions such as CPUID, WRMSR, OUT, and MOV CR.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FETCH (m8);\n", + "url": "https://www.felixcloutier.com/x86/prefetchh" + }, + "prefetchw": { + "instruction": "PREFETCHW", + "title": "PREFETCHW\n\t\t— Prefetch Data Into Caches in Anticipation of a Write", + "opcode": "0F 0D /1 PREFETCHW m8", + "description": "Fetches the cache line of data from memory that contains the byte specified with the source operand to a location in the 1st or 2nd level cache and invalidates other cached instances of the line.\nThe source operand is a byte memory location. If the line selected is already present in the lowest level cache and is already in an exclusively owned state, no data movement occurs. Prefetches from non-writeback memory are ignored.\nThe PREFETCHW instruction is merely a hint and does not affect program behavior. If executed, this instruction moves data closer to the processor and invalidates other cached copies in anticipation of the line being written to in the future.\nThe characteristic of prefetch locality hints is implementation-dependent, and can be overloaded or ignored by a processor implementation. The amount of data prefetched is also processor implementation-dependent. It will, however, be a minimum of 32 bytes. Additional details of the implementation-dependent locality hints are described in Section 7.4 of Intel® 64 and IA-32 Architectures Optimization Reference Manual.\nIt should be noted that processors are free to speculatively fetch and cache data with exclusive ownership from system memory regions that permit such accesses (that is, the WB memory type). A PREFETCHW instruction is considered a hint to this speculative behavior. Because this speculative fetching can occur at any time and is not tied to instruction execution, a PREFETCHW instruction is not ordered with respect to the fence instructions (MFENCE, SFENCE, and LFENCE) or locked memory references. A PREFETCHW instruction is also unordered with respect to CLFLUSH and CLFLUSHOPT instructions, other PREFETCHW instructions, or any other general instruction\nIt is ordered with respect to serializing instructions such as CPUID, WRMSR, OUT, and MOV CR.\nThis instruction's operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "FETCH_WITH_EXCLUSIVE_OWNERSHIP (m8);\n", + "url": "https://www.felixcloutier.com/x86/prefetchw" + }, + "prefetchwt1": { + "instruction": "PREFETCHWT1", + "title": "PREFETCHWT1\n\t\t— Prefetch Vector Data Into Caches With Intent to Write and T1 Hint", + "opcode": "0F 0D /2 PREFETCHWT1 m8", + "description": "Fetches the line of data from memory that contains the byte specified with the source operand to a location in the cache hierarchy specified by an intent to write hint (so that data is brought into ‘Exclusive’ state via a request for ownership) and a locality hint:\nThe source operand is a byte memory location. (The locality hints are encoded into the machine level instruction using bits 3 through 5 of the ModR/M byte. Use of any ModR/M value other than the specified ones will lead to unpredictable behavior.)\nIf the line selected is already present in the cache hierarchy at a level closer to the processor, no data movement occurs. Prefetches from uncacheable or WC memory are ignored.\nThe PREFETCHWT1 instruction is merely a hint and does not affect program behavior. If executed, this instruction moves data closer to the processor in anticipation of future use.\nThe implementation of prefetch locality hints is implementation-dependent, and can be overloaded or ignored by a processor implementation. The amount of data prefetched is also processor implementation-dependent. It will, however, be a minimum of 32 bytes. Additional details of the implementation-dependent locality hints are described in Section 9.5, “Memory Optimization Using Prefetch” of the Intel® 64 and IA-32 Architectures Optimization Reference Manual.\nIt should be noted that processors are free to speculatively fetch and cache data from system memory regions that are assigned a memory-type that permits speculative reads (that is, the WB, WC, and WT memory types). A PREFETCHWT1 instruction is considered a hint to this speculative behavior. Because this speculative fetching can occur at any time and is not tied to instruction execution, a PREFETCHWT1 instruction is not ordered with respect to the fence instructions (MFENCE, SFENCE, and LFENCE) or locked memory references. A PREFETCHWT1 instruction is also unordered with respect to CLFLUSH and CLFLUSHOPT instructions, other PREFETCHWT1 instructions, or any other general instruction. It is ordered with respect to serializing instructions such as CPUID, WRMSR, OUT, and MOV CR.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "PREFETCH(mem, Level, State) Prefetches a byte memory location pointed by ‘mem’ into the cache level specified by ‘Level’; a request\nfor exclusive/ownership is done if ‘State’ is 1. Note that the memory location ignore cache line splits. This operation is considered a\nhint for the processor and may be skipped depending on implementation.\nPrefetch (m8, Level = 1, EXCLUSIVE=1);\n", + "url": "https://www.felixcloutier.com/x86/prefetchwt1" + }, + "psadbw": { + "instruction": "PSADBW", + "title": "PSADBW\n\t\t— Compute Sum of Absolute Differences", + "opcode": "NP 0F F6 /r1 PSADBW mm1, mm2/m64", + "description": "Computes the absolute value of the difference of 8 unsigned byte integers from the source operand (second operand) and from the destination operand (first operand). These 8 differences are then summed to produce an unsigned word integer result that is stored in the destination operand. Figure 4-14 shows the operation of the PSADBW instruction when using 64-bit operands.\nWhen operating on 64-bit operands, the word integer result is stored in the low word of the destination operand, and the remaining bytes in the destination operand are cleared to all 0s.\nWhen operating on 128-bit operands, two packed results are computed. Here, the 8 low-order bytes of the source and destination operands are operated on to produce a word result that is stored in the low word of the destination operand, and the 8 high-order bytes are operated on to produce a word result that is stored in bits 64 through 79 of the destination operand. The remaining bytes of the destination operand are cleared.\nFor 256-bit version, the third group of 8 differences are summed to produce an unsigned word in bits[143:128] of the destination register and the fourth group of 8 differences are summed to produce an unsigned word in bits[207:192] of the destination register. The remaining words of the destination are set to 0.\nFor 512-bit version, the fifth group result is stored in bits [271:256] of the destination. The result from the sixth group is stored in bits [335:320]. The results for the seventh and eighth group are stored respectively in bits [399:384] and bits [463:447], respectively. The remaining bits in the destination are set to 0.\nIn 64-bit mode and not encoded by VEX/EVEX prefix, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE version: The first source operand and destination register are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\nVEX.128 and EVEX.128 encoded versions: The first source operand and destination register are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding ZMM register are zeroed.\nVEX.256 and EVEX.256 encoded versions: The first source operand and destination register are YMM registers. The second source operand is an YMM register or a 256-bit memory location. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX.512 encoded version: The first source operand and destination register are ZMM registers. The second source operand is a ZMM register or a 512-bit memory location.", + "operation": "VL = 128, 256, 512\nTEMP0 := ABS(SRC1[7:0] - SRC2[7:0])\n(* Repeat operation for bytes 1 through 15 *)\nTEMP15 := ABS(SRC1[127:120] - SRC2[127:120])\nDEST[15:0] := SUM(TEMP0:TEMP7)\nDEST[63:16] := 000000000000H\nDEST[79:64] := SUM(TEMP8:TEMP15)\nDEST[127:80] := 00000000000H\nIF VL >= 256\n (* Repeat operation for bytes 16 through 31*)\n TEMP31 := ABS(SRC1[255:248] - SRC2[255:248])\n DEST[143:128] := SUM(TEMP16:TEMP23)\n DEST[191:144] := 000000000000H\n DEST[207:192] := SUM(TEMP24:TEMP31)\n DEST[223:208] := 00000000000H\nFI;\nIF VL >= 512\n(* Repeat operation for bytes 32 through 63*)\n TEMP63 := ABS(SRC1[511:504] - SRC2[511:504])\n DEST[271:256] := SUM(TEMP0:TEMP7)\n DEST[319:272] := 000000000000H\n DEST[335:320] := SUM(TEMP8:TEMP15)\n DEST[383:336] := 00000000000H\n DEST[399:384] := SUM(TEMP16:TEMP23)\n DEST[447:400] := 000000000000H\n DEST[463:448] := SUM(TEMP24:TEMP31)\n DEST[511:464] := 00000000000H\nFI;\nDEST[MAXVL-1:VL] := 0\n\n\nTEMP0 := ABS(SRC1[7:0] - SRC2[7:0])\n(* Repeat operation for bytes 2 through 30*)\nTEMP31 := ABS(SRC1[255:248] - SRC2[255:248])\nDEST[15:0] := SUM(TEMP0:TEMP7)\nDEST[63:16] := 000000000000H\nDEST[79:64] := SUM(TEMP8:TEMP15)\nDEST[127:80] := 00000000000H\nDEST[143:128] := SUM(TEMP16:TEMP23)\nDEST[191:144] := 000000000000H\nDEST[207:192] := SUM(TEMP24:TEMP31)\nDEST[223:208] := 00000000000H\nDEST[MAXVL-1:256] := 0\n\n\nTEMP0 := ABS(SRC1[7:0] - SRC2[7:0])\n(* Repeat operation for bytes 2 through 14 *)\nTEMP15 := ABS(SRC1[127:120] - SRC2[127:120])\nDEST[15:0] := SUM(TEMP0:TEMP7)\nDEST[63:16] := 000000000000H\nDEST[79:64] := SUM(TEMP8:TEMP15)\nDEST[127:80] := 00000000000H\nDEST[MAXVL-1:128] := 0\n\n\nTEMP0 := ABS(DEST[7:0] - SRC[7:0])\n(* Repeat operation for bytes 2 through 14 *)\nTEMP15 := ABS(DEST[127:120] - SRC[127:120])\nDEST[15:0] := SUM(TEMP0:TEMP7)\nDEST[63:16] := 000000000000H\nDEST[79:64] := SUM(TEMP8:TEMP15)\nDEST[127:80] := 00000000000\nDEST[MAXVL-1:128] (Unmodified)\n\n\nTEMP0 := ABS(DEST[7:0] - SRC[7:0])\n(* Repeat operation for bytes 2 through 6 *)\nTEMP7 := ABS(DEST[63:56] - SRC[63:56])\nDEST[15:0] := SUM(TEMP0:TEMP7)\nDEST[63:16] := 000000000000H\n", + "url": "https://www.felixcloutier.com/x86/psadbw" + }, + "pshufb": { + "instruction": "PSHUFB", + "title": "PSHUFB\n\t\t— Packed Shuffle Bytes", + "opcode": "NP 0F 38 00 /r1 PSHUFB mm1, mm2/m64", + "description": "PSHUFB performs in-place shuffles of bytes in the destination operand (the first operand) according to the shuffle control mask in the source operand (the second operand). The instruction permutes the data in the destination operand, leaving the shuffle mask unaffected. If the most significant bit (bit[7]) of each byte of the shuffle control mask is set, then constant zero is written in the result byte. Each byte in the shuffle control mask forms an index to permute the corresponding byte in the destination operand. The value of each index is the least significant 4 bits (128-bit operation) or 3 bits (64-bit operation) of the shuffle control byte. When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.\nIn 64-bit mode and not encoded with VEX/EVEX, use the REX prefix to access XMM8-XMM15 registers.\nLegacy SSE version 64-bit operand: Both operands can be MMX registers.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The destination operand is the first operand, the first source operand is the second operand, the second source operand is the third operand. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: Bits (255:128) of the destination YMM register stores the 16-byte shuffle result of the upper 16 bytes of the first source operand, using the upper 16-bytes of the second source operand as control mask.\nThe value of each index is for the high 128-bit lane is the least significant 4 bits of the respective shuffle control byte. The index value selects a source data element within each 128-bit lane.\nEVEX encoded version: The second source operand is an ZMM/YMM/XMM register or an 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX and VEX encoded version: Four/two in-lane 128-bit shuffles.", + "operation": "TEMP := DEST\nfor i = 0 to 7 {\n if (SRC[(i * 8)+7] = 1 ) then\n DEST[(i*8)+7...(i*8)+0] := 0;\n else\n index[2..0] := SRC[(i*8)+2 .. (i*8)+0];\n DEST[(i*8)+7...(i*8)+0] := TEMP[(index*8+7)..(index*8+0)];\n endif;\n}\nPSHUFB (with 128 bit operands)\nTEMP := DEST\nfor i = 0 to 15 {\n if (SRC[(i * 8)+7] = 1 ) then\n DEST[(i*8)+7..(i*8)+0] := 0;\n else\n index[3..0] := SRC[(i*8)+3 .. (i*8)+0];\n DEST[(i*8)+7..(i*8)+0] := TEMP[(index*8+7)..(index*8+0)];\n endif\n}\n\n\nfor i = 0 to 15 {\n if (SRC2[(i * 8)+7] = 1) then\n DEST[(i*8)+7..(i*8)+0] := 0;\n else\n index[3..0] := SRC2[(i*8)+3 .. (i*8)+0];\n DEST[(i*8)+7..(i*8)+0] := SRC1[(index*8+7)..(index*8+0)];\n endif\n}\nDEST[MAXVL-1:128] := 0\n\n\nfor i = 0 to 15 {\n if (SRC2[(i * 8)+7] == 1 ) then\n DEST[(i*8)+7..(i*8)+0] := 0;\n else\n index[3..0] := SRC2[(i*8)+3 .. (i*8)+0];\n DEST[(i*8)+7..(i*8)+0] := SRC1[(index*8+7)..(index*8+0)];\n endif\n if (SRC2[128 + (i * 8)+7] == 1 ) then\n DEST[128 + (i*8)+7..(i*8)+0] := 0;\n else\n index[3..0] := SRC2[128 + (i*8)+3 .. (i*8)+0];\n DEST[128 + (i*8)+7..(i*8)+0] := SRC1[128 + (index*8+7)..(index*8+0)];\n endif\n}\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\njmask := (KL-1) & ~0xF\n // 0x00, 0x10, 0x30 depending on the VL\nFOR j = 0 TO KL-1\n // dest\n IF kl[ i ] or no_masking\n index := src.byte[ j ];\n IF index & 0x80\n Dest.byte[ j ] := 0;\n ELSE\n index := (index & 0xF) + (j & jmask);\n // 16-element in-lane lookup\n Dest.byte[ j ] := src.byte[ index ];\n ELSE if zeroing\n Dest.byte[ j ] := 0;\nDEST[MAXVL-1:VL] := 0;\n", + "url": "https://www.felixcloutier.com/x86/pshufb" + }, + "pshufd": { + "instruction": "PSHUFD", + "title": "PSHUFD\n\t\t— Shuffle Packed Doublewords", + "opcode": "66 0F 70 /r ib PSHUFD xmm1, xmm2/m128, imm8", + "description": "Copies doublewords from source operand (second operand) and inserts them in the destination operand (first operand) at the locations selected with the order operand (third operand). Figure 4-16 shows the operation of the 256-bit VPSHUFD instruction and the encoding of the order operand. Each 2-bit field in the order operand selects the contents of one doubleword location within a 128-bit lane and copy to the target element in the destination operand. For example, bits 0 and 1 of the order operand targets the first doubleword element in the low and high 128-bit lane of the destination operand for 256-bit VPSHUFD. The encoded value of bits 1:0 of the order operand (see the field encoding in Figure 4-16) determines which doubleword element (from the respective 128-bit lane) of the source operand will be copied to doubleword 0 of the destination operand.\nFor 128-bit operation, only the low 128-bit lane are operative. The source operand can be an XMM register or a 128-bit memory location. The destination operand is an XMM register. The order operand is an 8-bit immediate. Note that this instruction permits a doubleword in the source operand to be copied to more than one doubleword location in the destination operand.\n10B - X2 ORDER 11B - X7 7 6 5 4 3 2 1 0 Operand 11B - X3 Operand\nThe source operand can be an XMM register or a 128-bit memory location. The destination operand is an XMM register. The order operand is an 8-bit immediate. Note that this instruction permits a doubleword in the source operand to be copied to more than one doubleword location in the destination operand.\nIn 64-bit mode and not encoded in VEX/EVEX, using REX.R permits this instruction to access XMM8-XMM15.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The source operand can be an XMM register or a 128-bit memory location. The destination operand is an XMM register. Bits (MAXVL-1:128) of the corresponding ZMM register are zeroed.\nVEX.256 encoded version: The source operand can be an YMM register or a 256-bit memory location. The destination operand is an YMM register. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed. Bits (255-1:128) of the destination stores the shuffled results of the upper 16 bytes of the source operand using the immediate byte as the order operand.\nEVEX encoded version: The source operand can be an ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nEach 128-bit lane of the destination stores the shuffled results of the respective lane of the source operand using the immediate byte as the order operand.\nNote: EVEX.vvvv and VEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "DEST[31:0] := (SRC >> (ORDER[1:0] * 32))[31:0];\nDEST[63:32] := (SRC >> (ORDER[3:2] * 32))[31:0];\nDEST[95:64] := (SRC >> (ORDER[5:4] * 32))[31:0];\nDEST[127:96] := (SRC >> (ORDER[7:6] * 32))[31:0];\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := (SRC >> (ORDER[1:0] * 32))[31:0];\nDEST[63:32] := (SRC >> (ORDER[3:2] * 32))[31:0];\nDEST[95:64] := (SRC >> (ORDER[5:4] * 32))[31:0];\nDEST[127:96] := (SRC >> (ORDER[7:6] * 32))[31:0];\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := (SRC[127:0] >> (ORDER[1:0] * 32))[31:0];\nDEST[63:32] := (SRC[127:0] >> (ORDER[3:2] * 32))[31:0];\nDEST[95:64] := (SRC[127:0] >> (ORDER[5:4] * 32))[31:0];\nDEST[127:96] := (SRC[127:0] >> (ORDER[7:6] * 32))[31:0];\nDEST[159:128] := (SRC[255:128] >> (ORDER[1:0] * 32))[31:0];\nDEST[191:160] := (SRC[255:128] >> (ORDER[3:2] * 32))[31:0];\nDEST[223:192] := (SRC[255:128] >> (ORDER[5:4] * 32))[31:0];\nDEST[255:224] := (SRC[255:128] >> (ORDER[7:6] * 32))[31:0];\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN TMP_SRC[i+31:i] := SRC[31:0]\n ELSE TMP_SRC[i+31:i] := SRC[i+31:i]\n FI;\nENDFOR;\nIF VL >= 128\n TMP_DEST[31:0] := (TMP_SRC[127:0] >> (ORDER[1:0] * 32))[31:0];\n TMP_DEST[63:32] := (TMP_SRC[127:0] >> (ORDER[3:2] * 32))[31:0];\n TMP_DEST[95:64] := (TMP_SRC[127:0] >> (ORDER[5:4] * 32))[31:0];\n TMP_DEST[127:96] := (TMP_SRC[127:0] >> (ORDER[7:6] * 32))[31:0];\nFI;\nIF VL >= 256\n TMP_DEST[159:128] := (TMP_SRC[255:128]\n >> (ORDER[1:0] * 32))[31:0];\n TMP_DEST[191:160] := (TMP_SRC[255:128]\n >> (ORDER[3:2] * 32))[31:0];\n TMP_DEST[223:192] := (TMP_SRC[255:128]\n >> (ORDER[5:4] * 32))[31:0];\n TMP_DEST[255:224] := (TMP_SRC[255:128]\n >> (ORDER[7:6] * 32))[31:0];\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := (TMP_SRC[383:256]\n >> (ORDER[1:0] * 32))[31:0];\n TMP_DEST[319:288] := (TMP_SRC[383:256]\n >> (ORDER[3:2] * 32))[31:0];\n TMP_DEST[351:320] := (TMP_SRC[383:256]\n >> (ORDER[5:4] * 32))[31:0];\n TMP_DEST[383:352] := (TMP_SRC[383:256]\n >> (ORDER[7:6] * 32))[31:0];\n TMP_DEST[415:384] := (TMP_SRC[511:384]\n >> (ORDER[1:0] * 32))[31:0];\n TMP_DEST[447:416] := (TMP_SRC[511:384]\n >> (ORDER[3:2] * 32))[31:0];\n TMP_DEST[479:448] := (TMP_SRC[511:384]\n >> (ORDER[5:4] * 32))[31:0];\n TMP_DEST[511:480] := (TMP_SRC[511:384]\n >> (ORDER[7:6] * 32))[31:0];\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pshufd" + }, + "pshufhw": { + "instruction": "PSHUFHW", + "title": "PSHUFHW\n\t\t— Shuffle Packed High Words", + "opcode": "F3 0F 70 /r ib PSHUFHW xmm1, xmm2/m128, imm8", + "description": "Copies words from the high quadword of a 128-bit lane of the source operand and inserts them in the high quadword of the destination operand at word locations (of the respective lane) selected with the immediate operand. This 256-bit operation is similar to the in-lane operation used by the 256-bit VPSHUFD instruction, which is illustrated in Figure 4-16. For 128-bit operation, only the low 128-bit lane is operative. Each 2-bit field in the immediate operand selects the contents of one word location in the high quadword of the destination operand. The binary encodings of the immediate operand fields select words (0, 1, 2 or 3, 4) from the high quadword of the source operand to be copied to the destination operand. The low quadword of the source operand is copied to the low quadword of the destination operand, for each 128-bit lane.\nNote that this instruction permits a word in the high quadword of the source operand to be copied to more than one word location in the high quadword of the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD.\nVEX.256 encoded version: The destination operand is an YMM register. The source operand can be an YMM register or a 256-bit memory location.\nEVEX encoded version: The destination operand is a ZMM/YMM/XMM registers. The source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination is updated according to the write-mask.\nNote: In VEX encoded versions, VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.", + "operation": "DEST[63:0] := SRC[63:0]\nDEST[79:64] := (SRC >> (imm[1:0] *16))[79:64]\nDEST[95:80] := (SRC >> (imm[3:2] * 16))[79:64]\nDEST[111:96] := (SRC >> (imm[5:4] * 16))[79:64]\nDEST[127:112] := (SRC >> (imm[7:6] * 16))[79:64]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[79:64] := (SRC1 >> (imm[1:0] *16))[79:64]\nDEST[95:80] := (SRC1 >> (imm[3:2] * 16))[79:64]\nDEST[111:96] := (SRC1 >> (imm[5:4] * 16))[79:64]\nDEST[127:112] := (SRC1 >> (imm[7:6] * 16))[79:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[79:64] := (SRC1 >> (imm[1:0] *16))[79:64]\nDEST[95:80] := (SRC1 >> (imm[3:2] * 16))[79:64]\nDEST[111:96] := (SRC1 >> (imm[5:4] * 16))[79:64]\nDEST[127:112] := (SRC1 >> (imm[7:6] * 16))[79:64]\nDEST[191:128] := SRC1[191:128]\nDEST[207192] := (SRC1 >> (imm[1:0] *16))[207:192]\nDEST[223:208] := (SRC1 >> (imm[3:2] * 16))[207:192]\nDEST[239:224] := (SRC1 >> (imm[5:4] * 16))[207:192]\nDEST[255:240] := (SRC1 >> (imm[7:6] * 16))[207:192]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL >= 128\n TMP_DEST[63:0] := SRC1[63:0]\n TMP_DEST[79:64] := (SRC1 >> (imm[1:0] *16))[79:64]\n TMP_DEST[95:80] := (SRC1 >> (imm[3:2] * 16))[79:64]\n TMP_DEST[111:96] := (SRC1 >> (imm[5:4] * 16))[79:64]\n TMP_DEST[127:112] := (SRC1 >> (imm[7:6] * 16))[79:64]\nFI;\nIF VL >= 256\n TMP_DEST[191:128] := SRC1[191:128]\n TMP_DEST[207:192] := (SRC1 >> (imm[1:0] *16))[207:192]\n TMP_DEST[223:208] := (SRC1 >> (imm[3:2] * 16))[207:192]\n TMP_DEST[239:224] := (SRC1 >> (imm[5:4] * 16))[207:192]\n TMP_DEST[255:240] := (SRC1 >> (imm[7:6] * 16))[207:192]\nFI;\nIF VL >= 512\n TMP_DEST[319:256] := SRC1[319:256]\n TMP_DEST[335:320] := (SRC1 >> (imm[1:0] *16))[335:320]\n TMP_DEST[351:336] := (SRC1 >> (imm[3:2] * 16))[335:320]\n TMP_DEST[367:352] := (SRC1 >> (imm[5:4] * 16))[335:320]\n TMP_DEST[383:368] := (SRC1 >> (imm[7:6] * 16))[335:320]\n TMP_DEST[447:384] := SRC1[447:384]\n TMP_DEST[463:448] := (SRC1 >> (imm[1:0] *16))[463:448]\n TMP_DEST[479:464] := (SRC1 >> (imm[3:2] * 16))[463:448]\n TMP_DEST[495:480] := (SRC1 >> (imm[5:4] * 16))[463:448]\n TMP_DEST[511:496] := (SRC1 >> (imm[7:6] * 16))[463:448]\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i];\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pshufhw" + }, + "pshuflw": { + "instruction": "PSHUFLW", + "title": "PSHUFLW\n\t\t— Shuffle Packed Low Words", + "opcode": "F2 0F 70 /r ib PSHUFLW xmm1, xmm2/m128, imm8", + "description": "Copies words from the low quadword of a 128-bit lane of the source operand and inserts them in the low quadword of the destination operand at word locations (of the respective lane) selected with the immediate operand. The 256-bit operation is similar to the in-lane operation used by the 256-bit VPSHUFD instruction, which is illustrated in Figure 4-16. For 128-bit operation, only the low 128-bit lane is operative. Each 2-bit field in the immediate operand selects the contents of one word location in the low quadword of the destination operand. The binary encodings of the immediate operand fields select words (0, 1, 2 or 3) from the low quadword of the source operand to be copied to the destination operand. The high quadword of the source operand is copied to the high quadword of the destination operand, for each 128-bit lane.\nNote that this instruction permits a word in the low quadword of the source operand to be copied to more than one word location in the low quadword of the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The destination operand is an YMM register. The source operand can be an YMM register or a 256-bit memory location.\nEVEX encoded version: The destination operand is a ZMM/YMM/XMM registers. The source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination is updated according to the write-mask.\nNote: In VEX encoded versions, VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.", + "operation": "DEST[15:0] := (SRC >> (imm[1:0] *16))[15:0]\nDEST[31:16] := (SRC >> (imm[3:2] * 16))[15:0]\nDEST[47:32] := (SRC >> (imm[5:4] * 16))[15:0]\nDEST[63:48] := (SRC >> (imm[7:6] * 16))[15:0]\nDEST[127:64] := SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := (SRC1 >> (imm[1:0] *16))[15:0]\nDEST[31:16] := (SRC1 >> (imm[3:2] * 16))[15:0]\nDEST[47:32] := (SRC1 >> (imm[5:4] * 16))[15:0]\nDEST[63:48] := (SRC1 >> (imm[7:6] * 16))[15:0]\nDEST[127:64] := SRC[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := (SRC1 >> (imm[1:0] *16))[15:0]\nDEST[31:16] := (SRC1 >> (imm[3:2] * 16))[15:0]\nDEST[47:32] := (SRC1 >> (imm[5:4] * 16))[15:0]\nDEST[63:48] := (SRC1 >> (imm[7:6] * 16))[15:0]\nDEST[127:64] := SRC1[127:64]\nDEST[143:128] := (SRC1 >> (imm[1:0] *16))[143:128]\nDEST[159:144] := (SRC1 >> (imm[3:2] * 16))[143:128]\nDEST[175:160] := (SRC1 >> (imm[5:4] * 16))[143:128]\nDEST[191:176] := (SRC1 >> (imm[7:6] * 16))[143:128]\nDEST[255:192] := SRC1[255:192]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL >= 128\n TMP_DEST[15:0] := (SRC1 >> (imm[1:0] *16))[15:0]\n TMP_DEST[31:16] := (SRC1 >> (imm[3:2] * 16))[15:0]\n TMP_DEST[47:32] := (SRC1 >> (imm[5:4] * 16))[15:0]\n TMP_DEST[63:48] := (SRC1 >> (imm[7:6] * 16))[15:0]\n TMP_DEST[127:64] := SRC1[127:64]\nFI;\nIF VL >= 256\n TMP_DEST[143:128] := (SRC1 >> (imm[1:0] *16))[143:128]\n TMP_DEST[159:144] := (SRC1 >> (imm[3:2] * 16))[143:128]\n TMP_DEST[175:160] := (SRC1 >> (imm[5:4] * 16))[143:128]\n TMP_DEST[191:176] := (SRC1 >> (imm[7:6] * 16))[143:128]\n TMP_DEST[255:192] := SRC1[255:192]\nFI;\nIF VL >= 512\n TMP_DEST[271:256] := (SRC1 >> (imm[1:0] *16))[271:256]\n TMP_DEST[287:272] := (SRC1 >> (imm[3:2] * 16))[271:256]\n TMP_DEST[303:288] := (SRC1 >> (imm[5:4] * 16))[271:256]\n TMP_DEST[319:304] := (SRC1 >> (imm[7:6] * 16))[271:256]\n TMP_DEST[383:320] := SRC1[383:320]\n TMP_DEST[399:384] := (SRC1 >> (imm[1:0] *16))[399:384]\n TMP_DEST[415:400] := (SRC1 >> (imm[3:2] * 16))[399:384]\n TMP_DEST[431:416] := (SRC1 >> (imm[5:4] * 16))[399:384]\n TMP_DEST[447:432] := (SRC1 >> (imm[7:6] * 16))[399:384]\n TMP_DEST[511:448] := SRC1[511:448]\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i];\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pshuflw" + }, + "pshufw": { + "instruction": "PSHUFW", + "title": "PSHUFW\n\t\t— Shuffle Packed Words", + "opcode": "NP 0F 70 /r ib PSHUFW mm1, mm2/m64, imm8", + "description": "Copies words from the source operand (second operand) and inserts them in the destination operand (first operand) at word locations selected with the order operand (third operand). This operation is similar to the operation used by the PSHUFD instruction, which is illustrated in Figure 4-16. For the PSHUFW instruction, each 2-bit field in the order operand selects the contents of one word location in the destination operand. The encodings of the order operand fields select words from the source operand to be copied to the destination operand.\nThe source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register. The order operand is an 8-bit immediate. Note that this instruction permits a word in the source operand to be copied to more than one word location in the destination operand.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).", + "operation": "DEST[15:0] := (SRC >> (ORDER[1:0] * 16))[15:0];\nDEST[31:16] := (SRC >> (ORDER[3:2] * 16))[15:0];\nDEST[47:32] := (SRC >> (ORDER[5:4] * 16))[15:0];\nDEST[63:48] := (SRC >> (ORDER[7:6] * 16))[15:0];\n", + "url": "https://www.felixcloutier.com/x86/pshufw" + }, + "psignb": { + "instruction": "PSIGNB", + "title": "PSIGNB/PSIGNW/PSIGND\n\t\t— Packed SIGN", + "opcode": "NP 0F 38 08 /r1 PSIGNB mm1, mm2/m64", + "description": "(V)PSIGNB/(V)PSIGNW/(V)PSIGND negates each data element of the destination operand (the first operand) if the signed integer value of the corresponding data element in the source operand (the second operand) is less than zero. If the signed integer value of a data element in the source operand is positive, the corresponding data element in the destination operand is unchanged. If a data element in the source operand is zero, the corresponding data element in the destination operand is set to zero.\n(V)PSIGNB operates on signed bytes. (V)PSIGNW operates on 16-bit signed words. (V)PSIGND operates on signed 32-bit integers.\nLegacy SSE instructions: Both operands can be MMX registers. In 64-bit mode, use the REX prefix to access additional registers.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L must be 0, otherwise instructions will #UD.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand is an YMM register or a 256-bit memory location.", + "operation": "def byte_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\ndef word_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\ndef dword_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\n\n\nVL=64\nKL := VL/8\nfor i in 0...KL-1:\n srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i])\n\n\nVL=64\nKL := VL/16\nFOR i in 0...KL-1:\n srcdest.word[i] := word_sign(src.word[i], srcdest.word[i])\n\n\nVL=64\nKL := VL/32\nFOR i in 0...KL-1:\n srcdest.dword[i] := dword_sign(src.dword[i], srcdest.dword[i])\n\n\nVL=128\nKL := VL/8\nFOR i in 0...KL-1:\n srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i])\n\n\nVL=128\nKL := VL/16\nFOR i in 0...KL-1:\n srcdest.word[i] := word_sign(src.word[i], srcdest.word[i])\n\n\nVL=128\nKL := VL/32\nFOR i in 0...KL-1:\n srcdest.dword[i] := dword_sign(src.dword[i], srcdest.dword[i])\n\n\nVL=(128,256)\nKL := VL/8\nFOR i in 0...KL-1:\n dest.byte[i] := byte_sign(src2.byte[i], src1.byte[i])\nDEST[MAXVL-1:VL] := 0\n\n\nVL=(128,256)\nKL := VL/16\nFOR i in 0...KL-1:\n dest.word[i] := word_sign(src2.word[i], src1.word[i])\nDEST[MAXVL-1:VL] := 0\n\n\nVL=(128,256)\nKL := VL/32\nFOR i in 0...KL-1:\n dest.dword[i] := dword_sign(src2.dword[i], src1.dword[i])\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psignb:psignw:psignd" + }, + "psignd": { + "instruction": "PSIGND", + "title": "PSIGNB/PSIGNW/PSIGND\n\t\t— Packed SIGN", + "opcode": "NP 0F 38 08 /r1 PSIGNB mm1, mm2/m64", + "description": "(V)PSIGNB/(V)PSIGNW/(V)PSIGND negates each data element of the destination operand (the first operand) if the signed integer value of the corresponding data element in the source operand (the second operand) is less than zero. If the signed integer value of a data element in the source operand is positive, the corresponding data element in the destination operand is unchanged. If a data element in the source operand is zero, the corresponding data element in the destination operand is set to zero.\n(V)PSIGNB operates on signed bytes. (V)PSIGNW operates on 16-bit signed words. (V)PSIGND operates on signed 32-bit integers.\nLegacy SSE instructions: Both operands can be MMX registers. In 64-bit mode, use the REX prefix to access additional registers.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L must be 0, otherwise instructions will #UD.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand is an YMM register or a 256-bit memory location.", + "operation": "def byte_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\ndef word_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\ndef dword_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\n\n\nVL=64\nKL := VL/8\nfor i in 0...KL-1:\n srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i])\n\n\nVL=64\nKL := VL/16\nFOR i in 0...KL-1:\n srcdest.word[i] := word_sign(src.word[i], srcdest.word[i])\n\n\nVL=64\nKL := VL/32\nFOR i in 0...KL-1:\n srcdest.dword[i] := dword_sign(src.dword[i], srcdest.dword[i])\n\n\nVL=128\nKL := VL/8\nFOR i in 0...KL-1:\n srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i])\n\n\nVL=128\nKL := VL/16\nFOR i in 0...KL-1:\n srcdest.word[i] := word_sign(src.word[i], srcdest.word[i])\n\n\nVL=128\nKL := VL/32\nFOR i in 0...KL-1:\n srcdest.dword[i] := dword_sign(src.dword[i], srcdest.dword[i])\n\n\nVL=(128,256)\nKL := VL/8\nFOR i in 0...KL-1:\n dest.byte[i] := byte_sign(src2.byte[i], src1.byte[i])\nDEST[MAXVL-1:VL] := 0\n\n\nVL=(128,256)\nKL := VL/16\nFOR i in 0...KL-1:\n dest.word[i] := word_sign(src2.word[i], src1.word[i])\nDEST[MAXVL-1:VL] := 0\n\n\nVL=(128,256)\nKL := VL/32\nFOR i in 0...KL-1:\n dest.dword[i] := dword_sign(src2.dword[i], src1.dword[i])\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psignb:psignw:psignd" + }, + "psignw": { + "instruction": "PSIGNW", + "title": "PSIGNB/PSIGNW/PSIGND\n\t\t— Packed SIGN", + "opcode": "NP 0F 38 08 /r1 PSIGNB mm1, mm2/m64", + "description": "(V)PSIGNB/(V)PSIGNW/(V)PSIGND negates each data element of the destination operand (the first operand) if the signed integer value of the corresponding data element in the source operand (the second operand) is less than zero. If the signed integer value of a data element in the source operand is positive, the corresponding data element in the destination operand is unchanged. If a data element in the source operand is zero, the corresponding data element in the destination operand is set to zero.\n(V)PSIGNB operates on signed bytes. (V)PSIGNW operates on 16-bit signed words. (V)PSIGND operates on signed 32-bit integers.\nLegacy SSE instructions: Both operands can be MMX registers. In 64-bit mode, use the REX prefix to access additional registers.\n128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The first source and destination operands are XMM registers. The second source operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are zeroed. VEX.L must be 0, otherwise instructions will #UD.\nVEX.256 encoded version: The first source and destination operands are YMM registers. The second source operand is an YMM register or a 256-bit memory location.", + "operation": "def byte_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\ndef word_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\ndef dword_sign(control, input_val):\n if control<0:\n return negate(input_val)\n elif control==0:\n return 0\n return input_val\n\n\nVL=64\nKL := VL/8\nfor i in 0...KL-1:\n srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i])\n\n\nVL=64\nKL := VL/16\nFOR i in 0...KL-1:\n srcdest.word[i] := word_sign(src.word[i], srcdest.word[i])\n\n\nVL=64\nKL := VL/32\nFOR i in 0...KL-1:\n srcdest.dword[i] := dword_sign(src.dword[i], srcdest.dword[i])\n\n\nVL=128\nKL := VL/8\nFOR i in 0...KL-1:\n srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i])\n\n\nVL=128\nKL := VL/16\nFOR i in 0...KL-1:\n srcdest.word[i] := word_sign(src.word[i], srcdest.word[i])\n\n\nVL=128\nKL := VL/32\nFOR i in 0...KL-1:\n srcdest.dword[i] := dword_sign(src.dword[i], srcdest.dword[i])\n\n\nVL=(128,256)\nKL := VL/8\nFOR i in 0...KL-1:\n dest.byte[i] := byte_sign(src2.byte[i], src1.byte[i])\nDEST[MAXVL-1:VL] := 0\n\n\nVL=(128,256)\nKL := VL/16\nFOR i in 0...KL-1:\n dest.word[i] := word_sign(src2.word[i], src1.word[i])\nDEST[MAXVL-1:VL] := 0\n\n\nVL=(128,256)\nKL := VL/32\nFOR i in 0...KL-1:\n dest.dword[i] := dword_sign(src2.dword[i], src1.dword[i])\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psignb:psignw:psignd" + }, + "pslld": { + "instruction": "PSLLD", + "title": "PSLLW/PSLLD/PSLLQ\n\t\t— Shift Packed Data Left Logical", + "opcode": "NP 0F F1 /r1 PSLLW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords, or quadword) in the destination operand (first operand) to the left by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted left, the empty low-order bits are cleared (set to 0). If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for a quadword), then the destination operand is set to all 0s. Figure 4-17 gives an example of shifting words in a 64-bit operand.\nThe (V)PSLLW instruction shifts each of the words in the destination operand to the left by the number of bits specified in the count operand; the (V)PSLLD instruction shifts each of the doublewords in the destination operand; and the (V)PSLLQ instruction shifts the quadword (or quadwords) in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.128 encoded version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /6, or EVEX.128.66.0F 71-73 /6), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": " IF (COUNT > 15)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST[15:0] := ZeroExtend(DEST[15:0] << COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := ZeroExtend(DEST[63:48] << COUNT);\n FI;\nPSLLD (with 64-bit operand)\n IF (COUNT > 31)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST[31:0] := ZeroExtend(DEST[31:0] << COUNT);\n DEST[63:32] := ZeroExtend(DEST[63:32] << COUNT);\n FI;\n\n\n IF (COUNT > 63)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST := ZeroExtend(DEST << COUNT);\n FI;\nLOGICAL_LEFT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] << COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[127:112] := ZeroExtend(SRC[127:112] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[127:96] := ZeroExtend(SRC[127:96] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] << COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\n DEST[255:240] := ZeroExtend(SRC[255:240] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[255:224] := ZeroExtend(SRC[255:224] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] << COUNT)\n DEST[191:128] := ZeroExtend(SRC[191:128] << COUNT);\n DEST[255:192] := ZeroExtend(SRC[255:192] << COUNT);\nFI;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_WORD_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := LOGICAL_LEFT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := LOGICAL_LEFT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := LOGICAL_LEFT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := LOGICAL_LEFT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psllw:pslld:psllq" + }, + "pslldq": { + "instruction": "PSLLDQ", + "title": "PSLLDQ\n\t\t— Shift Double Quadword Left Logical", + "opcode": "66 0F 73 /7 ib PSLLDQ xmm1, imm8", + "description": "Shifts the destination operand (first operand) to the left by the number of bytes specified in the count operand (second operand). The empty low-order bytes are cleared (set to all 0s). If the value specified by the count operand is greater than 15, the destination operand is set to all 0s. The count operand is an 8-bit immediate.\n128-bit Legacy SSE version: The source and destination operands are the same. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The source and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The source operand is YMM register. The destination operand is an YMM register. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed. The count operand applies to both the low and high 128-bit lanes.\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register. The count operand applies to each 128-bit lanes.", + "operation": "TEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST[127:0] := SRC[127:0] << (TEMP * 8)\nDEST[255:128] := SRC[255:128] << (TEMP * 8)\nDEST[383:256] := SRC[383:256] << (TEMP * 8)\nDEST[511:384] := SRC[511:384] << (TEMP * 8)\nDEST[MAXVL-1:512] := 0\n\n\nTEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST[127:0] := SRC[127:0] << (TEMP * 8)\nDEST[255:128] := SRC[255:128] << (TEMP * 8)\nDEST[MAXVL-1:256] := 0\n\n\nTEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST := SRC << (TEMP * 8)\nDEST[MAXVL-1:128] := 0\n\n\nTEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST := DEST << (TEMP * 8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/pslldq" + }, + "psllq": { + "instruction": "PSLLQ", + "title": "PSLLW/PSLLD/PSLLQ\n\t\t— Shift Packed Data Left Logical", + "opcode": "NP 0F F1 /r1 PSLLW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords, or quadword) in the destination operand (first operand) to the left by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted left, the empty low-order bits are cleared (set to 0). If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for a quadword), then the destination operand is set to all 0s. Figure 4-17 gives an example of shifting words in a 64-bit operand.\nThe (V)PSLLW instruction shifts each of the words in the destination operand to the left by the number of bits specified in the count operand; the (V)PSLLD instruction shifts each of the doublewords in the destination operand; and the (V)PSLLQ instruction shifts the quadword (or quadwords) in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.128 encoded version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /6, or EVEX.128.66.0F 71-73 /6), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": " IF (COUNT > 15)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST[15:0] := ZeroExtend(DEST[15:0] << COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := ZeroExtend(DEST[63:48] << COUNT);\n FI;\nPSLLD (with 64-bit operand)\n IF (COUNT > 31)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST[31:0] := ZeroExtend(DEST[31:0] << COUNT);\n DEST[63:32] := ZeroExtend(DEST[63:32] << COUNT);\n FI;\n\n\n IF (COUNT > 63)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST := ZeroExtend(DEST << COUNT);\n FI;\nLOGICAL_LEFT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] << COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[127:112] := ZeroExtend(SRC[127:112] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[127:96] := ZeroExtend(SRC[127:96] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] << COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\n DEST[255:240] := ZeroExtend(SRC[255:240] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[255:224] := ZeroExtend(SRC[255:224] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] << COUNT)\n DEST[191:128] := ZeroExtend(SRC[191:128] << COUNT);\n DEST[255:192] := ZeroExtend(SRC[255:192] << COUNT);\nFI;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_WORD_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := LOGICAL_LEFT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := LOGICAL_LEFT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := LOGICAL_LEFT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := LOGICAL_LEFT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psllw:pslld:psllq" + }, + "psllw": { + "instruction": "PSLLW", + "title": "PSLLW/PSLLD/PSLLQ\n\t\t— Shift Packed Data Left Logical", + "opcode": "NP 0F F1 /r1 PSLLW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords, or quadword) in the destination operand (first operand) to the left by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted left, the empty low-order bits are cleared (set to 0). If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for a quadword), then the destination operand is set to all 0s. Figure 4-17 gives an example of shifting words in a 64-bit operand.\nThe (V)PSLLW instruction shifts each of the words in the destination operand to the left by the number of bits specified in the count operand; the (V)PSLLD instruction shifts each of the doublewords in the destination operand; and the (V)PSLLQ instruction shifts the quadword (or quadwords) in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.128 encoded version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /6, or EVEX.128.66.0F 71-73 /6), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": " IF (COUNT > 15)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST[15:0] := ZeroExtend(DEST[15:0] << COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := ZeroExtend(DEST[63:48] << COUNT);\n FI;\nPSLLD (with 64-bit operand)\n IF (COUNT > 31)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST[31:0] := ZeroExtend(DEST[31:0] << COUNT);\n DEST[63:32] := ZeroExtend(DEST[63:32] << COUNT);\n FI;\n\n\n IF (COUNT > 63)\n THEN\n DEST[64:0] := 0000000000000000H;\n ELSE\n DEST := ZeroExtend(DEST << COUNT);\n FI;\nLOGICAL_LEFT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] << COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[127:112] := ZeroExtend(SRC[127:112] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[127:96] := ZeroExtend(SRC[127:96] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] << COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\n DEST[255:240] := ZeroExtend(SRC[255:240] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] << COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[255:224] := ZeroExtend(SRC[255:224] << COUNT);\nFI;\nLOGICAL_LEFT_SHIFT_QWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\n DEST[255:128] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] << COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] << COUNT)\n DEST[191:128] := ZeroExtend(SRC[191:128] << COUNT);\n DEST[255:192] := ZeroExtend(SRC[255:192] << COUNT);\nFI;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_WORD_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := LOGICAL_LEFT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := LOGICAL_LEFT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := LOGICAL_LEFT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := LOGICAL_LEFT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_LEFT_SHIFT_QWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_LEFT_SHIFT_QWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psllw:pslld:psllq" + }, + "psrad": { + "instruction": "PSRAD", + "title": "PSRAW/PSRAD/PSRAQ\n\t\t— Shift Packed Data Right Arithmetic", + "opcode": "NP 0F E1 /r1 PSRAW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords or quadwords) in the destination operand (first operand) to the right by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted right, the empty high-order bits are filled with the initial value of the sign bit of the data element. If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for quadwords), each destination data element is filled with the initial value of the sign bit of the element. (Figure 4-18 gives an example of shifting words in a 64-bit operand.)\nNote that only the first 64-bits of a 128-bit count operand are checked to compute the count. If the second source operand is a memory address, 128 bits are loaded.\nThe (V)PSRAW instruction shifts each of the words in the destination operand to the right by the number of bits specified in the count operand, and the (V)PSRAD instruction shifts each of the doublewords in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.128 encoded version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /4, EVEX.128.66.0F 71-73 /4), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": " IF (COUNT > 15)\n THEN COUNT := 16;\n FI;\n DEST[15:0] := SignExtend(DEST[15:0] >> COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := SignExtend(DEST[63:48] >> COUNT);\nPSRAD (with 64-bit operand)\n IF (COUNT > 31)\n THEN COUNT := 32;\n FI;\n DEST[31:0] := SignExtend(DEST[31:0] >> COUNT);\n DEST[63:32] := SignExtend(DEST[63:32] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := SignBit\nELSE\n DEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\nFI;\nARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := SignBit\nELSE\n DEST[63:0] := SignExtend(SRC[63:0] >> COUNT);\nFI;\nARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\n THEN COUNT := 16;\nFI;\nDEST[15:0] := SignExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\nDEST[255:240] := SignExtend(SRC[255:240] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\n THEN COUNT := 32;\nFI;\nDEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[255:224] := SignExtend(SRC[255:224] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_QWORDS(SRC, COUNT_SRC, VL) ; VL: 128b, 256b or 512b\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\n THEN COUNT := 64;\nFI;\nDEST[63:0] := SignExtend(SRC[63:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[VL-1:VL-64] := SignExtend(SRC[VL-1:VL-64] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\n THEN COUNT := 16;\nFI;\nDEST[15:0] := SignExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[127:112] := SignExtend(SRC[127:112] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\n THEN COUNT := 32;\nFI;\nDEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\nDEST[127:96] := SignExtend(SRC[127:96] >> COUNT);\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := ARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := ARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := ARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := ARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_DEST[VL-1:0] := ARITHMETIC_RIGHT_SHIFT_QWORDS(SRC1[VL-1:0], SRC2, VL)\nFOR j := 0 TO 7\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psraw:psrad:psraq" + }, + "psraq": { + "instruction": "PSRAQ", + "title": "PSRAW/PSRAD/PSRAQ\n\t\t— Shift Packed Data Right Arithmetic", + "opcode": "NP 0F E1 /r1 PSRAW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords or quadwords) in the destination operand (first operand) to the right by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted right, the empty high-order bits are filled with the initial value of the sign bit of the data element. If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for quadwords), each destination data element is filled with the initial value of the sign bit of the element. (Figure 4-18 gives an example of shifting words in a 64-bit operand.)\nNote that only the first 64-bits of a 128-bit count operand are checked to compute the count. If the second source operand is a memory address, 128 bits are loaded.\nThe (V)PSRAW instruction shifts each of the words in the destination operand to the right by the number of bits specified in the count operand, and the (V)PSRAD instruction shifts each of the doublewords in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.128 encoded version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /4, EVEX.128.66.0F 71-73 /4), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": " IF (COUNT > 15)\n THEN COUNT := 16;\n FI;\n DEST[15:0] := SignExtend(DEST[15:0] >> COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := SignExtend(DEST[63:48] >> COUNT);\nPSRAD (with 64-bit operand)\n IF (COUNT > 31)\n THEN COUNT := 32;\n FI;\n DEST[31:0] := SignExtend(DEST[31:0] >> COUNT);\n DEST[63:32] := SignExtend(DEST[63:32] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := SignBit\nELSE\n DEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\nFI;\nARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := SignBit\nELSE\n DEST[63:0] := SignExtend(SRC[63:0] >> COUNT);\nFI;\nARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\n THEN COUNT := 16;\nFI;\nDEST[15:0] := SignExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\nDEST[255:240] := SignExtend(SRC[255:240] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\n THEN COUNT := 32;\nFI;\nDEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[255:224] := SignExtend(SRC[255:224] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_QWORDS(SRC, COUNT_SRC, VL) ; VL: 128b, 256b or 512b\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\n THEN COUNT := 64;\nFI;\nDEST[63:0] := SignExtend(SRC[63:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[VL-1:VL-64] := SignExtend(SRC[VL-1:VL-64] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\n THEN COUNT := 16;\nFI;\nDEST[15:0] := SignExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[127:112] := SignExtend(SRC[127:112] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\n THEN COUNT := 32;\nFI;\nDEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\nDEST[127:96] := SignExtend(SRC[127:96] >> COUNT);\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := ARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := ARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := ARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := ARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_DEST[VL-1:0] := ARITHMETIC_RIGHT_SHIFT_QWORDS(SRC1[VL-1:0], SRC2, VL)\nFOR j := 0 TO 7\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psraw:psrad:psraq" + }, + "psraw": { + "instruction": "PSRAW", + "title": "PSRAW/PSRAD/PSRAQ\n\t\t— Shift Packed Data Right Arithmetic", + "opcode": "NP 0F E1 /r1 PSRAW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords or quadwords) in the destination operand (first operand) to the right by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted right, the empty high-order bits are filled with the initial value of the sign bit of the data element. If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for quadwords), each destination data element is filled with the initial value of the sign bit of the element. (Figure 4-18 gives an example of shifting words in a 64-bit operand.)\nNote that only the first 64-bits of a 128-bit count operand are checked to compute the count. If the second source operand is a memory address, 128 bits are loaded.\nThe (V)PSRAW instruction shifts each of the words in the destination operand to the right by the number of bits specified in the count operand, and the (V)PSRAD instruction shifts each of the doublewords in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.128 encoded version: The destination and first source operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed. The count operand can be either an XMM register or a 128-bit memory location or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /4, EVEX.128.66.0F 71-73 /4), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": " IF (COUNT > 15)\n THEN COUNT := 16;\n FI;\n DEST[15:0] := SignExtend(DEST[15:0] >> COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := SignExtend(DEST[63:48] >> COUNT);\nPSRAD (with 64-bit operand)\n IF (COUNT > 31)\n THEN COUNT := 32;\n FI;\n DEST[31:0] := SignExtend(DEST[31:0] >> COUNT);\n DEST[63:32] := SignExtend(DEST[63:32] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := SignBit\nELSE\n DEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\nFI;\nARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := SignBit\nELSE\n DEST[63:0] := SignExtend(SRC[63:0] >> COUNT);\nFI;\nARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\n THEN COUNT := 16;\nFI;\nDEST[15:0] := SignExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\nDEST[255:240] := SignExtend(SRC[255:240] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\n THEN COUNT := 32;\nFI;\nDEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[255:224] := SignExtend(SRC[255:224] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_QWORDS(SRC, COUNT_SRC, VL) ; VL: 128b, 256b or 512b\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\n THEN COUNT := 64;\nFI;\nDEST[63:0] := SignExtend(SRC[63:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[VL-1:VL-64] := SignExtend(SRC[VL-1:VL-64] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\n THEN COUNT := 16;\nFI;\nDEST[15:0] := SignExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\nDEST[127:112] := SignExtend(SRC[127:112] >> COUNT);\nARITHMETIC_RIGHT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\n THEN COUNT := 32;\nFI;\nDEST[31:0] := SignExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\nDEST[127:96] := SignExtend(SRC[127:96] >> COUNT);\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_WORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := ARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := ARITHMETIC_RIGHT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := ARITHMETIC_RIGHT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := ARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := ARITHMETIC_RIGHT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_DEST[VL-1:0] := ARITHMETIC_RIGHT_SHIFT_QWORDS(SRC1[VL-1:0], SRC2, VL)\nFOR j := 0 TO 7\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psraw:psrad:psraq" + }, + "psrld": { + "instruction": "PSRLD", + "title": "PSRLW/PSRLD/PSRLQ\n\t\t— Shift Packed Data Right Logical", + "opcode": "NP 0F D1 /r1 PSRLW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords, or quadword) in the destination operand (first operand) to the right by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted right, the empty high-order bits are cleared (set to 0). If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for a quadword), then the destination operand is set to all 0s. Figure 4-19 gives an example of shifting words in a 64-bit operand.\nNote that only the low 64-bits of a 128-bit count operand are checked to compute the count.\nThe (V)PSRLW instruction shifts each of the words in the destination operand to the right by the number of bits specified in the count operand; the (V)PSRLD instruction shifts each of the doublewords in the destination operand; and the PSRLQ instruction shifts the quadword (or quadwords) in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instruction 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination operand is an XMM register; the count operand can be either an XMM register or a 128-bit memory location, or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The destination operand is an XMM register; the count operand can be either an XMM register or a 128-bit memory location, or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /2, or EVEX.128.66.0F 71-73 /2), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": "IF (COUNT > 15)\nTHEN\n DEST[64:0] := 0000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(DEST[15:0] >> COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := ZeroExtend(DEST[63:48] >> COUNT);\nFI;\n\n\nIF (COUNT > 31)\nTHEN\n DEST[64:0] := 0000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(DEST[31:0] >> COUNT);\n DEST[63:32] := ZeroExtend(DEST[63:32] >> COUNT);\nFI;\n\n\n IF (COUNT > 63)\n THEN\n DEST[64:0] := 0000000000000000H\n ELSE\n DEST := ZeroExtend(DEST >> COUNT);\n FI;\nLOGICAL_RIGHT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\n DEST[255:240] := ZeroExtend(SRC[255:240] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[127:112] := ZeroExtend(SRC[127:112] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[255:224] := ZeroExtend(SRC[255:224] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[127:96] := ZeroExtend(SRC[127:96] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] >> COUNT);\n DEST[191:128] := ZeroExtend(SRC[191:128] >> COUNT);\n DEST[255:192] := ZeroExtend(SRC[255:192] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] >> COUNT);\nFI;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := LOGICAL_RIGHT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := LOGICAL_RIGHT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nTMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := LOGICAL_RIGHT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := LOGICAL_RIGHT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psrlw:psrld:psrlq" + }, + "psrldq": { + "instruction": "PSRLDQ", + "title": "PSRLDQ\n\t\t— Shift Double Quadword Right Logical", + "opcode": "66 0F 73 /3 ib PSRLDQ xmm1, imm8", + "description": "Shifts the destination operand (first operand) to the right by the number of bytes specified in the count operand (second operand). The empty high-order bytes are cleared (set to all 0s). If the value specified by the count operand is greater than 15, the destination operand is set to all 0s. The count operand is an 8-bit immediate.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The source and destination operands are the same. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The source and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The source operand is a YMM register. The destination operand is a YMM register. The count operand applies to both the low and high 128-bit lanes.\nVEX.256 encoded version: The source operand is YMM register. The destination operand is an YMM register. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed. The count operand applies to both the low and high 128-bit lanes.\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register or a 512/256/128-bit memory location. The destination operand is a ZMM/YMM/XMM register. The count operand applies to each 128-bit lanes.\nNote: VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": "TEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST[127:0] := SRC[127:0] >> (TEMP * 8)\nDEST[255:128] := SRC[255:128] >> (TEMP * 8)\nDEST[383:256] := SRC[383:256] >> (TEMP * 8)\nDEST[511:384] := SRC[511:384] >> (TEMP * 8)\nDEST[MAXVL-1:512] := 0;\n\n\nTEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST[127:0] := SRC[127:0] >> (TEMP * 8)\nDEST[255:128] := SRC[255:128] >> (TEMP * 8)\nDEST[MAXVL-1:256] := 0;\n\n\nTEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST := SRC >> (TEMP * 8)\nDEST[MAXVL-1:128] := 0;\n\n\nTEMP := COUNT\nIF (TEMP > 15) THEN TEMP := 16; FI\nDEST := DEST >> (TEMP * 8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psrldq" + }, + "psrlq": { + "instruction": "PSRLQ", + "title": "PSRLW/PSRLD/PSRLQ\n\t\t— Shift Packed Data Right Logical", + "opcode": "NP 0F D1 /r1 PSRLW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords, or quadword) in the destination operand (first operand) to the right by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted right, the empty high-order bits are cleared (set to 0). If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for a quadword), then the destination operand is set to all 0s. Figure 4-19 gives an example of shifting words in a 64-bit operand.\nNote that only the low 64-bits of a 128-bit count operand are checked to compute the count.\nThe (V)PSRLW instruction shifts each of the words in the destination operand to the right by the number of bits specified in the count operand; the (V)PSRLD instruction shifts each of the doublewords in the destination operand; and the PSRLQ instruction shifts the quadword (or quadwords) in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instruction 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination operand is an XMM register; the count operand can be either an XMM register or a 128-bit memory location, or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The destination operand is an XMM register; the count operand can be either an XMM register or a 128-bit memory location, or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /2, or EVEX.128.66.0F 71-73 /2), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": "IF (COUNT > 15)\nTHEN\n DEST[64:0] := 0000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(DEST[15:0] >> COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := ZeroExtend(DEST[63:48] >> COUNT);\nFI;\n\n\nIF (COUNT > 31)\nTHEN\n DEST[64:0] := 0000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(DEST[31:0] >> COUNT);\n DEST[63:32] := ZeroExtend(DEST[63:32] >> COUNT);\nFI;\n\n\n IF (COUNT > 63)\n THEN\n DEST[64:0] := 0000000000000000H\n ELSE\n DEST := ZeroExtend(DEST >> COUNT);\n FI;\nLOGICAL_RIGHT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\n DEST[255:240] := ZeroExtend(SRC[255:240] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[127:112] := ZeroExtend(SRC[127:112] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[255:224] := ZeroExtend(SRC[255:224] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[127:96] := ZeroExtend(SRC[127:96] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] >> COUNT);\n DEST[191:128] := ZeroExtend(SRC[191:128] >> COUNT);\n DEST[255:192] := ZeroExtend(SRC[255:192] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] >> COUNT);\nFI;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := LOGICAL_RIGHT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := LOGICAL_RIGHT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nTMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := LOGICAL_RIGHT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := LOGICAL_RIGHT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psrlw:psrld:psrlq" + }, + "psrlw": { + "instruction": "PSRLW", + "title": "PSRLW/PSRLD/PSRLQ\n\t\t— Shift Packed Data Right Logical", + "opcode": "NP 0F D1 /r1 PSRLW mm, mm/m64", + "description": "Shifts the bits in the individual data elements (words, doublewords, or quadword) in the destination operand (first operand) to the right by the number of bits specified in the count operand (second operand). As the bits in the data elements are shifted right, the empty high-order bits are cleared (set to 0). If the value specified by the count operand is greater than 15 (for words), 31 (for doublewords), or 63 (for a quadword), then the destination operand is set to all 0s. Figure 4-19 gives an example of shifting words in a 64-bit operand.\nNote that only the low 64-bits of a 128-bit count operand are checked to compute the count.\nThe (V)PSRLW instruction shifts each of the words in the destination operand to the right by the number of bits specified in the count operand; the (V)PSRLD instruction shifts each of the doublewords in the destination operand; and the PSRLQ instruction shifts the quadword (or quadwords) in the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instruction 64-bit operand: The destination operand is an MMX technology register; the count operand can be either an MMX technology register or an 64-bit memory location.\n128-bit Legacy SSE version: The destination operand is an XMM register; the count operand can be either an XMM register or a 128-bit memory location, or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The destination operand is an XMM register; the count operand can be either an XMM register or a 128-bit memory location, or an 8-bit immediate. If the count operand is a memory address, 128 bits are loaded but the upper 64 bits are ignored. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The destination operand is a YMM register. The source operand is a YMM register or a memory location. The count operand can come either from an XMM register or a memory location or an 8-bit immediate. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded versions: The destination operand is a ZMM register updated according to the writemask. The count operand is either an 8-bit immediate (the immediate count version) or an 8-bit value from an XMM register or a memory location (the variable count version). For the immediate count version, the source operand (the second operand) can be a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32/64-bit memory location. For the variable count version, the first source operand (the second operand) is a ZMM register, the second source operand (the third operand, 8-bit variable count) can be an XMM register or a memory location.\nNote: In VEX/EVEX encoded versions of shifts with an immediate count, vvvv of VEX/EVEX encode the destination register, and VEX.B/EVEX.B + ModRM.r/m encodes the source register.\nNote: For shifts with an immediate count (VEX.128.66.0F 71-73 /2, or EVEX.128.66.0F 71-73 /2), VEX.vvvv/EVEX.vvvv encodes the destination register.", + "operation": "IF (COUNT > 15)\nTHEN\n DEST[64:0] := 0000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(DEST[15:0] >> COUNT);\n (* Repeat shift operation for 2nd and 3rd words *)\n DEST[63:48] := ZeroExtend(DEST[63:48] >> COUNT);\nFI;\n\n\nIF (COUNT > 31)\nTHEN\n DEST[64:0] := 0000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(DEST[31:0] >> COUNT);\n DEST[63:32] := ZeroExtend(DEST[63:32] >> COUNT);\nFI;\n\n\n IF (COUNT > 63)\n THEN\n DEST[64:0] := 0000000000000000H\n ELSE\n DEST := ZeroExtend(DEST >> COUNT);\n FI;\nLOGICAL_RIGHT_SHIFT_DWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[31:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS1(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[63:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_WORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 15th words *)\n DEST[255:240] := ZeroExtend(SRC[255:240] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_WORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 15)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[15:0] := ZeroExtend(SRC[15:0] >> COUNT);\n (* Repeat shift operation for 2nd through 7th words *)\n DEST[127:112] := ZeroExtend(SRC[127:112] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[255:224] := ZeroExtend(SRC[255:224] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_DWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 31)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[31:0] := ZeroExtend(SRC[31:0] >> COUNT);\n (* Repeat shift operation for 2nd through 3rd words *)\n DEST[127:96] := ZeroExtend(SRC[127:96] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[255:0] := 0\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] >> COUNT);\n DEST[191:128] := ZeroExtend(SRC[191:128] >> COUNT);\n DEST[255:192] := ZeroExtend(SRC[255:192] >> COUNT);\nFI;\nLOGICAL_RIGHT_SHIFT_QWORDS(SRC, COUNT_SRC)\nCOUNT := COUNT_SRC[63:0];\nIF (COUNT > 63)\nTHEN\n DEST[127:0] := 00000000000000000000000000000000H\nELSE\n DEST[63:0] := ZeroExtend(SRC[63:0] >> COUNT);\n DEST[127:64] := ZeroExtend(SRC[127:64] >> COUNT);\nFI;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS_128b(SRC1[127:0], imm8)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[255:0], imm8)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1[511:256], imm8)\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_WORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_WORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+31:i] := LOGICAL_RIGHT_SHIFT_DWORDS1(SRC1[31:0], imm8)\n ELSE DEST[i+31:i] := LOGICAL_RIGHT_SHIFT_DWORDS1(SRC1[i+31:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_DWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_DWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nTMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nTMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nIF VL = 128\n TMP_DEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS_128b(SRC1[127:0], SRC2)\nFI;\nIF VL = 256\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\nFI;\nIF VL = 512\n TMP_DEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[255:0], SRC2)\n TMP_DEST[511:256] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1[511:256], SRC2)\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC1 *is memory*)\n THEN DEST[i+63:i] := LOGICAL_RIGHT_SHIFT_QWORDS1(SRC1[63:0], imm8)\n ELSE DEST[i+63:i] := LOGICAL_RIGHT_SHIFT_QWORDS1(SRC1[i+63:i], imm8)\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[255:0] := LOGICAL_RIGHT_SHIFT_QWORDS_256b(SRC1, imm8)\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(SRC1, imm8)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := LOGICAL_RIGHT_SHIFT_QWORDS(DEST, imm8)\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psrlw:psrld:psrlq" + }, + "psubb": { + "instruction": "PSUBB", + "title": "PSUBB/PSUBW/PSUBD\n\t\t— Subtract Packed Integers", + "opcode": "NP 0F F8 /r1 PSUBB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed integers of the source operand (second operand) from the packed integers of the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe (V)PSUBB instruction subtracts packed byte integers. When an individual result is too large or too small to be represented in a byte, the result is wrapped around and the low 8 bits are written to the destination element.\nThe (V)PSUBW instruction subtracts packed word integers. When an individual result is too large or too small to be represented in a word, the result is wrapped around and the low 16 bits are written to the destination element.\nThe (V)PSUBD instruction subtracts packed doubleword integers. When an individual result is too large or too small to be represented in a doubleword, the result is wrapped around and the low 32 bits are written to the destination element.\nNote that the (V)PSUBB, (V)PSUBW, and (V)PSUBD instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values upon which it operates.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPSUBD: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPSUBB/W: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[7:0] − SRC[7:0];\n(* Repeat subtract operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] − SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] − SRC[15:0];\n(* Repeat subtract operation for 2nd and 3rd word *)\nDEST[63:48] := DEST[63:48] − SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] − SRC[31:0];\nDEST[63:32] := DEST[63:32] − SRC[63:32];\n\n\nDEST[31:0] := DEST[31:0] − SRC[31:0];\n(* Repeat subtract operation for 2nd and 3rd doubleword *)\nDEST[127:96] := DEST[127:96] − SRC[127:96];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] - SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] - SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] - SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] - SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[7:0] := SRC1[7:0]-SRC2[7:0]\nDEST[15:8] := SRC1[15:8]-SRC2[15:8]\nDEST[23:16] := SRC1[23:16]-SRC2[23:16]\nDEST[31:24] := SRC1[31:24]-SRC2[31:24]\nDEST[39:32] := SRC1[39:32]-SRC2[39:32]\nDEST[47:40] := SRC1[47:40]-SRC2[47:40]\nDEST[55:48] := SRC1[55:48]-SRC2[55:48]\nDEST[63:56] := SRC1[63:56]-SRC2[63:56]\nDEST[71:64] := SRC1[71:64]-SRC2[71:64]\nDEST[79:72] := SRC1[79:72]-SRC2[79:72]\nDEST[87:80] := SRC1[87:80]-SRC2[87:80]\nDEST[95:88] := SRC1[95:88]-SRC2[95:88]\nDEST[103:96] := SRC1[103:96]-SRC2[103:96]\nDEST[111:104] := SRC1[111:104]-SRC2[111:104]\nDEST[119:112] := SRC1[119:112]-SRC2[119:112]\nDEST[127:120] := SRC1[127:120]-SRC2[127:120]\nDEST[135:128] := SRC1[135:128]-SRC2[135:128]\nDEST[143:136] := SRC1[143:136]-SRC2[143:136]\nDEST[151:144] := SRC1[151:144]-SRC2[151:144]\nDEST[159:152] := SRC1[159:152]-SRC2[159:152]\nDEST[167:160] := SRC1[167:160]-SRC2[167:160]\nDEST[175:168] := SRC1[175:168]-SRC2[175:168]\nDEST[183:176] := SRC1[183:176]-SRC2[183:176]\nDEST[191:184] := SRC1[191:184]-SRC2[191:184]\nDEST[199:192] := SRC1[199:192]-SRC2[199:192]\nDEST[207:200] := SRC1[207:200]-SRC2[207:200]\nDEST[215:208] := SRC1[215:208]-SRC2[215:208]\nDEST[223:216] := SRC1[223:216]-SRC2[223:216]\nDEST[231:224] := SRC1[231:224]-SRC2[231:224]\nDEST[239:232] := SRC1[239:232]-SRC2[239:232]\nDEST[247:240] := SRC1[247:240]-SRC2[247:240]\nDEST[255:248] := SRC1[255:248]-SRC2[255:248]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[7:0] := SRC1[7:0]-SRC2[7:0]\nDEST[15:8] := SRC1[15:8]-SRC2[15:8]\nDEST[23:16] := SRC1[23:16]-SRC2[23:16]\nDEST[31:24] := SRC1[31:24]-SRC2[31:24]\nDEST[39:32] := SRC1[39:32]-SRC2[39:32]\nDEST[47:40] := SRC1[47:40]-SRC2[47:40]\nDEST[55:48] := SRC1[55:48]-SRC2[55:48]\nDEST[63:56] := SRC1[63:56]-SRC2[63:56]\nDEST[71:64] := SRC1[71:64]-SRC2[71:64]\nDEST[79:72] := SRC1[79:72]-SRC2[79:72]\nDEST[87:80] := SRC1[87:80]-SRC2[87:80]\nDEST[95:88] := SRC1[95:88]-SRC2[95:88]\nDEST[103:96] := SRC1[103:96]-SRC2[103:96]\nDEST[111:104] := SRC1[111:104]-SRC2[111:104]\nDEST[119:112] := SRC1[119:112]-SRC2[119:112]\nDEST[127:120] := SRC1[127:120]-SRC2[127:120]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := DEST[7:0]-SRC[7:0]\nDEST[15:8] := DEST[15:8]-SRC[15:8]\nDEST[23:16] := DEST[23:16]-SRC[23:16]\nDEST[31:24] := DEST[31:24]-SRC[31:24]\nDEST[39:32] := DEST[39:32]-SRC[39:32]\nDEST[47:40] := DEST[47:40]-SRC[47:40]\nDEST[55:48] := DEST[55:48]-SRC[55:48]\nDEST[63:56] := DEST[63:56]-SRC[63:56]\nDEST[71:64] := DEST[71:64]-SRC[71:64]\nDEST[79:72] := DEST[79:72]-SRC[79:72]\nDEST[87:80] := DEST[87:80]-SRC[87:80]\nDEST[95:88] := DEST[95:88]-SRC[95:88]\nDEST[103:96] := DEST[103:96]-SRC[103:96]\nDEST[111:104] := DEST[111:104]-SRC[111:104]\nDEST[119:112] := DEST[119:112]-SRC[119:112]\nDEST[127:120] := DEST[127:120]-SRC[127:120]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SRC1[15:0]-SRC2[15:0]\nDEST[31:16] := SRC1[31:16]-SRC2[31:16]\nDEST[47:32] := SRC1[47:32]-SRC2[47:32]\nDEST[63:48] := SRC1[63:48]-SRC2[63:48]\nDEST[79:64] := SRC1[79:64]-SRC2[79:64]\nDEST[95:80] := SRC1[95:80]-SRC2[95:80]\nDEST[111:96] := SRC1[111:96]-SRC2[111:96]\nDEST[127:112] := SRC1[127:112]-SRC2[127:112]\nDEST[143:128] := SRC1[143:128]-SRC2[143:128]\nDEST[159:144] := SRC1[159:144]-SRC2[159:144]\nDEST[175:160] := SRC1[175:160]-SRC2[175:160]\nDEST[191:176] := SRC1[191:176]-SRC2[191:176]\nDEST[207:192] := SRC1207:192]-SRC2[207:192]\nDEST[223:208] := SRC1[223:208]-SRC2[223:208]\nDEST[239:224] := SRC1[239:224]-SRC2[239:224]\nDEST[255:240] := SRC1[255:240]-SRC2[255:240]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[15:0] := SRC1[15:0]-SRC2[15:0]\nDEST[31:16] := SRC1[31:16]-SRC2[31:16]\nDEST[47:32] := SRC1[47:32]-SRC2[47:32]\nDEST[63:48] := SRC1[63:48]-SRC2[63:48]\nDEST[79:64] := SRC1[79:64]-SRC2[79:64]\nDEST[95:80] := SRC1[95:80]-SRC2[95:80]\nDEST[111:96] := SRC1[111:96]-SRC2[111:96]\nDEST[127:112] := SRC1[127:112]-SRC2[127:112]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := DEST[15:0]-SRC[15:0]\nDEST[31:16] := DEST[31:16]-SRC[31:16]\nDEST[47:32] := DEST[47:32]-SRC[47:32]\nDEST[63:48] := DEST[63:48]-SRC[63:48]\nDEST[79:64] := DEST[79:64]-SRC[79:64]\nDEST[95:80] := DEST[95:80]-SRC[95:80]\nDEST[111:96] := DEST[111:96]-SRC[111:96]\nDEST[127:112] := DEST[127:112]-SRC[127:112]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := SRC1[31:0]-SRC2[31:0]\nDEST[63:32] := SRC1[63:32]-SRC2[63:32]\nDEST[95:64] := SRC1[95:64]-SRC2[95:64]\nDEST[127:96] := SRC1[127:96]-SRC2[127:96]\nDEST[159:128] := SRC1[159:128]-SRC2[159:128]\nDEST[191:160] := SRC1[191:160]-SRC2[191:160]\nDEST[223:192] := SRC1[223:192]-SRC2[223:192]\nDEST[255:224] := SRC1[255:224]-SRC2[255:224]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0]-SRC2[31:0]\nDEST[63:32] := SRC1[63:32]-SRC2[63:32]\nDEST[95:64] := SRC1[95:64]-SRC2[95:64]\nDEST[127:96] := SRC1[127:96]-SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0]-SRC[31:0]\nDEST[63:32] := DEST[63:32]-SRC[63:32]\nDEST[95:64] := DEST[95:64]-SRC[95:64]\nDEST[127:96] := DEST[127:96]-SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psubb:psubw:psubd" + }, + "psubd": { + "instruction": "PSUBD", + "title": "PSUBB/PSUBW/PSUBD\n\t\t— Subtract Packed Integers", + "opcode": "NP 0F F8 /r1 PSUBB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed integers of the source operand (second operand) from the packed integers of the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe (V)PSUBB instruction subtracts packed byte integers. When an individual result is too large or too small to be represented in a byte, the result is wrapped around and the low 8 bits are written to the destination element.\nThe (V)PSUBW instruction subtracts packed word integers. When an individual result is too large or too small to be represented in a word, the result is wrapped around and the low 16 bits are written to the destination element.\nThe (V)PSUBD instruction subtracts packed doubleword integers. When an individual result is too large or too small to be represented in a doubleword, the result is wrapped around and the low 32 bits are written to the destination element.\nNote that the (V)PSUBB, (V)PSUBW, and (V)PSUBD instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values upon which it operates.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPSUBD: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPSUBB/W: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[7:0] − SRC[7:0];\n(* Repeat subtract operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] − SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] − SRC[15:0];\n(* Repeat subtract operation for 2nd and 3rd word *)\nDEST[63:48] := DEST[63:48] − SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] − SRC[31:0];\nDEST[63:32] := DEST[63:32] − SRC[63:32];\n\n\nDEST[31:0] := DEST[31:0] − SRC[31:0];\n(* Repeat subtract operation for 2nd and 3rd doubleword *)\nDEST[127:96] := DEST[127:96] − SRC[127:96];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] - SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] - SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] - SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] - SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[7:0] := SRC1[7:0]-SRC2[7:0]\nDEST[15:8] := SRC1[15:8]-SRC2[15:8]\nDEST[23:16] := SRC1[23:16]-SRC2[23:16]\nDEST[31:24] := SRC1[31:24]-SRC2[31:24]\nDEST[39:32] := SRC1[39:32]-SRC2[39:32]\nDEST[47:40] := SRC1[47:40]-SRC2[47:40]\nDEST[55:48] := SRC1[55:48]-SRC2[55:48]\nDEST[63:56] := SRC1[63:56]-SRC2[63:56]\nDEST[71:64] := SRC1[71:64]-SRC2[71:64]\nDEST[79:72] := SRC1[79:72]-SRC2[79:72]\nDEST[87:80] := SRC1[87:80]-SRC2[87:80]\nDEST[95:88] := SRC1[95:88]-SRC2[95:88]\nDEST[103:96] := SRC1[103:96]-SRC2[103:96]\nDEST[111:104] := SRC1[111:104]-SRC2[111:104]\nDEST[119:112] := SRC1[119:112]-SRC2[119:112]\nDEST[127:120] := SRC1[127:120]-SRC2[127:120]\nDEST[135:128] := SRC1[135:128]-SRC2[135:128]\nDEST[143:136] := SRC1[143:136]-SRC2[143:136]\nDEST[151:144] := SRC1[151:144]-SRC2[151:144]\nDEST[159:152] := SRC1[159:152]-SRC2[159:152]\nDEST[167:160] := SRC1[167:160]-SRC2[167:160]\nDEST[175:168] := SRC1[175:168]-SRC2[175:168]\nDEST[183:176] := SRC1[183:176]-SRC2[183:176]\nDEST[191:184] := SRC1[191:184]-SRC2[191:184]\nDEST[199:192] := SRC1[199:192]-SRC2[199:192]\nDEST[207:200] := SRC1[207:200]-SRC2[207:200]\nDEST[215:208] := SRC1[215:208]-SRC2[215:208]\nDEST[223:216] := SRC1[223:216]-SRC2[223:216]\nDEST[231:224] := SRC1[231:224]-SRC2[231:224]\nDEST[239:232] := SRC1[239:232]-SRC2[239:232]\nDEST[247:240] := SRC1[247:240]-SRC2[247:240]\nDEST[255:248] := SRC1[255:248]-SRC2[255:248]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[7:0] := SRC1[7:0]-SRC2[7:0]\nDEST[15:8] := SRC1[15:8]-SRC2[15:8]\nDEST[23:16] := SRC1[23:16]-SRC2[23:16]\nDEST[31:24] := SRC1[31:24]-SRC2[31:24]\nDEST[39:32] := SRC1[39:32]-SRC2[39:32]\nDEST[47:40] := SRC1[47:40]-SRC2[47:40]\nDEST[55:48] := SRC1[55:48]-SRC2[55:48]\nDEST[63:56] := SRC1[63:56]-SRC2[63:56]\nDEST[71:64] := SRC1[71:64]-SRC2[71:64]\nDEST[79:72] := SRC1[79:72]-SRC2[79:72]\nDEST[87:80] := SRC1[87:80]-SRC2[87:80]\nDEST[95:88] := SRC1[95:88]-SRC2[95:88]\nDEST[103:96] := SRC1[103:96]-SRC2[103:96]\nDEST[111:104] := SRC1[111:104]-SRC2[111:104]\nDEST[119:112] := SRC1[119:112]-SRC2[119:112]\nDEST[127:120] := SRC1[127:120]-SRC2[127:120]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := DEST[7:0]-SRC[7:0]\nDEST[15:8] := DEST[15:8]-SRC[15:8]\nDEST[23:16] := DEST[23:16]-SRC[23:16]\nDEST[31:24] := DEST[31:24]-SRC[31:24]\nDEST[39:32] := DEST[39:32]-SRC[39:32]\nDEST[47:40] := DEST[47:40]-SRC[47:40]\nDEST[55:48] := DEST[55:48]-SRC[55:48]\nDEST[63:56] := DEST[63:56]-SRC[63:56]\nDEST[71:64] := DEST[71:64]-SRC[71:64]\nDEST[79:72] := DEST[79:72]-SRC[79:72]\nDEST[87:80] := DEST[87:80]-SRC[87:80]\nDEST[95:88] := DEST[95:88]-SRC[95:88]\nDEST[103:96] := DEST[103:96]-SRC[103:96]\nDEST[111:104] := DEST[111:104]-SRC[111:104]\nDEST[119:112] := DEST[119:112]-SRC[119:112]\nDEST[127:120] := DEST[127:120]-SRC[127:120]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SRC1[15:0]-SRC2[15:0]\nDEST[31:16] := SRC1[31:16]-SRC2[31:16]\nDEST[47:32] := SRC1[47:32]-SRC2[47:32]\nDEST[63:48] := SRC1[63:48]-SRC2[63:48]\nDEST[79:64] := SRC1[79:64]-SRC2[79:64]\nDEST[95:80] := SRC1[95:80]-SRC2[95:80]\nDEST[111:96] := SRC1[111:96]-SRC2[111:96]\nDEST[127:112] := SRC1[127:112]-SRC2[127:112]\nDEST[143:128] := SRC1[143:128]-SRC2[143:128]\nDEST[159:144] := SRC1[159:144]-SRC2[159:144]\nDEST[175:160] := SRC1[175:160]-SRC2[175:160]\nDEST[191:176] := SRC1[191:176]-SRC2[191:176]\nDEST[207:192] := SRC1207:192]-SRC2[207:192]\nDEST[223:208] := SRC1[223:208]-SRC2[223:208]\nDEST[239:224] := SRC1[239:224]-SRC2[239:224]\nDEST[255:240] := SRC1[255:240]-SRC2[255:240]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[15:0] := SRC1[15:0]-SRC2[15:0]\nDEST[31:16] := SRC1[31:16]-SRC2[31:16]\nDEST[47:32] := SRC1[47:32]-SRC2[47:32]\nDEST[63:48] := SRC1[63:48]-SRC2[63:48]\nDEST[79:64] := SRC1[79:64]-SRC2[79:64]\nDEST[95:80] := SRC1[95:80]-SRC2[95:80]\nDEST[111:96] := SRC1[111:96]-SRC2[111:96]\nDEST[127:112] := SRC1[127:112]-SRC2[127:112]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := DEST[15:0]-SRC[15:0]\nDEST[31:16] := DEST[31:16]-SRC[31:16]\nDEST[47:32] := DEST[47:32]-SRC[47:32]\nDEST[63:48] := DEST[63:48]-SRC[63:48]\nDEST[79:64] := DEST[79:64]-SRC[79:64]\nDEST[95:80] := DEST[95:80]-SRC[95:80]\nDEST[111:96] := DEST[111:96]-SRC[111:96]\nDEST[127:112] := DEST[127:112]-SRC[127:112]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := SRC1[31:0]-SRC2[31:0]\nDEST[63:32] := SRC1[63:32]-SRC2[63:32]\nDEST[95:64] := SRC1[95:64]-SRC2[95:64]\nDEST[127:96] := SRC1[127:96]-SRC2[127:96]\nDEST[159:128] := SRC1[159:128]-SRC2[159:128]\nDEST[191:160] := SRC1[191:160]-SRC2[191:160]\nDEST[223:192] := SRC1[223:192]-SRC2[223:192]\nDEST[255:224] := SRC1[255:224]-SRC2[255:224]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0]-SRC2[31:0]\nDEST[63:32] := SRC1[63:32]-SRC2[63:32]\nDEST[95:64] := SRC1[95:64]-SRC2[95:64]\nDEST[127:96] := SRC1[127:96]-SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0]-SRC[31:0]\nDEST[63:32] := DEST[63:32]-SRC[63:32]\nDEST[95:64] := DEST[95:64]-SRC[95:64]\nDEST[127:96] := DEST[127:96]-SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psubb:psubw:psubd" + }, + "psubq": { + "instruction": "PSUBQ", + "title": "PSUBQ\n\t\t— Subtract Packed Quadword Integers", + "opcode": "NP 0F FB /r1 PSUBQ mm1, mm2/m64", + "description": "Subtracts the second operand (source operand) from the first operand (destination operand) and stores the result in the destination operand. When packed quadword operands are used, a SIMD subtract is performed. When a quadword result is too large to be represented in 64 bits (overflow), the result is wrapped around and the low 64 bits are written to the destination element (that is, the carry is ignored).\nNote that the (V)PSUBQ instruction can operate on either unsigned or signed (two’s complement notation) integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of the values upon which it operates.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The source operand can be a quadword integer stored in an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPSUBQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[63:0] := DEST[63:0] − SRC[63:0];\n\n\nDEST[63:0] := DEST[63:0] − SRC[63:0];\nDEST[127:64] := DEST[127:64] − SRC[127:64];\n\n\nDEST[63:0] := SRC1[63:0]-SRC2[63:0]\nDEST[127:64] := SRC1[127:64]-SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0]-SRC2[63:0]\nDEST[127:64] := SRC1[127:64]-SRC2[127:64]\nDEST[191:128] := SRC1[191:128]-SRC2[191:128]\nDEST[255:192] := SRC1[255:192]-SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] - SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] - SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/psubq" + }, + "psubsb": { + "instruction": "PSUBSB", + "title": "PSUBSB/PSUBSW\n\t\t— Subtract Packed Signed Integers With Signed Saturation", + "opcode": "NP 0F E8 /r1 PSUBSB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed signed integers of the source operand (second operand) from the packed signed integers of the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with signed saturation, as described in the following paragraphs.\nThe (V)PSUBSB instruction subtracts packed signed byte integers. When an individual byte result is beyond the range of a signed byte integer (that is, greater than 7FH or less than 80H), the saturated value of 7FH or 80H, respectively, is written to the destination operand.\nThe (V)PSUBSW instruction subtracts packed signed word integers. When an individual word result is beyond the range of a signed word integer (that is, greater than 7FFFH or less than 8000H), the saturated value of 7FFFH or 8000H, respectively, is written to the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded version: The second source operand is an ZMM/YMM/XMM register or an 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := SaturateToSignedByte (DEST[7:0] − SRC (7:0]);\n(* Repeat subtract operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToSignedByte (DEST[63:56] − SRC[63:56] );\n\n\nDEST[15:0] := SaturateToSignedWord (DEST[15:0] − SRC[15:0] );\n(* Repeat subtract operation for 2nd and 7th words *)\nDEST[63:48] := SaturateToSignedWord (DEST[63:48] − SRC[63:48] );\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8;\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToSignedByte (SRC1[i+7:i] - SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToSignedWord (SRC1[i+15:i] - SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0;\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 31th bytes *)\nDEST[255:248] := SaturateToSignedByte (SRC1[255:248] - SRC2[255:248]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (SRC1[127:120] - SRC2[127:120]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SaturateToSignedByte (DEST[7:0] - SRC[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (DEST[127:120] - SRC[127:120]);\nDEST[MAXVL-1:128] (Unmodified);\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToSignedWord (SRC1[255:240] - SRC2[255:240]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToSignedWord (SRC1[127:112] - SRC2[127:112]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SaturateToSignedWord (DEST[15:0] - SRC[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToSignedWord (DEST[127:112] - SRC[127:112]);\nDEST[MAXVL-1:128] (Unmodified);\n", + "url": "https://www.felixcloutier.com/x86/psubsb:psubsw" + }, + "psubsw": { + "instruction": "PSUBSW", + "title": "PSUBSB/PSUBSW\n\t\t— Subtract Packed Signed Integers With Signed Saturation", + "opcode": "NP 0F E8 /r1 PSUBSB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed signed integers of the source operand (second operand) from the packed signed integers of the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with signed saturation, as described in the following paragraphs.\nThe (V)PSUBSB instruction subtracts packed signed byte integers. When an individual byte result is beyond the range of a signed byte integer (that is, greater than 7FH or less than 80H), the saturated value of 7FH or 80H, respectively, is written to the destination operand.\nThe (V)PSUBSW instruction subtracts packed signed word integers. When an individual word result is beyond the range of a signed word integer (that is, greater than 7FFFH or less than 8000H), the saturated value of 7FFFH or 8000H, respectively, is written to the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded version: The second source operand is an ZMM/YMM/XMM register or an 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := SaturateToSignedByte (DEST[7:0] − SRC (7:0]);\n(* Repeat subtract operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToSignedByte (DEST[63:56] − SRC[63:56] );\n\n\nDEST[15:0] := SaturateToSignedWord (DEST[15:0] − SRC[15:0] );\n(* Repeat subtract operation for 2nd and 7th words *)\nDEST[63:48] := SaturateToSignedWord (DEST[63:48] − SRC[63:48] );\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8;\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToSignedByte (SRC1[i+7:i] - SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToSignedWord (SRC1[i+15:i] - SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0;\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 31th bytes *)\nDEST[255:248] := SaturateToSignedByte (SRC1[255:248] - SRC2[255:248]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[7:0] := SaturateToSignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (SRC1[127:120] - SRC2[127:120]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[7:0] := SaturateToSignedByte (DEST[7:0] - SRC[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToSignedByte (DEST[127:120] - SRC[127:120]);\nDEST[MAXVL-1:128] (Unmodified);\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToSignedWord (SRC1[255:240] - SRC2[255:240]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[15:0] := SaturateToSignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToSignedWord (SRC1[127:112] - SRC2[127:112]);\nDEST[MAXVL-1:128] := 0;\n\n\nDEST[15:0] := SaturateToSignedWord (DEST[15:0] - SRC[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToSignedWord (DEST[127:112] - SRC[127:112]);\nDEST[MAXVL-1:128] (Unmodified);\n", + "url": "https://www.felixcloutier.com/x86/psubsb:psubsw" + }, + "psubusb": { + "instruction": "PSUBUSB", + "title": "PSUBUSB/PSUBUSW\n\t\t— Subtract Packed Unsigned Integers With Unsigned Saturation", + "opcode": "NP 0F D8 /r1 PSUBUSB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed unsigned integers of the source operand (second operand) from the packed unsigned integers of the destination operand (first operand), and stores the packed unsigned integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with unsigned saturation, as described in the following paragraphs.\nThese instructions can operate on either 64-bit or 128-bit operands.\nThe (V)PSUBUSB instruction subtracts packed unsigned byte integers. When an individual byte result is less than zero, the saturated value of 00H is written to the destination operand.\nThe (V)PSUBUSW instruction subtracts packed unsigned word integers. When an individual word result is less than zero, the saturated value of 0000H is written to the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded version: The second source operand is an ZMM/YMM/XMM register or an 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := SaturateToUnsignedByte (DEST[7:0] − SRC (7:0] );\n(* Repeat add operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToUnsignedByte (DEST[63:56] − SRC[63:56];\n\n\nDEST[15:0] := SaturateToUnsignedWord (DEST[15:0] − SRC[15:0] );\n(* Repeat add operation for 2nd and 3rd words *)\nDEST[63:48] := SaturateToUnsignedWord (DEST[63:48] − SRC[63:48] );\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8;\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToUnsignedByte (SRC1[i+7:i] - SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16;\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToUnsignedWord (SRC1[i+15:i] - SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0;\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 31st bytes *)\nDEST[255:148] := SaturateToUnsignedByte (SRC1[255:248] - SRC2[255:248]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnsignedByte (SRC1[127:120] - SRC2[127:120]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := SaturateToUnsignedByte (DEST[7:0] - SRC[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnsignedByte (DEST[127:120] - SRC[127:120]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToUnsignedWord (SRC1[255:240] - SRC2[255:240]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnsignedWord (SRC1[127:112] - SRC2[127:112]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToUnsignedWord (DEST[15:0] - SRC[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnsignedWord (DEST[127:112] - SRC[127:112]);\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psubusb:psubusw" + }, + "psubusw": { + "instruction": "PSUBUSW", + "title": "PSUBUSB/PSUBUSW\n\t\t— Subtract Packed Unsigned Integers With Unsigned Saturation", + "opcode": "NP 0F D8 /r1 PSUBUSB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed unsigned integers of the source operand (second operand) from the packed unsigned integers of the destination operand (first operand), and stores the packed unsigned integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with unsigned saturation, as described in the following paragraphs.\nThese instructions can operate on either 64-bit or 128-bit operands.\nThe (V)PSUBUSB instruction subtracts packed unsigned byte integers. When an individual byte result is less than zero, the saturated value of 00H is written to the destination operand.\nThe (V)PSUBUSW instruction subtracts packed unsigned word integers. When an individual word result is less than zero, the saturated value of 0000H is written to the destination operand.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded version: The second source operand is an ZMM/YMM/XMM register or an 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := SaturateToUnsignedByte (DEST[7:0] − SRC (7:0] );\n(* Repeat add operation for 2nd through 7th bytes *)\nDEST[63:56] := SaturateToUnsignedByte (DEST[63:56] − SRC[63:56];\n\n\nDEST[15:0] := SaturateToUnsignedWord (DEST[15:0] − SRC[15:0] );\n(* Repeat add operation for 2nd and 3rd words *)\nDEST[63:48] := SaturateToUnsignedWord (DEST[63:48] − SRC[63:48] );\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8;\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SaturateToUnsignedByte (SRC1[i+7:i] - SRC2[i+7:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16;\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SaturateToUnsignedWord (SRC1[i+15:i] - SRC2[i+15:i])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0;\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0;\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 31st bytes *)\nDEST[255:148] := SaturateToUnsignedByte (SRC1[255:248] - SRC2[255:248]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[7:0] := SaturateToUnsignedByte (SRC1[7:0] - SRC2[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnsignedByte (SRC1[127:120] - SRC2[127:120]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := SaturateToUnsignedByte (DEST[7:0] - SRC[7:0]);\n(* Repeat subtract operation for 2nd through 14th bytes *)\nDEST[127:120] := SaturateToUnsignedByte (DEST[127:120] - SRC[127:120]);\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 15th words *)\nDEST[255:240] := SaturateToUnsignedWord (SRC1[255:240] - SRC2[255:240]);\nDEST[MAXVL-1:256] := 0;\n\n\nDEST[15:0] := SaturateToUnsignedWord (SRC1[15:0] - SRC2[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnsignedWord (SRC1[127:112] - SRC2[127:112]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := SaturateToUnsignedWord (DEST[15:0] - SRC[15:0]);\n(* Repeat subtract operation for 2nd through 7th words *)\nDEST[127:112] := SaturateToUnsignedWord (DEST[127:112] - SRC[127:112]);\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psubusb:psubusw" + }, + "psubw": { + "instruction": "PSUBW", + "title": "PSUBB/PSUBW/PSUBD\n\t\t— Subtract Packed Integers", + "opcode": "NP 0F F8 /r1 PSUBB mm, mm/m64", + "description": "Performs a SIMD subtract of the packed integers of the source operand (second operand) from the packed integers of the destination operand (first operand), and stores the packed integer results in the destination operand. See Figure 9-4 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD operation. Overflow is handled with wraparound, as described in the following paragraphs.\nThe (V)PSUBB instruction subtracts packed byte integers. When an individual result is too large or too small to be represented in a byte, the result is wrapped around and the low 8 bits are written to the destination element.\nThe (V)PSUBW instruction subtracts packed word integers. When an individual result is too large or too small to be represented in a word, the result is wrapped around and the low 16 bits are written to the destination element.\nThe (V)PSUBD instruction subtracts packed doubleword integers. When an individual result is too large or too small to be represented in a doubleword, the result is wrapped around and the low 32 bits are written to the destination element.\nNote that the (V)PSUBB, (V)PSUBW, and (V)PSUBD instructions can operate on either unsigned or signed (two's complement notation) packed integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of values upon which it operates.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE version 64-bit operand: The destination operand must be an MMX technology register and the source operand can be either an MMX technology register or a 64-bit memory location.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPSUBD: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPSUBB/W: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[7:0] − SRC[7:0];\n(* Repeat subtract operation for 2nd through 7th byte *)\nDEST[63:56] := DEST[63:56] − SRC[63:56];\n\n\nDEST[15:0] := DEST[15:0] − SRC[15:0];\n(* Repeat subtract operation for 2nd and 3rd word *)\nDEST[63:48] := DEST[63:48] − SRC[63:48];\n\n\nDEST[31:0] := DEST[31:0] − SRC[31:0];\nDEST[63:32] := DEST[63:32] − SRC[63:32];\n\n\nDEST[31:0] := DEST[31:0] − SRC[31:0];\n(* Repeat subtract operation for 2nd and 3rd doubleword *)\nDEST[127:96] := DEST[127:96] − SRC[127:96];\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC1[i+7:i] - SRC2[i+7:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC1[i+15:i] - SRC2[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] = 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] - SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] - SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[7:0] := SRC1[7:0]-SRC2[7:0]\nDEST[15:8] := SRC1[15:8]-SRC2[15:8]\nDEST[23:16] := SRC1[23:16]-SRC2[23:16]\nDEST[31:24] := SRC1[31:24]-SRC2[31:24]\nDEST[39:32] := SRC1[39:32]-SRC2[39:32]\nDEST[47:40] := SRC1[47:40]-SRC2[47:40]\nDEST[55:48] := SRC1[55:48]-SRC2[55:48]\nDEST[63:56] := SRC1[63:56]-SRC2[63:56]\nDEST[71:64] := SRC1[71:64]-SRC2[71:64]\nDEST[79:72] := SRC1[79:72]-SRC2[79:72]\nDEST[87:80] := SRC1[87:80]-SRC2[87:80]\nDEST[95:88] := SRC1[95:88]-SRC2[95:88]\nDEST[103:96] := SRC1[103:96]-SRC2[103:96]\nDEST[111:104] := SRC1[111:104]-SRC2[111:104]\nDEST[119:112] := SRC1[119:112]-SRC2[119:112]\nDEST[127:120] := SRC1[127:120]-SRC2[127:120]\nDEST[135:128] := SRC1[135:128]-SRC2[135:128]\nDEST[143:136] := SRC1[143:136]-SRC2[143:136]\nDEST[151:144] := SRC1[151:144]-SRC2[151:144]\nDEST[159:152] := SRC1[159:152]-SRC2[159:152]\nDEST[167:160] := SRC1[167:160]-SRC2[167:160]\nDEST[175:168] := SRC1[175:168]-SRC2[175:168]\nDEST[183:176] := SRC1[183:176]-SRC2[183:176]\nDEST[191:184] := SRC1[191:184]-SRC2[191:184]\nDEST[199:192] := SRC1[199:192]-SRC2[199:192]\nDEST[207:200] := SRC1[207:200]-SRC2[207:200]\nDEST[215:208] := SRC1[215:208]-SRC2[215:208]\nDEST[223:216] := SRC1[223:216]-SRC2[223:216]\nDEST[231:224] := SRC1[231:224]-SRC2[231:224]\nDEST[239:232] := SRC1[239:232]-SRC2[239:232]\nDEST[247:240] := SRC1[247:240]-SRC2[247:240]\nDEST[255:248] := SRC1[255:248]-SRC2[255:248]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[7:0] := SRC1[7:0]-SRC2[7:0]\nDEST[15:8] := SRC1[15:8]-SRC2[15:8]\nDEST[23:16] := SRC1[23:16]-SRC2[23:16]\nDEST[31:24] := SRC1[31:24]-SRC2[31:24]\nDEST[39:32] := SRC1[39:32]-SRC2[39:32]\nDEST[47:40] := SRC1[47:40]-SRC2[47:40]\nDEST[55:48] := SRC1[55:48]-SRC2[55:48]\nDEST[63:56] := SRC1[63:56]-SRC2[63:56]\nDEST[71:64] := SRC1[71:64]-SRC2[71:64]\nDEST[79:72] := SRC1[79:72]-SRC2[79:72]\nDEST[87:80] := SRC1[87:80]-SRC2[87:80]\nDEST[95:88] := SRC1[95:88]-SRC2[95:88]\nDEST[103:96] := SRC1[103:96]-SRC2[103:96]\nDEST[111:104] := SRC1[111:104]-SRC2[111:104]\nDEST[119:112] := SRC1[119:112]-SRC2[119:112]\nDEST[127:120] := SRC1[127:120]-SRC2[127:120]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[7:0] := DEST[7:0]-SRC[7:0]\nDEST[15:8] := DEST[15:8]-SRC[15:8]\nDEST[23:16] := DEST[23:16]-SRC[23:16]\nDEST[31:24] := DEST[31:24]-SRC[31:24]\nDEST[39:32] := DEST[39:32]-SRC[39:32]\nDEST[47:40] := DEST[47:40]-SRC[47:40]\nDEST[55:48] := DEST[55:48]-SRC[55:48]\nDEST[63:56] := DEST[63:56]-SRC[63:56]\nDEST[71:64] := DEST[71:64]-SRC[71:64]\nDEST[79:72] := DEST[79:72]-SRC[79:72]\nDEST[87:80] := DEST[87:80]-SRC[87:80]\nDEST[95:88] := DEST[95:88]-SRC[95:88]\nDEST[103:96] := DEST[103:96]-SRC[103:96]\nDEST[111:104] := DEST[111:104]-SRC[111:104]\nDEST[119:112] := DEST[119:112]-SRC[119:112]\nDEST[127:120] := DEST[127:120]-SRC[127:120]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[15:0] := SRC1[15:0]-SRC2[15:0]\nDEST[31:16] := SRC1[31:16]-SRC2[31:16]\nDEST[47:32] := SRC1[47:32]-SRC2[47:32]\nDEST[63:48] := SRC1[63:48]-SRC2[63:48]\nDEST[79:64] := SRC1[79:64]-SRC2[79:64]\nDEST[95:80] := SRC1[95:80]-SRC2[95:80]\nDEST[111:96] := SRC1[111:96]-SRC2[111:96]\nDEST[127:112] := SRC1[127:112]-SRC2[127:112]\nDEST[143:128] := SRC1[143:128]-SRC2[143:128]\nDEST[159:144] := SRC1[159:144]-SRC2[159:144]\nDEST[175:160] := SRC1[175:160]-SRC2[175:160]\nDEST[191:176] := SRC1[191:176]-SRC2[191:176]\nDEST[207:192] := SRC1207:192]-SRC2[207:192]\nDEST[223:208] := SRC1[223:208]-SRC2[223:208]\nDEST[239:224] := SRC1[239:224]-SRC2[239:224]\nDEST[255:240] := SRC1[255:240]-SRC2[255:240]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[15:0] := SRC1[15:0]-SRC2[15:0]\nDEST[31:16] := SRC1[31:16]-SRC2[31:16]\nDEST[47:32] := SRC1[47:32]-SRC2[47:32]\nDEST[63:48] := SRC1[63:48]-SRC2[63:48]\nDEST[79:64] := SRC1[79:64]-SRC2[79:64]\nDEST[95:80] := SRC1[95:80]-SRC2[95:80]\nDEST[111:96] := SRC1[111:96]-SRC2[111:96]\nDEST[127:112] := SRC1[127:112]-SRC2[127:112]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[15:0] := DEST[15:0]-SRC[15:0]\nDEST[31:16] := DEST[31:16]-SRC[31:16]\nDEST[47:32] := DEST[47:32]-SRC[47:32]\nDEST[63:48] := DEST[63:48]-SRC[63:48]\nDEST[79:64] := DEST[79:64]-SRC[79:64]\nDEST[95:80] := DEST[95:80]-SRC[95:80]\nDEST[111:96] := DEST[111:96]-SRC[111:96]\nDEST[127:112] := DEST[127:112]-SRC[127:112]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := SRC1[31:0]-SRC2[31:0]\nDEST[63:32] := SRC1[63:32]-SRC2[63:32]\nDEST[95:64] := SRC1[95:64]-SRC2[95:64]\nDEST[127:96] := SRC1[127:96]-SRC2[127:96]\nDEST[159:128] := SRC1[159:128]-SRC2[159:128]\nDEST[191:160] := SRC1[191:160]-SRC2[191:160]\nDEST[223:192] := SRC1[223:192]-SRC2[223:192]\nDEST[255:224] := SRC1[255:224]-SRC2[255:224]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0]-SRC2[31:0]\nDEST[63:32] := SRC1[63:32]-SRC2[63:32]\nDEST[95:64] := SRC1[95:64]-SRC2[95:64]\nDEST[127:96] := SRC1[127:96]-SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0]-SRC[31:0]\nDEST[63:32] := DEST[63:32]-SRC[63:32]\nDEST[95:64] := DEST[95:64]-SRC[95:64]\nDEST[127:96] := DEST[127:96]-SRC[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/psubb:psubw:psubd" + }, + "ptest": { + "instruction": "PTEST", + "title": "PTEST\n\t\t— Logical Compare", + "opcode": "66 0F 38 17 /r PTEST xmm1, xmm2/m128", + "description": "PTEST and VPTEST set the ZF flag if all bits in the result are 0 of the bitwise AND of the first source operand (first operand) and the second source operand (second operand). VPTEST sets the CF flag if all bits in the result are 0 of the bitwise AND of the second source operand (second operand) and the logical NOT of the destination operand.\nThe first source register is specified by the ModR/M reg field.\n128-bit versions: The first source register is an XMM register. The second source register can be an XMM register or a 128-bit memory location. The destination register is not modified.\nVEX.256 encoded version: The first source register is a YMM register. The second source register can be a YMM register or a 256-bit memory location. The destination register is not modified.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "IF (SRC[127:0] BITWISE AND DEST[127:0] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nIF (SRC[127:0] BITWISE AND NOT DEST[127:0] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nIF (SRC[255:0] BITWISE AND DEST[255:0] = 0) THEN ZF := 1;\n ELSE ZF := 0;\nIF (SRC[255:0] BITWISE AND NOT DEST[255:0] = 0) THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/ptest" + }, + "ptwrite": { + "instruction": "PTWRITE", + "title": "PTWRITE\n\t\t— Write Data to a Processor Trace Packet", + "opcode": "F3 REX.W 0F AE /4 PTWRITE r64/m64", + "description": "This instruction reads data in the source operand and sends it to the Intel Processor Trace hardware to be encoded in a PTW packet if TriggerEn, ContextEn, FilterEn, and PTWEn are all set to 1. For more details on these values, see Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, Section 33.2.2, “Software Trace Instrumentation with PTWRITE.” The size of data is 64-bit if using REX.W in 64-bit mode, otherwise 32-bits of data are copied from the source operand.\nNote: The instruction will #UD if prefix 66H is used.", + "operation": "IF (IA32_RTIT_STATUS.TriggerEn & IA32_RTIT_STATUS.ContextEn & IA32_RTIT_STATUS.FilterEn & IA32_RTIT_CTL.PTWEn) = 1\n PTW.PayloadBytes := Encoded payload size;\n PTW.IP := IA32_RTIT_CTL.FUPonPTW\n IF IA32_RTIT_CTL.FUPonPTW = 1\n Insert FUP packet with IP of PTWRITE;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ptwrite" + }, + "punpckhbw": { + "instruction": "PUNPCKHBW", + "title": "PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ\n\t\t— Unpack High Data", + "opcode": "NP 0F 68 /r1 PUNPCKHBW mm, mm/m64", + "description": "Unpacks and interleaves the high-order data elements (bytes, words, doublewords, or quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. Figure 4-20 shows the unpack operation for bytes in 64-bit operands. The low-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 64-bit memory operand, the full 64-bit operand is accessed from memory, but the instruction uses only the high-order 32 bits. When the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKHBW instruction interleaves the high-order bytes of the source and destination operands, the (V)PUNPCKHWD instruction interleaves the high-order words of the source and destination operands, the (V)PUNPCKHDQ instruction interleaves the high-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKHQDQ instruction interleaves the high-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKHBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKHWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers.\nEVEX encoded VPUNPCKHDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKHWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[39:32];\nDEST[15:8] := SRC[39:32];\nDEST[23:16] := DEST[47:40];\nDEST[31:24] := SRC[47:40];\nDEST[39:32] := DEST[55:48];\nDEST[47:40] := SRC[55:48];\nDEST[55:48] := DEST[63:56];\nDEST[63:56] := SRC[63:56];\n\n\nDEST[15:0] := DEST[47:32];\nDEST[31:16] := SRC[47:32];\nDEST[47:32] := DEST[63:48];\nDEST[63:48] := SRC[63:48];\n\n\n DEST[31:0] := DEST[63:32];\n DEST[63:32] := SRC[63:32];\nINTERLEAVE_HIGH_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nDEST[135:128] := SRC1[199:192]\nDEST[143:136] := SRC2[199:192]\nDEST[151:144] := SRC1[207:200]\nDEST[159:152] := SRC2[207:200]\nDEST[167:160] := SRC1[215:208]\nDEST[175:168] := SRC2[215:208]\nDEST[183:176] := SRC1[223:216]\nDEST[191:184] := SRC2[223:216]\nDEST[199:192] := SRC1[231:224]\nDEST[207:200] := SRC2[231:224]\nDEST[215:208] := SRC1[239:232]\nDEST[223:216] := SRC2[239:232]\nDEST[231:224] := SRC1[247:240]\nDEST[239:232] := SRC2[247:240]\nDEST[247:240] := SRC1[255:248]\nDEST[255:248] := SRC2[255:248]\nINTERLEAVE_HIGH_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nINTERLEAVE_HIGH_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nDEST[143:128] := SRC1[207:192]\nDEST[159:144] := SRC2[207:192]\nDEST[175:160] := SRC1[223:208]\nDEST[191:176] := SRC2[223:208]\nDEST[207:192] := SRC1[239:224]\nDEST[223:208] := SRC2[239:224]\nDEST[239:224] := SRC1[255:240]\nDEST[255:240] := SRC2[255:240]\nINTERLEAVE_HIGH_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nINTERLEAVE_HIGH_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[159:128] := SRC1[223:192]\nDEST[191:160] := SRC2[223:192]\nDEST[223:192] := SRC1[255:224]\nDEST[255:224] := SRC2[255:224]\nINTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nINTERLEAVE_HIGH_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[191:128] := SRC1[255:192]\nDEST[255:192] := SRC2[255:192]\nINTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpckhbw:punpckhwd:punpckhdq:punpckhqdq" + }, + "punpckhdq": { + "instruction": "PUNPCKHDQ", + "title": "PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ\n\t\t— Unpack High Data", + "opcode": "NP 0F 68 /r1 PUNPCKHBW mm, mm/m64", + "description": "Unpacks and interleaves the high-order data elements (bytes, words, doublewords, or quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. Figure 4-20 shows the unpack operation for bytes in 64-bit operands. The low-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 64-bit memory operand, the full 64-bit operand is accessed from memory, but the instruction uses only the high-order 32 bits. When the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKHBW instruction interleaves the high-order bytes of the source and destination operands, the (V)PUNPCKHWD instruction interleaves the high-order words of the source and destination operands, the (V)PUNPCKHDQ instruction interleaves the high-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKHQDQ instruction interleaves the high-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKHBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKHWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers.\nEVEX encoded VPUNPCKHDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKHWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[39:32];\nDEST[15:8] := SRC[39:32];\nDEST[23:16] := DEST[47:40];\nDEST[31:24] := SRC[47:40];\nDEST[39:32] := DEST[55:48];\nDEST[47:40] := SRC[55:48];\nDEST[55:48] := DEST[63:56];\nDEST[63:56] := SRC[63:56];\n\n\nDEST[15:0] := DEST[47:32];\nDEST[31:16] := SRC[47:32];\nDEST[47:32] := DEST[63:48];\nDEST[63:48] := SRC[63:48];\n\n\n DEST[31:0] := DEST[63:32];\n DEST[63:32] := SRC[63:32];\nINTERLEAVE_HIGH_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nDEST[135:128] := SRC1[199:192]\nDEST[143:136] := SRC2[199:192]\nDEST[151:144] := SRC1[207:200]\nDEST[159:152] := SRC2[207:200]\nDEST[167:160] := SRC1[215:208]\nDEST[175:168] := SRC2[215:208]\nDEST[183:176] := SRC1[223:216]\nDEST[191:184] := SRC2[223:216]\nDEST[199:192] := SRC1[231:224]\nDEST[207:200] := SRC2[231:224]\nDEST[215:208] := SRC1[239:232]\nDEST[223:216] := SRC2[239:232]\nDEST[231:224] := SRC1[247:240]\nDEST[239:232] := SRC2[247:240]\nDEST[247:240] := SRC1[255:248]\nDEST[255:248] := SRC2[255:248]\nINTERLEAVE_HIGH_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nINTERLEAVE_HIGH_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nDEST[143:128] := SRC1[207:192]\nDEST[159:144] := SRC2[207:192]\nDEST[175:160] := SRC1[223:208]\nDEST[191:176] := SRC2[223:208]\nDEST[207:192] := SRC1[239:224]\nDEST[223:208] := SRC2[239:224]\nDEST[239:224] := SRC1[255:240]\nDEST[255:240] := SRC2[255:240]\nINTERLEAVE_HIGH_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nINTERLEAVE_HIGH_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[159:128] := SRC1[223:192]\nDEST[191:160] := SRC2[223:192]\nDEST[223:192] := SRC1[255:224]\nDEST[255:224] := SRC2[255:224]\nINTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nINTERLEAVE_HIGH_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[191:128] := SRC1[255:192]\nDEST[255:192] := SRC2[255:192]\nINTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpckhbw:punpckhwd:punpckhdq:punpckhqdq" + }, + "punpckhqdq": { + "instruction": "PUNPCKHQDQ", + "title": "PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ\n\t\t— Unpack High Data", + "opcode": "NP 0F 68 /r1 PUNPCKHBW mm, mm/m64", + "description": "Unpacks and interleaves the high-order data elements (bytes, words, doublewords, or quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. Figure 4-20 shows the unpack operation for bytes in 64-bit operands. The low-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 64-bit memory operand, the full 64-bit operand is accessed from memory, but the instruction uses only the high-order 32 bits. When the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKHBW instruction interleaves the high-order bytes of the source and destination operands, the (V)PUNPCKHWD instruction interleaves the high-order words of the source and destination operands, the (V)PUNPCKHDQ instruction interleaves the high-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKHQDQ instruction interleaves the high-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKHBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKHWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers.\nEVEX encoded VPUNPCKHDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKHWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[39:32];\nDEST[15:8] := SRC[39:32];\nDEST[23:16] := DEST[47:40];\nDEST[31:24] := SRC[47:40];\nDEST[39:32] := DEST[55:48];\nDEST[47:40] := SRC[55:48];\nDEST[55:48] := DEST[63:56];\nDEST[63:56] := SRC[63:56];\n\n\nDEST[15:0] := DEST[47:32];\nDEST[31:16] := SRC[47:32];\nDEST[47:32] := DEST[63:48];\nDEST[63:48] := SRC[63:48];\n\n\n DEST[31:0] := DEST[63:32];\n DEST[63:32] := SRC[63:32];\nINTERLEAVE_HIGH_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nDEST[135:128] := SRC1[199:192]\nDEST[143:136] := SRC2[199:192]\nDEST[151:144] := SRC1[207:200]\nDEST[159:152] := SRC2[207:200]\nDEST[167:160] := SRC1[215:208]\nDEST[175:168] := SRC2[215:208]\nDEST[183:176] := SRC1[223:216]\nDEST[191:184] := SRC2[223:216]\nDEST[199:192] := SRC1[231:224]\nDEST[207:200] := SRC2[231:224]\nDEST[215:208] := SRC1[239:232]\nDEST[223:216] := SRC2[239:232]\nDEST[231:224] := SRC1[247:240]\nDEST[239:232] := SRC2[247:240]\nDEST[247:240] := SRC1[255:248]\nDEST[255:248] := SRC2[255:248]\nINTERLEAVE_HIGH_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nINTERLEAVE_HIGH_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nDEST[143:128] := SRC1[207:192]\nDEST[159:144] := SRC2[207:192]\nDEST[175:160] := SRC1[223:208]\nDEST[191:176] := SRC2[223:208]\nDEST[207:192] := SRC1[239:224]\nDEST[223:208] := SRC2[239:224]\nDEST[239:224] := SRC1[255:240]\nDEST[255:240] := SRC2[255:240]\nINTERLEAVE_HIGH_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nINTERLEAVE_HIGH_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[159:128] := SRC1[223:192]\nDEST[191:160] := SRC2[223:192]\nDEST[223:192] := SRC1[255:224]\nDEST[255:224] := SRC2[255:224]\nINTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nINTERLEAVE_HIGH_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[191:128] := SRC1[255:192]\nDEST[255:192] := SRC2[255:192]\nINTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpckhbw:punpckhwd:punpckhdq:punpckhqdq" + }, + "punpckhwd": { + "instruction": "PUNPCKHWD", + "title": "PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ\n\t\t— Unpack High Data", + "opcode": "NP 0F 68 /r1 PUNPCKHBW mm, mm/m64", + "description": "Unpacks and interleaves the high-order data elements (bytes, words, doublewords, or quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. Figure 4-20 shows the unpack operation for bytes in 64-bit operands. The low-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 64-bit memory operand, the full 64-bit operand is accessed from memory, but the instruction uses only the high-order 32 bits. When the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKHBW instruction interleaves the high-order bytes of the source and destination operands, the (V)PUNPCKHWD instruction interleaves the high-order words of the source and destination operands, the (V)PUNPCKHDQ instruction interleaves the high-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKHQDQ instruction interleaves the high-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKHBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKHWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers.\nEVEX encoded VPUNPCKHDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKHWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[7:0] := DEST[39:32];\nDEST[15:8] := SRC[39:32];\nDEST[23:16] := DEST[47:40];\nDEST[31:24] := SRC[47:40];\nDEST[39:32] := DEST[55:48];\nDEST[47:40] := SRC[55:48];\nDEST[55:48] := DEST[63:56];\nDEST[63:56] := SRC[63:56];\n\n\nDEST[15:0] := DEST[47:32];\nDEST[31:16] := SRC[47:32];\nDEST[47:32] := DEST[63:48];\nDEST[63:48] := SRC[63:48];\n\n\n DEST[31:0] := DEST[63:32];\n DEST[63:32] := SRC[63:32];\nINTERLEAVE_HIGH_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nDEST[135:128] := SRC1[199:192]\nDEST[143:136] := SRC2[199:192]\nDEST[151:144] := SRC1[207:200]\nDEST[159:152] := SRC2[207:200]\nDEST[167:160] := SRC1[215:208]\nDEST[175:168] := SRC2[215:208]\nDEST[183:176] := SRC1[223:216]\nDEST[191:184] := SRC2[223:216]\nDEST[199:192] := SRC1[231:224]\nDEST[207:200] := SRC2[231:224]\nDEST[215:208] := SRC1[239:232]\nDEST[223:216] := SRC2[239:232]\nDEST[231:224] := SRC1[247:240]\nDEST[239:232] := SRC2[247:240]\nDEST[247:240] := SRC1[255:248]\nDEST[255:248] := SRC2[255:248]\nINTERLEAVE_HIGH_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[71:64]\nDEST[15:8] := SRC2[71:64]\nDEST[23:16] := SRC1[79:72]\nDEST[31:24] := SRC2[79:72]\nDEST[39:32] := SRC1[87:80]\nDEST[47:40] := SRC2[87:80]\nDEST[55:48] := SRC1[95:88]\nDEST[63:56] := SRC2[95:88]\nDEST[71:64] := SRC1[103:96]\nDEST[79:72] := SRC2[103:96]\nDEST[87:80] := SRC1[111:104]\nDEST[95:88] := SRC2[111:104]\nDEST[103:96] := SRC1[119:112]\nDEST[111:104] := SRC2[119:112]\nDEST[119:112] := SRC1[127:120]\nDEST[127:120] := SRC2[127:120]\nINTERLEAVE_HIGH_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nDEST[143:128] := SRC1[207:192]\nDEST[159:144] := SRC2[207:192]\nDEST[175:160] := SRC1[223:208]\nDEST[191:176] := SRC2[223:208]\nDEST[207:192] := SRC1[239:224]\nDEST[223:208] := SRC2[239:224]\nDEST[239:224] := SRC1[255:240]\nDEST[255:240] := SRC2[255:240]\nINTERLEAVE_HIGH_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[79:64]\nDEST[31:16] := SRC2[79:64]\nDEST[47:32] := SRC1[95:80]\nDEST[63:48] := SRC2[95:80]\nDEST[79:64] := SRC1[111:96]\nDEST[95:80] := SRC2[111:96]\nDEST[111:96] := SRC1[127:112]\nDEST[127:112] := SRC2[127:112]\nINTERLEAVE_HIGH_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[159:128] := SRC1[223:192]\nDEST[191:160] := SRC2[223:192]\nDEST[223:192] := SRC1[255:224]\nDEST[255:224] := SRC2[255:224]\nINTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nINTERLEAVE_HIGH_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[191:128] := SRC1[255:192]\nDEST[255:192] := SRC2[255:192]\nINTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_HIGH_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_HIGH_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpckhbw:punpckhwd:punpckhdq:punpckhqdq" + }, + "punpcklbw": { + "instruction": "PUNPCKLBW", + "title": "PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ\n\t\t— Unpack Low Data", + "opcode": "NP 0F 60 /r1 PUNPCKLBW mm, mm/m32", + "description": "Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. (Figure 4-22 shows the unpack operation for bytes in 64-bit operands.). The high-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKLBW instruction interleaves the low-order bytes of the source and destination operands, the (V)PUNPCKLWD instruction interleaves the low-order words of the source and destination operands, the (V)PUNPCKLDQ instruction interleaves the low-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKLQDQ instruction interleaves the low-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKLBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKLWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 32-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPUNPCKLDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source\noperand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKLWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[63:56] := SRC[31:24];\nDEST[55:48] := DEST[31:24];\nDEST[47:40] := SRC[23:16];\nDEST[39:32] := DEST[23:16];\nDEST[31:24] := SRC[15:8];\nDEST[23:16] := DEST[15:8];\nDEST[15:8] := SRC[7:0];\nDEST[7:0] := DEST[7:0];\n\n\nDEST[63:48] := SRC[31:16];\nDEST[47:32] := DEST[31:16];\nDEST[31:16] := SRC[15:0];\nDEST[15:0] := DEST[15:0];\n\n\n DEST[63:32] := SRC[31:0];\n DEST[31:0] := DEST[31:0];\nINTERLEAVE_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nDEST[135:128] := SRC1[135:128]\nDEST[143:136] := SRC2[135:128]\nDEST[151:144] := SRC1[143:136]\nDEST[159:152] := SRC2[143:136]\nDEST[167:160] := SRC1[151:144]\nDEST[175:168] := SRC2[151:144]\nDEST[183:176] := SRC1[159:152]\nDEST[191:184] := SRC2[159:152]\nDEST[199:192] := SRC1[167:160]\nDEST[207:200] := SRC2[167:160]\nDEST[215:208] := SRC1[175:168]\nDEST[223:216] := SRC2[175:168]\nDEST[231:224] := SRC1[183:176]\nDEST[239:232] := SRC2[183:176]\nDEST[247:240] := SRC1[191:184]\nDEST[255:248] := SRC2[191:184]\nINTERLEAVE_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nINTERLEAVE_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nDEST[143:128] := SRC1[143:128]\nDEST[159:144] := SRC2[143:128]\nDEST[175:160] := SRC1[159:144]\nDEST[191:176] := SRC2[159:144]\nDEST[207:192] := SRC1[175:160]\nDEST[223:208] := SRC2[175:160]\nDEST[239:224] := SRC1[191:176]\nDEST[255:240] := SRC2[191:176]\nINTERLEAVE_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nINTERLEAVE_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[159:128] := SRC1[159:128]\nDEST[191:160] := SRC2[159:128]\nDEST[223:192] := SRC1[191:160]\nDEST[255:224] := SRC2[191:160]\nINTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nINTERLEAVE_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[191:128] := SRC1[191:128]\nDEST[255:192] := SRC2[191:128]\nINTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\n\n\nDEST[127:0] := INTERLEAVE_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_BYTES_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_WORDS_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST511:0] := INTERLEAVE_DWORDS_512b(SRC1, SRC2)\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpcklbw:punpcklwd:punpckldq:punpcklqdq" + }, + "punpckldq": { + "instruction": "PUNPCKLDQ", + "title": "PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ\n\t\t— Unpack Low Data", + "opcode": "NP 0F 60 /r1 PUNPCKLBW mm, mm/m32", + "description": "Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. (Figure 4-22 shows the unpack operation for bytes in 64-bit operands.). The high-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKLBW instruction interleaves the low-order bytes of the source and destination operands, the (V)PUNPCKLWD instruction interleaves the low-order words of the source and destination operands, the (V)PUNPCKLDQ instruction interleaves the low-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKLQDQ instruction interleaves the low-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKLBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKLWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 32-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPUNPCKLDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source\noperand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKLWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[63:56] := SRC[31:24];\nDEST[55:48] := DEST[31:24];\nDEST[47:40] := SRC[23:16];\nDEST[39:32] := DEST[23:16];\nDEST[31:24] := SRC[15:8];\nDEST[23:16] := DEST[15:8];\nDEST[15:8] := SRC[7:0];\nDEST[7:0] := DEST[7:0];\n\n\nDEST[63:48] := SRC[31:16];\nDEST[47:32] := DEST[31:16];\nDEST[31:16] := SRC[15:0];\nDEST[15:0] := DEST[15:0];\n\n\n DEST[63:32] := SRC[31:0];\n DEST[31:0] := DEST[31:0];\nINTERLEAVE_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nDEST[135:128] := SRC1[135:128]\nDEST[143:136] := SRC2[135:128]\nDEST[151:144] := SRC1[143:136]\nDEST[159:152] := SRC2[143:136]\nDEST[167:160] := SRC1[151:144]\nDEST[175:168] := SRC2[151:144]\nDEST[183:176] := SRC1[159:152]\nDEST[191:184] := SRC2[159:152]\nDEST[199:192] := SRC1[167:160]\nDEST[207:200] := SRC2[167:160]\nDEST[215:208] := SRC1[175:168]\nDEST[223:216] := SRC2[175:168]\nDEST[231:224] := SRC1[183:176]\nDEST[239:232] := SRC2[183:176]\nDEST[247:240] := SRC1[191:184]\nDEST[255:248] := SRC2[191:184]\nINTERLEAVE_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nINTERLEAVE_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nDEST[143:128] := SRC1[143:128]\nDEST[159:144] := SRC2[143:128]\nDEST[175:160] := SRC1[159:144]\nDEST[191:176] := SRC2[159:144]\nDEST[207:192] := SRC1[175:160]\nDEST[223:208] := SRC2[175:160]\nDEST[239:224] := SRC1[191:176]\nDEST[255:240] := SRC2[191:176]\nINTERLEAVE_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nINTERLEAVE_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[159:128] := SRC1[159:128]\nDEST[191:160] := SRC2[159:128]\nDEST[223:192] := SRC1[191:160]\nDEST[255:224] := SRC2[191:160]\nINTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nINTERLEAVE_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[191:128] := SRC1[191:128]\nDEST[255:192] := SRC2[191:128]\nINTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\n\n\nDEST[127:0] := INTERLEAVE_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_BYTES_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_WORDS_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST511:0] := INTERLEAVE_DWORDS_512b(SRC1, SRC2)\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpcklbw:punpcklwd:punpckldq:punpcklqdq" + }, + "punpcklqdq": { + "instruction": "PUNPCKLQDQ", + "title": "PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ\n\t\t— Unpack Low Data", + "opcode": "NP 0F 60 /r1 PUNPCKLBW mm, mm/m32", + "description": "Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. (Figure 4-22 shows the unpack operation for bytes in 64-bit operands.). The high-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKLBW instruction interleaves the low-order bytes of the source and destination operands, the (V)PUNPCKLWD instruction interleaves the low-order words of the source and destination operands, the (V)PUNPCKLDQ instruction interleaves the low-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKLQDQ instruction interleaves the low-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKLBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKLWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 32-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPUNPCKLDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source\noperand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKLWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[63:56] := SRC[31:24];\nDEST[55:48] := DEST[31:24];\nDEST[47:40] := SRC[23:16];\nDEST[39:32] := DEST[23:16];\nDEST[31:24] := SRC[15:8];\nDEST[23:16] := DEST[15:8];\nDEST[15:8] := SRC[7:0];\nDEST[7:0] := DEST[7:0];\n\n\nDEST[63:48] := SRC[31:16];\nDEST[47:32] := DEST[31:16];\nDEST[31:16] := SRC[15:0];\nDEST[15:0] := DEST[15:0];\n\n\n DEST[63:32] := SRC[31:0];\n DEST[31:0] := DEST[31:0];\nINTERLEAVE_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nDEST[135:128] := SRC1[135:128]\nDEST[143:136] := SRC2[135:128]\nDEST[151:144] := SRC1[143:136]\nDEST[159:152] := SRC2[143:136]\nDEST[167:160] := SRC1[151:144]\nDEST[175:168] := SRC2[151:144]\nDEST[183:176] := SRC1[159:152]\nDEST[191:184] := SRC2[159:152]\nDEST[199:192] := SRC1[167:160]\nDEST[207:200] := SRC2[167:160]\nDEST[215:208] := SRC1[175:168]\nDEST[223:216] := SRC2[175:168]\nDEST[231:224] := SRC1[183:176]\nDEST[239:232] := SRC2[183:176]\nDEST[247:240] := SRC1[191:184]\nDEST[255:248] := SRC2[191:184]\nINTERLEAVE_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nINTERLEAVE_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nDEST[143:128] := SRC1[143:128]\nDEST[159:144] := SRC2[143:128]\nDEST[175:160] := SRC1[159:144]\nDEST[191:176] := SRC2[159:144]\nDEST[207:192] := SRC1[175:160]\nDEST[223:208] := SRC2[175:160]\nDEST[239:224] := SRC1[191:176]\nDEST[255:240] := SRC2[191:176]\nINTERLEAVE_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nINTERLEAVE_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[159:128] := SRC1[159:128]\nDEST[191:160] := SRC2[159:128]\nDEST[223:192] := SRC1[191:160]\nDEST[255:224] := SRC2[191:160]\nINTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nINTERLEAVE_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[191:128] := SRC1[191:128]\nDEST[255:192] := SRC2[191:128]\nINTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\n\n\nDEST[127:0] := INTERLEAVE_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_BYTES_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_WORDS_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST511:0] := INTERLEAVE_DWORDS_512b(SRC1, SRC2)\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpcklbw:punpcklwd:punpckldq:punpcklqdq" + }, + "punpcklwd": { + "instruction": "PUNPCKLWD", + "title": "PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ\n\t\t— Unpack Low Data", + "opcode": "NP 0F 60 /r1 PUNPCKLBW mm, mm/m32", + "description": "Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords) of the destination operand (first operand) and source operand (second operand) into the destination operand. (Figure 4-22 shows the unpack operation for bytes in 64-bit operands.). The high-order data elements are ignored.\n255 31 0 255 31 0\nWhen the source data comes from a 128-bit memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to a 16-byte boundary and normal segment checking will still be enforced.\nThe (V)PUNPCKLBW instruction interleaves the low-order bytes of the source and destination operands, the (V)PUNPCKLWD instruction interleaves the low-order words of the source and destination operands, the (V)PUNPCKLDQ instruction interleaves the low-order doubleword (or doublewords) of the source and destination operands, and the (V)PUNPCKLQDQ instruction interleaves the low-order quadwords of the source and destination operands.\nThese instructions can be used to convert bytes to words, words to doublewords, doublewords to quadwords, and quadwords to double quadwords, respectively, by placing all 0s in the source operand. Here, if the source operand contains all 0s, the result (stored in the destination operand) contains zero extensions of the high-order data elements from the original value in the destination operand. For example, with the (V)PUNPCKLBW instruction the high-order bytes are zero extended (that is, unpacked into unsigned word integers), and with the (V)PUNPCKLWD instruction, the high-order words are zero extended (unpacked into unsigned doubleword integers).\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE versions 64-bit operand: The source operand can be an MMX technology register or a 32-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded versions: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding ZMM register are zeroed.\nEVEX encoded VPUNPCKLDQ/QDQ: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The first source\noperand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.\nEVEX encoded VPUNPCKLWD/BW: The second source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The first source operand and destination operands are ZMM/YMM/XMM registers. The destination is conditionally updated with writemask k1.", + "operation": "DEST[63:56] := SRC[31:24];\nDEST[55:48] := DEST[31:24];\nDEST[47:40] := SRC[23:16];\nDEST[39:32] := DEST[23:16];\nDEST[31:24] := SRC[15:8];\nDEST[23:16] := DEST[15:8];\nDEST[15:8] := SRC[7:0];\nDEST[7:0] := DEST[7:0];\n\n\nDEST[63:48] := SRC[31:16];\nDEST[47:32] := DEST[31:16];\nDEST[31:16] := SRC[15:0];\nDEST[15:0] := DEST[15:0];\n\n\n DEST[63:32] := SRC[31:0];\n DEST[31:0] := DEST[31:0];\nINTERLEAVE_BYTES_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_BYTES_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_BYTES_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_BYTES_256b (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nDEST[135:128] := SRC1[135:128]\nDEST[143:136] := SRC2[135:128]\nDEST[151:144] := SRC1[143:136]\nDEST[159:152] := SRC2[143:136]\nDEST[167:160] := SRC1[151:144]\nDEST[175:168] := SRC2[151:144]\nDEST[183:176] := SRC1[159:152]\nDEST[191:184] := SRC2[159:152]\nDEST[199:192] := SRC1[167:160]\nDEST[207:200] := SRC2[167:160]\nDEST[215:208] := SRC1[175:168]\nDEST[223:216] := SRC2[175:168]\nDEST[231:224] := SRC1[183:176]\nDEST[239:232] := SRC2[183:176]\nDEST[247:240] := SRC1[191:184]\nDEST[255:248] := SRC2[191:184]\nINTERLEAVE_BYTES (SRC1, SRC2)\nDEST[7:0] := SRC1[7:0]\nDEST[15:8] := SRC2[7:0]\nDEST[23:16] := SRC1[15:8]\nDEST[31:24] := SRC2[15:8]\nDEST[39:32] := SRC1[23:16]\nDEST[47:40] := SRC2[23:16]\nDEST[55:48] := SRC1[31:24]\nDEST[63:56] := SRC2[31:24]\nDEST[71:64] := SRC1[39:32]\nDEST[79:72] := SRC2[39:32]\nDEST[87:80] := SRC1[47:40]\nDEST[95:88] := SRC2[47:40]\nDEST[103:96] := SRC1[55:48]\nDEST[111:104] := SRC2[55:48]\nDEST[119:112] := SRC1[63:56]\nDEST[127:120] := SRC2[63:56]\nINTERLEAVE_WORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_WORDS_256b(SRC1[255:0], SRC[255:0])\nTMP_DEST[511:256] := INTERLEAVE_WORDS_256b(SRC1[511:256], SRC[511:256])\nINTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nDEST[143:128] := SRC1[143:128]\nDEST[159:144] := SRC2[143:128]\nDEST[175:160] := SRC1[159:144]\nDEST[191:176] := SRC2[159:144]\nDEST[207:192] := SRC1[175:160]\nDEST[223:208] := SRC2[175:160]\nDEST[239:224] := SRC1[191:176]\nDEST[255:240] := SRC2[191:176]\nINTERLEAVE_WORDS (SRC1, SRC2)\nDEST[15:0] := SRC1[15:0]\nDEST[31:16] := SRC2[15:0]\nDEST[47:32] := SRC1[31:16]\nDEST[63:48] := SRC2[31:16]\nDEST[79:64] := SRC1[47:32]\nDEST[95:80] := SRC2[47:32]\nDEST[111:96] := SRC1[63:48]\nDEST[127:112] := SRC2[63:48]\nINTERLEAVE_DWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_DWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[159:128] := SRC1[159:128]\nDEST[191:160] := SRC2[159:128]\nDEST[223:192] := SRC1[191:160]\nDEST[255:224] := SRC2[191:160]\nINTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nINTERLEAVE_QWORDS_512b (SRC1, SRC2)\nTMP_DEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1[255:0], SRC2[255:0])\nTMP_DEST[511:256] := INTERLEAVE_QWORDS_256b(SRC1[511:256], SRC2[511:256])\nINTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[191:128] := SRC1[191:128]\nDEST[255:192] := SRC2[191:128]\nINTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\n\n\nDEST[127:0] := INTERLEAVE_BYTES(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_BYTES(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_BYTES_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_BYTES_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := TMP_DEST[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+7:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_BYTES_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(DEST, SRC)\nDEST[255:127] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_WORDS(SRC1, SRC2)\nDEST[MAXVL-1:127] := 0\n\n\nDEST[255:0] := INTERLEAVE_WORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_256b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_WORDS_512b(SRC1[VL-1:0], SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := TMP_DEST[i+15:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+15:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+15:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\nDEST[511:0] := INTERLEAVE_WORDS_512b(SRC1, SRC2)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_DWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_DWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_DWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST511:0] := INTERLEAVE_DWORDS_512b(SRC1, SRC2)\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(DEST, SRC)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := INTERLEAVE_QWORDS(SRC1, SRC2)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[255:0] := INTERLEAVE_QWORDS_256b(SRC1, SRC2)\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL = 128\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 256\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_256b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nIF VL = 512\n TMP_DEST[VL-1:0] := INTERLEAVE_QWORDS_512b(SRC1[VL-1:0], TMP_SRC2[VL-1:0])\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/punpcklbw:punpcklwd:punpckldq:punpcklqdq" + }, + "push": { + "instruction": "PUSH", + "title": "PUSH\n\t\t— Push Word, Doubleword, or Quadword Onto the Stack", + "opcode": "FF /6", + "description": "Decrements the stack pointer and then stores the source operand on the top of the stack. Address and operand sizes are determined and used as follows:\nThe address size is used only when referencing a source operand in memory.\nThe operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is decremented (2, 4 or 8).\nIf the source operand is an immediate of size less than the operand size, a sign-extended value is pushed on the stack. If the source operand is a segment register (16 bits) and the operand size is 64-bits, a zero-extended value is pushed on the stack; if the operand size is 32-bits, either a zero-extended value is pushed on the stack or the segment selector is written on the stack using a 16-bit move. For the last case, all recent Intel Core and Intel Atom processors perform a 16-bit move, leaving the upper portion of the stack location unmodified.\nThe stack-address size determines the width of the stack pointer when writing to the stack in memory and when decrementing the stack pointer. (As stated above, the amount by which the stack pointer is decremented is determined by the operand size.)\nIf the operand size is less than the stack-address size, the PUSH instruction may result in a misaligned stack pointer (a stack pointer that is not aligned on a doubleword or quadword boundary).\nThe PUSH ESP instruction pushes the value of the ESP register as it existed before the instruction was executed. If a PUSH instruction uses a memory operand in which the ESP register is used for computing the operand address, the address of the operand is computed before the ESP register is decremented.\nIf the ESP or SP register is 1 when the PUSH instruction is executed in real-address mode, a stack-fault exception (#SS) is generated (because the limit of the stack segment is violated). Its delivery encounters a second stack-fault exception (for the same reason), causing generation of a double-fault exception (#DF). Delivery of the double-fault exception encounters a third stack-fault exception, and the logical processor enters shutdown mode. See the discussion of the double-fault exception in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.", + "operation": "(* See Description section for possible sign-extension or zero-extension of source operand and for *)\n(* a case in which the size of the memory store may be\n smaller than the instruction’s operand size *)\nIF StackAddrSize = 64\n THEN\n IF OperandSize = 64\n THEN\n RSP := RSP – 8;\n Memory[SS:RSP] := SRC;\n (* push quadword *)\n ELSE IF OperandSize = 32\n THEN\n RSP := RSP – 4;\n Memory[SS:RSP] := SRC;\n (* push dword *)\n ELSE (* OperandSize = 16 *)\n RSP := RSP – 2;\n Memory[SS:RSP] := SRC;\n (* push word *)\n FI;\nELSE IF StackAddrSize = 32\n THEN\n IF OperandSize = 64\n THEN\n ESP := ESP – 8;\n Memory[SS:ESP] := SRC;\n (* push quadword *)\n ELSE IF OperandSize = 32\n THEN\n ESP := ESP – 4;\n Memory[SS:ESP] := SRC;\n (* push dword *)\n ELSE (* OperandSize = 16 *)\n ESP := ESP – 2;\n Memory[SS:ESP] := SRC;\n (* push word *)\n FI;\n ELSE (* StackAddrSize = 16 *)\n IF OperandSize = 32\n THEN\n SP := SP – 4;\n Memory[SS:SP] := SRC;\n (* push dword *)\n ELSE (* OperandSize = 16 *)\n SP := SP – 2;\n Memory[SS:SP] := SRC;\n (* push word *)\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/push" + }, + "pusha": { + "instruction": "PUSHA", + "title": "PUSHA/PUSHAD\n\t\t— Push All General-Purpose Registers", + "opcode": "60", + "description": "Pushes the contents of the general-purpose registers onto the stack. The registers are stored on the stack in the following order: EAX, ECX, EDX, EBX, ESP (original value), EBP, ESI, and EDI (if the current operand-size attribute is 32) and AX, CX, DX, BX, SP (original value), BP, SI, and DI (if the operand-size attribute is 16). These instructions perform the reverse operation of the POPA/POPAD instructions. The value pushed for the ESP or SP register is its value before prior to pushing the first register (see the “Operation” section below).\nThe PUSHA (push all) and PUSHAD (push all double) mnemonics reference the same opcode. The PUSHA instruction is intended for use when the operand-size attribute is 16 and the PUSHAD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when PUSHA is used and to 32 when PUSHAD is used. Others may treat these mnemonics as synonyms (PUSHA/PUSHAD) and use the current setting of the operand-size attribute to determine the size of values to be pushed from the stack, regardless of the mnemonic used.\nIn the real-address mode, if the ESP or SP register is 1, 3, or 5 when PUSHA/PUSHAD executes: an #SS exception is generated but not delivered (the stack error reported prevents #SS delivery). Next, the processor generates a #DF exception and enters a shutdown state as described in the #DF discussion in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-bit Mode\n THEN #UD\nFI;\nIF OperandSize = 32 (* PUSHAD instruction *)\n THEN\n Temp := (ESP);\n Push(EAX);\n Push(ECX);\n Push(EDX);\n Push(EBX);\n Push(Temp);\n Push(EBP);\n Push(ESI);\n Push(EDI);\n ELSE (* OperandSize = 16, PUSHA instruction *)\n Temp := (SP);\n Push(AX);\n Push(CX);\n Push(DX);\n Push(BX);\n Push(Temp);\n Push(BP);\n Push(SI);\n Push(DI);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/pusha:pushad" + }, + "pushad": { + "instruction": "PUSHAD", + "title": "PUSHA/PUSHAD\n\t\t— Push All General-Purpose Registers", + "opcode": "60", + "description": "Pushes the contents of the general-purpose registers onto the stack. The registers are stored on the stack in the following order: EAX, ECX, EDX, EBX, ESP (original value), EBP, ESI, and EDI (if the current operand-size attribute is 32) and AX, CX, DX, BX, SP (original value), BP, SI, and DI (if the operand-size attribute is 16). These instructions perform the reverse operation of the POPA/POPAD instructions. The value pushed for the ESP or SP register is its value before prior to pushing the first register (see the “Operation” section below).\nThe PUSHA (push all) and PUSHAD (push all double) mnemonics reference the same opcode. The PUSHA instruction is intended for use when the operand-size attribute is 16 and the PUSHAD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when PUSHA is used and to 32 when PUSHAD is used. Others may treat these mnemonics as synonyms (PUSHA/PUSHAD) and use the current setting of the operand-size attribute to determine the size of values to be pushed from the stack, regardless of the mnemonic used.\nIn the real-address mode, if the ESP or SP register is 1, 3, or 5 when PUSHA/PUSHAD executes: an #SS exception is generated but not delivered (the stack error reported prevents #SS delivery). Next, the processor generates a #DF exception and enters a shutdown state as described in the #DF discussion in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nThis instruction executes as described in compatibility mode and legacy mode. It is not valid in 64-bit mode.", + "operation": "IF 64-bit Mode\n THEN #UD\nFI;\nIF OperandSize = 32 (* PUSHAD instruction *)\n THEN\n Temp := (ESP);\n Push(EAX);\n Push(ECX);\n Push(EDX);\n Push(EBX);\n Push(Temp);\n Push(EBP);\n Push(ESI);\n Push(EDI);\n ELSE (* OperandSize = 16, PUSHA instruction *)\n Temp := (SP);\n Push(AX);\n Push(CX);\n Push(DX);\n Push(BX);\n Push(Temp);\n Push(BP);\n Push(SI);\n Push(DI);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/pusha:pushad" + }, + "pushf": { + "instruction": "PUSHF", + "title": "PUSHF/PUSHFD/PUSHFQ\n\t\t— Push EFLAGS Register Onto the Stack", + "opcode": "9C", + "description": "Decrements the stack pointer by 4 (if the current operand-size attribute is 32) and pushes the entire contents of the EFLAGS register onto the stack, or decrements the stack pointer by 2 (if the operand-size attribute is 16) and pushes the lower 16 bits of the EFLAGS register (that is, the FLAGS register) onto the stack. These instructions reverse the operation of the POPF/POPFD instructions.\nWhen copying the entire EFLAGS register to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, the values for these flags are cleared in the EFLAGS image stored on the stack. See Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS register.\nThe PUSHF (push flags) and PUSHFD (push flags double) mnemonics reference the same opcode. The PUSHF instruction is intended for use when the operand-size attribute is 16 and the PUSHFD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when PUSHF is used and to 32 when PUSHFD is used. Others may treat these mnemonics as synonyms (PUSHF/PUSHFD) and use the current setting of the operand-size attribute to determine the size of values to be pushed from the stack, regardless of the mnemonic used.\nIn 64-bit mode, the instruction’s default operation is to decrement the stack pointer (RSP) by 8 and pushes RFLAGS on the stack. 16-bit operation is supported using the operand size override prefix 66H. 32-bit operand size cannot be encoded in this mode. When copying RFLAGS to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, values for these flags are cleared in the RFLAGS image stored on the stack.\nWhen operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the PUSHF/PUSHFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), PUSHF (but not PUSHFD) can be executed in virtual-8086 mode with IOPL < 3.\n(The protected-mode virtual-interrupt feature — enabled by setting CR4.PVI — affects the CLI and STI instructions in the same manner as the virtual-8086 mode extensions. PUSHF, however, is not affected by CR4.PVI.)\nIn the real-address mode, if the ESP or SP register is 1 when PUSHF/PUSHFD instruction executes: an #SS exception is generated but not delivered (the stack error reported prevents #SS delivery). Next, the processor generates a #DF exception and enters a shutdown state as described in the #DF discussion in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.", + "operation": "IF (PE = 0) or (PE = 1 and ((VM = 0) or (VM = 1 and IOPL = 3)))\n(* Real-Address Mode, Protected mode, or Virtual-8086 mode with IOPL equal to 3 *)\n THEN\n IF OperandSize = 32\n THEN\n push (EFLAGS AND 00FCFFFFH);\n (* VM and RF bits are cleared in image stored on the stack *)\n ELSE\n push (EFLAGS); (* Lower 16 bits only *)\n FI;\n ELSE IF 64-bit MODE (* In 64-bit Mode *)\n IF OperandSize = 64\n THEN\n push (RFLAGS AND 00000000_00FCFFFFH);\n (* VM and RF bits are cleared in image stored on the stack; *)\n ELSE\n push (EFLAGS); (* Lower 16 bits only *)\n FI;\n ELSE (* In Virtual-8086 Mode with IOPL less than 3 *)\n IF (CR4.VME = 0) OR (OperandSize = 32)\n THEN #GP(0); (* Trap to virtual-8086 monitor *)\n ELSE\n tempFLAGS = EFLAGS[15:0];\n tempFLAGS[9] = tempFLAGS[19]; (* VIF replaces IF *)\n tempFlags[13:12]=3; (*IOPLissetto3inimagestoredonthestack*)\n push (tempFLAGS);\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/pushf:pushfd:pushfq" + }, + "pushfd": { + "instruction": "PUSHFD", + "title": "PUSHF/PUSHFD/PUSHFQ\n\t\t— Push EFLAGS Register Onto the Stack", + "opcode": "9C", + "description": "Decrements the stack pointer by 4 (if the current operand-size attribute is 32) and pushes the entire contents of the EFLAGS register onto the stack, or decrements the stack pointer by 2 (if the operand-size attribute is 16) and pushes the lower 16 bits of the EFLAGS register (that is, the FLAGS register) onto the stack. These instructions reverse the operation of the POPF/POPFD instructions.\nWhen copying the entire EFLAGS register to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, the values for these flags are cleared in the EFLAGS image stored on the stack. See Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS register.\nThe PUSHF (push flags) and PUSHFD (push flags double) mnemonics reference the same opcode. The PUSHF instruction is intended for use when the operand-size attribute is 16 and the PUSHFD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when PUSHF is used and to 32 when PUSHFD is used. Others may treat these mnemonics as synonyms (PUSHF/PUSHFD) and use the current setting of the operand-size attribute to determine the size of values to be pushed from the stack, regardless of the mnemonic used.\nIn 64-bit mode, the instruction’s default operation is to decrement the stack pointer (RSP) by 8 and pushes RFLAGS on the stack. 16-bit operation is supported using the operand size override prefix 66H. 32-bit operand size cannot be encoded in this mode. When copying RFLAGS to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, values for these flags are cleared in the RFLAGS image stored on the stack.\nWhen operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the PUSHF/PUSHFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), PUSHF (but not PUSHFD) can be executed in virtual-8086 mode with IOPL < 3.\n(The protected-mode virtual-interrupt feature — enabled by setting CR4.PVI — affects the CLI and STI instructions in the same manner as the virtual-8086 mode extensions. PUSHF, however, is not affected by CR4.PVI.)\nIn the real-address mode, if the ESP or SP register is 1 when PUSHF/PUSHFD instruction executes: an #SS exception is generated but not delivered (the stack error reported prevents #SS delivery). Next, the processor generates a #DF exception and enters a shutdown state as described in the #DF discussion in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.", + "operation": "IF (PE = 0) or (PE = 1 and ((VM = 0) or (VM = 1 and IOPL = 3)))\n(* Real-Address Mode, Protected mode, or Virtual-8086 mode with IOPL equal to 3 *)\n THEN\n IF OperandSize = 32\n THEN\n push (EFLAGS AND 00FCFFFFH);\n (* VM and RF bits are cleared in image stored on the stack *)\n ELSE\n push (EFLAGS); (* Lower 16 bits only *)\n FI;\n ELSE IF 64-bit MODE (* In 64-bit Mode *)\n IF OperandSize = 64\n THEN\n push (RFLAGS AND 00000000_00FCFFFFH);\n (* VM and RF bits are cleared in image stored on the stack; *)\n ELSE\n push (EFLAGS); (* Lower 16 bits only *)\n FI;\n ELSE (* In Virtual-8086 Mode with IOPL less than 3 *)\n IF (CR4.VME = 0) OR (OperandSize = 32)\n THEN #GP(0); (* Trap to virtual-8086 monitor *)\n ELSE\n tempFLAGS = EFLAGS[15:0];\n tempFLAGS[9] = tempFLAGS[19]; (* VIF replaces IF *)\n tempFlags[13:12]=3; (*IOPLissetto3inimagestoredonthestack*)\n push (tempFLAGS);\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/pushf:pushfd:pushfq" + }, + "pushfq": { + "instruction": "PUSHFQ", + "title": "PUSHF/PUSHFD/PUSHFQ\n\t\t— Push EFLAGS Register Onto the Stack", + "opcode": "9C", + "description": "Decrements the stack pointer by 4 (if the current operand-size attribute is 32) and pushes the entire contents of the EFLAGS register onto the stack, or decrements the stack pointer by 2 (if the operand-size attribute is 16) and pushes the lower 16 bits of the EFLAGS register (that is, the FLAGS register) onto the stack. These instructions reverse the operation of the POPF/POPFD instructions.\nWhen copying the entire EFLAGS register to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, the values for these flags are cleared in the EFLAGS image stored on the stack. See Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information about the EFLAGS register.\nThe PUSHF (push flags) and PUSHFD (push flags double) mnemonics reference the same opcode. The PUSHF instruction is intended for use when the operand-size attribute is 16 and the PUSHFD instruction for when the operand-size attribute is 32. Some assemblers may force the operand size to 16 when PUSHF is used and to 32 when PUSHFD is used. Others may treat these mnemonics as synonyms (PUSHF/PUSHFD) and use the current setting of the operand-size attribute to determine the size of values to be pushed from the stack, regardless of the mnemonic used.\nIn 64-bit mode, the instruction’s default operation is to decrement the stack pointer (RSP) by 8 and pushes RFLAGS on the stack. 16-bit operation is supported using the operand size override prefix 66H. 32-bit operand size cannot be encoded in this mode. When copying RFLAGS to the stack, the VM and RF flags (bits 16 and 17) are not copied; instead, values for these flags are cleared in the RFLAGS image stored on the stack.\nWhen operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the PUSHF/PUSHFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), PUSHF (but not PUSHFD) can be executed in virtual-8086 mode with IOPL < 3.\n(The protected-mode virtual-interrupt feature — enabled by setting CR4.PVI — affects the CLI and STI instructions in the same manner as the virtual-8086 mode extensions. PUSHF, however, is not affected by CR4.PVI.)\nIn the real-address mode, if the ESP or SP register is 1 when PUSHF/PUSHFD instruction executes: an #SS exception is generated but not delivered (the stack error reported prevents #SS delivery). Next, the processor generates a #DF exception and enters a shutdown state as described in the #DF discussion in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.", + "operation": "IF (PE = 0) or (PE = 1 and ((VM = 0) or (VM = 1 and IOPL = 3)))\n(* Real-Address Mode, Protected mode, or Virtual-8086 mode with IOPL equal to 3 *)\n THEN\n IF OperandSize = 32\n THEN\n push (EFLAGS AND 00FCFFFFH);\n (* VM and RF bits are cleared in image stored on the stack *)\n ELSE\n push (EFLAGS); (* Lower 16 bits only *)\n FI;\n ELSE IF 64-bit MODE (* In 64-bit Mode *)\n IF OperandSize = 64\n THEN\n push (RFLAGS AND 00000000_00FCFFFFH);\n (* VM and RF bits are cleared in image stored on the stack; *)\n ELSE\n push (EFLAGS); (* Lower 16 bits only *)\n FI;\n ELSE (* In Virtual-8086 Mode with IOPL less than 3 *)\n IF (CR4.VME = 0) OR (OperandSize = 32)\n THEN #GP(0); (* Trap to virtual-8086 monitor *)\n ELSE\n tempFLAGS = EFLAGS[15:0];\n tempFLAGS[9] = tempFLAGS[19]; (* VIF replaces IF *)\n tempFlags[13:12]=3; (*IOPLissetto3inimagestoredonthestack*)\n push (tempFLAGS);\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/pushf:pushfd:pushfq" + }, + "pxor": { + "instruction": "PXOR", + "title": "PXOR\n\t\t— Logical Exclusive OR", + "opcode": "NP 0F EF /r1 PXOR mm, mm/m64", + "description": "Performs a bitwise logical exclusive-OR (XOR) operation on the source operand (second operand) and the destination operand (first operand) and stores the result in the destination operand. Each bit of the result is 1 if the corresponding bits of the two operands are different; each bit is 0 if the corresponding bits of the operands are the same.\nIn 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\nLegacy SSE instructions 64-bit operand: The source operand can be an MMX technology register or a 64-bit memory location. The destination operand is an MMX technology register.\n128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding register destination are zeroed.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with write-mask k1.", + "operation": "DEST := DEST XOR SRC\n\n\nDEST := DEST XOR SRC\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST := SRC1 XOR SRC2\nDEST[MAXVL-1:128] := 0\n\n\nDEST := SRC1 XOR SRC2\nDEST[MAXVL-1:256] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+31:i] := SRC1[i+31:i] BITWISE XOR SRC2[31:0]\n ELSE DEST[i+31:i] := SRC1[i+31:i] BITWISE XOR SRC2[i+31:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE\n ; zeroing-masking\n DEST[31:0] := 0\n FI;\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC2 *is memory*)\n THEN DEST[i+63:i] := SRC1[i+63:i] BITWISE XOR SRC2[63:0]\n ELSE DEST[i+63:i] := SRC1[i+63:i] BITWISE XOR SRC2[i+63:i]\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[63:0] := 0\n FI;\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n", + "url": "https://www.felixcloutier.com/x86/pxor" + }, + "rcl": { + "instruction": "RCL", + "title": "RCL/RCR/ROL/ROR\n\t\t— Rotate", + "opcode": "D0 /2", + "description": "Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the second operand (count operand) and stores the result in the destination operand. The destination operand can be a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W = 1).\nThe rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit positions, except for the most-significant bit, which is rotated to the least-significant bit location. The rotate right (ROR) and rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except for the least-significant bit, which is rotated to the most-significant bit location.\nThe RCL and RCR instructions include the CF flag in the rotation. The RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag. The RCR instruction shifts the CF flag into the most-significant bit and shifts the least-significant bit into the CF flag. For the ROL and ROR instructions, the original value of the CF flag is not a part of the result, but the CF flag receives a copy of the bit that was shifted from one end to the other.\nThe OF flag is defined only for the 1-bit rotates; it is undefined in all other cases (except RCL and RCR instructions only: a zero-bit rotate does nothing, that is affects no flags). For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result. For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Use of REX.W promotes the first operand to 64 bits and causes the count operand to become a 6-bit counter.", + "operation": "SIZE := OperandSize;\nCASE (determine count) OF\n SIZE := 8:\n tempCOUNT := (COUNT AND 1FH) MOD 9;\n SIZE := 16:\n tempCOUNT := (COUNT AND 1FH) MOD 17;\n SIZE := 32:\n tempCOUNT := COUNT AND 1FH;\n SIZE := 64:\n tempCOUNT := COUNT AND 3FH;\nESAC;\nIF OperandSize = 64\n THEN COUNTMASK = 3FH;\n ELSE COUNTMASK = 1FH;\nFI;\n\n\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + CF;\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (CF * 2SIZE);\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := LSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (tempCF ∗ 2SIZE);\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := MSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR MSB − 1(DEST);\n ELSE OF is undefined;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rcl:rcr:rol:ror" + }, + "rcpps": { + "instruction": "RCPPS", + "title": "RCPPS\n\t\t— Compute Reciprocals of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 53 /r RCPPS xmm1, xmm2/m128", + "description": "Performs a SIMD computation of the approximate reciprocals of the four packed single precision floating-point values in the source operand (second operand) stores the packed single precision floating-point results in the destination operand. The source operand can be an XMM register or a 128-bit memory location. The destination operand is an XMM register. See Figure 10-5 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD single precision floating-point operation.\nThe relative error for this approximation is:\n|Relative Error| ≤ 1.5 ∗ 2−12\nThe RCPPS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is a 0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same sign). Tiny results (see Section 4.9.1.5, “Numeric Underflow Exception (#U)” in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1) are always flushed to 0.0, with the sign of the operand. (Input values greater than or equal to |1.11111111110100000000000B∗2125| are guaranteed to not produce tiny results; input values less than or equal to |1.00000000000110000000001B*2126| are guaranteed to produce tiny results, which are in turn flushed to 0.0; and input values in between this range may or may not produce tiny results, depending on the implementation.) When a source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN is returned.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "DEST[31:0] := APPROXIMATE(1/SRC[31:0])\nDEST[63:32] := APPROXIMATE(1/SRC[63:32])\nDEST[95:64] := APPROXIMATE(1/SRC[95:64])\nDEST[127:96] := APPROXIMATE(1/SRC[127:96])\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := APPROXIMATE(1/SRC[31:0])\nDEST[63:32] := APPROXIMATE(1/SRC[63:32])\nDEST[95:64] := APPROXIMATE(1/SRC[95:64])\nDEST[127:96] := APPROXIMATE(1/SRC[127:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := APPROXIMATE(1/SRC[31:0])\nDEST[63:32] := APPROXIMATE(1/SRC[63:32])\nDEST[95:64] := APPROXIMATE(1/SRC[95:64])\nDEST[127:96] := APPROXIMATE(1/SRC[127:96])\nDEST[159:128] := APPROXIMATE(1/SRC[159:128])\nDEST[191:160] := APPROXIMATE(1/SRC[191:160])\nDEST[223:192] := APPROXIMATE(1/SRC[223:192])\nDEST[255:224] := APPROXIMATE(1/SRC[255:224])\n", + "url": "https://www.felixcloutier.com/x86/rcpps" + }, + "rcpss": { + "instruction": "RCPSS", + "title": "RCPSS\n\t\t— Compute Reciprocal of Scalar Single Precision Floating-Point Values", + "opcode": "F3 0F 53 /r RCPSS xmm1, xmm2/m32", + "description": "Computes of an approximate reciprocal of the low single precision floating-point value in the source operand (second operand) and stores the single precision floating-point result in the destination operand. The source operand can be an XMM register or a 32-bit memory location. The destination operand is an XMM register. The three high-order doublewords of the destination operand remain unchanged. See Figure 10-6 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a scalar single precision floating-point operation.\nThe relative error for this approximation is:\n|Relative Error| ≤ 1.5 ∗ 2−12\nThe RCPSS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is a 0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same sign). Tiny results (see Section 4.9.1.5, “Numeric Underflow Exception (#U)” in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1) are always flushed to 0.0, with the sign of the operand. (Input values greater than or equal to |1.11111111110100000000000B∗2125| are guaranteed to not produce tiny results; input values less than or equal to |1.00000000000110000000001B*2126| are guaranteed to produce tiny results, which are in turn flushed to 0.0; and input values in between this range may or may not produce tiny results, depending on the implementation.) When a source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN is returned.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.", + "operation": "DEST[31:0] := APPROXIMATE(1/SRC[31:0])\nDEST[MAXVL-1:32] (Unmodified)\n\n\nDEST[31:0] := APPROXIMATE(1/SRC2[31:0])\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/rcpss" + }, + "rcr": { + "instruction": "RCR", + "title": "RCL/RCR/ROL/ROR\n\t\t— Rotate", + "opcode": "D0 /3", + "description": "Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the second operand (count operand) and stores the result in the destination operand. The destination operand can be a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W = 1).\nThe rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit positions, except for the most-significant bit, which is rotated to the least-significant bit location. The rotate right (ROR) and rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except for the least-significant bit, which is rotated to the most-significant bit location.\nThe RCL and RCR instructions include the CF flag in the rotation. The RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag. The RCR instruction shifts the CF flag into the most-significant bit and shifts the least-significant bit into the CF flag. For the ROL and ROR instructions, the original value of the CF flag is not a part of the result, but the CF flag receives a copy of the bit that was shifted from one end to the other.\nThe OF flag is defined only for the 1-bit rotates; it is undefined in all other cases (except RCL and RCR instructions only: a zero-bit rotate does nothing, that is affects no flags). For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result. For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Use of REX.W promotes the first operand to 64 bits and causes the count operand to become a 6-bit counter.", + "operation": "SIZE := OperandSize;\nCASE (determine count) OF\n SIZE := 8:\n tempCOUNT := (COUNT AND 1FH) MOD 9;\n SIZE := 16:\n tempCOUNT := (COUNT AND 1FH) MOD 17;\n SIZE := 32:\n tempCOUNT := COUNT AND 1FH;\n SIZE := 64:\n tempCOUNT := COUNT AND 3FH;\nESAC;\nIF OperandSize = 64\n THEN COUNTMASK = 3FH;\n ELSE COUNTMASK = 1FH;\nFI;\n\n\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + CF;\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (CF * 2SIZE);\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := LSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (tempCF ∗ 2SIZE);\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := MSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR MSB − 1(DEST);\n ELSE OF is undefined;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rcl:rcr:rol:ror" + }, + "rdfsbase": { + "instruction": "RDFSBASE", + "title": "RDFSBASE/RDGSBASE\n\t\t— Read FS/GS Segment Base", + "opcode": "F3 0F AE /0 RDFSBASE r32", + "description": "Loads the general-purpose register indicated by the ModR/M:r/m field with the FS or GS segment base address.\nThe destination operand may be either a 32-bit or a 64-bit general-purpose register. The REX.W prefix indicates the operand size is 64 bits. If no REX.W prefix is used, the operand size is 32 bits; the upper 32 bits of the source base address (for FS or GS) are ignored and upper 32 bits of the destination register are cleared.\nThis instruction is supported only in 64-bit mode.", + "operation": "DEST := FS/GS segment base address;\n", + "url": "https://www.felixcloutier.com/x86/rdfsbase:rdgsbase" + }, + "rdgsbase": { + "instruction": "RDGSBASE", + "title": "RDFSBASE/RDGSBASE\n\t\t— Read FS/GS Segment Base", + "opcode": "F3 0F AE /0 RDFSBASE r32", + "description": "Loads the general-purpose register indicated by the ModR/M:r/m field with the FS or GS segment base address.\nThe destination operand may be either a 32-bit or a 64-bit general-purpose register. The REX.W prefix indicates the operand size is 64 bits. If no REX.W prefix is used, the operand size is 32 bits; the upper 32 bits of the source base address (for FS or GS) are ignored and upper 32 bits of the destination register are cleared.\nThis instruction is supported only in 64-bit mode.", + "operation": "DEST := FS/GS segment base address;\n", + "url": "https://www.felixcloutier.com/x86/rdfsbase:rdgsbase" + }, + "rdmsr": { + "instruction": "RDMSR", + "title": "RDMSR\n\t\t— Read From Model Specific Register", + "opcode": "0F 32", + "description": "Reads the contents of a 64-bit model specific register (MSR) specified in the ECX register into registers EDX:EAX. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The EDX register is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.) If fewer than 64 bits are implemented in the MSR being read, the values returned to EDX:EAX in unimplemented bit locations are undefined.\nThis instruction must be executed at privilege level 0 or in real-address mode; otherwise, a general protection exception #GP(0) will be generated. Specifying a reserved or unimplemented MSR address in ECX will also cause a general protection exception.\nThe MSRs control functions for testability, execution tracing, performance-monitoring, and machine check errors. Chapter 2, “Model-Specific Registers (MSRs)” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 4, lists all the MSRs that can be read with this instruction and their addresses. Note that each processor family has its own set of MSRs.\nThe CPUID instruction should be used to determine whether MSRs are supported (CPUID.01H:EDX[5] = 1) before using this instruction.", + "operation": "EDX:EAX := MSR[ECX];\n", + "url": "https://www.felixcloutier.com/x86/rdmsr" + }, + "rdpid": { + "instruction": "RDPID", + "title": "RDPID\n\t\t— Read Processor ID", + "opcode": "F3 0F C7 /7 RDPID r32", + "description": "Reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the destination register. The value of CS.D and operand-size prefixes (66H and REX.W) do not affect the behavior of the RDPID instruction.", + "operation": "DEST := IA32_TSC_AUX\n", + "url": "https://www.felixcloutier.com/x86/rdpid" + }, + "rdpkru": { + "instruction": "RDPKRU", + "title": "RDPKRU\n\t\t— Read Protection Key Rights for User Pages", + "opcode": "NP 0F 01 EE", + "description": "Reads the value of PKRU into EAX and clears EDX. ECX must be 0 when RDPKRU is executed; otherwise, a general-protection exception (#GP) occurs.\nRDPKRU can be executed only if CR4.PKE = 1; otherwise, an invalid-opcode exception (#UD) occurs. Software can discover the value of CR4.PKE by examining CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4].\nOn processors that support the Intel 64 Architecture, the high-order 32-bits of RCX are ignored and the high-order 32-bits of RDX and RAX are cleared.", + "operation": "IF (ECX = 0)\n THEN\n EAX := PKRU;\n EDX := 0;\n ELSE #GP(0);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rdpkru" + }, + "rdpmc": { + "instruction": "RDPMC", + "title": "RDPMC\n\t\t— Read Performance-Monitoring Counters", + "opcode": "0F 33", + "description": "Reads the contents of the performance monitoring counter (PMC) specified in ECX register into registers EDX:EAX. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The EDX register is loaded with the high-order 32 bits of the PMC and the EAX register is loaded with the low-order 32 bits. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.) If fewer than 64 bits are implemented in the PMC being read, unimplemented bits returned to EDX:EAX will have value zero.\nThe width of PMCs on processors supporting architectural performance monitoring (CPUID.0AH:EAX[7:0] ≠ 0) are reported by CPUID.0AH:EAX[23:16]. On processors that do not support architectural performance monitoring (CPUID.0AH:EAX[7:0]=0), the width of general-purpose performance PMCs is 40 bits, while the widths of special-purpose PMCs are implementation specific.\nUse of ECX to specify a PMC depends on whether the processor supports architectural performance monitoring:\nSpecifying an unsupported PMC encoding will cause a general protection exception #GP(0). For PMC details see Chapter 20, “Performance Monitoring,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.\nWhen in protected or virtual 8086 mode, the Performance-monitoring Counters Enabled (PCE) flag in register CR4 restricts the use of the RDPMC instruction. When the PCE flag is set, the RDPMC instruction can be executed at any privilege level; when the flag is clear, the instruction can only be executed at privilege level 0. (When in real-address mode, the RDPMC instruction is always enabled.) The PMCs can also be read with the RDMSR instruction, when executing at privilege level 0.\nThe RDPMC instruction is not a serializing instruction; that is, it does not imply that all the events caused by the preceding instructions have been completed or that events caused by subsequent instructions have not begun. If an exact event count is desired, software must insert a serializing instruction (such as the CPUID instruction) before and/or after the RDPMC instruction.\nPerforming back-to-back fast reads are not guaranteed to be monotonic. To guarantee monotonicity on back-to-back reads, a serializing instruction must be placed between the two RDPMC instructions.\nThe RDPMC instruction can execute in 16-bit addressing mode or virtual-8086 mode; however, the full contents of the ECX register are used to select the PMC, and the event count is stored in the full EAX and EDX registers. The\nRDPMC instruction was introduced into the IA-32 Architecture in the Pentium Pro processor and the Pentium processor with MMX technology. The earlier Pentium processors have PMCs, but they must be read with the RDMSR instruction.", + "operation": "MSCB = Most Significant Counter Bit (* Model-specific *)\nIF (((CR4.PCE = 1) or (CPL = 0) or (CR0.PE = 0)) and (ECX indicates a supported counter))\n THEN\n EAX := counter[31:0];\n EDX := ZeroExtend(counter[MSCB:32]);\n ELSE (* ECX is not valid or CR4.PCE is 0 and CPL is 1, 2, or 3 and CR0.PE is 1 *)\n #GP(0);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rdpmc" + }, + "rdrand": { + "instruction": "RDRAND", + "title": "RDRAND\n\t\t— Read Random Number", + "opcode": "NFx 0F C7 /6 RDRAND r16", + "description": "Loads a hardware generated random value and store it in the destination register. The size of the random value is determined by the destination register size and operating mode. The Carry Flag indicates whether a random value is available at the time the instruction is executed. CF=1 indicates that the data in the destination is valid. Otherwise CF=0 and the data in the destination operand will be returned as zeros for the specified width. All other flags are forced to 0 in either situation. Software must check the state of CF=1 for determining if a valid random value has been returned, otherwise it is expected to loop and retry execution of RDRAND (see Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, Section 7.3.17, “Random Number Generator Instructions”).\nThis instruction is available at all privilege levels.\nIn 64-bit mode, the instruction's default operand size is 32 bits. Using a REX prefix in the form of REX.B permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit operands. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF HW_RND_GEN.ready = 1\n THEN\n CASE of\n operand size is 64: DEST[63:0] := HW_RND_GEN.data;\n operand size is 32: DEST[31:0] := HW_RND_GEN.data;\n operand size is 16: DEST[15:0] := HW_RND_GEN.data;\n ESAC\n CF := 1;\n ELSE\n CASE of\n operand size is 64: DEST[63:0] := 0;\n operand size is 32: DEST[31:0] := 0;\n operand size is 16: DEST[15:0] := 0;\n ESAC\n CF := 0;\nFI\nOF, SF, ZF, AF, PF := 0;\n", + "url": "https://www.felixcloutier.com/x86/rdrand" + }, + "rdseed": { + "instruction": "RDSEED", + "title": "RDSEED\n\t\t— Read Random SEED", + "opcode": "NFx 0F C7 /7 RDSEED r16", + "description": "Loads a hardware generated random value and store it in the destination register. The random value is generated from an Enhanced NRBG (Non Deterministic Random Bit Generator) that is compliant to NIST SP800-90B and NIST SP800-90C in the XOR construction mode. The size of the random value is determined by the destination register size and operating mode. The Carry Flag indicates whether a random value is available at the time the instruction is executed. CF=1 indicates that the data in the destination is valid. Otherwise CF=0 and the data in the destination operand will be returned as zeros for the specified width. All other flags are forced to 0 in either situation. Software must check the state of CF=1 for determining if a valid random seed value has been returned, otherwise it is expected to loop and retry execution of RDSEED (see Section 1.2).\nThe RDSEED instruction is available at all privilege levels. The RDSEED instruction executes normally either inside or outside a transaction region.\nIn 64-bit mode, the instruction's default operand size is 32 bits. Using a REX prefix in the form of REX.B permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit operands. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF HW_NRND_GEN.ready = 1\n THEN\n CASE of\n operand size is 64: DEST[63:0] := HW_NRND_GEN.data;\n operand size is 32: DEST[31:0] := HW_NRND_GEN.data;\n operand size is 16: DEST[15:0] := HW_NRND_GEN.data;\n ESAC;\n CF := 1;\n ELSE\n CASE of\n operand size is 64: DEST[63:0] := 0;\n operand size is 32: DEST[31:0] := 0;\n operand size is 16: DEST[15:0] := 0;\n ESAC;\n CF := 0;\nFI;\nOF, SF, ZF, AF, PF := 0;\n", + "url": "https://www.felixcloutier.com/x86/rdseed" + }, + "rdsspd": { + "instruction": "RDSSPD", + "title": "RDSSPD/RDSSPQ\n\t\t— Read Shadow Stack Pointer", + "opcode": "F3 0F 1E /1 (mod=11) RDSSPD r32", + "description": "Copies the current shadow stack pointer (SSP) register to the register destination. This opcode is a NOP when CET shadow stacks are not enabled and on processors that do not support CET.", + "operation": "IF CPL = 3\n IF CR4.CET & IA32_U_CET.SH_STK_EN\n IF (operand size is 64 bit)\n THEN\n Dest := SSP;\n ELSE\n Dest := SSP[31:0];\n FI;\n FI;\nELSE\n IF CR4.CET & IA32_S_CET.SH_STK_EN\n IF (operand size is 64 bit)\n THEN\n Dest := SSP;\n ELSE\n Dest := SSP[31:0];\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rdsspd:rdsspq" + }, + "rdsspq": { + "instruction": "RDSSPQ", + "title": "RDSSPD/RDSSPQ\n\t\t— Read Shadow Stack Pointer", + "opcode": "F3 0F 1E /1 (mod=11) RDSSPD r32", + "description": "Copies the current shadow stack pointer (SSP) register to the register destination. This opcode is a NOP when CET shadow stacks are not enabled and on processors that do not support CET.", + "operation": "IF CPL = 3\n IF CR4.CET & IA32_U_CET.SH_STK_EN\n IF (operand size is 64 bit)\n THEN\n Dest := SSP;\n ELSE\n Dest := SSP[31:0];\n FI;\n FI;\nELSE\n IF CR4.CET & IA32_S_CET.SH_STK_EN\n IF (operand size is 64 bit)\n THEN\n Dest := SSP;\n ELSE\n Dest := SSP[31:0];\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rdsspd:rdsspq" + }, + "rdtsc": { + "instruction": "RDTSC", + "title": "RDTSC\n\t\t— Read Time-Stamp Counter", + "opcode": "0F 31", + "description": "Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers. The EDX register is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.)\nThe processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever the processor is reset. See “Time Stamp Counter” in Chapter 18 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B, for specific details of the time stamp counter behavior.\nThe time stamp disable (TSD) flag in register CR4 restricts the use of the RDTSC instruction as follows. When the flag is clear, the RDTSC instruction can be executed at any privilege level; when the flag is set, the instruction can only be executed at privilege level 0.\nThe time-stamp counter can also be read with the RDMSR instruction, when executing at privilege level 0.\nThe RDTSC instruction is not a serializing instruction. It does not necessarily wait until all previous instructions have been executed before reading the counter. Similarly, subsequent instructions may begin execution before the read operation is performed. The following items may guide software seeking to order executions of RDTSC:\nThis instruction was introduced by the Pentium processor.\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "IF (CR4.TSD = 0) or (CPL = 0) or (CR0.PE = 0)\n THEN EDX:EAX := TimeStampCounter;\n ELSE (* CR4.TSD = 1 and (CPL = 1, 2, or 3) and CR0.PE = 1 *)\n #GP(0);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rdtsc" + }, + "rdtscp": { + "instruction": "RDTSCP", + "title": "RDTSCP\n\t\t— Read Time-Stamp Counter and Processor ID", + "opcode": "0F 01 F9", + "description": "Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers and also reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the ECX register. The EDX register is loaded with the high-order 32 bits of the IA32_TSC MSR; the EAX register is loaded with the low-order 32 bits of the IA32_TSC MSR; and the ECX register is loaded with the low-order 32-bits of IA32_TSC_AUX MSR. On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX, RDX, and RCX are cleared.\nThe processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever the processor is reset. See “Time Stamp Counter” in Chapter 18 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B, for specific details of the time stamp counter behavior.\nThe time stamp disable (TSD) flag in register CR4 restricts the use of the RDTSCP instruction as follows. When the flag is clear, the RDTSCP instruction can be executed at any privilege level; when the flag is set, the instruction can only be executed at privilege level 0.\nThe RDTSCP instruction is not a serializing instruction, but it does wait until all previous instructions have executed and all previous loads are globally visible.1 But it does not wait for previous stores to be globally visible, and subsequent instructions may begin execution before the read operation is performed. The following items may guide software seeking to order executions of RDTSCP:\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "IF (CR4.TSD = 0) or (CPL = 0) or (CR0.PE = 0)\n THEN\n EDX:EAX := TimeStampCounter;\n ECX := IA32_TSC_AUX[31:0];\n ELSE (* CR4.TSD = 1 and (CPL = 1, 2, or 3) and CR0.PE = 1 *)\n #GP(0);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rdtscp" + }, + "rep": { + "instruction": "REP", + "title": "REP/REPE/REPZ/REPNE/REPNZ\n\t\t— Repeat String Operation Prefix", + "opcode": "F3 6C", + "description": "Repeats a string instruction the number of times specified in the count register or until the indicated condition of the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ (repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the following instructions and undefined for the rest:\nThe REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be repeated until the count in register is decremented to 0. See Table 4-17.\nThe REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing the ZF flag (with a JZ, JNZ, or JNE instruction).\nWhen the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.\nA repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt handler. The source and destination registers point to the next string elements to be operated on, the EIP register points to the string instruction, and the ECX register has the value it held following the last successful iteration of the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response time of the system.\nWhen a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instructions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.\nUse the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.\nIn 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used to override address size attribute, the count register is ECX and any implicit source/destination operand will use the corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and limits.\nREP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF AddressSize = 16\n THEN\n Use CX for CountReg;\n Implicit Source/Dest operand for memory use of SI/DI;\n ELSE IF AddressSize = 64\n THEN Use RCX for CountReg;\n Implicit Source/Dest operand for memory use of RSI/RDI;\n ELSE\n Use ECX for CountReg;\n Implicit Source/Dest operand for memory use of ESI/EDI;\nFI;\nWHILE CountReg ≠ 0\n DO\n Service pending interrupts (if any);\n Execute associated string instruction;\n CountReg := (CountReg – 1);\n IF CountReg = 0\n THEN exit WHILE loop; FI;\n IF (Repeat prefix is REPZ or REPE) and (ZF = 0)\n or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)\n THEN exit WHILE loop; FI;\n OD;\n", + "url": "https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz" + }, + "repe": { + "instruction": "REPE", + "title": "REP/REPE/REPZ/REPNE/REPNZ\n\t\t— Repeat String Operation Prefix", + "opcode": "F3 A6", + "description": "Repeats a string instruction the number of times specified in the count register or until the indicated condition of the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ (repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the following instructions and undefined for the rest:\nThe REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be repeated until the count in register is decremented to 0. See Table 4-17.\nThe REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing the ZF flag (with a JZ, JNZ, or JNE instruction).\nWhen the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.\nA repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt handler. The source and destination registers point to the next string elements to be operated on, the EIP register points to the string instruction, and the ECX register has the value it held following the last successful iteration of the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response time of the system.\nWhen a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instructions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.\nUse the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.\nIn 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used to override address size attribute, the count register is ECX and any implicit source/destination operand will use the corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and limits.\nREP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF AddressSize = 16\n THEN\n Use CX for CountReg;\n Implicit Source/Dest operand for memory use of SI/DI;\n ELSE IF AddressSize = 64\n THEN Use RCX for CountReg;\n Implicit Source/Dest operand for memory use of RSI/RDI;\n ELSE\n Use ECX for CountReg;\n Implicit Source/Dest operand for memory use of ESI/EDI;\nFI;\nWHILE CountReg ≠ 0\n DO\n Service pending interrupts (if any);\n Execute associated string instruction;\n CountReg := (CountReg – 1);\n IF CountReg = 0\n THEN exit WHILE loop; FI;\n IF (Repeat prefix is REPZ or REPE) and (ZF = 0)\n or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)\n THEN exit WHILE loop; FI;\n OD;\n", + "url": "https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz" + }, + "repne": { + "instruction": "REPNE", + "title": "REP/REPE/REPZ/REPNE/REPNZ\n\t\t— Repeat String Operation Prefix", + "opcode": "F2 A6", + "description": "Repeats a string instruction the number of times specified in the count register or until the indicated condition of the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ (repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the following instructions and undefined for the rest:\nThe REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be repeated until the count in register is decremented to 0. See Table 4-17.\nThe REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing the ZF flag (with a JZ, JNZ, or JNE instruction).\nWhen the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.\nA repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt handler. The source and destination registers point to the next string elements to be operated on, the EIP register points to the string instruction, and the ECX register has the value it held following the last successful iteration of the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response time of the system.\nWhen a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instructions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.\nUse the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.\nIn 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used to override address size attribute, the count register is ECX and any implicit source/destination operand will use the corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and limits.\nREP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF AddressSize = 16\n THEN\n Use CX for CountReg;\n Implicit Source/Dest operand for memory use of SI/DI;\n ELSE IF AddressSize = 64\n THEN Use RCX for CountReg;\n Implicit Source/Dest operand for memory use of RSI/RDI;\n ELSE\n Use ECX for CountReg;\n Implicit Source/Dest operand for memory use of ESI/EDI;\nFI;\nWHILE CountReg ≠ 0\n DO\n Service pending interrupts (if any);\n Execute associated string instruction;\n CountReg := (CountReg – 1);\n IF CountReg = 0\n THEN exit WHILE loop; FI;\n IF (Repeat prefix is REPZ or REPE) and (ZF = 0)\n or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)\n THEN exit WHILE loop; FI;\n OD;\n", + "url": "https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz" + }, + "repnz": { + "instruction": "REPNZ", + "title": "REP/REPE/REPZ/REPNE/REPNZ\n\t\t— Repeat String Operation Prefix", + "opcode": "F3 6C", + "description": "Repeats a string instruction the number of times specified in the count register or until the indicated condition of the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ (repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the following instructions and undefined for the rest:\nThe REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be repeated until the count in register is decremented to 0. See Table 4-17.\nThe REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing the ZF flag (with a JZ, JNZ, or JNE instruction).\nWhen the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.\nA repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt handler. The source and destination registers point to the next string elements to be operated on, the EIP register points to the string instruction, and the ECX register has the value it held following the last successful iteration of the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response time of the system.\nWhen a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instructions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.\nUse the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.\nIn 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used to override address size attribute, the count register is ECX and any implicit source/destination operand will use the corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and limits.\nREP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF AddressSize = 16\n THEN\n Use CX for CountReg;\n Implicit Source/Dest operand for memory use of SI/DI;\n ELSE IF AddressSize = 64\n THEN Use RCX for CountReg;\n Implicit Source/Dest operand for memory use of RSI/RDI;\n ELSE\n Use ECX for CountReg;\n Implicit Source/Dest operand for memory use of ESI/EDI;\nFI;\nWHILE CountReg ≠ 0\n DO\n Service pending interrupts (if any);\n Execute associated string instruction;\n CountReg := (CountReg – 1);\n IF CountReg = 0\n THEN exit WHILE loop; FI;\n IF (Repeat prefix is REPZ or REPE) and (ZF = 0)\n or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)\n THEN exit WHILE loop; FI;\n OD;\n", + "url": "https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz" + }, + "repz": { + "instruction": "REPZ", + "title": "REP/REPE/REPZ/REPNE/REPNZ\n\t\t— Repeat String Operation Prefix", + "opcode": "F3 6C", + "description": "Repeats a string instruction the number of times specified in the count register or until the indicated condition of the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ (repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the following instructions and undefined for the rest:\nThe REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be repeated until the count in register is decremented to 0. See Table 4-17.\nThe REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing the ZF flag (with a JZ, JNZ, or JNE instruction).\nWhen the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.\nA repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt handler. The source and destination registers point to the next string elements to be operated on, the EIP register points to the string instruction, and the ECX register has the value it held following the last successful iteration of the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response time of the system.\nWhen a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instructions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.\nUse the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.\nIn 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used to override address size attribute, the count register is ECX and any implicit source/destination operand will use the corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and limits.\nREP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, software should ensure the write to the memory location does not cause an exception or VM exit.", + "operation": "IF AddressSize = 16\n THEN\n Use CX for CountReg;\n Implicit Source/Dest operand for memory use of SI/DI;\n ELSE IF AddressSize = 64\n THEN Use RCX for CountReg;\n Implicit Source/Dest operand for memory use of RSI/RDI;\n ELSE\n Use ECX for CountReg;\n Implicit Source/Dest operand for memory use of ESI/EDI;\nFI;\nWHILE CountReg ≠ 0\n DO\n Service pending interrupts (if any);\n Execute associated string instruction;\n CountReg := (CountReg – 1);\n IF CountReg = 0\n THEN exit WHILE loop; FI;\n IF (Repeat prefix is REPZ or REPE) and (ZF = 0)\n or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)\n THEN exit WHILE loop; FI;\n OD;\n", + "url": "https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz" + }, + "ret": { + "instruction": "RET", + "title": "RET\n\t\t— Return From Procedure", + "opcode": "C3", + "description": "Transfers program control to a return address located on the top of the stack. The address is usually placed on the stack by a CALL instruction, and the return is made to the instruction that follows the CALL instruction.\nThe optional source operand specifies the number of stack bytes to be released after the return address is popped; the default is none. This operand can be used to release parameters from the stack that were passed to the called procedure and are no longer needed. It must be used when the CALL instruction used to switch to a new procedure uses a call gate with a non-zero word count to access the new procedure. Here, the source operand for the RET instruction must specify the same number of bytes as is specified in the word count field of the call gate.\nThe RET instruction can be used to execute three different types of returns:\nThe inter-privilege-level return type can only be executed in protected mode. See the section titled “Calling Procedures Using Call and RET” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for detailed information on near, far, and inter-privilege-level returns.\nWhen executing a near return, the processor pops the return instruction pointer (offset) from the top of the stack into the EIP register and begins program execution at the new instruction pointer. The CS register is unchanged.\nWhen executing a far return, the processor pops the return instruction pointer from the top of the stack into the EIP register, then pops the segment selector from the top of the stack into the CS register. The processor then begins program execution in the new code segment at the new instruction pointer.\nThe mechanics of an inter-privilege-level far return are similar to an intersegment return, except that the processor examines the privilege levels and access rights of the code and stack segments being returned to determine if the control transfer is allowed to be made. The DS, ES, FS, and GS segment registers are cleared by the RET instruction during an inter-privilege-level return if they refer to segments that are not allowed to be accessed at the new privilege level. Since a stack switch also occurs on an inter-privilege level return, the ESP and SS registers are loaded from the stack.\nIf parameters are passed to the called procedure during an inter-privilege level call, the optional source operand must be used with the RET instruction to release the parameters on the return. Here, the parameters are released both from the called procedure’s stack and the calling procedure’s stack (that is, the stack being returned to).\nIn 64-bit mode, the default operation size of this instruction is the stack-address size, i.e., 64 bits. This applies to near returns, not far returns; the default operation size of far returns is 32 bits.\nRefer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions‚” and Chapter 17, “Control-flow Enforcement Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.\nInstruction ordering. Instructions following a far return may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the far return have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).\nUnlike near indirect CALL and near indirect JMP, the processor will not speculatively execute the next sequential instruction after a near RET unless that instruction is also the target of a jump or is a target in a branch predictor.", + "operation": "(* Near return *)\nIF instruction = near return\n THEN;\n IF OperandSize = 32\n THEN\n IF top 4 bytes of stack not within stack limits\n THEN #SS(0); FI;\n EIP := Pop();\n IF ShadowStackEnabled(CPL)\n tempSsEIP = ShadowStackPop4B();\n IF EIP != TempSsEIP\n THEN #CP(NEAR_RET); FI;\n FI;\n ELSE\n IF OperandSize = 64\n THEN\n IF top 8 bytes of stack not within stack limits\n THEN #SS(0); FI;\n RIP := Pop();\n IF ShadowStackEnabled(CPL)\n tempSsEIP = ShadowStackPop8B();\n IF RIP != tempSsEIP\n THEN #CP(NEAR_RET); FI;\n FI;\n ELSE (* OperandSize = 16 *)\n IF top 2 bytes of stack not within stack limits\n THEN #SS(0); FI;\n tempEIP := Pop();\n tempEIP := tempEIP AND 0000FFFFH;\n IF tempEIP not within code segment limits\n THEN #GP(0); FI;\n EIP := tempEIP;\n IF ShadowStackEnabled(CPL)\n tempSsEip = ShadowStackPop4B();\n IF EIP != tempSsEIP\n THEN #CP(NEAR_RET); FI;\n FI;\n FI;\n FI;\n IF instruction has immediate operand\n THEN (* Release parameters from stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE\n IF StackAddressSize = 64\n THEN\n RSP := RSP + SRC;\n ELSE (* StackAddressSize = 16 *)\n SP := SP + SRC;\n FI;\n FI;\n FI;\nFI;\n(* Real-address mode or virtual-8086 mode *)\nIF ((PE = 0) or (PE = 1 AND VM = 1)) and instruction = far return\n THEN\n IF OperandSize = 32\n THEN\n IF top 8 bytes of stack not within stack limits\n THEN #SS(0); FI;\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE (* OperandSize = 16 *)\n IF top 4 bytes of stack not within stack limits\n THEN #SS(0); FI;\n tempEIP := Pop();\n tempEIP := tempEIP AND 0000FFFFH;\n IF tempEIP not within code segment limits\n THEN #GP(0); FI;\n EIP := tempEIP;\n CS := Pop(); (* 16-bit pop *)\n FI;\n IF instruction has immediate operand\n THEN (* Release parameters from stack *)\n SP := SP + (SRC AND FFFFH);\n FI;\nFI;\n(* Protected mode, not virtual-8086 mode *)\nIF (PE = 1 and VM = 0 and IA32_EFER.LMA = 0) and instruction = far return\n THEN\n IF OperandSize = 32\n THEN\n IF second doubleword on stack is not within stack limits\n THEN #SS(0); FI;\n ELSE (* OperandSize = 16 *)\n IF second word on stack is not within stack limits\n THEN #SS(0); FI;\n FI;\n IF return code segment selector is NULL\n THEN #GP(0); FI;\n IF return code segment selector addresses descriptor beyond descriptor table limit\n THEN #GP(selector); FI;\n Obtain descriptor to which return code segment selector points from descriptor table;\n IF return code segment descriptor is not a code segment\n THEN #GP(selector); FI;\n IF return code segment selector RPL < CPL\n THEN #GP(selector); FI;\n IF return code segment descriptor is conforming\n and return code segment DPL > return code segment selector RPL\n THEN #GP(selector); FI;\n IF return code segment descriptor is non-conforming and return code\n segment DPL ≠ return code segment selector RPL\n THEN #GP(selector); FI;\n IF return code segment descriptor is not present\n THEN #NP(selector); FI:\n IF return code segment selector RPL > CPL\n THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL;\n FI;\nFI;\nRETURN-TO-SAME-PRIVILEGE-LEVEL:\n IF the return instruction pointer is not within the return code segment limit\n THEN #GP(0); FI;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE (* OperandSize = 16 *)\n EIP := Pop();\n EIP := EIP AND 0000FFFFH;\n CS := Pop(); (* 16-bit pop *)\n FI;\n IF instruction has immediate operand\n THEN (* Release parameters from stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE (* StackAddressSize = 16 *)\n SP := SP + SRC;\n FI;\n FI;\n IF ShadowStackEnabled(CPL)\n (* SSP must be 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n prevSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n (* do a 64 bit-compare to check if any bits beyond bit 15 are set *)\n tempCS = CS; (* zero pad to 64 bit *)\n IF tempCS != tempSsCS\n THEN #CP(FAR-RET/IRET); FI;\n (* do a 64 bit-compare; pad CSBASE+RIP with 0 for 32 bit LIP*)\n IF CSBASE + RIP != tempSsLIP\n THEN #CP(FAR-RET/IRET); FI;\n (* prevSSP must be 4 byte aligned *)\n IF prevSSP AND 0x3 != 0\n THEN #CP(FAR-RET/IRET); FI;\n (* In legacy mode SSP must be in low 4GB *)\n IF prevSSP[63:32] != 0\n THEN #GP(0); FI;\n SSP := prevSSP\n FI;\nRETURN-TO-OUTER-PRIVILEGE-LEVEL:\n IF top (16 + SRC) bytes of stack are not within stack limits (OperandSize = 32)\n or top (8 + SRC) bytes of stack are not within stack limits (OperandSize = 16)\n THEN #SS(0); FI;\n Read return segment selector;\n IF stack segment selector is NULL\n THEN #GP(0); FI;\n IF return stack segment selector index is not within its descriptor table limits\n THEN #GP(selector); FI;\n Read segment descriptor pointed to by return segment selector;\n IF stack segment selector RPL ≠ RPL of the return code segment selector\n or stack segment is not a writable data segment\n or stack segment descriptor DPL ≠ RPL of the return code segment selector\n THEN #GP(selector); FI;\n IF stack segment not present\n THEN #SS(StackSegmentSelector); FI;\n IF the return instruction pointer is not within the return code segment limit\n THEN #GP(0); FI;\n IF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded; segment descriptor loaded *)\n CS(RPL) := ReturnCodeSegmentSelector(RPL);\n IF instruction has immediate operand\n THEN (* Release parameters from called procedure’s stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE (* StackAddressSize = 16 *)\n SP := SP + SRC;\n FI;\n FI;\n tempESP := Pop();\n tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded; seg. descriptor loaded *)\n ELSE (* OperandSize = 16 *)\n EIP := Pop();\n EIP := EIP AND 0000FFFFH;\n CS := Pop(); (* 16-bit pop; segment descriptor loaded *)\n CS(RPL) := ReturnCodeSegmentSelector(RPL);\n IF instruction has immediate operand\n THEN (* Release parameters from called procedure’s stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE (* StackAddressSize = 16 *)\n SP := SP + SRC;\n FI;\n FI;\n tempESP := Pop();\n tempSS := Pop(); (* 16-bit pop; segment descriptor loaded *)\n FI;\n IF ShadowStackEnabled(CPL)\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n IF ReturnCodeSegmentSelector(RPL) !=3\n THEN\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n (* Do 64 bit compare to detect bits beyond 15 being set *)\n tempCS = CS; (* zero extended to 64 bit *)\n IF tempCS != tempSsCS\n THEN #CP(FAR-RET/IRET); FI;\n (* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LA *)\n IF CSBASE + RIP != tempSsLIP\n THEN #CP(FAR-RET/IRET); FI;\n (* check if 4 byte aligned *)\n IF tempSSP AND 0x3 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\n FI;\n tempOldCPL = CPL;\n CPL := ReturnCodeSegmentSelector(RPL);\n ESP := tempESP;\n SS := tempSS;\n tempOldSSP = SSP;\n IF ShadowStackEnabled(CPL)\n IF CPL = 3\n THEN tempSSP := IA32_PL3_SSP; FI;\n IF tempSSP[63:32] != 0\n THEN #GP(0); FI;\n SSP := tempSSP\n FI;\n (* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n * and using a supervisor override as old CPL was a supervisor privilege level *)\n IF ShadowStackEnabled(tempOldCPL)\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\n FI;\n FI;\n FOR each SegReg in (ES, FS, GS, and DS)\n DO\n tempDesc := descriptor cache for SegReg (* hidden part of segment register *)\n IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))\n THEN (* Segment register invalid *)\n SegmentSelector := 0; (*Segment selector becomes null*)\n FI;\n OD;\n IF instruction has immediate operand\n THEN (* Release parameters from calling procedure’s stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE (* StackAddressSize = 16 *)\n SP := SP + SRC;\n FI;\n FI;\n(* IA-32e Mode *)\n IF (PE = 1 and VM = 0 and IA32_EFER.LMA = 1) and instruction = far return\n THEN\n IF OperandSize = 32\n THEN\n IF second doubleword on stack is not within stack limits\n THEN #SS(0); FI;\n IF first or second doubleword on stack is not in canonical space\n THEN #SS(0); FI;\n ELSE\n IF OperandSize = 16\n THEN\n IF second word on stack is not within stack limits\n THEN #SS(0); FI;\n IF first or second word on stack is not in canonical space\n THEN #SS(0); FI;\n ELSE (* OperandSize = 64 *)\n IF first or second quadword on stack is not in canonical space\n THEN #SS(0); FI;\n FI\n FI;\n IF return code segment selector is NULL\n THEN GP(0); FI;\n IF return code segment selector addresses descriptor beyond descriptor table limit\n THEN GP(selector); FI;\n IF return code segment selector addresses descriptor in non-canonical space\n THEN GP(selector); FI;\n Obtain descriptor to which return code segment selector points from descriptor table;\n IF return code segment descriptor is not a code segment\n THEN #GP(selector); FI;\n IF return code segment descriptor has L-bit = 1 and D-bit = 1\n THEN #GP(selector); FI;\n IF return code segment selector RPL < CPL\n THEN #GP(selector); FI;\n IF return code segment descriptor is conforming\n and return code segment DPL > return code segment selector RPL\n THEN #GP(selector); FI;\n IF return code segment descriptor is non-conforming\n and return code segment DPL ≠ return code segment selector RPL\n THEN #GP(selector); FI;\n IF return code segment descriptor is not present\n THEN #NP(selector); FI:\n IF return code segment selector RPL > CPL\n THEN GOTO IA-32E-MODE-RETURN-TO-OUTER-PRIVILEGE-LEVEL;\n ELSE GOTO IA-32E-MODE-RETURN-TO-SAME-PRIVILEGE-LEVEL;\n FI;\n FI;\nIA-32E-MODE-RETURN-TO-SAME-PRIVILEGE-LEVEL:\nIF the return instruction pointer is not within the return code segment limit\n THEN #GP(0); FI;\nIF the return instruction pointer is not within canonical address space\n THEN #GP(0); FI;\nIF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)\n ELSE\n IF OperandSize = 16\n THEN\n EIP := Pop();\n EIP := EIP AND 0000FFFFH;\n CS := Pop(); (* 16-bit pop *)\n ELSE (* OperandSize = 64 *)\n RIP := Pop();\n CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)\n FI;\nFI;\nIF instruction has immediate operand\n THEN (* Release parameters from stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE\n IF StackAddressSize = 16\n THEN\n SP := SP + SRC;\n ELSE (* StackAddressSize = 64 *)\n RSP := RSP + SRC;\n FI;\n FI;\nFI;\nIF ShadowStackEnabled(CPL)\n IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)\n THEN #CP(FAR-RET/IRET); FI;\n IF CSBASE + RIP != tempSsLIP (* 64 bit compare *)\n THEN #CP(FAR-RET/IRET); FI;\n IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)\n THEN #CP(FAR-RET/IRET); FI;\n IF (CS.L = 0 AND tempSSP[63:32] != 0) OR\n (CS.L = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n SSP := tempSSP\nFI;\nIA-32E-MODE-RETURN-TO-OUTER-PRIVILEGE-LEVEL:\nIF top (16 + SRC) bytes of stack are not within stack limits (OperandSize = 32)\nor top (8 + SRC) bytes of stack are not within stack limits (OperandSize = 16)\n THEN #SS(0); FI;\nIF top (16 + SRC) bytes of stack are not in canonical address space (OperandSize =32)\nor top (8 + SRC) bytes of stack are not in canonical address space (OperandSize = 16)\nor top (32 + SRC) bytes of stack are not in canonical address space (OperandSize = 64)\n THEN #SS(0); FI;\nRead return stack segment selector;\nIF stack segment selector is NULL\n THEN\n IF new CS descriptor L-bit = 0\n THEN #GP(selector);\n IF stack segment selector RPL = 3\n THEN #GP(selector);\nFI;\nIF return stack segment descriptor is not within descriptor table limits\n THEN #GP(selector); FI;\nIF return stack segment descriptor is in non-canonical address space\n THEN #GP(selector); FI;\nRead segment descriptor pointed to by return segment selector;\nIF stack segment selector RPL ≠ RPL of the return code segment selector\nor stack segment is not a writable data segment\nor stack segment descriptor DPL ≠ RPL of the return code segment selector\n THEN #GP(selector); FI;\nIF stack segment not present\n THEN #SS(StackSegmentSelector); FI;\nIF the return instruction pointer is not within the return code segment limit\n THEN #GP(0); FI:\nIF the return instruction pointer is not within canonical address space\n THEN #GP(0); FI;\nIF OperandSize = 32\n THEN\n EIP := Pop();\n CS := Pop(); (* 32-bit pop, high-order 16 bits discarded, segment descriptor loaded *)\n CS(RPL) := ReturnCodeSegmentSelector(RPL);\n IF instruction has immediate operand\n THEN (* Release parameters from called procedure’s stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE\n IF StackAddressSize = 16\n THEN\n SP := SP + SRC;\n ELSE (* StackAddressSize = 64 *)\n RSP := RSP + SRC;\n FI;\n FI;\n FI;\n tempESP := Pop();\n tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded, segment descriptor loaded *)\n ELSE\n IF OperandSize = 16\n THEN\n EIP := Pop();\n EIP := EIP AND 0000FFFFH;\n CS := Pop(); (* 16-bit pop; segment descriptor loaded *)\n CS(RPL) := ReturnCodeSegmentSelector(RPL);\n IF instruction has immediate operand\n THEN (* Release parameters from called procedure’s stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE\n IF StackAddressSize = 16\n THEN\n SP := SP + SRC;\n ELSE (* StackAddressSize = 64 *)\n RSP := RSP + SRC;\n FI;\n FI;\n FI;\n tempESP := Pop();\n tempSS := Pop(); (* 16-bit pop; segment descriptor loaded *)\n ELSE (* OperandSize = 64 *)\n RIP := Pop();\n CS := Pop(); (* 64-bit pop; high-order 48 bits discarded; seg. descriptor loaded *)\n CS(RPL) := ReturnCodeSegmentSelector(RPL);\n IF instruction has immediate operand\n THEN (* Release parameters from called procedure’s stack *)\n RSP := RSP + SRC;\n FI;\n tempESP := Pop();\n tempSS := Pop(); (* 64-bit pop; high-order 48 bits discarded; seg. desc. loaded *)\n FI;\nFI;\nIF ShadowStackEnabled(CPL)\n (* check if 8 byte aligned *)\n IF SSP AND 0x7 != 0\n THEN #CP(FAR-RET/IRET); FI;\n IF ReturnCodeSegmentSelector(RPL) !=3\n THEN\n tempSsCS = shadow_stack_load 8 bytes from SSP+16;\n tempSsLIP = shadow_stack_load 8 bytes from SSP+8;\n tempSSP = shadow_stack_load 8 bytes from SSP;\n SSP = SSP + 24;\n (* Do 64 bit compare to detect bits beyond 15 being set *)\n tempCS = CS; (* zero padded to 64 bit *)\n IF tempCS != tempSsCS\n THEN #CP(FAR-RET/IRET); FI;\n (* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)\n IF CSBASE + RIP != tempSsLIP\n THEN #CP(FAR-RET/IRET); FI;\n (* check if 4 byte aligned *)\n IF tempSSP AND 0x3 != 0\n THEN #CP(FAR-RET/IRET); FI;\n FI;\nFI;\ntempOldCPL = CPL;\nCPL := ReturnCodeSegmentSelector(RPL);\nESP := tempESP;\nSS := tempSS;\ntempOldSSP = SSP;\nIF ShadowStackEnabled(CPL)\n IF CPL = 3\n THEN tempSSP := IA32_PL3_SSP; FI;\n IF (CS.L = 0 AND tempSSP[63:32] != 0) OR\n (CS.L = 1 AND tempSSP is not canonical relative to the current paging mode)\n THEN #GP(0); FI;\n SSP := tempSSP\nFI;\n(* Now past all faulting points; safe to free the token. The token free is done using the old SSP\n* and using a supervisor override as old CPL was a supervisor privilege level *)\nIF ShadowStackEnabled(tempOldCPL)\n expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)\n new_token_value = tempOldSSP (* clear the busy bit *)\n shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)\nFI;\nFOR each of segment register (ES, FS, GS, and DS)\n DO\n IF segment register points to data or non-conforming code segment\n and CPL > segment descriptor DPL; (* DPL in hidden part of segment register *)\n THEN SegmentSelector := 0; (* SegmentSelector invalid *)\n FI;\n OD;\nIF instruction has immediate operand\n THEN (* Release parameters from calling procedure’s stack *)\n IF StackAddressSize = 32\n THEN\n ESP := ESP + SRC;\n ELSE\n IF StackAddressSize = 16\n THEN\n SP := SP + SRC;\n ELSE (* StackAddressSize = 64 *)\n RSP := RSP + SRC;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/ret" + }, + "rol": { + "instruction": "ROL", + "title": "RCL/RCR/ROL/ROR\n\t\t— Rotate", + "opcode": "D0 /0", + "description": "Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the second operand (count operand) and stores the result in the destination operand. The destination operand can be a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W = 1).\nThe rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit positions, except for the most-significant bit, which is rotated to the least-significant bit location. The rotate right (ROR) and rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except for the least-significant bit, which is rotated to the most-significant bit location.\nThe RCL and RCR instructions include the CF flag in the rotation. The RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag. The RCR instruction shifts the CF flag into the most-significant bit and shifts the least-significant bit into the CF flag. For the ROL and ROR instructions, the original value of the CF flag is not a part of the result, but the CF flag receives a copy of the bit that was shifted from one end to the other.\nThe OF flag is defined only for the 1-bit rotates; it is undefined in all other cases (except RCL and RCR instructions only: a zero-bit rotate does nothing, that is affects no flags). For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result. For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Use of REX.W promotes the first operand to 64 bits and causes the count operand to become a 6-bit counter.", + "operation": "SIZE := OperandSize;\nCASE (determine count) OF\n SIZE := 8:\n tempCOUNT := (COUNT AND 1FH) MOD 9;\n SIZE := 16:\n tempCOUNT := (COUNT AND 1FH) MOD 17;\n SIZE := 32:\n tempCOUNT := COUNT AND 1FH;\n SIZE := 64:\n tempCOUNT := COUNT AND 3FH;\nESAC;\nIF OperandSize = 64\n THEN COUNTMASK = 3FH;\n ELSE COUNTMASK = 1FH;\nFI;\n\n\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + CF;\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (CF * 2SIZE);\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := LSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (tempCF ∗ 2SIZE);\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := MSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR MSB − 1(DEST);\n ELSE OF is undefined;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rcl:rcr:rol:ror" + }, + "ror": { + "instruction": "ROR", + "title": "RCL/RCR/ROL/ROR\n\t\t— Rotate", + "opcode": "D0 /2", + "description": "Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the second operand (count operand) and stores the result in the destination operand. The destination operand can be a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W = 1).\nThe rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit positions, except for the most-significant bit, which is rotated to the least-significant bit location. The rotate right (ROR) and rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except for the least-significant bit, which is rotated to the most-significant bit location.\nThe RCL and RCR instructions include the CF flag in the rotation. The RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag. The RCR instruction shifts the CF flag into the most-significant bit and shifts the least-significant bit into the CF flag. For the ROL and ROR instructions, the original value of the CF flag is not a part of the result, but the CF flag receives a copy of the bit that was shifted from one end to the other.\nThe OF flag is defined only for the 1-bit rotates; it is undefined in all other cases (except RCL and RCR instructions only: a zero-bit rotate does nothing, that is affects no flags). For left rotates, the OF flag is set to the exclusive OR of the CF bit (after the rotate) and the most-significant bit of the result. For right rotates, the OF flag is set to the exclusive OR of the two most-significant bits of the result.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Use of REX.W promotes the first operand to 64 bits and causes the count operand to become a 6-bit counter.", + "operation": "SIZE := OperandSize;\nCASE (determine count) OF\n SIZE := 8:\n tempCOUNT := (COUNT AND 1FH) MOD 9;\n SIZE := 16:\n tempCOUNT := (COUNT AND 1FH) MOD 17;\n SIZE := 32:\n tempCOUNT := COUNT AND 1FH;\n SIZE := 64:\n tempCOUNT := COUNT AND 3FH;\nESAC;\nIF OperandSize = 64\n THEN COUNTMASK = 3FH;\n ELSE COUNTMASK = 1FH;\nFI;\n\n\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + CF;\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (CF * 2SIZE);\n CF := tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := MSB(DEST);\n DEST := (DEST ∗ 2) + tempCF;\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := LSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR CF;\n ELSE OF is undefined;\nFI;\n\n\ntempCOUNT := (COUNT & COUNTMASK) MOD SIZE\nWHILE (tempCOUNT ≠ 0)\n DO\n tempCF := LSB(SRC);\n DEST := (DEST / 2) + (tempCF ∗ 2SIZE);\n tempCOUNT := tempCOUNT – 1;\n OD;\nELIHW;\nIF (COUNT & COUNTMASK) ≠ 0\n THEN CF := MSB(DEST);\nFI;\nIF (COUNT & COUNTMASK) = 1\n THEN OF := MSB(DEST) XOR MSB − 1(DEST);\n ELSE OF is undefined;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rcl:rcr:rol:ror" + }, + "rorx": { + "instruction": "RORX", + "title": "RORX\n\t\t— Rotate Right Logical Without Affecting Flags", + "opcode": "VEX.LZ.F2.0F3A.W0 F0 /r ib RORX r32, r/m32, imm8", + "description": "Rotates the bits of second operand right by the count value specified in imm8 without affecting arithmetic flags. The RORX instruction does not read or write the arithmetic flags.\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.", + "operation": "IF (OperandSize = 32)\n y := imm8 AND 1FH;\n DEST := (SRC >> y) | (SRC << (32-y));\nELSEIF (OperandSize = 64 )\n y := imm8 AND 3FH;\n DEST := (SRC >> y) | (SRC << (64-y));\nFI;\n", + "url": "https://www.felixcloutier.com/x86/rorx" + }, + "roundpd": { + "instruction": "ROUNDPD", + "title": "ROUNDPD\n\t\t— Round Packed Double Precision Floating-Point Values", + "opcode": "66 0F 3A 09 /r ib ROUNDPD xmm1, xmm2/m128, imm8", + "description": "Round the 2 double precision floating-point values in the source operand (second operand) using the rounding mode specified in the immediate operand (third operand) and place the results in the destination operand (first operand). The rounding process rounds each input floating-point value to an integer value and returns the integer result as a double precision floating-point value.\nThe immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded values for rounding-mode field).\nThe Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before rounding.\n128-bit Legacy SSE version: The second source can be an XMM register or 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the source operand second source operand or a 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.\nRounding RC Field Description Mode Setting\nRound to 00B Rounded result is the closest to the infinitely precise result. If two values are equally close, the result is nearest (even) the even value (i.e., the integer value with the least-significant bit of zero).\nRound down 01B Rounded result is closest to but no greater than the infinitely precise result. (toward −∞)\nRound up 10B Rounded result is closest to but no less than the infinitely precise result. (toward +∞)\nRound toward 11B Rounded result is closest to but no greater in absolute value than the infinitely precise result. zero (Truncate)", + "operation": "IF (imm[2] = ‘1)\n THEN // rounding mode is determined by MXCSR.RC\n DEST[63:0] := ConvertDPFPToInteger_M(SRC[63:0]);\n DEST[127:64] := ConvertDPFPToInteger_M(SRC[127:64]);\n ELSE // rounding mode is determined by IMM8.RC\n DEST[63:0] := ConvertDPFPToInteger_Imm(SRC[63:0]);\n DEST[127:64] := ConvertDPFPToInteger_Imm(SRC[127:64]);\nFI\n\n\nDEST[63:0] := RoundToInteger(SRC[63:0]], ROUND_CONTROL)\nDEST[127:64] := RoundToInteger(SRC[127:64]], ROUND_CONTROL)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[63:0] := RoundToInteger(SRC[63:0]], ROUND_CONTROL)\nDEST[127:64] := RoundToInteger(SRC[127:64]], ROUND_CONTROL)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := RoundToInteger(SRC[63:0], ROUND_CONTROL)\nDEST[127:64] := RoundToInteger(SRC[127:64]], ROUND_CONTROL)\nDEST[191:128] := RoundToInteger(SRC[191:128]], ROUND_CONTROL)\nDEST[255:192] := RoundToInteger(SRC[255:192] ], ROUND_CONTROL)\n", + "url": "https://www.felixcloutier.com/x86/roundpd" + }, + "roundps": { + "instruction": "ROUNDPS", + "title": "ROUNDPS\n\t\t— Round Packed Single Precision Floating-Point Values", + "opcode": "66 0F 3A 08 /r ib ROUNDPS xmm1, xmm2/m128, imm8", + "description": "Round the 4 single precision floating-point values in the source operand (second operand) using the rounding mode specified in the immediate operand (third operand) and place the results in the destination operand (first operand). The rounding process rounds each input floating-point value to an integer value and returns the integer result as a single precision floating-point value.\nThe immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded values for rounding-mode field).\nThe Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before rounding.\n128-bit Legacy SSE version: The second source can be an XMM register or 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the source operand second source operand or a 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.", + "operation": "IF (imm[2] = ‘1)\n THEN // rounding mode is determined by MXCSR.RC\n DEST[31:0] := ConvertSPFPToInteger_M(SRC[31:0]);\n DEST[63:32] := ConvertSPFPToInteger_M(SRC[63:32]);\n DEST[95:64] := ConvertSPFPToInteger_M(SRC[95:64]);\n DEST[127:96] := ConvertSPFPToInteger_M(SRC[127:96]);\n ELSE // rounding mode is determined by IMM8.RC\n DEST[31:0] := ConvertSPFPToInteger_Imm(SRC[31:0]);\n DEST[63:32] := ConvertSPFPToInteger_Imm(SRC[63:32]);\n DEST[95:64] := ConvertSPFPToInteger_Imm(SRC[95:64]);\n DEST[127:96] := ConvertSPFPToInteger_Imm(SRC[127:96]);\nFI;\n\n\nDEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)\nDEST[63:32] := RoundToInteger(SRC[63:32], ROUND_CONTROL)\nDEST[95:64] := RoundToInteger(SRC[95:64]], ROUND_CONTROL)\nDEST[127:96] := RoundToInteger(SRC[127:96]], ROUND_CONTROL)\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)\nDEST[63:32] := RoundToInteger(SRC[63:32], ROUND_CONTROL)\nDEST[95:64] := RoundToInteger(SRC[95:64]], ROUND_CONTROL)\nDEST[127:96] := RoundToInteger(SRC[127:96]], ROUND_CONTROL)\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)\nDEST[63:32] := RoundToInteger(SRC[63:32], ROUND_CONTROL)\nDEST[95:64] := RoundToInteger(SRC[95:64]], ROUND_CONTROL)\nDEST[127:96] := RoundToInteger(SRC[127:96]], ROUND_CONTROL)\nDEST[159:128] := RoundToInteger(SRC[159:128]], ROUND_CONTROL)\nDEST[191:160] := RoundToInteger(SRC[191:160]], ROUND_CONTROL)\nDEST[223:192] := RoundToInteger(SRC[223:192] ], ROUND_CONTROL)\nDEST[255:224] := RoundToInteger(SRC[255:224] ], ROUND_CONTROL)\n", + "url": "https://www.felixcloutier.com/x86/roundps" + }, + "roundsd": { + "instruction": "ROUNDSD", + "title": "ROUNDSD\n\t\t— Round Scalar Double Precision Floating-Point Values", + "opcode": "66 0F 3A 0B /r ib ROUNDSD xmm1, xmm2/m64, imm8", + "description": "Round the double precision floating-point value in the lower qword of the source operand (second operand) using the rounding mode specified in the immediate operand (third operand) and place the result in the destination operand (first operand). The rounding process rounds a double precision floating-point input to an integer value and returns the integer result as a double precision floating-point value in the lowest position. The upper double precision floating-point value in the destination is retained.\nThe immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded values for rounding-mode field).\nThe Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before rounding.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:64) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.", + "operation": "IF (imm[2] = ‘1)\n THEN // rounding mode is determined by MXCSR.RC\n DEST[63:0] := ConvertDPFPToInteger_M(SRC[63:0]);\n ELSE // rounding mode is determined by IMM8.RC\n DEST[63:0] := ConvertDPFPToInteger_Imm(SRC[63:0]);\nFI;\nDEST[127:63] remains unchanged ;\n\n\nDEST[63:0] := RoundToInteger(SRC[63:0], ROUND_CONTROL)\nDEST[MAXVL-1:64] (Unmodified)\n\n\nDEST[63:0] := RoundToInteger(SRC2[63:0], ROUND_CONTROL)\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/roundsd" + }, + "roundss": { + "instruction": "ROUNDSS", + "title": "ROUNDSS\n\t\t— Round Scalar Single Precision Floating-Point Values", + "opcode": "66 0F 3A 0A /r ib ROUNDSS xmm1, xmm2/m32, imm8", + "description": "Round the single precision floating-point value in the lowest dword of the source operand (second operand) using the rounding mode specified in the immediate operand (third operand) and place the result in the destination operand (first operand). The rounding process rounds a single precision floating-point input to an integer value and returns the result as a single precision floating-point value in the lowest position. The upper three single precision floating-point values in the destination are retained.\nThe immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded values for rounding-mode field).\nThe Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before rounding.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.", + "operation": "IF (imm[2] = ‘1)\n THEN // rounding mode is determined by MXCSR.RC\n DEST[31:0] := ConvertSPFPToInteger_M(SRC[31:0]);\n ELSE // rounding mode is determined by IMM8.RC\n DEST[31:0] := ConvertSPFPToInteger_Imm(SRC[31:0]);\nFI;\nDEST[127:32] remains unchanged ;\n\n\nDEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)\nDEST[MAXVL-1:32] (Unmodified)\n\n\nDEST[31:0] := RoundToInteger(SRC2[31:0], ROUND_CONTROL)\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/roundss" + }, + "rsm": { + "instruction": "RSM", + "title": "RSM\n\t\t— Resume From System Management Mode", + "opcode": "0F AA", + "description": "Returns program control from system management mode (SMM) to the application program or operating-system procedure that was interrupted when the processor received an SMM interrupt. The processor’s state is restored from the dump created upon entering SMM. If the processor detects invalid state information during state restoration, it enters the shutdown state. The following invalid information can cause a shutdown:\nThe contents of the model-specific registers are not affected by a return from SMM.\nThe SMM state map used by RSM supports resuming processor context for non-64-bit modes and 64-bit mode.\nSee Chapter 32, “System Management Mode,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about SMM and the behavior of the RSM instruction.", + "operation": "ReturnFromSMM;\nIF (IA-32e mode supported) or (CPUID DisplayFamily_DisplayModel = 06H_0CH )\n THEN\n ProcessorState := Restore(SMMDump(IA-32e SMM STATE MAP));\n Else\n ProcessorState := Restore(SMMDump(Non-32-Bit-Mode SMM STATE MAP));\nFI\n", + "url": "https://www.felixcloutier.com/x86/rsm" + }, + "rsqrtps": { + "instruction": "RSQRTPS", + "title": "RSQRTPS\n\t\t— Compute Reciprocals of Square Roots of Packed Single Precision Floating-PointValues", + "opcode": "NP 0F 52 /r RSQRTPS xmm1, xmm2/m128", + "description": "Performs a SIMD computation of the approximate reciprocals of the square roots of the four packed single precision floating-point values in the source operand (second operand) and stores the packed single precision floating-point results in the destination operand. The source operand can be an XMM register or a 128-bit memory location. The destination operand is an XMM register. See Figure 10-5 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a SIMD single precision floating-point operation.\nThe relative error for this approximation is:\n|Relative Error| ≤ 1.5 ∗ 2−12\nThe RSQRTPS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is a 0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same sign). When a source value is a negative value (other than −0.0), a floating-point indefinite is returned. When a source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN is returned.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM register destination are unmodified.\nVEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "DEST[31:0] := APPROXIMATE(1/SQRT(SRC[31:0]))\nDEST[63:32] := APPROXIMATE(1/SQRT(SRC1[63:32]))\nDEST[95:64] := APPROXIMATE(1/SQRT(SRC1[95:64]))\nDEST[127:96] := APPROXIMATE(1/SQRT(SRC2[127:96]))\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[31:0] := APPROXIMATE(1/SQRT(SRC[31:0]))\nDEST[63:32] := APPROXIMATE(1/SQRT(SRC1[63:32]))\nDEST[95:64] := APPROXIMATE(1/SQRT(SRC1[95:64]))\nDEST[127:96] := APPROXIMATE(1/SQRT(SRC2[127:96]))\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := APPROXIMATE(1/SQRT(SRC[31:0]))\nDEST[63:32] := APPROXIMATE(1/SQRT(SRC1[63:32]))\nDEST[95:64] := APPROXIMATE(1/SQRT(SRC1[95:64]))\nDEST[127:96] := APPROXIMATE(1/SQRT(SRC2[127:96]))\nDEST[159:128] := APPROXIMATE(1/SQRT(SRC2[159:128]))\nDEST[191:160] := APPROXIMATE(1/SQRT(SRC2[191:160]))\nDEST[223:192] := APPROXIMATE(1/SQRT(SRC2[223:192]))\nDEST[255:224] := APPROXIMATE(1/SQRT(SRC2[255:224]))\n", + "url": "https://www.felixcloutier.com/x86/rsqrtps" + }, + "rsqrtss": { + "instruction": "RSQRTSS", + "title": "RSQRTSS\n\t\t— Compute Reciprocal of Square Root of Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F 52 /r RSQRTSS xmm1, xmm2/m32", + "description": "Computes an approximate reciprocal of the square root of the low single precision floating-point value in the source operand (second operand) stores the single precision floating-point result in the destination operand. The source operand can be an XMM register or a 32-bit memory location. The destination operand is an XMM register. The three high-order doublewords of the destination operand remain unchanged. See Figure 10-6 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a scalar single precision floating-point operation.\nThe relative error for this approximation is:\n|Relative Error| ≤ 1.5 ∗ 2−12\nThe RSQRTSS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is a 0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same sign). When a source value is a negative value (other than −0.0), a floating-point indefinite is returned. When a source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN is returned.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers (XMM8-XMM15).\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.", + "operation": "DEST[31:0] := APPROXIMATE(1/SQRT(SRC2[31:0]))\nDEST[MAXVL-1:32] (Unmodified)\n\n\nDEST[31:0] := APPROXIMATE(1/SQRT(SRC2[31:0]))\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/rsqrtss" + }, + "rstorssp": { + "instruction": "RSTORSSP", + "title": "RSTORSSP\n\t\t— Restore Saved Shadow Stack Pointer", + "opcode": "F3 0F 01 /5 (mod!=11, /5, memory only) RSTORSSP m64", + "description": "Restores SSP from the shadow-stack-restore token pointed to by m64. If the SSP restore was successful then the instruction replaces the shadow-stack-restore token with a previous-ssp token. The instruction sets the CF flag to indicate whether the SSP address recorded in the shadow-stack-restore token that was processed was 4 byte aligned, i.e., whether an alignment hole was created when the restore-shadow-stack token was pushed on this shadow stack.\nFollowing RSTORSSP if a restore-shadow-stack token needs to be saved on the previous shadow stack, use the SAVEPREVSSP instruction.\nIf pushing a restore-shadow-stack token on the previous shadow stack is not required, the previous-ssp token can be popped using the INCSSPQ instruction. If the CF flag was set to indicate presence of an alignment hole, an additional INCSSPD instruction is needed to advance the SSP past the alignment hole.", + "operation": "IF CPL = 3\n IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nELSE\n IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nFI;\nSSP_LA = Linear_Address(mem operand)\nIF SSP_LA not aligned to 8 bytes\n THEN #GP(0); FI;\nprevious_ssp_token = SSP | (IA32_EFER.LMA AND CS.L) | 0x02\nStart Atomic Execution\nrestore_ssp_token = Locked shadow_stack_load 8 bytes from SSP_LA\nfault = 0\nIF ((restore_ssp_token & 0x03) != (IA32_EFER.LMA & CS.L))\n THEN fault = 1; FI; (* If L flag in token does not match IA32_EFER.LMA & CS.L or bit 1 is not 0 *)\nIF ((IA32_EFER.LMA AND CS.L) = 0 AND restore_ssp_token[63:32] != 0)\n THEN fault = 1; FI; (* If compatibility/legacy mode and SSP to be restored not below 4G *)\nTMP = restore_ssp_token & ~0x01\nTMP = (TMP - 8)\nTMP = TMP & ~0x07\nIF TMP != SSP_LA\n THEN fault = 1; FI; (* If address in token does not match the requested top of stack *)\nTMP = (fault == 0) ? previous_ssp_token : restore_ssp_token\nshadow_stack_store 8 bytes of TMP to SSP_LA and release lock\nEnd Atomic Execution\nIF fault == 1\n THEN #CP(RSTORSSP); FI;\nSSP = SSP_LA\n// Set the CF if the SSP in the restore token was 4 byte aligned, i.e., there is an alignment hole\nRFLAGS.CF = (restore_ssp_token & 0x04) ? 1 : 0;\nRFLAGS.ZF,PF,AF,OF,SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/rstorssp" + }, + "sahf": { + "instruction": "SAHF", + "title": "SAHF\n\t\t— Store AH Into Flags", + "opcode": "9E", + "description": "Loads the SF, ZF, AF, PF, and CF flags of the EFLAGS register with values from the corresponding bits in the AH register (bits 7, 6, 4, 2, and 0, respectively). Bits 1, 3, and 5 of register AH are ignored; the corresponding reserved bits (1, 3, and 5) in the EFLAGS register remain as shown in the “Operation” section below.\nThis instruction executes as described above in compatibility mode and legacy mode. It is valid in 64-bit mode only if CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1.", + "operation": "IF IA-64 Mode\n THEN\n IF CPUID.80000001H.ECX[0] = 1;\n THEN\n RFLAGS(SF:ZF:0:AF:0:PF:1:CF) := AH;\n ELSE\n #UD;\n FI\n ELSE\n EFLAGS(SF:ZF:0:AF:0:PF:1:CF) := AH;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sahf" + }, + "sal": { + "instruction": "SAL", + "title": "SAL/SAR/SHL/SHR\n\t\t— Shift", + "opcode": "D0 /4", + "description": "Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination operand.\nThe destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits with a 64-bit operand). The count range is limited to 0 to 31 (or 63 with a 64-bit operand). A special opcode encoding is provided for a count of 1.\nThe shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the bits in the destination operand to the left (toward more significant bit locations). For each shift count, the most significant bit of the destination operand is shifted into the CF flag, and the least significant bit is cleared (see Figure 7-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to the right (toward less significant bit locations). For each shift count, the least significant bit of the destination operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction type. The SHR instruction clears the most significant bit (see Figure 7-8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most significant bit to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR instruction fills the empty bit position’s shifted value with the sign of the unshifted value (see Figure 7-9 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination operand by powers of 2. For example, using the SAR instruction to shift a signed integer 1 bit to the right divides the value by 2.\nUsing the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction. The quotient from the IDIV instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is rounded toward negative infinity. This difference is apparent only for negative numbers. For example, when the IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1. If the SAR instruction is used to shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores only the most significant bit of the remainder (in the CF flag).\nThe OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1. For the SAR instruction, the OF flag is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set to the most-significant bit of the original operand.\nIn 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64-bits and sets the mask width for CL to 6 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 64\n THEN\n countMASK := 3FH;\n ELSE\n countMASK := 1FH;\nFI\ntempCOUNT := (COUNT AND countMASK);\ntempDEST := DEST;\nWHILE (tempCOUNT ≠ 0)\nDO\n IF instruction is SAL or SHL\n THEN\n CF := MSB(DEST);\n ELSE (* Instruction is SAR or SHR *)\n CF := LSB(DEST);\n FI;\n IF instruction is SAL or SHL\n THEN\n DEST := DEST ∗ 2;\n ELSE\n IF instruction is SAR\n THEN\n DEST := DEST / 2; (* Signed divide, rounding toward negative infinity *)\n ELSE (* Instruction is SHR *)\n DEST := DEST / 2 ; (* Unsigned divide *)\n FI;\n FI;\n tempCOUNT := tempCOUNT – 1;\nOD;\n(* Determine overflow for the various instructions *)\nIF (COUNT and countMASK) = 1\n THEN\n IF instruction is SAL or SHL\n THEN\n OF := MSB(DEST) XOR CF;\n ELSE\n IF instruction is SAR\n THEN\n OF := 0;\n ELSE (* Instruction is SHR *)\n OF := MSB(tempDEST);\n FI;\n FI;\n ELSE IF (COUNT AND countMASK) = 0\n THEN\n All flags unchanged;\n ELSE (* COUNT not 1 or 0 *)\n OF := undefined;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sal:sar:shl:shr" + }, + "sar": { + "instruction": "SAR", + "title": "SAL/SAR/SHL/SHR\n\t\t— Shift", + "opcode": "D0 /7", + "description": "Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination operand.\nThe destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits with a 64-bit operand). The count range is limited to 0 to 31 (or 63 with a 64-bit operand). A special opcode encoding is provided for a count of 1.\nThe shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the bits in the destination operand to the left (toward more significant bit locations). For each shift count, the most significant bit of the destination operand is shifted into the CF flag, and the least significant bit is cleared (see Figure 7-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to the right (toward less significant bit locations). For each shift count, the least significant bit of the destination operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction type. The SHR instruction clears the most significant bit (see Figure 7-8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most significant bit to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR instruction fills the empty bit position’s shifted value with the sign of the unshifted value (see Figure 7-9 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination operand by powers of 2. For example, using the SAR instruction to shift a signed integer 1 bit to the right divides the value by 2.\nUsing the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction. The quotient from the IDIV instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is rounded toward negative infinity. This difference is apparent only for negative numbers. For example, when the IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1. If the SAR instruction is used to shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores only the most significant bit of the remainder (in the CF flag).\nThe OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1. For the SAR instruction, the OF flag is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set to the most-significant bit of the original operand.\nIn 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64-bits and sets the mask width for CL to 6 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 64\n THEN\n countMASK := 3FH;\n ELSE\n countMASK := 1FH;\nFI\ntempCOUNT := (COUNT AND countMASK);\ntempDEST := DEST;\nWHILE (tempCOUNT ≠ 0)\nDO\n IF instruction is SAL or SHL\n THEN\n CF := MSB(DEST);\n ELSE (* Instruction is SAR or SHR *)\n CF := LSB(DEST);\n FI;\n IF instruction is SAL or SHL\n THEN\n DEST := DEST ∗ 2;\n ELSE\n IF instruction is SAR\n THEN\n DEST := DEST / 2; (* Signed divide, rounding toward negative infinity *)\n ELSE (* Instruction is SHR *)\n DEST := DEST / 2 ; (* Unsigned divide *)\n FI;\n FI;\n tempCOUNT := tempCOUNT – 1;\nOD;\n(* Determine overflow for the various instructions *)\nIF (COUNT and countMASK) = 1\n THEN\n IF instruction is SAL or SHL\n THEN\n OF := MSB(DEST) XOR CF;\n ELSE\n IF instruction is SAR\n THEN\n OF := 0;\n ELSE (* Instruction is SHR *)\n OF := MSB(tempDEST);\n FI;\n FI;\n ELSE IF (COUNT AND countMASK) = 0\n THEN\n All flags unchanged;\n ELSE (* COUNT not 1 or 0 *)\n OF := undefined;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sal:sar:shl:shr" + }, + "sarx": { + "instruction": "SARX", + "title": "SARX/SHLX/SHRX\n\t\t— Shift Without Affecting Flags", + "opcode": "VEX.LZ.F3.0F38.W0 F7 /r SARX r32a, r/m32, r32b", + "description": "Shifts the bits of the first source operand (the second operand) to the left or right by a COUNT value specified in the second source operand (the third operand). The result is written to the destination operand (the first operand).\nThe shift arithmetic right (SARX) and shift logical right (SHRX) instructions shift the bits of the destination operand to the right (toward less significant bit locations), SARX keeps and propagates the most significant bit (sign bit) while shifting.\nThe logical shift left (SHLX) shifts the bits of the destination operand to the left (toward more significant bit locations).\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.\nIf the value specified in the first source operand exceeds OperandSize -1, the COUNT value is masked.\nSARX,SHRX, and SHLX instructions do not update flags.", + "operation": "TEMP := SRC1;\nIF VEX.W1 and CS.L = 1\nTHEN\n countMASK := 3FH;\nELSE\n countMASK := 1FH;\nFI\nCOUNT := (SRC2 AND countMASK)\nDEST[OperandSize -1] = TEMP[OperandSize -1];\nDO WHILE (COUNT ≠ 0)\n IF instruction is SHLX\n THEN\n DEST[] := DEST *2;\n ELSE IF instruction is SHRX\n THEN\n DEST[] := DEST /2; //unsigned divide\n ELSE // SARX\n DEST[] := DEST /2; // signed divide, round toward negative infinity\n FI;\n COUNT := COUNT - 1;\nOD\n", + "url": "https://www.felixcloutier.com/x86/sarx:shlx:shrx" + }, + "saveprevssp": { + "instruction": "SAVEPREVSSP", + "title": "SAVEPREVSSP\n\t\t— Save Previous Shadow Stack Pointer", + "opcode": "F3 0F 01 EA (mod!=11, /5, RM=010) SAVEPREVSSP", + "description": "Push a restore-shadow-stack token on the previous shadow stack at the next 8 byte aligned boundary. The previous SSP is obtained from the previous-ssp token at the top of the current shadow stack.", + "operation": "IF CPL = 3\n IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nELSE\n IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0\n THEN #UD; FI;\nFI;\nIF SSP not aligned to 8 bytes\n THEN #GP(0); FI;\n(* Pop the “previous-ssp” token from current shadow stack *)\nprevious_ssp_token = ShadowStackPop8B(SSP)\n(* If the CF flag indicates there was a alignment hole on current shadow stack then pop that alignment hole *)\n(* Note that the alignment hole must be zero and can be present only when in legacy/compatibility mode *)\nIF RFLAGS.CF == 1 AND (IA32_EFER.LMA AND CS.L)\n #GP(0)\nFI;\nIF RFLAGS.CF == 1\n must_be_zero = ShadowStackPop4B(SSP)\n IF must_be_zero != 0 THEN #GP(0)\nFI;\n(* Previous SSP token must have the bit 1 set *)\nIF ((previous_ssp_token & 0x02) == 0)\n THEN #GP(0); (* bit 1 was 0 *)\nIF ((IA32_EFER.LMA AND CS.L) = 0 AND previous_ssp_token [63:32] != 0)\nTHEN #GP(0); FI; (* If compatibility/legacy mode and SSP not in 4G *)\n(* Save Prev SSP from previous_ssp_token to the old shadow stack at next 8 byte aligned address *)\nold_SSP = previous_ssp_token & ~0x03\ntemp := (old_SSP | (IA32_EFER.LMA & CS.L));\nShadow_stack_store 4 bytes of 0 to (old_SSP - 4)\nold_SSP := old_SSP & ~0x07;\nShadow_stack_store 8 bytes of temp to (old_SSP - 8)\n", + "url": "https://www.felixcloutier.com/x86/saveprevssp" + }, + "sbb": { + "instruction": "SBB", + "title": "SBB\n\t\t— Integer Subtraction With Borrow", + "opcode": "1C ib", + "description": "Adds the source operand (second operand) and the carry (CF) flag, and subtracts the result from the destination operand (first operand). The result of the subtraction is stored in the destination operand. The destination operand can be a register or a memory location; the source operand can be an immediate, a register, or a memory location.\n(However, two memory operands cannot be used in one instruction.) The state of the CF flag represents a borrow from a previous subtraction.\nWhen an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.\nThe SBB instruction does not distinguish between signed or unsigned operands. Instead, the processor evaluates the result for both data types and sets the OF and CF flags to indicate a borrow in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.\nThe SBB instruction is usually executed as part of a multibyte or multiword subtraction in which a SUB instruction is followed by a SBB instruction.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := (DEST – (SRC + CF));\n", + "url": "https://www.felixcloutier.com/x86/sbb" + }, + "scas": { + "instruction": "SCAS", + "title": "SCAS/SCASB/SCASW/SCASD\n\t\t— Scan String", + "opcode": "AE", + "description": "In non-64-bit modes and in default 64-bit mode: this instruction compares a byte, word, doubleword or quadword specified using a memory operand with the value in AL, AX, or EAX. It then sets status flags in EFLAGS recording the results. The memory operand address is read from ES:(E)DI register (depending on the address-size attribute of the instruction and the current operational mode). Note that ES cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed. The explicit-operand form and the no-operands form. The explicit-operand form (specified using the SCAS mnemonic) allows a memory operand to be specified explicitly. The memory operand must be a symbol that indicates the size and location of the operand value. The register operand is then automatically selected to match the size of the memory operand (AL register for byte comparisons, AX for word comparisons, EAX for doubleword comparisons). The explicit-operand form is provided to allow documentation. Note that the documentation provided by this form can be misleading. That is, the memory operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword) but it does not have to specify the correct location. The location is always specified by ES:(E)DI.\nThe no-operands form of the instruction uses a short form of SCAS. Again, ES:(E)DI is assumed to be the memory operand and AL, AX, or EAX is assumed to be the register operand. The size of operands is selected by the mnemonic: SCASB (byte comparison), SCASW (word comparison), or SCASD (doubleword comparison).\nAfter the comparison, the (E)DI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented. The register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nSCAS, SCASB, SCASW, SCASD, and SCASQ can be preceded by the REP prefix for block comparisons of ECX bytes, words, doublewords, or quadwords. Often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of status flags. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64-bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The 64-bit no-operand mnemonic is SCASQ. Address of the memory operand is specified in either RDI or EDI, and AL/AX/EAX/RAX may be used as the register operand. After a comparison, the destination register is incremented or decremented by the current operand size (depending on the value of the DF flag). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\n\n\nIF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4; FI;\n FI;\n ELSE IF (Quadword comparison using REX.W )\n THEN\n temp := RAX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/scas:scasb:scasw:scasd" + }, + "scasb": { + "instruction": "SCASB", + "title": "SCAS/SCASB/SCASW/SCASD\n\t\t— Scan String", + "opcode": "AE", + "description": "In non-64-bit modes and in default 64-bit mode: this instruction compares a byte, word, doubleword or quadword specified using a memory operand with the value in AL, AX, or EAX. It then sets status flags in EFLAGS recording the results. The memory operand address is read from ES:(E)DI register (depending on the address-size attribute of the instruction and the current operational mode). Note that ES cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed. The explicit-operand form and the no-operands form. The explicit-operand form (specified using the SCAS mnemonic) allows a memory operand to be specified explicitly. The memory operand must be a symbol that indicates the size and location of the operand value. The register operand is then automatically selected to match the size of the memory operand (AL register for byte comparisons, AX for word comparisons, EAX for doubleword comparisons). The explicit-operand form is provided to allow documentation. Note that the documentation provided by this form can be misleading. That is, the memory operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword) but it does not have to specify the correct location. The location is always specified by ES:(E)DI.\nThe no-operands form of the instruction uses a short form of SCAS. Again, ES:(E)DI is assumed to be the memory operand and AL, AX, or EAX is assumed to be the register operand. The size of operands is selected by the mnemonic: SCASB (byte comparison), SCASW (word comparison), or SCASD (doubleword comparison).\nAfter the comparison, the (E)DI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented. The register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nSCAS, SCASB, SCASW, SCASD, and SCASQ can be preceded by the REP prefix for block comparisons of ECX bytes, words, doublewords, or quadwords. Often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of status flags. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64-bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The 64-bit no-operand mnemonic is SCASQ. Address of the memory operand is specified in either RDI or EDI, and AL/AX/EAX/RAX may be used as the register operand. After a comparison, the destination register is incremented or decremented by the current operand size (depending on the value of the DF flag). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\n\n\nIF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4; FI;\n FI;\n ELSE IF (Quadword comparison using REX.W )\n THEN\n temp := RAX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/scas:scasb:scasw:scasd" + }, + "scasd": { + "instruction": "SCASD", + "title": "SCAS/SCASB/SCASW/SCASD\n\t\t— Scan String", + "opcode": "AF", + "description": "In non-64-bit modes and in default 64-bit mode: this instruction compares a byte, word, doubleword or quadword specified using a memory operand with the value in AL, AX, or EAX. It then sets status flags in EFLAGS recording the results. The memory operand address is read from ES:(E)DI register (depending on the address-size attribute of the instruction and the current operational mode). Note that ES cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed. The explicit-operand form and the no-operands form. The explicit-operand form (specified using the SCAS mnemonic) allows a memory operand to be specified explicitly. The memory operand must be a symbol that indicates the size and location of the operand value. The register operand is then automatically selected to match the size of the memory operand (AL register for byte comparisons, AX for word comparisons, EAX for doubleword comparisons). The explicit-operand form is provided to allow documentation. Note that the documentation provided by this form can be misleading. That is, the memory operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword) but it does not have to specify the correct location. The location is always specified by ES:(E)DI.\nThe no-operands form of the instruction uses a short form of SCAS. Again, ES:(E)DI is assumed to be the memory operand and AL, AX, or EAX is assumed to be the register operand. The size of operands is selected by the mnemonic: SCASB (byte comparison), SCASW (word comparison), or SCASD (doubleword comparison).\nAfter the comparison, the (E)DI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented. The register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nSCAS, SCASB, SCASW, SCASD, and SCASQ can be preceded by the REP prefix for block comparisons of ECX bytes, words, doublewords, or quadwords. Often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of status flags. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64-bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The 64-bit no-operand mnemonic is SCASQ. Address of the memory operand is specified in either RDI or EDI, and AL/AX/EAX/RAX may be used as the register operand. After a comparison, the destination register is incremented or decremented by the current operand size (depending on the value of the DF flag). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\n\n\nIF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4; FI;\n FI;\n ELSE IF (Quadword comparison using REX.W )\n THEN\n temp := RAX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/scas:scasb:scasw:scasd" + }, + "scasw": { + "instruction": "SCASW", + "title": "SCAS/SCASB/SCASW/SCASD\n\t\t— Scan String", + "opcode": "AF", + "description": "In non-64-bit modes and in default 64-bit mode: this instruction compares a byte, word, doubleword or quadword specified using a memory operand with the value in AL, AX, or EAX. It then sets status flags in EFLAGS recording the results. The memory operand address is read from ES:(E)DI register (depending on the address-size attribute of the instruction and the current operational mode). Note that ES cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of this instruction are allowed. The explicit-operand form and the no-operands form. The explicit-operand form (specified using the SCAS mnemonic) allows a memory operand to be specified explicitly. The memory operand must be a symbol that indicates the size and location of the operand value. The register operand is then automatically selected to match the size of the memory operand (AL register for byte comparisons, AX for word comparisons, EAX for doubleword comparisons). The explicit-operand form is provided to allow documentation. Note that the documentation provided by this form can be misleading. That is, the memory operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword) but it does not have to specify the correct location. The location is always specified by ES:(E)DI.\nThe no-operands form of the instruction uses a short form of SCAS. Again, ES:(E)DI is assumed to be the memory operand and AL, AX, or EAX is assumed to be the register operand. The size of operands is selected by the mnemonic: SCASB (byte comparison), SCASW (word comparison), or SCASD (doubleword comparison).\nAfter the comparison, the (E)DI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented. The register is incremented or decremented by 1 for byte operations, by 2 for word operations, and by 4 for doubleword operations.\nSCAS, SCASB, SCASW, SCASD, and SCASQ can be preceded by the REP prefix for block comparisons of ECX bytes, words, doublewords, or quadwords. Often, however, these instructions will be used in a LOOP construct that takes some action based on the setting of status flags. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.\nIn 64-bit mode, the instruction’s default address size is 64-bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The 64-bit no-operand mnemonic is SCASQ. Address of the memory operand is specified in either RDI or EDI, and AL/AX/EAX/RAX may be used as the register operand. After a comparison, the destination register is incremented or decremented by the current operand size (depending on the value of the DF flag). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4; FI;\n FI;\nFI;\n\n\nIF (Byte comparison)\n THEN\n temp := AL − SRC;\n SetStatusFlags(temp);\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1; FI;\n ELSE IF (Word comparison)\n THEN\n temp := AX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2; FI;\n FI;\n ELSE IF (Doubleword comparison)\n THEN\n temp := EAX – SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4; FI;\n FI;\n ELSE IF (Quadword comparison using REX.W )\n THEN\n temp := RAX − SRC;\n SetStatusFlags(temp);\n IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/scas:scasb:scasw:scasd" + }, + "senduipi": { + "instruction": "SENDUIPI", + "title": "SENDUIPI\n\t\t— Send User Interprocessor Interrupt", + "opcode": "F3 0F C7 /6 SENDUIPI reg", + "description": "The SENDUIPI instruction sends the user interprocessor interrupt (IPI) indicated by its register operand. (The operand always has 64 bits; operand-size overrides such as the prefix 66 are ignored.)\nSENDUIPI uses a data structure called the user-interrupt target table (UITT). This table is located at the linear address UITTADDR (in the IA32_UINTR_TT MSR); it comprises UITTSZ+1 16-byte entries, where UITTSZ = IA32_UINT_MISC[31:0]. SENDUIPI uses the UITT entry (UITTE) indexed by the instruction's register operand. Each UITTE has the following format:\nEach UPID has the following format (fields and bits not referenced are reserved):\nAlthough SENDUIPI may be executed at any privilege level, all of the instruction’s memory accesses (to a UITTE and a UPID) are performed with supervisor privilege.\nSENDUIPI sends a user interrupt by posting a user interrupt with vector V in the UPID referenced by UPIDADDR and then sending, as an ordinary IPI, any notification interrupt specified in that UPID.", + "operation": "IF reg > UITTSZ;\n THEN #GP(0);\nFI;\nread tempUITTE from 16 bytes at UITTADDR+ (reg « 4);\nIF tempUITTE.V = 0 or tempUITTE sets any reserved bit\n THEN #GP(0);\nFI;\nread tempUPID from 16 bytes at tempUITTE.UPIDADDR;// under lock\nIF tempUPID sets any reserved bits or bits that must be zero\n THEN #GP(0); // release lock\nFI;\ntempUPID.PIR[tempUITTE.UV] := 1;\nIF tempUPID.SN = tempUPID.ON = 0\n THEN\n tempUPID.ON := 1;\n sendNotify := 1;\n ELSE sendNotify := 0;\nFI;\nwrite tempUPID to 16 bytes at tempUITTE.UPIDADDR;// release lock\nIF sendNotify = 1\n THEN\n IF local APIC is in x2APIC mode\n THEN send ordinary IPI with vector tempUPID.NV\n to 32-bit physical APIC ID tempUPID.NDST;\n ELSE send ordinary IPI with vector tempUPID.NV\n to 8-bit physical APIC ID tempUPID.NDST[15:8];\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/senduipi" + }, + "senter": { + "instruction": "SENTER", + "title": "GETSEC[SENTER]\n\t\t— Enter a Measured Environment", + "opcode": "NP 0F 37 (EAX=4)", + "description": "The GETSEC[SENTER] instruction initiates the launch of a measured environment and places the initiating logical processor (ILP) into the authenticated code execution mode. The SENTER leaf of GETSEC is selected with EAX set to 4 at execution. The physical base address of the AC module to be loaded and authenticated is specified in EBX. The size of the module in bytes is specified in ECX. EDX controls the level of functionality supported by the measured environment launch. To enable the full functionality of the protected environment launch, EDX must be initialized to zero.\nThe authenticated code base address and size parameters (in bytes) are passed to the GETSEC[SENTER] instruction using EBX and ECX respectively. The ILP evaluates the contents of these registers according to the rules for the AC module address in GETSEC[ENTERACCS]. AC module execution follows the same rules, as set by GETSEC[ENTERACCS].\nThe launching software must ensure that the TPM.ACCESS_0.activeLocality bit is clear before executing the GETSEC[SENTER] instruction.\nThere are restrictions enforced by the processor for execution of the GETSEC[SENTER] instruction:\nFailure to abide by the above conditions results in the processor signaling a general protection violation.\nThis instruction leaf starts the launch of a measured environment by initiating a rendezvous sequence for all logical processors in the platform. The rendezvous sequence involves the initiating logical processor sending a message (by executing GETSEC[SENTER]) and other responding logical processors (RLPs) acknowledging the message, thus synchronizing the RLP(s) with the ILP.\nIn response to a message signaling the completion of rendezvous, RLPs clear the bootstrap processor indicator flag (IA32_APIC_BASE.BSP) and enter an SENTER sleep state. In this sleep state, RLPs enter an idle processor condition while waiting to be activated after a measured environment has been established by the system executive. RLPs in the SENTER sleep state can only be activated by the GETSEC leaf function WAKEUP in a measured environment.\nA successful launch of the measured environment results in the initiating logical processor entering the authenticated code execution mode. Prior to reaching this point, the ILP performs the following steps internally:\nAs an integrity check for proper processor hardware operation, execution of GETSEC[SENTER] will also check the contents of all the machine check status registers (as reported by the MSRs IA32_MCi_STATUS) for any valid uncorrectable error condition. In addition, the global machine check status register IA32_MCG_STATUS MCIP bit must be cleared and the IERR processor package pin (or its equivalent) must be not asserted, indicating that no machine check exception processing is currently in-progress. These checks are performed twice: once by the ILP prior to the broadcast of the rendezvous message to RLPs, and later in response to RLPs acknowledging the rendezvous message. Any outstanding valid uncorrectable machine check error condition present in the machine check status registers at the first check point will result in the ILP signaling a general protection violation. If an outstanding valid uncorrectable machine check error condition is present at the second check point, then this will result in the corresponding logical processor signaling the more severe TXT-shutdown condition with an error code of 12.\nBefore loading and authentication of the target code module is performed, the processor also checks that the current voltage and bus ratio encodings correspond to known good values supportable by the processor. The MSR IA32_PERF_STATUS values are compared against either the processor supported maximum operating target setting, system reset setting, or the thermal monitor operating target. If the current settings do not meet any of these criteria then the SENTER function will attempt to change the voltage and bus ratio select controls in a processor-specific manner. This adjustment may be to the thermal monitor, minimum (if different), or maximum operating target depending on the processor.\nThis implies that some thermal operating target parameters configured by BIOS may be overridden by SENTER. The measured environment software may need to take responsibility for restoring such settings that are deemed to be safe, but not necessarily recognized by SENTER. If an adjustment is not possible when an out of range setting is discovered, then the processor will abort the measured launch. This may be the case for chipset controlled settings of these values or if the controllability is not enabled on the processor. In this case it is the responsibility of the external software to program the chipset voltage ID and/or bus ratio select settings to known good values recognized by the processor, prior to executing SENTER.\nThe ILP and RLPs mask the response to the assertion of the external signals INIT#, A20M, NMI#, and SMI#. The purpose of this masking control is to prevent exposure to existing external event handlers until a protected handler has been put in place to directly handle these events. Masked external pin events may be unmasked conditionally or unconditionally via the GETSEC[EXITAC], GETSEC[SEXIT], GETSEC[SMCTRL] or for specific VMX related operations such as a VM entry or the VMXOFF instruction (see respective GETSEC leaves and Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more details). The state of the A20M pin is masked and forced internally to a de-asserted state so that external assertion is not recognized. A20M masking as set by\nGETSEC[SENTER] is undone only after taking down the measured environment with the GETSEC[SEXIT] instruction or processor reset. INTR is masked by simply clearing the EFLAGS.IF bit. It is the responsibility of system software to control the processor response to INTR through appropriate management of EFLAGS.\nTo prevent other (logical) processors from interfering with the ILP operating in authenticated code execution mode, memory (excluding implicit write-back transactions) and I/O activities originating from other processor agents are blocked. This protection starts when the ILP enters into authenticated code execution mode. Only memory and I/O transactions initiated from the ILP are allowed to proceed. Exiting authenticated code execution mode is done by executing GETSEC[EXITAC]. The protection of memory and I/O activities remains in effect until the ILP executes GETSEC[EXITAC].\nOnce the authenticated code module has been loaded into the authenticated code execution area, it is protected against further modification from external bus snoops. There is also a requirement that the memory type for the authenticated code module address range be WB (via initialization of the MTRRs prior to execution of this instruction). If this condition is not satisfied, it is a violation of security and the processor will force a TXT system reset (after writing an error code to the chipset LT.ERRORCODE register). This action is referred to as a Intel® TXT reset condition. It is performed when it is considered unreliable to signal an error through the conventional exception reporting mechanism.\nTo conform to the minimum granularity of MTRR MSRs for specifying the memory type, authenticated code RAM (ACRAM) is allocated to the processor in 4096 byte granular blocks. If an AC module size as specified in ECX is not a multiple of 4096 then the processor will allocate up to the next 4096 byte boundary for mapping as ACRAM with indeterminate data. This pad area will not be visible to the authenticated code module as external memory nor can it depend on the value of the data used to fill the pad area.\nOnce successful authentication has been completed by the ILP, the computed hash is stored in a trusted storage facility in the platform. The following trusted storage facility are supported:\nAfter successful execution of SENTER, either PCR17 (if FTM is not enabled) or the FTM (if enabled) contains the measurement of AC code and the SENTER launching parameters.\nAfter authentication is completed successfully, the private configuration space of the Intel® TXT-capable chipset is unlocked so that the authenticated code module and measured environment software can gain access to this normally restricted chipset state. The Intel® TXT-capable chipset private configuration space can be locked later by software writing to the chipset LT.CMD.CLOSE-PRIVATE register or unconditionally using the GETSEC[SEXIT] instruction.\nThe SENTER leaf function also initializes some processor architecture state for the ILP from contents held in the header of the authenticated code module. Since the authenticated code module is relocatable, all address references are relative to the base address passed in via EBX. The ILP GDTR base value is initialized to EBX + [GDTBasePtr] and GDTR limit set to [GDTLimit]. The CS selector is initialized to the value held in the AC module header field SegSel, while the DS, SS, and ES selectors are initialized to CS+8. The segment descriptor fields are initialized implicitly with BASE=0, LIMIT=FFFFFh, G=1, D=1, P=1, S=1, read/write/accessed for DS, SS, and ES, while execute/read/accessed for CS. Execution in the authenticated code module for the ILP begins with the EIP set to EBX + [EntryPoint]. AC module defined fields used for initializing processor state are consistency checked with a failure resulting in an TXT-shutdown condition.\nTable 7-6 provides a summary of processor state initialization for the ILP and RLP(s) after successful completion of GETSEC[SENTER]. For both ILP and RLP(s), paging is disabled upon entry to the measured environment. It is up to the ILP to establish a trusted paging environment, with appropriate mappings, to meet protection requirements established during the launch of the measured environment. RLP state initialization is not completed until a subsequent wake-up has been signaled by execution of the GETSEC[WAKEUP] function by the ILP.\nmust be reestablished with a valid machine check exception handler to otherwise avoid an TXT-shutdown under such conditions.\nThe MSR IA32_EFER is also unconditionally cleared as part of the processor state initialized by SENTER for both the ILP and RLP. Since paging is disabled upon entering authenticated code execution mode, a new paging environment will have to be re-established if it is desired to enable IA-32e mode while operating in authenticated code execution mode.\nThe miscellaneous feature control MSR, IA32_MISC_ENABLE, is initialized as part of the measured environment launch. Certain bits of this MSR are preserved because preserving these bits may be important to maintain previously established platform settings. See the footnote for Table 7-5 The remaining bits are cleared for the purpose of establishing a more consistent environment for the execution of authenticated code modules. Among the impact of initializing this MSR, any previous condition established by the MONITOR instruction will be cleared.\nEffect of MSR IA32_FEATURE_CONTROL MSR\nBits 15:8 of the IA32_FEATURE_CONTROL MSR affect the execution of GETSEC[SENTER]. These bits consist of two fields:\nThe layout of these fields in the IA32_FEATURE_CONTROL MSR is shown in Table 7-1.\nPrior to the execution of GETSEC[SENTER], the lock bit of IA32_FEATURE_CONTROL MSR must be bit set to affirm the settings to be used. Once the lock bit is set, only a power-up reset condition will clear this MSR. The IA32_FEA-TURE_CONTROL MSR must be configured in accordance to the intended usage at platform initialization. Note that this MSR is only available on SMX or VMX enabled processors. Otherwise, IA32_FEATURE_CONTROL is treated as reserved.\nThe Intel® Trusted Execution Technology Measured Launched Environment Programming Guide provides additional details and requirements for programming measured environment software to launch in an Intel TXT platform.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/senter" + }, + "serialize": { + "instruction": "SERIALIZE", + "title": "SERIALIZE\n\t\t— Serialize Instruction Execution", + "opcode": "NP 0F 01 E8 SERIALIZE", + "description": "Serializes instruction execution. Before the next instruction is fetched and executed, the SERIALIZE instruction ensures that all modifications to flags, registers, and memory by previous instructions are completed, draining all buffered writes to memory. This instruction is also a serializing instruction as defined in the section “Serializing Instructions” in Chapter 9 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nSERIALIZE does not modify registers, arithmetic flags, or memory.", + "operation": "Wait_On_Fetch_And_Execution_Of_Next_Instruction_Until(preceding_instructions_complete_and_preceding_stores_globally_visible);\n", + "url": "https://www.felixcloutier.com/x86/serialize" + }, + "setcc": { + "instruction": "SETCC", + "title": "SETcc\n\t\t— Set Byte on Condition", + "opcode": "0F 97", + "description": "Sets the destination operand to 0 or 1 depending on the settings of the status flags (CF, SF, OF, ZF, and PF) in the EFLAGS register. The destination operand points to a byte register or a byte in memory. The condition code suffix (cc) indicates the condition being tested for.\nThe terms “above” and “below” are associated with the CF flag and refer to the relationship between two unsigned integer values. The terms “greater” and “less” are associated with the SF and OF flags and refer to the relationship between two signed integer values.\nMany of the SETcc instruction opcodes have alternate mnemonics. For example, SETG (set byte if greater) and SETNLE (set if not less or equal) have the same opcode and test for the same condition: ZF equals 0 and SF equals OF. These alternate mnemonics are provided to make code more intelligible. Appendix B, “EFLAGS Condition Codes,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, shows the alternate mnemonics for various test conditions.\nSome languages represent a logical one as an integer with all bits set. This representation can be obtained by choosing the logically opposite condition for the SETcc instruction, then decrementing the result. For example, to test for overflow, use the SETNO instruction, then decrement the result.\nThe reg field of the ModR/M byte is not used for the SETCC instruction and those opcode bits are ignored by the processor.\nIn IA-64 mode, the operand size is fixed at 8 bits. Use of REX prefix enable uniform addressing to additional byte registers. Otherwise, this instruction’s operation is the same as in legacy mode and compatibility mode.", + "operation": "IF condition\n THEN DEST := 1;\n ELSE DEST := 0;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/setcc" + }, + "setssbsy": { + "instruction": "SETSSBSY", + "title": "SETSSBSY\n\t\t— Mark Shadow Stack Busy", + "opcode": "F3 0F 01 E8 SETSSBSY", + "description": "The SETSSBSY instruction verifies the presence of a non-busy supervisor shadow stack token at the address in the IA32_PL0_SSP MSR and marks it busy. Following successful execution of the instruction, the SSP is set to the value of the IA32_PL0_SSP MSR.", + "operation": "IF (CR4.CET = 0)\n THEN #UD; FI;\nIF (IA32_S_CET.SH_STK_EN = 0)\n THEN #UD; FI;\nIF CPL > 0\n THEN GP(0); FI;\nSSP_LA = IA32_PL0_SSP\nIf SSP_LA not aligned to 8 bytes\n THEN #GP(0); FI;\nexpected_token_value = SSP_LA\nnew_token_value = SSP_LA | BUSY_BIT\nIF shadow_stack_lock_cmpxchg8B(SSP_LA, new_token_value, expected_token_value) != expected_token_value\n THEN #CP(SETSSBSY); FI;\nSSP = SSP_LA\n", + "url": "https://www.felixcloutier.com/x86/setssbsy" + }, + "sexit": { + "instruction": "SEXIT", + "title": "GETSEC[SEXIT]\n\t\t— Exit Measured Environment", + "opcode": "NP 0F 37 (EAX=5)", + "description": "The GETSEC[SEXIT] instruction initiates an exit of a measured environment established by GETSEC[SENTER]. The SEXIT leaf of GETSEC is selected with EAX set to 5 at execution. This instruction leaf sends a message to all logical processors in the platform to signal the measured environment exit.\nThere are restrictions enforced by the processor for the execution of the GETSEC[SEXIT] instruction:\nFailure to abide by the above conditions results in the processor signaling a general protection violation.\nThis instruction initiates a sequence to rendezvous the RLPs with the ILP. It then clears the internal processor flag indicating the processor is operating in a measured environment.\nIn response to a message signaling the completion of rendezvous, all RLPs restart execution with the instruction that was to be executed at the time GETSEC[SEXIT] was recognized. This applies to all processor conditions, with the following exceptions:\nPrior to completion of the GETSEC[SEXIT] operation, both the ILP and any active RLPs unmask the response of the external event signals INIT#, A20M, NMI#, and SMI#. This unmasking is performed unconditionally to recognize pin events which are masked after a GETSEC[SENTER]. The state of A20M is unmasked, as the A20M pin is not recognized while the measured environment is active.\nOn a successful exit of the measured environment, the ILP re-locks the Intel® TXT-capable chipset private configuration space. GETSEC[SEXIT] does not affect the content of any PCR.\nAt completion of GETSEC[SEXIT] by the ILP, execution proceeds to the next instruction. Since EFLAGS and the debug register state are not modified by this instruction, a pending trap condition is free to be signaled if previously enabled.", + "operation": "", + "url": "https://www.felixcloutier.com/x86/sexit" + }, + "sfence": { + "instruction": "SFENCE", + "title": "SFENCE\n\t\t— Store Fence", + "opcode": "NP 0F AE F8", + "description": "Orders processor execution relative to all memory stores prior to the SFENCE instruction. The processor ensures that every store prior to SFENCE is globally visible before any store after SFENCE becomes globally visible. The SFENCE instruction is ordered with respect to memory stores, other SFENCE instructions, MFENCE instructions, and any serializing instructions (such as the CPUID instruction). It is not ordered with respect to memory loads or the LFENCE instruction.\nWeakly ordered memory types can be used to achieve higher processor performance through such techniques as out-of-order issue, write-combining, and write-collapsing. The degree to which a consumer of data recognizes or knows that the data is weakly ordered varies among applications and may be unknown to the producer of this data. The SFENCE instruction provides a performance-efficient way of ensuring store ordering between routines that produce weakly-ordered results and routines that consume this data.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.\nSpecification of the instruction's opcode above indicates a ModR/M byte of F8. For this instruction, the processor ignores the r/m field of the ModR/M byte. Thus, SFENCE is encoded by any opcode of the form 0F AE Fx, where x is in the range 8-F.", + "operation": "Wait_On_Following_Stores_Until(preceding_stores_globally_visible);\n", + "url": "https://www.felixcloutier.com/x86/sfence" + }, + "sgdt": { + "instruction": "SGDT", + "title": "SGDT\n\t\t— Store Global Descriptor Table Register", + "opcode": "0F 01 /0", + "description": "Stores the content of the global descriptor table register (GDTR) in the destination operand. The destination operand specifies a memory location.\nIn legacy or compatibility mode, the destination operand is a 6-byte memory location. If the operand-size attribute is 16 or 32 bits, the 16-bit limit field of the register is stored in the low 2 bytes of the memory location and the 32-bit base address is stored in the high 4 bytes.\nIn 64-bit mode, the operand size is fixed at 8+2 bytes. The instruction stores an 8-byte base and a 2-byte limit.\nSGDT is useful only by operating-system software. However, it can be used in application programs without causing an exception to be generated if CR4.UMIP = 0. See “LGDT/LIDT—Load Global/Interrupt Descriptor Table Register” in Chapter 3, Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A, for information on loading the GDTR and IDTR.", + "operation": "IF instruction is SGDT\n IF OperandSize =16 or OperandSize = 32 (* Legacy or Compatibility Mode *)\n THEN\n DEST[0:15] := GDTR(Limit);\n DEST[16:47] := GDTR(Base); (* Full 32-bit base address stored *)\n FI;\n ELSE (* 64-bit Mode *)\n DEST[0:15] := GDTR(Limit);\n DEST[16:79] := GDTR(Base); (* Full 64-bit base address stored *)\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sgdt" + }, + "sha1msg1": { + "instruction": "SHA1MSG1", + "title": "SHA1MSG1\n\t\t— Perform an Intermediate Calculation for the Next Four SHA1 Message Dwords", + "opcode": "NP 0F 38 C9 /r SHA1MSG1 xmm1, xmm2/m128", + "description": "The SHA1MSG1 instruction is one of two SHA1 message scheduling instructions. The instruction performs an intermediate calculation for the next four SHA1 message dwords.", + "operation": "W0 := SRC1[127:96] ;\nW1 := SRC1[95:64] ;\nW2 := SRC1[63: 32] ;\nW3 := SRC1[31: 0] ;\nW4 := SRC2[127:96] ;\nW5 := SRC2[95:64] ;\nDEST[127:96] := W2 XOR W0;\nDEST[95:64] := W3 XOR W1;\nDEST[63:32] := W4 XOR W2;\nDEST[31:0] := W5 XOR W3;\n", + "url": "https://www.felixcloutier.com/x86/sha1msg1" + }, + "sha1msg2": { + "instruction": "SHA1MSG2", + "title": "SHA1MSG2\n\t\t— Perform a Final Calculation for the Next Four SHA1 Message Dwords", + "opcode": "NP 0F 38 CA /r SHA1MSG2 xmm1, xmm2/m128", + "description": "The SHA1MSG2 instruction is one of two SHA1 message scheduling instructions. The instruction performs the final calculation to derive the next four SHA1 message dwords.", + "operation": "W13 := SRC2[95:64] ;\nW14 := SRC2[63: 32] ;\nW15 := SRC2[31: 0] ;\nW16 := (SRC1[127:96] XOR W13 ) ROL 1;\nW17 := (SRC1[95:64] XOR W14) ROL 1;\nW18 := (SRC1[63: 32] XOR W15) ROL 1;\nW19 := (SRC1[31: 0] XOR W16) ROL 1;\nDEST[127:96] := W16;\nDEST[95:64] := W17;\nDEST[63:32] := W18;\nDEST[31:0] := W19;\n", + "url": "https://www.felixcloutier.com/x86/sha1msg2" + }, + "sha1nexte": { + "instruction": "SHA1NEXTE", + "title": "SHA1NEXTE\n\t\t— Calculate SHA1 State Variable E After Four Rounds", + "opcode": "NP 0F 38 C8 /r SHA1NEXTE xmm1, xmm2/m128", + "description": "The SHA1NEXTE calculates the SHA1 state variable E after four rounds of operation from the current SHA1 state variable A in the destination operand. The calculated value of the SHA1 state variable E is added to the source operand, which contains the scheduled dwords.", + "operation": "TMP := (SRC1[127:96] ROL 30);\nDEST[127:96] := SRC2[127:96] + TMP;\nDEST[95:64] := SRC2[95:64];\nDEST[63:32] := SRC2[63:32];\nDEST[31:0] := SRC2[31:0];\n", + "url": "https://www.felixcloutier.com/x86/sha1nexte" + }, + "sha1rnds4": { + "instruction": "SHA1RNDS4", + "title": "SHA1RNDS4\n\t\t— Perform Four Rounds of SHA1 Operation", + "opcode": "NP 0F 3A CC /r ib SHA1RNDS4 xmm1, xmm2/m128, imm8", + "description": "The SHA1RNDS4 instruction performs four rounds of SHA1 operation using an initial SHA1 state (A,B,C,D) from the first operand (which is a source operand and the destination operand) and some pre-computed sum of the next 4 round message dwords, and state variable E from the second operand (a source operand). The updated SHA1 state (A,B,C,D) after four rounds of processing is stored in the destination operand.", + "operation": "The function f() and Constant K are dependent on the value of the immediate.\nIF ( imm8[1:0] = 0 )\n THEN f() := f0(),\n K := K0;\nELSE IF ( imm8[1:0]\n = 1 )\n THEN f() := f1(),\n K := K1;\nELSE IF ( imm8[1:0]\n = 2 )\n THEN f() := f2(),\n K := K2;\nELSE IF ( imm8[1:0]\n = 3 )\n THEN f() := f3(),\n K := K3;\nFI;\nA := SRC1[127:96];\nB := SRC1[95:64];\nC := SRC1[63:32];\nD := SRC1[31:0];\nW0E := SRC2[127:96];\nW1 := SRC2[95:64];\nW2 := SRC2[63:32];\nW3 := SRC2[31:0];\nRound i = 0 operation:\nA_1 := f (B, C, D) + (A ROL 5) +W0E +K;\nB_1 := A;\nC_1 := B ROL 30;\nD_1 := C;\nE_1 := D;\nFOR i = 1 to 3\n A_(i +1) := f (B_i, C_i, D_i) + (A_i ROL 5) +Wi+ E_i +K;\n B_(i +1) := A_i;\n C_(i +1) := B_i ROL 30;\n D_(i +1) := C_i;\n E_(i +1) := D_i;\nENDFOR\nDEST[127:96] := A_4;\nDEST[95:64] := B_4;\nDEST[63:32] := C_4;\nDEST[31:0] := D_4;\n", + "url": "https://www.felixcloutier.com/x86/sha1rnds4" + }, + "sha256msg1": { + "instruction": "SHA256MSG1", + "title": "SHA256MSG1\n\t\t— Perform an Intermediate Calculation for the Next Four SHA256 MessageDwords", + "opcode": "NP 0F 38 CC /r SHA256MSG1 xmm1, xmm2/m128", + "description": "The SHA256MSG1 instruction is one of two SHA256 message scheduling instructions. The instruction performs an intermediate calculation for the next four SHA256 message dwords.", + "operation": "W4 := SRC2[31: 0] ;\nW3 := SRC1[127:96] ;\nW2 := SRC1[95:64] ;\nW1 := SRC1[63: 32] ;\nW0 := SRC1[31: 0] ;\nDEST[127:96] := W3 + σ0( W4);\nDEST[95:64] := W2 + σ0( W3);\nDEST[63:32] := W1 + σ0( W2);\nDEST[31:0] := W0 + σ0( W1);\n", + "url": "https://www.felixcloutier.com/x86/sha256msg1" + }, + "sha256msg2": { + "instruction": "SHA256MSG2", + "title": "SHA256MSG2\n\t\t— Perform a Final Calculation for the Next Four SHA256 Message Dwords", + "opcode": "NP 0F 38 CD /r SHA256MSG2 xmm1, xmm2/m128", + "description": "The SHA256MSG2 instruction is one of two SHA2 message scheduling instructions. The instruction performs the final calculation for the next four SHA256 message dwords.", + "operation": "W14 := SRC2[95:64] ;\nW15 := SRC2[127:96] ;\nW16 := SRC1[31: 0] + σ1( W14) ;\nW17 := SRC1[63: 32] + σ1( W15) ;\nW18 := SRC1[95: 64] + σ1( W16) ;\nW19 := SRC1[127: 96] + σ1( W17) ;\nDEST[127:96] := W19 ;\nDEST[95:64] := W18 ;\nDEST[63:32] := W17 ;\nDEST[31:0] := W16;\n", + "url": "https://www.felixcloutier.com/x86/sha256msg2" + }, + "sha256rnds2": { + "instruction": "SHA256RNDS2", + "title": "SHA256RNDS2\n\t\t— Perform Two Rounds of SHA256 Operation", + "opcode": "NP 0F 38 CB /r SHA256RNDS2 xmm1, xmm2/m128, ", + "description": "The SHA256RNDS2 instruction performs 2 rounds of SHA256 operation using an initial SHA256 state (C,D,G,H) from the first operand, an initial SHA256 state (A,B,E,F) from the second operand, and a pre-computed sum of the next 2 round message dwords and the corresponding round constants from the implicit operand xmm0. Note that only the two lower dwords of XMM0 are used by the instruction.\nThe updated SHA256 state (A,B,E,F) is written to the first operand, and the second operand can be used as the updated state (C,D,G,H) in later rounds.", + "operation": "A_0 := SRC2[127:96];\nB_0 := SRC2[95:64];\nC_0 := SRC1[127:96];\nD_0 := SRC1[95:64];\nE_0 := SRC2[63:32];\nF_0 := SRC2[31:0];\nG_0 := SRC1[63:32];\nH_0 := SRC1[31:0];\nWK0 := XMM0[31: 0];\nWK1 := XMM0[63: 32];\nFOR i = 0 to 1\n A_(i +1) :=\n Ch (E_i, F_i, G_i) +Σ1( E_i) +WKi+ H_i + Maj(A_i , B_i, C_i) +Σ0( A_i);\n B_(i +1) :=\n A_i;\n C_(i +1) :=\n B_i ;\n D_(i +1) :=\n C_i;\n E_(i +1) :=\n Ch (E_i, F_i, G_i) +Σ1( E_i) +WKi+ H_i + D_i;\n F_(i +1) :=\n E_i ;\n G_(i +1) :=\n F_i;\n H_(i +1) :=\n G_i;\nENDFOR\nDEST[127:96] := A_2;\nDEST[95:64] := B_2;\nDEST[63:32] := E_2;\nDEST[31:0] := F_2;\n", + "url": "https://www.felixcloutier.com/x86/sha256rnds2" + }, + "shl": { + "instruction": "SHL", + "title": "SAL/SAR/SHL/SHR\n\t\t— Shift", + "opcode": "D0 /4", + "description": "Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination operand.\nThe destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits with a 64-bit operand). The count range is limited to 0 to 31 (or 63 with a 64-bit operand). A special opcode encoding is provided for a count of 1.\nThe shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the bits in the destination operand to the left (toward more significant bit locations). For each shift count, the most significant bit of the destination operand is shifted into the CF flag, and the least significant bit is cleared (see Figure 7-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to the right (toward less significant bit locations). For each shift count, the least significant bit of the destination operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction type. The SHR instruction clears the most significant bit (see Figure 7-8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most significant bit to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR instruction fills the empty bit position’s shifted value with the sign of the unshifted value (see Figure 7-9 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination operand by powers of 2. For example, using the SAR instruction to shift a signed integer 1 bit to the right divides the value by 2.\nUsing the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction. The quotient from the IDIV instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is rounded toward negative infinity. This difference is apparent only for negative numbers. For example, when the IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1. If the SAR instruction is used to shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores only the most significant bit of the remainder (in the CF flag).\nThe OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1. For the SAR instruction, the OF flag is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set to the most-significant bit of the original operand.\nIn 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64-bits and sets the mask width for CL to 6 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 64\n THEN\n countMASK := 3FH;\n ELSE\n countMASK := 1FH;\nFI\ntempCOUNT := (COUNT AND countMASK);\ntempDEST := DEST;\nWHILE (tempCOUNT ≠ 0)\nDO\n IF instruction is SAL or SHL\n THEN\n CF := MSB(DEST);\n ELSE (* Instruction is SAR or SHR *)\n CF := LSB(DEST);\n FI;\n IF instruction is SAL or SHL\n THEN\n DEST := DEST ∗ 2;\n ELSE\n IF instruction is SAR\n THEN\n DEST := DEST / 2; (* Signed divide, rounding toward negative infinity *)\n ELSE (* Instruction is SHR *)\n DEST := DEST / 2 ; (* Unsigned divide *)\n FI;\n FI;\n tempCOUNT := tempCOUNT – 1;\nOD;\n(* Determine overflow for the various instructions *)\nIF (COUNT and countMASK) = 1\n THEN\n IF instruction is SAL or SHL\n THEN\n OF := MSB(DEST) XOR CF;\n ELSE\n IF instruction is SAR\n THEN\n OF := 0;\n ELSE (* Instruction is SHR *)\n OF := MSB(tempDEST);\n FI;\n FI;\n ELSE IF (COUNT AND countMASK) = 0\n THEN\n All flags unchanged;\n ELSE (* COUNT not 1 or 0 *)\n OF := undefined;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sal:sar:shl:shr" + }, + "shld": { + "instruction": "SHLD", + "title": "SHLD\n\t\t— Double Precision Shift Left", + "opcode": "0F A4 /r ib", + "description": "The SHLD instruction is used for multi-precision shifts of 64 bits or more.\nThe instruction shifts the first operand (destination operand) to the left the number of bits specified by the third operand (count operand). The second operand (source operand) provides bits to shift in from the right (starting with bit 0 of the destination operand).\nThe destination operand can be a register or a memory location; the source operand is a register. The count operand is an unsigned integer that can be stored in an immediate byte or in the CL register. If the count operand is CL, the shift count is the logical AND of CL and a count mask. In non-64-bit modes and default 64-bit mode; only bits 0 through 4 of the count are used. This masks the count to a value between 0 and 31. If a count is greater than the operand size, the result is undefined.\nIf the count is 1 or greater, the CF flag is filled with the last bit shifted out of the destination operand. For a 1-bit shift, the OF flag is set if a sign change occurred; otherwise, it is cleared. If the count operand is 0, flags are not affected.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits (upgrading the count mask to 6 bits). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (In 64-Bit Mode and REX.W = 1)\n THEN COUNT := COUNT MOD 64;\n ELSE COUNT := COUNT MOD 32;\nFI\nSIZE := OperandSize;\nIF COUNT = 0\n THEN\n No operation;\n ELSE\n IF COUNT > SIZE\n THEN (* Bad parameters *)\n DEST is undefined;\n CF, OF, SF, ZF, AF, PF are undefined;\n ELSE (* Perform the shift *)\n CF := BIT[DEST, SIZE – COUNT];\n (* Last bit shifted out on exit *)\n FOR i := SIZE – 1 DOWN TO COUNT\n DO\n Bit(DEST, i) := Bit(DEST, i – COUNT);\n OD;\n FOR i := COUNT – 1 DOWN TO 0\n DO\n BIT[DEST, i] := BIT[SRC, i – COUNT + SIZE];\n OD;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/shld" + }, + "shlx": { + "instruction": "SHLX", + "title": "SARX/SHLX/SHRX\n\t\t— Shift Without Affecting Flags", + "opcode": "VEX.LZ.F3.0F38.W0 F7 /r SARX r32a, r/m32, r32b", + "description": "Shifts the bits of the first source operand (the second operand) to the left or right by a COUNT value specified in the second source operand (the third operand). The result is written to the destination operand (the first operand).\nThe shift arithmetic right (SARX) and shift logical right (SHRX) instructions shift the bits of the destination operand to the right (toward less significant bit locations), SARX keeps and propagates the most significant bit (sign bit) while shifting.\nThe logical shift left (SHLX) shifts the bits of the destination operand to the left (toward more significant bit locations).\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.\nIf the value specified in the first source operand exceeds OperandSize -1, the COUNT value is masked.\nSARX,SHRX, and SHLX instructions do not update flags.", + "operation": "TEMP := SRC1;\nIF VEX.W1 and CS.L = 1\nTHEN\n countMASK := 3FH;\nELSE\n countMASK := 1FH;\nFI\nCOUNT := (SRC2 AND countMASK)\nDEST[OperandSize -1] = TEMP[OperandSize -1];\nDO WHILE (COUNT ≠ 0)\n IF instruction is SHLX\n THEN\n DEST[] := DEST *2;\n ELSE IF instruction is SHRX\n THEN\n DEST[] := DEST /2; //unsigned divide\n ELSE // SARX\n DEST[] := DEST /2; // signed divide, round toward negative infinity\n FI;\n COUNT := COUNT - 1;\nOD\n", + "url": "https://www.felixcloutier.com/x86/sarx:shlx:shrx" + }, + "shr": { + "instruction": "SHR", + "title": "SAL/SAR/SHL/SHR\n\t\t— Shift", + "opcode": "D0 /4", + "description": "Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination operand.\nThe destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits with a 64-bit operand). The count range is limited to 0 to 31 (or 63 with a 64-bit operand). A special opcode encoding is provided for a count of 1.\nThe shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the bits in the destination operand to the left (toward more significant bit locations). For each shift count, the most significant bit of the destination operand is shifted into the CF flag, and the least significant bit is cleared (see Figure 7-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to the right (toward less significant bit locations). For each shift count, the least significant bit of the destination operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction type. The SHR instruction clears the most significant bit (see Figure 7-8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most significant bit to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR instruction fills the empty bit position’s shifted value with the sign of the unshifted value (see Figure 7-9 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).\nThe SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination operand by powers of 2. For example, using the SAR instruction to shift a signed integer 1 bit to the right divides the value by 2.\nUsing the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction. The quotient from the IDIV instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is rounded toward negative infinity. This difference is apparent only for negative numbers. For example, when the IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1. If the SAR instruction is used to shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores only the most significant bit of the remainder (in the CF flag).\nThe OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1. For the SAR instruction, the OF flag is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set to the most-significant bit of the original operand.\nIn 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64-bits and sets the mask width for CL to 6 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF OperandSize = 64\n THEN\n countMASK := 3FH;\n ELSE\n countMASK := 1FH;\nFI\ntempCOUNT := (COUNT AND countMASK);\ntempDEST := DEST;\nWHILE (tempCOUNT ≠ 0)\nDO\n IF instruction is SAL or SHL\n THEN\n CF := MSB(DEST);\n ELSE (* Instruction is SAR or SHR *)\n CF := LSB(DEST);\n FI;\n IF instruction is SAL or SHL\n THEN\n DEST := DEST ∗ 2;\n ELSE\n IF instruction is SAR\n THEN\n DEST := DEST / 2; (* Signed divide, rounding toward negative infinity *)\n ELSE (* Instruction is SHR *)\n DEST := DEST / 2 ; (* Unsigned divide *)\n FI;\n FI;\n tempCOUNT := tempCOUNT – 1;\nOD;\n(* Determine overflow for the various instructions *)\nIF (COUNT and countMASK) = 1\n THEN\n IF instruction is SAL or SHL\n THEN\n OF := MSB(DEST) XOR CF;\n ELSE\n IF instruction is SAR\n THEN\n OF := 0;\n ELSE (* Instruction is SHR *)\n OF := MSB(tempDEST);\n FI;\n FI;\n ELSE IF (COUNT AND countMASK) = 0\n THEN\n All flags unchanged;\n ELSE (* COUNT not 1 or 0 *)\n OF := undefined;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sal:sar:shl:shr" + }, + "shrd": { + "instruction": "SHRD", + "title": "SHRD\n\t\t— Double Precision Shift Right", + "opcode": "0F AC /r ib", + "description": "The SHRD instruction is useful for multi-precision shifts of 64 bits or more.\nThe instruction shifts the first operand (destination operand) to the right the number of bits specified by the third operand (count operand). The second operand (source operand) provides bits to shift in from the left (starting with the most significant bit of the destination operand).\nThe destination operand can be a register or a memory location; the source operand is a register. The count operand is an unsigned integer that can be stored in an immediate byte or the CL register. If the count operand is CL, the shift count is the logical AND of CL and a count mask. In non-64-bit modes and default 64-bit mode, the width of the count mask is 5 bits. Only bits 0 through 4 of the count register are used (masking the count to a value between 0 and 31). If the count is greater than the operand size, the result is undefined.\nIf the count is 1 or greater, the CF flag is filled with the last bit shifted out of the destination operand. For a 1-bit shift, the OF flag is set if a sign change occurred; otherwise, it is cleared. If the count operand is 0, flags are not affected.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits (upgrading the count mask to 6 bits). See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF (In 64-Bit Mode and REX.W = 1)\n THEN COUNT := COUNT MOD 64;\n ELSE COUNT := COUNT MOD 32;\nFI\nSIZE := OperandSize;\nIF COUNT = 0\n THEN\n No operation;\n ELSE\n IF COUNT > SIZE\n THEN (* Bad parameters *)\n DEST is undefined;\n CF, OF, SF, ZF, AF, PF are undefined;\n ELSE (* Perform the shift *)\n CF := BIT[DEST, COUNT – 1]; (* Last bit shifted out on exit *)\n FOR i := 0 TO SIZE – 1 – COUNT\n DO\n BIT[DEST, i] := BIT[DEST, i + COUNT];\n OD;\n FOR i := SIZE – COUNT TO SIZE – 1\n DO\n BIT[DEST,i] := BIT[SRC, i + COUNT – SIZE];\n OD;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/shrd" + }, + "shrx": { + "instruction": "SHRX", + "title": "SARX/SHLX/SHRX\n\t\t— Shift Without Affecting Flags", + "opcode": "VEX.LZ.F3.0F38.W0 F7 /r SARX r32a, r/m32, r32b", + "description": "Shifts the bits of the first source operand (the second operand) to the left or right by a COUNT value specified in the second source operand (the third operand). The result is written to the destination operand (the first operand).\nThe shift arithmetic right (SARX) and shift logical right (SHRX) instructions shift the bits of the destination operand to the right (toward less significant bit locations), SARX keeps and propagates the most significant bit (sign bit) while shifting.\nThe logical shift left (SHLX) shifts the bits of the destination operand to the left (toward more significant bit locations).\nThis instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in 64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.\nIf the value specified in the first source operand exceeds OperandSize -1, the COUNT value is masked.\nSARX,SHRX, and SHLX instructions do not update flags.", + "operation": "TEMP := SRC1;\nIF VEX.W1 and CS.L = 1\nTHEN\n countMASK := 3FH;\nELSE\n countMASK := 1FH;\nFI\nCOUNT := (SRC2 AND countMASK)\nDEST[OperandSize -1] = TEMP[OperandSize -1];\nDO WHILE (COUNT ≠ 0)\n IF instruction is SHLX\n THEN\n DEST[] := DEST *2;\n ELSE IF instruction is SHRX\n THEN\n DEST[] := DEST /2; //unsigned divide\n ELSE // SARX\n DEST[] := DEST /2; // signed divide, round toward negative infinity\n FI;\n COUNT := COUNT - 1;\nOD\n", + "url": "https://www.felixcloutier.com/x86/sarx:shlx:shrx" + }, + "shufpd": { + "instruction": "SHUFPD", + "title": "SHUFPD\n\t\t— Packed Interleave Shuffle of Pairs of Double Precision Floating-Point Values", + "opcode": "66 0F C6 /r ib SHUFPD xmm1, xmm2/m128, imm8", + "description": "Selects a double precision floating-point value of an input pair using a bit control and move to a designated element of the destination operand. The low-to-high order of double precision element of the destination operand is interleaved between the first source operand and the second source operand at the granularity of input pair of 128 bits. Each bit in the imm8 byte, starting from bit 0, is the select control of the corresponding element of the destination to received the shuffled result of an input pair.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 64-bit memory location The destination operand is a ZMM/YMM/XMM register updated according to the writemask. The select controls are the lower 8/4/2 bits of the imm8 byte.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. The select controls are the bit 3:0 of the imm8 byte, imm8[7:4) are ignored.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of\nthe corresponding ZMM register destination are zeroed. The select controls are the bit 1:0 of the imm8 byte, imm8[7:2) are ignored.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination operand and the first source operand is the same and is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified. The select controls are the bit 1:0 of the imm8 byte, imm8[7:2) are ignored.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF IMM0[0] = 0\n THEN TMP_DEST[63:0] := SRC1[63:0]\n ELSE TMP_DEST[63:0] := SRC1[127:64] FI;\nIF IMM0[1] = 0\n THEN TMP_DEST[127:64] := SRC2[63:0]\n ELSE TMP_DEST[127:64] := SRC2[127:64] FI;\nIF VL >= 256\n IF IMM0[2] = 0\n THEN TMP_DEST[191:128] := SRC1[191:128]\n ELSE TMP_DEST[191:128] := SRC1[255:192] FI;\n IF IMM0[3] = 0\n THEN TMP_DEST[255:192] := SRC2[191:128]\n ELSE TMP_DEST[255:192] := SRC2[255:192] FI;\nFI;\nIF VL >= 512\n IF IMM0[4] = 0\n THEN TMP_DEST[319:256] := SRC1[319:256]\n ELSE TMP_DEST[319:256] := SRC1[383:320] FI;\n IF IMM0[5] = 0\n THEN TMP_DEST[383:320] := SRC2[319:256]\n ELSE TMP_DEST[383:320] := SRC2[383:320] FI;\n IF IMM0[6] = 0\n THEN TMP_DEST[447:384] := SRC1[447:384]\n ELSE TMP_DEST[447:384] := SRC1[511:448] FI;\n IF IMM0[7] = 0\n THEN TMP_DEST[511:448] := SRC2[447:384]\n ELSE TMP_DEST[511:448] := SRC2[511:448] FI;\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF IMM0[0] = 0\n THEN TMP_DEST[63:0] := SRC1[63:0]\n ELSE TMP_DEST[63:0] := SRC1[127:64] FI;\nIF IMM0[1] = 0\n THEN TMP_DEST[127:64] := TMP_SRC2[63:0]\n ELSE TMP_DEST[127:64] := TMP_SRC2[127:64] FI;\nIF VL >= 256\n IF IMM0[2] = 0\n THEN TMP_DEST[191:128] := SRC1[191:128]\n ELSE TMP_DEST[191:128] := SRC1[255:192] FI;\n IF IMM0[3] = 0\n THEN TMP_DEST[255:192] := TMP_SRC2[191:128]\n ELSE TMP_DEST[255:192] := TMP_SRC2[255:192] FI;\nFI;\nIF VL >= 512\n IF IMM0[4] = 0\n THEN TMP_DEST[319:256] := SRC1[319:256]\n ELSE TMP_DEST[319:256] := SRC1[383:320] FI;\n IF IMM0[5] = 0\n THEN TMP_DEST[383:320] := TMP_SRC2[319:256]\n ELSE TMP_DEST[383:320] := TMP_SRC2[383:320] FI;\n IF IMM0[6] = 0\n THEN TMP_DEST[447:384] := SRC1[447:384]\n ELSE TMP_DEST[447:384] := SRC1[511:448] FI;\n IF IMM0[7] = 0\n THEN TMP_DEST[511:448] := TMP_SRC2[447:384]\n ELSE TMP_DEST[511:448] := TMP_SRC2[511:448] FI;\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nIF IMM0[0] = 0\n THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST[63:0] := SRC1[127:64] FI;\nIF IMM0[1] = 0\n THEN DEST[127:64] := SRC2[63:0]\n ELSE DEST[127:64] := SRC2[127:64] FI;\nIF IMM0[2] = 0\n THEN DEST[191:128] := SRC1[191:128]\n ELSE DEST[191:128] := SRC1[255:192] FI;\nIF IMM0[3] = 0\n THEN DEST[255:192] := SRC2[191:128]\n ELSE DEST[255:192] := SRC2[255:192] FI;\nDEST[MAXVL-1:256] (Unmodified)\n\n\nIF IMM0[0] = 0\n THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST[63:0] := SRC1[127:64] FI;\nIF IMM0[1] = 0\n THEN DEST[127:64] := SRC2[63:0]\n ELSE DEST[127:64] := SRC2[127:64] FI;\nDEST[MAXVL-1:128] := 0\n\n\nIF IMM0[0] = 0\n THEN DEST[63:0] := SRC1[63:0]\n ELSE DEST[63:0] := SRC1[127:64] FI;\nIF IMM0[1] = 0\n THEN DEST[127:64] := SRC2[63:0]\n ELSE DEST[127:64] := SRC2[127:64] FI;\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/shufpd" + }, + "shufps": { + "instruction": "SHUFPS", + "title": "SHUFPS\n\t\t— Packed Interleave Shuffle of Quadruplets of Single Precision Floating-Point Values", + "opcode": "NP 0F C6 /r ib SHUFPS xmm1, xmm3/m128, imm8", + "description": "Selects a single precision floating-point value of an input quadruplet using a two-bit control and move to a designated element of the destination operand. Each 64-bit element-pair of a 128-bit lane of the destination operand is interleaved between the corresponding lane of the first source operand and the second source operand at the granularity 128 bits. Each two bits in the imm8 byte, starting from bit 0, is the select control of the corresponding element of a 128-bit lane of the destination to received the shuffled result of an input quadruplet. The two lower elements of a 128-bit lane in the destination receives shuffle results from the quadruple of the first source operand. The next two elements of the destination receives shuffle results from the quadruple of the second source operand.\nEVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask. imm8[7:0] provides 4 select controls for each applicable 128-bit lane of the destination.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register. Imm8[7:0] provides 4 select controls for the high and low 128-bit of the destination.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed. Imm8[7:0] provides 4 select controls for each element of the destination.\n128-bit Legacy SSE version: The source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified. Imm8[7:0] provides 4 select controls for each element of the destination.", + "operation": "Select4(SRC, control) {\nCASE (control[1:0]) OF\n 0: TMP := SRC[31:0];\n 1: TMP := SRC[63:32];\n 2: TMP := SRC[95:64];\n 3: TMP := SRC[127:96];\nESAC;\nRETURN TMP\n}\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nTMP_DEST[31:0] := Select4(SRC1[127:0], imm8[1:0]);\nTMP_DEST[63:32] := Select4(SRC1[127:0], imm8[3:2]);\nTMP_DEST[95:64] := Select4(SRC2[127:0], imm8[5:4]);\nTMP_DEST[127:96] := Select4(SRC2[127:0], imm8[7:6]);\nIF VL >= 256\n TMP_DEST[159:128] := Select4(SRC1[255:128], imm8[1:0]);\n TMP_DEST[191:160] := Select4(SRC1[255:128], imm8[3:2]);\n TMP_DEST[223:192] := Select4(SRC2[255:128], imm8[5:4]);\n TMP_DEST[255:224] := Select4(SRC2[255:128], imm8[7:6]);\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := Select4(SRC1[383:256], imm8[1:0]);\n TMP_DEST[319:288] := Select4(SRC1[383:256], imm8[3:2]);\n TMP_DEST[351:320] := Select4(SRC2[383:256], imm8[5:4]);\n TMP_DEST[383:352] := Select4(SRC2[383:256], imm8[7:6]);\n TMP_DEST[415:384] := Select4(SRC1[511:384], imm8[1:0]);\n TMP_DEST[447:416] := Select4(SRC1[511:384], imm8[3:2]);\n TMP_DEST[479:448] := Select4(SRC2[511:384], imm8[5:4]);\n TMP_DEST[511:480] := Select4(SRC2[511:384], imm8[7:6]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nTMP_DEST[31:0] := Select4(SRC1[127:0], imm8[1:0]);\nTMP_DEST[63:32] := Select4(SRC1[127:0], imm8[3:2]);\nTMP_DEST[95:64] := Select4(TMP_SRC2[127:0], imm8[5:4]);\nTMP_DEST[127:96] := Select4(TMP_SRC2[127:0], imm8[7:6]);\nIF VL >= 256\n TMP_DEST[159:128] := Select4(SRC1[255:128], imm8[1:0]);\n TMP_DEST[191:160] := Select4(SRC1[255:128], imm8[3:2]);\n TMP_DEST[223:192] := Select4(TMP_SRC2[255:128], imm8[5:4]);\n TMP_DEST[255:224] := Select4(TMP_SRC2[255:128], imm8[7:6]);\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := Select4(SRC1[383:256], imm8[1:0]);\n TMP_DEST[319:288] := Select4(SRC1[383:256], imm8[3:2]);\n TMP_DEST[351:320] := Select4(TMP_SRC2[383:256], imm8[5:4]);\n TMP_DEST[383:352] := Select4(TMP_SRC2[383:256], imm8[7:6]);\n TMP_DEST[415:384] := Select4(SRC1[511:384], imm8[1:0]);\n TMP_DEST[447:416] := Select4(SRC1[511:384], imm8[3:2]);\n TMP_DEST[479:448] := Select4(TMP_SRC2[511:384], imm8[5:4]);\n TMP_DEST[511:480] := Select4(TMP_SRC2[511:384], imm8[7:6]);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := Select4(SRC1[127:0], imm8[1:0]);\nDEST[63:32] := Select4(SRC1[127:0], imm8[3:2]);\nDEST[95:64] := Select4(SRC2[127:0], imm8[5:4]);\nDEST[127:96] := Select4(SRC2[127:0], imm8[7:6]);\nDEST[159:128] := Select4(SRC1[255:128], imm8[1:0]);\nDEST[191:160] := Select4(SRC1[255:128], imm8[3:2]);\nDEST[223:192] := Select4(SRC2[255:128], imm8[5:4]);\nDEST[255:224] := Select4(SRC2[255:128], imm8[7:6]);\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := Select4(SRC1[127:0], imm8[1:0]);\nDEST[63:32] := Select4(SRC1[127:0], imm8[3:2]);\nDEST[95:64] := Select4(SRC2[127:0], imm8[5:4]);\nDEST[127:96] := Select4(SRC2[127:0], imm8[7:6]);\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := Select4(SRC1[127:0], imm8[1:0]);\nDEST[63:32] := Select4(SRC1[127:0], imm8[3:2]);\nDEST[95:64] := Select4(SRC2[127:0], imm8[5:4]);\nDEST[127:96] := Select4(SRC2[127:0], imm8[7:6]);\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/shufps" + }, + "sidt": { + "instruction": "SIDT", + "title": "SIDT\n\t\t— Store Interrupt Descriptor Table Register", + "opcode": "0F 01 /1", + "description": "Stores the content the interrupt descriptor table register (IDTR) in the destination operand. The destination operand specifies a 6-byte memory location.\nIn non-64-bit modes, the 16-bit limit field of the register is stored in the low 2 bytes of the memory location and the 32-bit base address is stored in the high 4 bytes.\nIn 64-bit mode, the operand size fixed at 8+2 bytes. The instruction stores 8-byte base and 2-byte limit values.\nSIDT is only useful in operating-system software; however, it can be used in application programs without causing an exception to be generated if CR4.UMIP = 0. See “LGDT/LIDT—Load Global/Interrupt Descriptor Table Register” in Chapter 3, Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A, for information on loading the GDTR and IDTR.", + "operation": "IF instruction is SIDT\n THEN\n IF OperandSize =16 or OperandSize = 32 (* Legacy or Compatibility Mode *)\n THEN\n DEST[0:15] := IDTR(Limit);\n DEST[16:47] := IDTR(Base); FI; (* Full 32-bit base address stored *)\n ELSE (* 64-bit Mode *)\n DEST[0:15] := IDTR(Limit);\n DEST[16:79] := IDTR(Base); (* Full 64-bit base address stored *)\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sidt" + }, + "sldt": { + "instruction": "SLDT", + "title": "SLDT\n\t\t— Store Local Descriptor Table Register", + "opcode": "0F 00 /0", + "description": "Stores the segment selector from the local descriptor table register (LDTR) in the destination operand. The destination operand can be a general-purpose register or a memory location. The segment selector stored with this instruction points to the segment descriptor (located in the GDT) for the current LDT. This instruction can only be executed in protected mode.\nOutside IA-32e mode, when the destination operand is a 32-bit register, the 16-bit segment selector is copied into the low-order 16 bits of the register. The high-order 16 bits of the register are cleared for the Pentium 4, Intel Xeon, and P6 family processors. They are undefined for Pentium, Intel486, and Intel386 processors. When the destination operand is a memory location, the segment selector is written to memory as a 16-bit quantity, regardless of the operand size.\nIn compatibility mode, when the destination operand is a 32-bit register, the 16-bit segment selector is copied into the low-order 16 bits of the register. The high-order 16 bits of the register are cleared. When the destination operand is a memory location, the segment selector is written to memory as a 16-bit quantity, regardless of the operand size.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). The behavior of SLDT with a 64-bit register is to zero-extend the 16-bit selector and store it in the register. If the destination is memory and operand size is 64, SLDT will write the 16-bit selector to memory as a 16-bit quantity, regardless of the operand size.", + "operation": "DEST := LDTR(SegmentSelector);\n", + "url": "https://www.felixcloutier.com/x86/sldt" + }, + "smctrl": { + "instruction": "SMCTRL", + "title": "GETSEC[SMCTRL]\n\t\t— SMX Mode Control", + "opcode": "NP 0F 37 (EAX = 7)", + "description": "The GETSEC[SMCTRL] instruction is available for performing certain SMX specific mode control operations. The operation to be performed is selected through the input register EBX. Currently only an input value in EBX of 0 is supported. All other EBX settings will result in the signaling of a general protection violation.\nIf EBX is set to 0, then the SMCTRL leaf is used to re-enable SMI events. SMI is masked by the ILP executing the GETSEC[SENTER] instruction (SMI is also masked in the responding logical processors in response to SENTER rendezvous messages.). The determination of when this instruction is allowed and the events that are unmasked is dependent on the processor context (See Table 7-11). For brevity, the usage of SMCTRL where EBX=0 will be referred to as GETSEC[SMCTRL(0)].\nAs part of support for launching a measured environment, the SMI, NMI, and INIT events are masked after GETSEC[SENTER], and remain masked after exiting authenticated execution mode. Unmasking these events should be accompanied by securely enabling these event handlers. These security concerns can be addressed in VMX operation by a MVMM.\nThe VM monitor can choose two approaches:\nTable 7-11 defines the processor context in which GETSEC[SMCTRL(0)] can be used and which events will be unmasked. Note that the events that are unmasked are dependent upon the currently operating processor context.", + "operation": "(* The state of the internal flag ACMODEFLAG and SENTERFLAG persist across instruction boundary *)\nIF (CR4.SMXE=0)\n THEN #UD;\nELSE IF (in VMX non-root operation)\n THEN VM Exit (reason=”GETSEC instruction”);\nELSE IF (GETSEC leaf unsupported)\n THEN #UD;\nELSE IF ((CR0.PE=0) or (CPL>0) OR (EFLAGS.VM=1))\n THEN #GP(0);\nELSE IF((EBX=0) and (SENTERFLAG=1) and (ACMODEFLAG=0) and (IN_SMM=0) and\n (((in VMX root operation) and (SMM monitor not configured)) or (not in VMX operation)) )\n THEN unmask SMI;\nELSE\n #GP(0);\nEND\n", + "url": "https://www.felixcloutier.com/x86/smctrl" + }, + "smsw": { + "instruction": "SMSW", + "title": "SMSW\n\t\t— Store Machine Status Word", + "opcode": "0F 01 /4", + "description": "Stores the machine status word (bits 0 through 15 of control register CR0) into the destination operand. The destination operand can be a general-purpose register or a memory location.\nIn non-64-bit modes, when the destination operand is a 32-bit register, the low-order 16 bits of register CR0 are copied into the low-order 16 bits of the register and the high-order 16 bits are undefined. When the destination operand is a memory location, the low-order 16 bits of register CR0 are written to memory as a 16-bit quantity, regardless of the operand size.\nIn 64-bit mode, the behavior of the SMSW instruction is defined by the following examples:\nSMSW is only useful in operating-system software. However, it is not a privileged instruction and can be used in application programs if CR4.UMIP = 0. It is provided for compatibility with the Intel 286 processor. Programs and procedures intended to run on IA-32 and Intel 64 processors beginning with the Intel386 processors should use the MOV CR instruction to load the machine status word.\nSee “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.", + "operation": "DEST := CR0[15:0];\n(* Machine status word *)\n", + "url": "https://www.felixcloutier.com/x86/smsw" + }, + "sqrtpd": { + "instruction": "SQRTPD", + "title": "SQRTPD\n\t\t— Square Root of Double Precision Floating-Point Values", + "opcode": "66 0F 51 /r SQRTPD xmm1, xmm2/m128", + "description": "Performs a SIMD computation of the square roots of the two, four or eight packed double precision floating-point values in the source operand (the second operand) stores the packed double precision floating-point results in the destination operand (the first operand).\nEVEX encoded versions: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded version: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: the source operand second source operand or a 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1) AND (SRC *is register*)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN DEST[i+63:i] := SQRT(SRC[63:0])\n ELSE DEST[i+63:i] := SQRT(SRC[i+63:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SQRT(SRC[63:0])\nDEST[127:64] := SQRT(SRC[127:64])\nDEST[191:128] := SQRT(SRC[191:128])\nDEST[255:192] := SQRT(SRC[255:192])\nDEST[MAXVL-1:256] := 0\n.\n\n\nDEST[63:0] := SQRT(SRC[63:0])\nDEST[127:64] := SQRT(SRC[127:64])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SQRT(SRC[63:0])\nDEST[127:64] := SQRT(SRC[127:64])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/sqrtpd" + }, + "sqrtps": { + "instruction": "SQRTPS", + "title": "SQRTPS\n\t\t— Square Root of Single Precision Floating-Point Values", + "opcode": "NP 0F 51 /r SQRTPS xmm1, xmm2/m128", + "description": "Performs a SIMD computation of the square roots of the four, eight or sixteen packed single precision floating-point values in the source operand (second operand) stores the packed single precision floating-point results in the destination operand.\nEVEX.512 encoded versions: The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register updated according to the writemask.\nVEX.256 encoded version: The source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the corresponding ZMM register destination are zeroed.\nVEX.128 encoded version: the source operand second source operand or a 128-bit memory location. The destination operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\n128-bit Legacy SSE version: The second source can be an XMM register or 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1) AND (SRC *is register*)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1) AND (SRC *is memory*)\n THEN DEST[i+31:i] := SQRT(SRC[31:0])\n ELSE DEST[i+31:i] := SQRT(SRC[i+31:i])\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SQRT(SRC[31:0])\nDEST[63:32] := SQRT(SRC[63:32])\nDEST[95:64] := SQRT(SRC[95:64])\nDEST[127:96] := SQRT(SRC[127:96])\nDEST[159:128] := SQRT(SRC[159:128])\nDEST[191:160] := SQRT(SRC[191:160])\nDEST[223:192] := SQRT(SRC[223:192])\nDEST[255:224] := SQRT(SRC[255:224])\n\n\nDEST[31:0] := SQRT(SRC[31:0])\nDEST[63:32] := SQRT(SRC[63:32])\nDEST[95:64] := SQRT(SRC[95:64])\nDEST[127:96] := SQRT(SRC[127:96])\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SQRT(SRC[31:0])\nDEST[63:32] := SQRT(SRC[63:32])\nDEST[95:64] := SQRT(SRC[95:64])\nDEST[127:96] := SQRT(SRC[127:96])\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/sqrtps" + }, + "sqrtsd": { + "instruction": "SQRTSD", + "title": "SQRTSD\n\t\t— Compute Square Root of Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 51/r SQRTSD xmm1,xmm2/m64", + "description": "Computes the square root of the low double precision floating-point value in the second source operand and stores the double precision floating-point result in the destination operand. The second source operand can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. The quadword at bits 127:64 of the destination operand remains unchanged. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded versions: Bits 127:64 of the destination operand are copied from the corresponding bits of the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low quadword element of the destination operand is updated according to the write-mask.\nSoftware should ensure VSQRTSD is encoded with VEX.L=0. Encoding VSQRTSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND (SRC2 *is register*)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SQRT(SRC2[63:0])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SQRT(SRC2[63:0])\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SQRT(SRC[63:0])\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/sqrtsd" + }, + "sqrtss": { + "instruction": "SQRTSS", + "title": "SQRTSS\n\t\t— Compute Square Root of Scalar Single Precision Value", + "opcode": "F3 0F 51 /r SQRTSS xmm1, xmm2/m32", + "description": "Computes the square root of the low single precision floating-point value in the second source operand and stores the single precision floating-point result in the destination operand. The second source operand can be an XMM register or a 32-bit memory location. The first source and destination operands is an XMM register.\n128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-1:32) of the corresponding YMM destination register remain unchanged.\nVEX.128 and EVEX encoded versions: Bits 127:32 of the destination operand are copied from the corresponding bits of the first source operand. Bits (MAXVL-1:128) of the destination ZMM register are zeroed.\nEVEX encoded version: The low doubleword element of the destination operand is updated according to the write-mask.\nSoftware should ensure VSQRTSS is encoded with VEX.L=0. Encoding VSQRTSS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (EVEX.b = 1) AND (SRC2 *is register*)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SQRT(SRC2[31:0])\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SQRT(SRC2[31:0])\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SQRT(SRC2[31:0])\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/sqrtss" + }, + "stac": { + "instruction": "STAC", + "title": "STAC\n\t\t— Set AC Flag in EFLAGS Register", + "opcode": "NP 0F 01 CB STAC", + "description": "Sets the AC flag bit in EFLAGS register. This may enable alignment checking of user-mode data accesses. This allows explicit supervisor-mode data accesses to user-mode pages even if the SMAP bit is set in the CR4 register.\nThis instruction's operation is the same in non-64-bit modes and 64-bit mode. Attempts to execute STAC when CPL > 0 cause #UD.", + "operation": "EFLAGS.AC := 1;\n", + "url": "https://www.felixcloutier.com/x86/stac" + }, + "stc": { + "instruction": "STC", + "title": "STC\n\t\t— Set Carry Flag", + "opcode": "F9", + "description": "Sets the CF flag in the EFLAGS register. Operation is the same in all modes.", + "operation": "CF := 1;\n", + "url": "https://www.felixcloutier.com/x86/stc" + }, + "std": { + "instruction": "STD", + "title": "STD\n\t\t— Set Direction Flag", + "opcode": "FD", + "description": "Sets the DF flag in the EFLAGS register. When the DF flag is set to 1, string operations decrement the index registers (ESI and/or EDI). Operation is the same in all modes.", + "operation": "DF := 1;\n", + "url": "https://www.felixcloutier.com/x86/std" + }, + "sti": { + "instruction": "STI", + "title": "STI\n\t\t— Set Interrupt Flag", + "opcode": "FB", + "description": "In most cases, STI sets the interrupt flag (IF) in the EFLAGS register. This allows the processor to respond to maskable hardware interrupts.\nIf IF = 0, maskable hardware interrupts remain inhibited on the instruction boundary following an execution of STI. (The delayed effect of this instruction is provided to allow interrupts to be enabled just before returning from a procedure or subroutine. For instance, if an STI instruction is followed by an RET instruction, the RET instruction is allowed to execute before external interrupts are recognized. No interrupts can be recognized if an execution of CLI immediately follow such an execution of STI.) The inhibition ends after delivery of another event (e.g., exception) or the execution of the next instruction.\nThe IF flag and the STI and CLI instructions do not prohibit the generation of exceptions and nonmaskable interrupts (NMIs). However, NMIs (and system-management interrupts) may be inhibited on the instruction boundary following an execution of STI that begins with IF = 0.\nOperation is different in two modes defined as follows:\nIf IOPL < 3, EFLAGS.VIP = 1, and either VME mode or PVI mode is active, STI sets the VIF flag in the EFLAGS register, leaving IF unaffected.\nTable 4-19 indicates the action of the STI instruction depending on the processor operating mode, IOPL, CPL, and EFLAGS.VIP.\n2. For this table, “protected mode” applies whenever CR0.PE = 1 and EFLAGS.VM = 0; it includes compatibility mode and 64-bit mode.\n3. PVI mode and virtual-8086 mode each imply CPL = 3.", + "operation": "IF CR0.PE = 0 (* Executing in real-address mode *)\n THEN IF := 1; (* Set Interrupt Flag *)\n ELSE\n IF IOPL ≥ CPL (* CPL = 3 if EFLAGS.VM = 1 *)\n THEN IF := 1; (* Set Interrupt Flag *)\n ELSE\n IF VME mode OR PVI mode\n THEN\n IF EFLAGS.VIP = 0\n THEN VIF := 1; (* Set Virtual Interrupt Flag *)\n ELSE #GP(0);\n FI;\n ELSE #GP(0);\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/sti" + }, + "stmxcsr": { + "instruction": "STMXCSR", + "title": "STMXCSR\n\t\t— Store MXCSR Register State", + "opcode": "NP 0F AE /3 STMXCSR m32", + "description": "Stores the contents of the MXCSR control and status register to the destination operand. The destination operand is a 32-bit memory location. The reserved bits in the MXCSR register are stored as 0s.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.\nVEX.L must be 0, otherwise instructions will #UD.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "m32 := MXCSR;\n", + "url": "https://www.felixcloutier.com/x86/stmxcsr" + }, + "stos": { + "instruction": "STOS", + "title": "STOS/STOSB/STOSW/STOSD/STOSQ\n\t\t— Store String", + "opcode": "AA", + "description": "In non-64-bit and default 64-bit mode; stores a byte, word, or doubleword from the AL, AX, or EAX register (respectively) into the destination operand. The destination operand is a memory location, the address of which is read from either the ES:EDI or ES:DI register (depending on the address-size attribute of the instruction and the mode of operation). The ES segment cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of the instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the STOS mnemonic) allows the destination operand to be specified explicitly. Here, the destination operand should be a symbol that indicates the size and location of the destination value. The source operand is then automatically selected to match the size of the destination operand (the AL register for byte operands, AX for word operands, EAX for doubleword operands). The explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI register. These must be loaded correctly before the store string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, doubleword, and quadword versions of the STOS instructions. Here also ES:(E)DI is assumed to be the destination operand and AL, AX, or EAX is assumed to be the source operand. The size of the destination and source operands is selected by the mnemonic: STOSB (byte read from register AL), STOSW (word from AX), STOSD (doubleword from EAX).\nAfter the byte, word, or doubleword is transferred from the register to the memory location, the (E)DI register is incremented or decremented according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the register is incremented; if the DF flag is 1, the register is decremented (the register is incremented or decremented by 1 for byte operations, by 2 for word operations, by 4 for doubleword operations).\nIn 64-bit mode, the default address size is 64 bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The promoted no-operand mnemonic is STOSQ. STOSQ (and its explicit operands variant) store a quadword from the RAX register into the destination addressed by RDI or EDI. See the summary chart at the beginning of this section for encoding data and limits.\nThe STOS, STOSB, STOSW, STOSD, STOSQ instructions can be preceded by the REP prefix for block stores of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because data needs to be moved into the AL, AX, or EAX register before it can be stored. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.", + "operation": "IF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n\n\nIF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4;\n FI;\n FI;\n ELSE IF (Quadword store using REX.W )\n THEN\n DEST := RAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/stos:stosb:stosw:stosd:stosq" + }, + "stosb": { + "instruction": "STOSB", + "title": "STOS/STOSB/STOSW/STOSD/STOSQ\n\t\t— Store String", + "opcode": "AA", + "description": "In non-64-bit and default 64-bit mode; stores a byte, word, or doubleword from the AL, AX, or EAX register (respectively) into the destination operand. The destination operand is a memory location, the address of which is read from either the ES:EDI or ES:DI register (depending on the address-size attribute of the instruction and the mode of operation). The ES segment cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of the instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the STOS mnemonic) allows the destination operand to be specified explicitly. Here, the destination operand should be a symbol that indicates the size and location of the destination value. The source operand is then automatically selected to match the size of the destination operand (the AL register for byte operands, AX for word operands, EAX for doubleword operands). The explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI register. These must be loaded correctly before the store string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, doubleword, and quadword versions of the STOS instructions. Here also ES:(E)DI is assumed to be the destination operand and AL, AX, or EAX is assumed to be the source operand. The size of the destination and source operands is selected by the mnemonic: STOSB (byte read from register AL), STOSW (word from AX), STOSD (doubleword from EAX).\nAfter the byte, word, or doubleword is transferred from the register to the memory location, the (E)DI register is incremented or decremented according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the register is incremented; if the DF flag is 1, the register is decremented (the register is incremented or decremented by 1 for byte operations, by 2 for word operations, by 4 for doubleword operations).\nIn 64-bit mode, the default address size is 64 bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The promoted no-operand mnemonic is STOSQ. STOSQ (and its explicit operands variant) store a quadword from the RAX register into the destination addressed by RDI or EDI. See the summary chart at the beginning of this section for encoding data and limits.\nThe STOS, STOSB, STOSW, STOSD, STOSQ instructions can be preceded by the REP prefix for block stores of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because data needs to be moved into the AL, AX, or EAX register before it can be stored. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.", + "operation": "IF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n\n\nIF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4;\n FI;\n FI;\n ELSE IF (Quadword store using REX.W )\n THEN\n DEST := RAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/stos:stosb:stosw:stosd:stosq" + }, + "stosd": { + "instruction": "STOSD", + "title": "STOS/STOSB/STOSW/STOSD/STOSQ\n\t\t— Store String", + "opcode": "AB", + "description": "In non-64-bit and default 64-bit mode; stores a byte, word, or doubleword from the AL, AX, or EAX register (respectively) into the destination operand. The destination operand is a memory location, the address of which is read from either the ES:EDI or ES:DI register (depending on the address-size attribute of the instruction and the mode of operation). The ES segment cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of the instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the STOS mnemonic) allows the destination operand to be specified explicitly. Here, the destination operand should be a symbol that indicates the size and location of the destination value. The source operand is then automatically selected to match the size of the destination operand (the AL register for byte operands, AX for word operands, EAX for doubleword operands). The explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI register. These must be loaded correctly before the store string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, doubleword, and quadword versions of the STOS instructions. Here also ES:(E)DI is assumed to be the destination operand and AL, AX, or EAX is assumed to be the source operand. The size of the destination and source operands is selected by the mnemonic: STOSB (byte read from register AL), STOSW (word from AX), STOSD (doubleword from EAX).\nAfter the byte, word, or doubleword is transferred from the register to the memory location, the (E)DI register is incremented or decremented according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the register is incremented; if the DF flag is 1, the register is decremented (the register is incremented or decremented by 1 for byte operations, by 2 for word operations, by 4 for doubleword operations).\nIn 64-bit mode, the default address size is 64 bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The promoted no-operand mnemonic is STOSQ. STOSQ (and its explicit operands variant) store a quadword from the RAX register into the destination addressed by RDI or EDI. See the summary chart at the beginning of this section for encoding data and limits.\nThe STOS, STOSB, STOSW, STOSD, STOSQ instructions can be preceded by the REP prefix for block stores of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because data needs to be moved into the AL, AX, or EAX register before it can be stored. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.", + "operation": "IF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n\n\nIF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4;\n FI;\n FI;\n ELSE IF (Quadword store using REX.W )\n THEN\n DEST := RAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/stos:stosb:stosw:stosd:stosq" + }, + "stosq": { + "instruction": "STOSQ", + "title": "STOS/STOSB/STOSW/STOSD/STOSQ\n\t\t— Store String", + "opcode": "REX.W + AB", + "description": "In non-64-bit and default 64-bit mode; stores a byte, word, or doubleword from the AL, AX, or EAX register (respectively) into the destination operand. The destination operand is a memory location, the address of which is read from either the ES:EDI or ES:DI register (depending on the address-size attribute of the instruction and the mode of operation). The ES segment cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of the instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the STOS mnemonic) allows the destination operand to be specified explicitly. Here, the destination operand should be a symbol that indicates the size and location of the destination value. The source operand is then automatically selected to match the size of the destination operand (the AL register for byte operands, AX for word operands, EAX for doubleword operands). The explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI register. These must be loaded correctly before the store string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, doubleword, and quadword versions of the STOS instructions. Here also ES:(E)DI is assumed to be the destination operand and AL, AX, or EAX is assumed to be the source operand. The size of the destination and source operands is selected by the mnemonic: STOSB (byte read from register AL), STOSW (word from AX), STOSD (doubleword from EAX).\nAfter the byte, word, or doubleword is transferred from the register to the memory location, the (E)DI register is incremented or decremented according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the register is incremented; if the DF flag is 1, the register is decremented (the register is incremented or decremented by 1 for byte operations, by 2 for word operations, by 4 for doubleword operations).\nIn 64-bit mode, the default address size is 64 bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The promoted no-operand mnemonic is STOSQ. STOSQ (and its explicit operands variant) store a quadword from the RAX register into the destination addressed by RDI or EDI. See the summary chart at the beginning of this section for encoding data and limits.\nThe STOS, STOSB, STOSW, STOSD, STOSQ instructions can be preceded by the REP prefix for block stores of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because data needs to be moved into the AL, AX, or EAX register before it can be stored. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.", + "operation": "IF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n\n\nIF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4;\n FI;\n FI;\n ELSE IF (Quadword store using REX.W )\n THEN\n DEST := RAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/stos:stosb:stosw:stosd:stosq" + }, + "stosw": { + "instruction": "STOSW", + "title": "STOS/STOSB/STOSW/STOSD/STOSQ\n\t\t— Store String", + "opcode": "AB", + "description": "In non-64-bit and default 64-bit mode; stores a byte, word, or doubleword from the AL, AX, or EAX register (respectively) into the destination operand. The destination operand is a memory location, the address of which is read from either the ES:EDI or ES:DI register (depending on the address-size attribute of the instruction and the mode of operation). The ES segment cannot be overridden with a segment override prefix.\nAt the assembly-code level, two forms of the instruction are allowed: the “explicit-operands” form and the “no-operands” form. The explicit-operands form (specified with the STOS mnemonic) allows the destination operand to be specified explicitly. Here, the destination operand should be a symbol that indicates the size and location of the destination value. The source operand is then automatically selected to match the size of the destination operand (the AL register for byte operands, AX for word operands, EAX for doubleword operands). The explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI register. These must be loaded correctly before the store string instruction is executed.\nThe no-operands form provides “short forms” of the byte, word, doubleword, and quadword versions of the STOS instructions. Here also ES:(E)DI is assumed to be the destination operand and AL, AX, or EAX is assumed to be the source operand. The size of the destination and source operands is selected by the mnemonic: STOSB (byte read from register AL), STOSW (word from AX), STOSD (doubleword from EAX).\nAfter the byte, word, or doubleword is transferred from the register to the memory location, the (E)DI register is incremented or decremented according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the register is incremented; if the DF flag is 1, the register is decremented (the register is incremented or decremented by 1 for byte operations, by 2 for word operations, by 4 for doubleword operations).\nIn 64-bit mode, the default address size is 64 bits, 32-bit address size is supported using the prefix 67H. Using a REX prefix in the form of REX.W promotes operation on doubleword operand to 64 bits. The promoted no-operand mnemonic is STOSQ. STOSQ (and its explicit operands variant) store a quadword from the RAX register into the destination addressed by RDI or EDI. See the summary chart at the beginning of this section for encoding data and limits.\nThe STOS, STOSB, STOSW, STOSD, STOSQ instructions can be preceded by the REP prefix for block stores of ECX bytes, words, or doublewords. More often, however, these instructions are used within a LOOP construct because data needs to be moved into the AL, AX, or EAX register before it can be stored. See “REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix” in this chapter for a description of the REP prefix.", + "operation": "IF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 1;\n ELSE (E)DI := (E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 2;\n ELSE (E)DI := (E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (E)DI := (E)DI + 4;\n ELSE (E)DI := (E)DI – 4;\n FI;\n FI;\nFI;\n\n\nIF (Byte store)\n THEN\n DEST := AL;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 1;\n ELSE (R|E)DI := (R|E)DI – 1;\n FI;\n ELSE IF (Word store)\n THEN\n DEST := AX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 2;\n ELSE (R|E)DI := (R|E)DI – 2;\n FI;\n FI;\n ELSE IF (Doubleword store)\n THEN\n DEST := EAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 4;\n ELSE (R|E)DI := (R|E)DI – 4;\n FI;\n FI;\n ELSE IF (Quadword store using REX.W )\n THEN\n DEST := RAX;\n THEN IF DF = 0\n THEN (R|E)DI := (R|E)DI + 8;\n ELSE (R|E)DI := (R|E)DI – 8;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/stos:stosb:stosw:stosd:stosq" + }, + "str": { + "instruction": "STR", + "title": "STR\n\t\t— Store Task Register", + "opcode": "0F 00 /1", + "description": "Stores the segment selector from the task register (TR) in the destination operand. The destination operand can be a general-purpose register or a memory location. The segment selector stored with this instruction points to the task state segment (TSS) for the currently running task.\nWhen the destination operand is a 32-bit register, the 16-bit segment selector is copied into the lower 16 bits of the register and the upper 16 bits of the register are cleared. When the destination operand is a memory location, the segment selector is written to memory as a 16-bit quantity, regardless of operand size.\nIn 64-bit mode, operation is the same. The size of the memory operand is fixed at 16 bits. In register stores, the 2-byte TR is zero extended if stored to a 64-bit register.\nThe STR instruction is useful only in operating-system software. It can only be executed in protected mode.", + "operation": "DEST := TR(SegmentSelector);\n", + "url": "https://www.felixcloutier.com/x86/str" + }, + "sttilecfg": { + "instruction": "STTILECFG", + "title": "STTILECFG\n\t\t— Store Tile Configuration", + "opcode": "VEX.128.66.0F38.W0 49 !(11):000:bbb STTILECFG m512", + "description": "The STTILECFG instruction takes a pointer to a 64-byte memory location (described in Table 3-10 in the “LDTILECFG—Load Tile Configuration” entry) that will, after successful execution of this instruction, contain the description of the tiles that were configured. In order to configure tiles, the AMX-TILE bit in CPUID must be set and the operating system has to have enabled the tiles architecture.\nIf the tiles are not configured, then STTILECFG stores 64B of zeros to the indicated memory location.\nAny attempt to execute the STTILECFG instruction inside an Intel TSX transaction will result in a transaction abort.", + "operation": "if TILES_CONFIGURED == 0:\n //write 64 bytes of zeros at mem pointer\n buf[0..63] := 0\n write_memory(mem, 64, buf)\nelse:\n buf.byte[0] := tilecfg.palette_id\n buf.byte[1] := tilecfg.start_row\n buf.byte[2..15] := 0\n p := 16\n for n in 0 ... palette_table[tilecfg.palette_id].max_names-1:\n buf.word[p/2] := tilecfg.t[n].colsb\n p := p + 2\n if p < 47:\n buf.byte[p..47] := 0\n p := 48\n for n in 0 ... palette_table[tilecfg.palette_id].max_names-1:\n buf.byte[p++] := tilecfg.t[n].rows\n if p < 63:\n buf.byte[p..63] := 0\n write_memory(mem, 64, buf)\n", + "url": "https://www.felixcloutier.com/x86/sttilecfg" + }, + "stui": { + "instruction": "STUI", + "title": "STUI\n\t\t— Set User Interrupt Flag", + "opcode": "F3 0F 01 EF STUI", + "description": "STUI sets the user interrupt flag (UIF). Its effect takes place immediately; a user interrupt may be delivered on the instruction boundary following STUI. (This is in contrast with STI, whose effect is delayed by one instruction).\nAn execution of STUI inside a transactional region causes a transactional abort; the abort loads EAX as it would have had it been due to an execution of STI.", + "operation": "UIF := 1;\n", + "url": "https://www.felixcloutier.com/x86/stui" + }, + "sub": { + "instruction": "SUB", + "title": "SUB\n\t\t— Subtract", + "opcode": "2C ib", + "description": "Subtracts the second operand (source operand) from the first operand (destination operand) and stores the result in the destination operand. The destination operand can be a register or a memory location; the source operand can be an immediate, register, or memory location. (However, two memory operands cannot be used in one instruction.) When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format.\nThe SUB instruction performs integer subtraction. It evaluates the result for both signed and unsigned integer operands and sets the OF and CF flags to indicate an overflow in the signed or unsigned result, respectively. The SF flag indicates the sign of the signed result.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.", + "operation": "DEST := (DEST – SRC);\n", + "url": "https://www.felixcloutier.com/x86/sub" + }, + "subpd": { + "instruction": "SUBPD", + "title": "SUBPD\n\t\t— Subtract Packed Double Precision Floating-Point Values", + "opcode": "66 0F 5C /r SUBPD xmm1, xmm2/m128", + "description": "Performs a SIMD subtract of the two, four or eight packed double precision floating-point values of the second Source operand from the first Source operand, and stores the packed double precision floating-point results in the destination operand.\nVEX.128 and EVEX.128 encoded versions: The second source operand is an XMM register or an 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 and EVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX.512 encoded version: The second source operand is a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 64-bit memory location. The first source operand and destination operands are ZMM registers. The destination operand is conditionally updated according to the writemask.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper Bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC1[i+63:i] - SRC2[i+63:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[63:0] := 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1)\n THEN DEST[i+63:i] := SRC1[i+63:i] - SRC2[63:0];\n ELSE EST[i+63:i] := SRC1[i+63:i] - SRC2[i+63:i];\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[63:0] := 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0] - SRC2[63:0]\nDEST[127:64] := SRC1[127:64] - SRC2[127:64]\nDEST[191:128] := SRC1[191:128] - SRC2[191:128]\nDEST[255:192] := SRC1[255:192] - SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SRC1[63:0] - SRC2[63:0]\nDEST[127:64] := SRC1[127:64] - SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] - SRC[63:0]\nDEST[127:64] := DEST[127:64] - SRC[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/subpd" + }, + "subps": { + "instruction": "SUBPS", + "title": "SUBPS\n\t\t— Subtract Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 5C /r SUBPS xmm1, xmm2/m128", + "description": "Performs a SIMD subtract of the packed single precision floating-point values in the second Source operand from the First Source operand, and stores the packed single precision floating-point results in the destination operand.\nVEX.128 and EVEX.128 encoded versions: The second source operand is an XMM register or an 128-bit memory location. The first source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding destination register are zeroed.\nVEX.256 and EVEX.256 encoded versions: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers. Bits (MAXVL-1:256) of the corresponding destination register are zeroed.\nEVEX.512 encoded version: The second source operand is a ZMM register, a 512-bit memory location or a 512-bit vector broadcasted from a 32-bit memory location. The first source operand and destination operands are ZMM registers. The destination operand is conditionally updated according to the writemask.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper Bits (MAXVL-1:128) of the corresponding register destination are unmodified.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF (VL = 512) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC1[i+31:i] - SRC2[i+31:i]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[31:0] := 0\n FI;\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256),(16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask* THEN\n IF (EVEX.b = 1)\n THEN DEST[i+31:i] := SRC1[i+31:i] - SRC2[31:0];\n ELSE DEST[i+31:i] := SRC1[i+31:i] - SRC2[i+31:i];\n FI;\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n DEST[31:0] := 0\n FI;\n FI;\nENDFOR;\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC2[31:0]\nDEST[63:32] := SRC1[63:32] - SRC2[63:32]\nDEST[95:64] := SRC1[95:64] - SRC2[95:64]\nDEST[127:96] := SRC1[127:96] - SRC2[127:96]\nDEST[159:128] := SRC1[159:128] - SRC2[159:128]\nDEST[191:160] := SRC1[191:160] - SRC2[191:160]\nDEST[223:192] := SRC1[223:192] - SRC2[223:192]\nDEST[255:224] := SRC1[255:224] - SRC2[255:224].\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC2[31:0]\nDEST[63:32] := SRC1[63:32] - SRC2[63:32]\nDEST[95:64] := SRC1[95:64] - SRC2[95:64]\nDEST[127:96] := SRC1[127:96] - SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC2[31:0]\nDEST[63:32] := SRC1[63:32] - SRC2[63:32]\nDEST[95:64] := SRC1[95:64] - SRC2[95:64]\nDEST[127:96] := SRC1[127:96] - SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/subps" + }, + "subsd": { + "instruction": "SUBSD", + "title": "SUBSD\n\t\t— Subtract Scalar Double Precision Floating-Point Value", + "opcode": "F2 0F 5C /r SUBSD xmm1, xmm2/m64", + "description": "Subtract the low double precision floating-point value in the second source operand from the first source operand and stores the double precision floating-point result in the low quadword of the destination operand.\nThe second source operand can be an XMM register or a 64-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The destination and first source operand are the same. Bits (MAXVL-1:64) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded versions: Bits (127:64) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low quadword element of the destination operand is updated according to the write-mask.\nSoftware should ensure VSUBSD is encoded with VEX.L=0. Encoding VSUBSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (SRC2 *is register*) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[63:0] := SRC1[63:0] - SRC2[63:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[63:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[63:0] := 0\n FI;\nFI;\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0] - SRC2[63:0]\nDEST[127:64] := SRC1[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := DEST[63:0] - SRC[63:0]\nDEST[MAXVL-1:64] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/subsd" + }, + "subss": { + "instruction": "SUBSS", + "title": "SUBSS\n\t\t— Subtract Scalar Single Precision Floating-Point Value", + "opcode": "F3 0F 5C /r SUBSS xmm1, xmm2/m32", + "description": "Subtract the low single precision floating-point value from the second source operand and the first source operand and store the double precision floating-point result in the low doubleword of the destination operand.\nThe second source operand can be an XMM register or a 32-bit memory location. The first source and destination operands are XMM registers.\n128-bit Legacy SSE version: The destination and first source operand are the same. Bits (MAXVL-1:32) of the corresponding destination register remain unchanged.\nVEX.128 and EVEX encoded versions: Bits (127:32) of the XMM register destination are copied from corresponding bits in the first source operand. Bits (MAXVL-1:128) of the destination register are zeroed.\nEVEX encoded version: The low doubleword element of the destination operand is updated according to the write-mask.\nSoftware should ensure VSUBSS is encoded with VEX.L=0. Encoding VSUBSD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "IF (SRC2 *is register*) AND (EVEX.b = 1)\n THEN\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);\n ELSE\n SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);\nFI;\nIF k1[0] or *no writemask*\n THEN DEST[31:0] := SRC1[31:0] - SRC2[31:0]\n ELSE\n IF *merging-masking* ; merging-masking\n THEN *DEST[31:0] remains unchanged*\n ELSE ; zeroing-masking\n THEN DEST[31:0] := 0\n FI;\nFI;\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0] - SRC2[31:0]\nDEST[127:32] := SRC1[127:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := DEST[31:0] - SRC[31:0]\nDEST[MAXVL-1:32] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/subss" + }, + "swapgs": { + "instruction": "SWAPGS", + "title": "SWAPGS\n\t\t— Swap GS Base Register", + "opcode": "0F 01 F8", + "description": "SWAPGS exchanges the current GS base register value with the value contained in MSR address C0000102H (IA32_KERNEL_GS_BASE). The SWAPGS instruction is a privileged instruction intended for use by system software.\nWhen using SYSCALL to implement system calls, there is no kernel stack at the OS entry point. Neither is there a straightforward method to obtain a pointer to kernel structures from which the kernel stack pointer could be read. Thus, the kernel cannot save general purpose registers or reference memory.\nBy design, SWAPGS does not require any general purpose registers or memory operands. No registers need to be saved before using the instruction. SWAPGS exchanges the CPL 0 data pointer from the IA32_KERNEL_GS_BASE MSR with the GS base register. The kernel can then use the GS prefix on normal memory references to access kernel data structures. Similarly, when the OS kernel is entered using an interrupt or exception (where the kernel stack is already set up), SWAPGS can be used to quickly get a pointer to the kernel data structures.\nThe IA32_KERNEL_GS_BASE MSR itself is only accessible using RDMSR/WRMSR instructions. Those instructions are only accessible at privilege level 0. The WRMSR instruction ensures that the IA32_KERNEL_GS_BASE MSR contains a canonical address.", + "operation": "IF CS.L ≠ 1 (* Not in 64-Bit Mode *)\n THEN\n #UD; FI;\nIF CPL ≠ 0\n THEN #GP(0); FI;\ntmp := GS.base;\nGS.base := IA32_KERNEL_GS_BASE;\nIA32_KERNEL_GS_BASE := tmp;\n", + "url": "https://www.felixcloutier.com/x86/swapgs" + }, + "syscall": { + "instruction": "SYSCALL", + "title": "SYSCALL\n\t\t— Fast System Call", + "opcode": "0F 05", + "description": "SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.)\nSYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR.\nSYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSCALL instruction does not ensure this correspondence.\nThe SYSCALL instruction does not save the stack pointer (RSP). If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET.\nWhen shadow stacks are enabled at a privilege level where the SYSCALL instruction is invoked, the SSP is saved to the IA32_PL3_SSP MSR. If shadow stacks are enabled at privilege level 0, the SSP is loaded with 0. Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions‚” and Chapter 17, “Control-flow Enforcement Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for additional CET details.\nInstruction ordering. Instructions following a SYSCALL may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the SYSCALL have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).", + "operation": "IF (CS.L ≠ 1 ) or (IA32_EFER.LMA ≠ 1) or (IA32_EFER.SCE ≠ 1)\n(* Not in 64-Bit Mode or SYSCALL/SYSRET not enabled in IA32_EFER *)\n THEN #UD;\nFI;\nRCX := RIP; (* Will contain address of next instruction *)\nRIP := IA32_LSTAR;\nR11 := RFLAGS;\nRFLAGS := RFLAGS AND NOT(IA32_FMASK);\nCS.Selector := IA32_STAR[47:32] AND FFFCH (* Operating system provides CS; RPL forced to 0 *)\n(* Set rest of CS to a fixed value *)\nCS.Base := 0;\n (* Flat segment *)\nCS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nCS.Type := 11;\n (* Execute/read code, accessed *)\nCS.S := 1;\nCS.DPL := 0;\nCS.P := 1;\nCS.L := 1;\n (* Entry is to 64-bit mode *)\nCS.D := 0;\n (* Required if CS.L = 1 *)\nCS.G := 1;\n (* 4-KByte granularity *)\nIF ShadowStackEnabled(CPL)\n THEN (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n (* With shadow stacks enabled the system call is supported from Ring 3 to Ring 0 *)\n (* OS supporting Ring 0 to Ring 0 system calls or Ring 1/2 to ring 0 system call *)\n (* Must preserve the contents of IA32_PL3_SSP to avoid losing ring 3 state *)\nFI;\nCPL := 0;\nIF ShadowStackEnabled(CPL)\n SSP := 0;\nFI;\nIF EndbranchEnabled(CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\nFI;\nSS.Selector := IA32_STAR[47:32] + 8;\n (* SS just above CS *)\n(* Set rest of SS to a fixed value *)\nSS.Base := 0;\n (* Flat segment *)\nSS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nSS.Type := 3;\n (* Read/write data, accessed *)\nSS.S := 1;\nSS.DPL := 0;\nSS.P := 1;\nSS.B := 1;\n (* 32-bit stack segment *)\nSS.G := 1;\n (* 4-KByte granularity *)\n", + "url": "https://www.felixcloutier.com/x86/syscall" + }, + "sysenter": { + "instruction": "SYSENTER", + "title": "SYSENTER\n\t\t— Fast System Call", + "opcode": "0F 34", + "description": "Executes a fast call to a level 0 system procedure or routine. SYSENTER is a companion instruction to SYSEXIT. The instruction is optimized to provide the maximum performance for system calls from user code running at privilege level 3 to operating system or executive procedures running at privilege level 0.\nWhen executed in IA-32e mode, the SYSENTER instruction transitions the logical processor to 64-bit mode; otherwise, the logical processor remains in protected mode.\nPrior to executing the SYSENTER instruction, software must specify the privilege level 0 code segment and code entry point, and the privilege level 0 stack segment and stack pointer by writing values to the following MSRs:\nThese MSRs can be read from and written to using RDMSR/WRMSR. The WRMSR instruction ensures that the IA32_SYSENTER_EIP and IA32_SYSENTER_ESP MSRs always contain canonical addresses.\nWhile SYSENTER loads the CS and SS selectors with values derived from the IA32_SYSENTER_CS MSR, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSENTER instruction does not ensure this correspondence.\nThe SYSENTER instruction can be invoked from all operating modes except real-address mode.\nThe SYSENTER and SYSEXIT instructions are companion instructions, but they do not constitute a call/return pair. When executing a SYSENTER instruction, the processor does not save state information for the user code (e.g., the instruction pointer), and neither the SYSENTER nor the SYSEXIT instruction supports passing parameters on the stack.\nTo use the SYSENTER and SYSEXIT instructions as companion instructions for transitions between privilege level 3 code and privilege level 0 operating system procedures, the following conventions must be followed:\nThe SYSENTER and SYSEXIT instructions were introduced into the IA-32 architecture in the Pentium II processor. The availability of these instructions on a processor is indicated with the SYSENTER/SYSEXIT present (SEP) feature\nflag returned to the EDX register by the CPUID instruction. An operating system that qualifies the SEP flag must also qualify the processor family and model to ensure that the SYSENTER/SYSEXIT instructions are actually present. For example:\nIF CPUID SEP bit is set\nTHEN IF (Family = 6) and (Model < 3) and (Stepping < 3)\nTHEN\nSYSENTER/SYSEXIT_Not_Supported; FI;\nELSE\nSYSENTER/SYSEXIT_Supported; FI;\nFI;\nWhen the CPUID instruction is executed on the Pentium Pro processor (model 1), the processor returns a the SEP flag as set, but does not support the SYSENTER/SYSEXIT instructions.\nWhen shadow stacks are enabled at privilege level where SYSENTER instruction is invoked, the SSP is saved to the IA32_PL3_SSP MSR. If shadow stacks are enabled at privilege level 0, the SSP is loaded with 0. Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions‚” and Chapter 17, “Control-flow Enforcement Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for additional CET details.\nInstruction ordering. Instructions following a SYSENTER may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the SYSENTER have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).", + "operation": "IF CR0.PE = 0 OR IA32_SYSENTER_CS[15:2] = 0 THEN #GP(0); FI;\nRFLAGS.VM := 0;\n (* Ensures protected mode execution *)\nRFLAGS.IF := 0;\n (* Mask interrupts *)\nIF in IA-32e mode\n THEN\n RSP := IA32_SYSENTER_ESP;\n RIP := IA32_SYSENTER_EIP;\nELSE\n ESP := IA32_SYSENTER_ESP[31:0];\n EIP := IA32_SYSENTER_EIP[31:0];\nFI;\nCS.Selector := IA32_SYSENTER_CS[15:0] AND\n FFFCH;\n (* Operating system provides CS; RPL forced to 0 *)\n(* Set rest of CS to a fixed value *)\nCS.Base := 0;\n (* Flat segment *)\nCS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nCS.Type := 11;\n (* Execute/read code, accessed *)\nCS.S := 1;\nCS.DPL := 0;\nCS.P := 1;\nIF in IA-32e mode\n THEN\n CS.L := 1;\n (* Entry is to 64-bit mode *)\n CS.D := 0;\n (* Required if CS.L = 1 *)\n ELSE\n CS.L := 0;\n CS.D := 1;\n (* 32-bit code segment*)\nFI;\nCS.G := 1;\n (* 4-KByte granularity *)\nIF ShadowStackEnabled(CPL)\n THEN\n IF IA32_EFER.LMA = 0\n THEN IA32_PL3_SSP := SSP;\n ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *)\n IA32_PL3_SSP := LA_adjust(SSP);\n FI;\nFI;\nCPL := 0;\nIF ShadowStackEnabled(CPL)\n SSP := 0;\nFI;\nIF EndbranchEnabled(CPL)\n IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH\n IA32_S_CET.SUPPRESS = 0\nFI;\nSS.Selector := CS.Selector + 8;\n (* SS just above CS *)\n(* Set rest of SS to a fixed value *)\nSS.Base := 0;\n (* Flat segment *)\nSS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nSS.Type := 3;\n (* Read/write data, accessed *)\nSS.S := 1;\nSS.DPL := 0;\nSS.P := 1;\nSS.B := 1;\n (* 32-bit stack segment*)\nSS.G := 1;\n (* 4-KByte granularity *)\n", + "url": "https://www.felixcloutier.com/x86/sysenter" + }, + "sysexit": { + "instruction": "SYSEXIT", + "title": "SYSEXIT\n\t\t— Fast Return from Fast System Call", + "opcode": "0F 35", + "description": "Executes a fast return to privilege level 3 user code. SYSEXIT is a companion instruction to the SYSENTER instruction. The instruction is optimized to provide the maximum performance for returns from system procedures executing at protections levels 0 to user procedures executing at protection level 3. It must be executed from code executing at privilege level 0.\nWith a 64-bit operand size, SYSEXIT remains in 64-bit mode; otherwise, it either enters compatibility mode (if the logical processor is in IA-32e mode) or remains in protected mode (if it is not).\nPrior to executing SYSEXIT, software must specify the privilege level 3 code segment and code entry point, and the privilege level 3 stack segment and stack pointer by writing values into the following MSR and general-purpose registers:\nThe IA32_SYSENTER_CS MSR can be read from and written to using RDMSR and WRMSR.\nWhile SYSEXIT loads the CS and SS selectors with values derived from the IA32_SYSENTER_CS MSR, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSEXIT instruction does not ensure this correspondence.\nThe SYSEXIT instruction can be invoked from all operating modes except real-address mode and virtual-8086 mode.\nThe SYSENTER and SYSEXIT instructions were introduced into the IA-32 architecture in the Pentium II processor. The availability of these instructions on a processor is indicated with the SYSENTER/SYSEXIT present (SEP) feature flag returned to the EDX register by the CPUID instruction. An operating system that qualifies the SEP flag must also qualify the processor family and model to ensure that the SYSENTER/SYSEXIT instructions are actually present. For example:\nIF CPUID SEP bit is set\nTHEN IF (Family = 6) and (Model < 3) and (Stepping < 3)\nTHEN\nSYSENTER/SYSEXIT_Not_Supported; FI;\nELSE\nSYSENTER/SYSEXIT_Supported; FI;\nFI;\nWhen the CPUID instruction is executed on the Pentium Pro processor (model 1), the processor returns a the SEP flag as set, but does not support the SYSENTER/SYSEXIT instructions.\nWhen shadow stacks are enabled at privilege level 3 the instruction loads SSP with value from IA32_PL3_SSP MSR. Refer to Chapter 6, “Interrupt and Exception Handling‚” and Chapter 17, “Control-flow Enforcement Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for additional CET details.\nInstruction ordering. Instructions following a SYSEXIT may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the SYSEXIT have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).", + "operation": "IF IA32_SYSENTER_CS[15:2] = 0 OR CR0.PE = 0 OR CPL ≠ 0 THEN #GP(0); FI;\nIF operand size is 64-bit\n THEN (* Return to 64-bit mode *)\n RSP := RCX;\n RIP := RDX;\n ELSE (* Return to protected mode or compatibility mode *)\n RSP := ECX;\n RIP := EDX;\nFI;\nIF operand size is 64-bit (* Operating system provides CS; RPL forced to 3 *)\n THEN CS.Selector := IA32_SYSENTER_CS[15:0] + 32;\n ELSE CS.Selector := IA32_SYSENTER_CS[15:0] + 16;\nFI;\nCS.Selector := CS.Selector OR 3;\n (* RPL forced to 3 *)\n(* Set rest of CS to a fixed value *)\nCS.Base := 0;\n (* Flat segment *)\nCS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nCS.Type := 11;\n (* Execute/read code, accessed *)\nCS.S := 1;\nCS.DPL := 3;\nCS.P := 1;\nIF operand size is 64-bit\n THEN (* return to 64-bit mode *)\n CS.L := 1;\n (* 64-bit code segment *)\n CS.D := 0;\n ELSE (* return to protected mode or compatibility mode *)\n CS.L := 0;\n CS.D := 1;\n (* 32-bit code segment*)\nFI;\nCS.G := 1;\n (* 4-KByte granularity *)\nCPL := 3;\nIF ShadowStackEnabled(CPL)\n THEN SSP := IA32_PL3_SSP;\nFI;\nSS.Selector := CS.Selector + 8;\n (* SS just above CS *)\n(* Set rest of SS to a fixed value *)\nSS.Base := 0;\n (* Flat segment *)\nSS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nSS.Type := 3;\n (* Read/write data, accessed *)\nSS.S := 1;\nSS.DPL := 3;\nSS.P := 1;\nSS.B := 1;\n (* 32-bit stack segment*)\nSS.G := 1; (* 4-KByte granularity *)\n", + "url": "https://www.felixcloutier.com/x86/sysexit" + }, + "sysret": { + "instruction": "SYSRET", + "title": "SYSRET\n\t\t— Return From Fast System Call", + "opcode": "0F 07", + "description": "SYSRET is a companion instruction to the SYSCALL instruction. It returns from an OS system-call handler to user code at privilege level 3. It does so by loading RIP from RCX and loading RFLAGS from R11.1 With a 64-bit operand size, SYSRET remains in 64-bit mode; otherwise, it enters compatibility mode and only the low 32 bits of the registers are loaded.\nSYSRET loads the CS and SS selectors with values derived from bits 63:48 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSRET instruction does not ensure this correspondence.\nThe SYSRET instruction does not modify the stack pointer (ESP or RSP). For that reason, it is necessary for software to switch to the user stack. The OS may load the user stack pointer (if it was saved after SYSCALL) before executing SYSRET; alternatively, user code may load the stack pointer (if it was saved before SYSCALL) after receiving control from SYSRET.\nIf the OS loads the stack pointer before executing SYSRET, it must ensure that the handler of any interrupt or exception delivered between restoring the stack pointer and successful execution of SYSRET is not invoked with the user stack. It can do so using approaches such as the following:\nWhen shadow stacks are enabled at privilege level 3 the instruction loads SSP with value from IA32_PL3_SSP MSR. Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions‚” and Chapter 17, “Control-flow Enforcement Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for additional CET details.\nInstruction ordering. Instructions following a SYSRET may be fetched from memory before earlier instructions complete execution, but they will not execute (even speculatively) until all instructions prior to the SYSRET have completed execution (the later instructions may execute before data stored by the earlier instructions have become globally visible).", + "operation": "IF (CS.L ≠ 1 ) or (IA32_EFER.LMA ≠ 1) or (IA32_EFER.SCE ≠ 1)\n(* Not in 64-Bit Mode or SYSCALL/SYSRET not enabled in IA32_EFER *)\n THEN #UD; FI;\nIF (CPL ≠ 0) THEN #GP(0); FI;\nIF (operand size is 64-bit)\n THEN (* Return to 64-Bit Mode *)\n IF (RCX is not canonical) THEN #GP(0);\n RIP := RCX;\n ELSE (* Return to Compatibility Mode *)\n RIP := ECX;\nFI;\nRFLAGS := (R11 & 3C7FD7H) | 2; (*\n Clear RF, VM, reserved bits; set bit 1 *)\nIF (operand size is 64-bit)\n THEN CS.Selector := IA32_STAR[63:48]+16;\n ELSE CS.Selector := IA32_STAR[63:48];\nFI;\nCS.Selector := CS.Selector OR 3;\n (* RPL forced to 3 *)\n(* Set rest of CS to a fixed value *)\nCS.Base := 0;\n (* Flat segment *)\nCS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nCS.Type := 11;\n (* Execute/read code, accessed *)\nCS.S := 1;\nCS.DPL := 3;\nCS.P := 1;\nIF (operand size is 64-bit)\n THEN (* Return to 64-Bit Mode *)\n CS.L := 1;\n (* 64-bit code segment *)\n CS.D := 0;\n (* Required if CS.L = 1 *)\n ELSE (* Return to Compatibility Mode *)\n CS.L := 0;\n (* Compatibility mode *)\n CS.D := 1;\n (* 32-bit code segment *)\nFI;\nCS.G := 1;\n (* 4-KByte granularity *)\nCPL := 3;\nIF ShadowStackEnabled(CPL)\n SSP := IA32_PL3_SSP;\nFI;\nSS.Selector := (IA32_STAR[63:48]+8) OR 3;\n (* RPL forced to 3 *)\n(* Set rest of SS to a fixed value *)\nSS.Base := 0;\n (* Flat segment *)\nSS.Limit := FFFFFH;\n (* With 4-KByte granularity, implies a 4-GByte limit *)\nSS.Type := 3;\n (* Read/write data, accessed *)\nSS.S := 1;\nSS.DPL := 3;\nSS.P := 1;\nSS.B := 1;\n (* 32-bit stack segment*)\nSS.G := 1;\n (* 4-KByte granularity *)\n", + "url": "https://www.felixcloutier.com/x86/sysret" + }, + "tdpbf16ps": { + "instruction": "TDPBF16PS", + "title": "TDPBF16PS\n\t\t— Dot Product of BF16 Tiles Accumulated into Packed Single Precision Tile", + "opcode": "VEX.128.F3.0F38.W0 5C 11:rrr:bbb TDPBF16PS tmm1, tmm2, tmm3", + "description": "This instruction performs a set of SIMD dot-products of two BF16 elements and accumulates the results into a packed single precision tile. Each dword element in input tiles tmm2 and tmm3 is interpreted as a BF16 pair. For each possible combination of (row of tmm2, column of tmm3), the instruction performs a set of SIMD dot-products on all corresponding BF16 pairs (one pair from tmm2 and one pair from tmm3), adds the results of those dot-products, and then accumulates the result into the corresponding row and column of tmm1.\n“Round to nearest even” rounding mode is used when doing each accumulation of the FMA. Output denormals are always flushed to zero and input denormals are always treated as zero. MXCSR is not consulted nor updated.\nAny attempt to execute the TDPBF16PS instruction inside a TSX transaction will result in a transaction abort.", + "operation": "define make_fp32(x):\n // The x parameter is bfloat16. Pack it in to upper 16b of a dword.\n // The bit pattern is a legal fp32 value. Return that bit pattern.\n dword: = 0\n dword[31:16] := x\nreturn dword\n\n\n// C = m x n (tsrcdest), A = m x k (tsrc1), B = k x n (tsrc2)\n# src1 and src2 elements are pairs of bfloat16\nelements_src1 := tsrc1.colsb / 4\nelements_src2 := tsrc2.colsb / 4\nelements_dest := tsrcdest.colsb / 4\nelements_temp := tsrcdest.colsb / 2\nfor m in 0 ... tsrcdest.rows-1:\n temp1[ 0 ... elements_temp-1 ] := 0\n for k in 0 ... elements_src1-1:\n for n in 0 ... elements_dest-1:\n // FP32 FMA with DAZ=FTZ=1, RNE rounding.\n // MXCSR is neither consulted nor updated.\n // No exceptions raised or denoted.\n temp1.fp32[2*n+0] += make_fp32(tsrc1.row[m].bfloat16[2*k+0]) * make_fp32(tsrc2.row[k].bfloat16[2*n+0])\n temp1.fp32[2*n+1] += make_fp32(tsrc1.row[m].bfloat16[2*k+1]) * make_fp32(tsrc2.row[k].bfloat16[2*n+1])\n for n in 0 ... elements_dest-1:\n // DAZ=FTZ=1, RNE rounding.\n // MXCSR is neither consulted nor updated.\n // No exceptions raised or denoted.\n tmpf32 := temp1.fp32[2*n] + temp1.fp32[2*n+1]\n tsrcdest.row[m].fp32[n] := tsrcdest.row[m].fp32[n] + tmpf32\n write_row_and_zero(tsrcdest, m, tmp, tsrcdest.colsb)\nzero_upper_rows(tsrcdest, tsrcdest.rows)\nzero_tilecfg_start()\n", + "url": "https://www.felixcloutier.com/x86/tdpbf16ps" + }, + "tdpbssd": { + "instruction": "TDPBSSD", + "title": "TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD\n\t\t— Dot Product of Signed/Unsigned Bytes with DwordAccumulation", + "opcode": "VEX.128.F2.0F38.W0 5E 11:rrr:bbb TDPBSSD tmm1, tmm2, tmm3", + "description": "For each possible combination of (row of tmm2, column of tmm3), the instruction performs a set of SIMD dot-products on all corresponding four byte elements, one from tmm2 and one from tmm3, adds the results of those dot-products, and then accumulates the result into the corresponding row and column of tmm1. Each dword in input tiles tmm2 and tmm3 is interpreted as four byte elements. These may be signed or unsigned. Each letter in the two-letter pattern SU, US, SS, UU indicates the signed/unsigned nature of the values in tmm2 and tmm3, respectively.\nAny attempt to execute the TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD instructions inside an Intel TSX transaction will result in a transaction abort.", + "operation": "define DPBD(c,x,y):// arguments are dwords\n if *x operand is signed*:\n extend_src1 := SIGN_EXTEND\n else:\n extend_src1 := ZERO_EXTEND\n if *y operand is signed*:\n extend_src2 := SIGN_EXTEND\n else:\n extend_src2 := ZERO_EXTEND\n p0dword := extend_src1(x.byte[0]) * extend_src2(y.byte[0])\n p1dword := extend_src1(x.byte[1]) * extend_src2(y.byte[1])\n p2dword := extend_src1(x.byte[2]) * extend_src2(y.byte[2])\n p3dword := extend_src1(x.byte[3]) * extend_src2(y.byte[3])\n c := c + p0dword + p1dword + p2dword + p3dword\n\n\n// C = m x n (tsrcdest), A = m x k (tsrc1), B = k x n (tsrc2)\ntsrc1_elements_per_row := tsrc1.colsb / 4\ntsrc2_elements_per_row := tsrc2.colsb / 4\ntsrcdest_elements_per_row := tsrcdest.colsb / 4\nfor m in 0 ... tsrcdest.rows-1:\n tmp := tsrcdest.row[m]\n for k in 0 ... tsrc1_elements_per_row-1:\n for n in 0 ... tsrcdest_elements_per_row-1:\n DPBD( tmp.dword[n], tsrc1.row[m].dword[k], tsrc2.row[k].dword[n] )\n write_row_and_zero(tsrcdest, m, tmp, tsrcdest.colsb)\nzero_upper_rows(tsrcdest, tsrcdest.rows)\nzero_tilecfg_start()\n", + "url": "https://www.felixcloutier.com/x86/tdpbssd:tdpbsud:tdpbusd:tdpbuud" + }, + "tdpbsud": { + "instruction": "TDPBSUD", + "title": "TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD\n\t\t— Dot Product of Signed/Unsigned Bytes with DwordAccumulation", + "opcode": "VEX.128.F2.0F38.W0 5E 11:rrr:bbb TDPBSSD tmm1, tmm2, tmm3", + "description": "For each possible combination of (row of tmm2, column of tmm3), the instruction performs a set of SIMD dot-products on all corresponding four byte elements, one from tmm2 and one from tmm3, adds the results of those dot-products, and then accumulates the result into the corresponding row and column of tmm1. Each dword in input tiles tmm2 and tmm3 is interpreted as four byte elements. These may be signed or unsigned. Each letter in the two-letter pattern SU, US, SS, UU indicates the signed/unsigned nature of the values in tmm2 and tmm3, respectively.\nAny attempt to execute the TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD instructions inside an Intel TSX transaction will result in a transaction abort.", + "operation": "define DPBD(c,x,y):// arguments are dwords\n if *x operand is signed*:\n extend_src1 := SIGN_EXTEND\n else:\n extend_src1 := ZERO_EXTEND\n if *y operand is signed*:\n extend_src2 := SIGN_EXTEND\n else:\n extend_src2 := ZERO_EXTEND\n p0dword := extend_src1(x.byte[0]) * extend_src2(y.byte[0])\n p1dword := extend_src1(x.byte[1]) * extend_src2(y.byte[1])\n p2dword := extend_src1(x.byte[2]) * extend_src2(y.byte[2])\n p3dword := extend_src1(x.byte[3]) * extend_src2(y.byte[3])\n c := c + p0dword + p1dword + p2dword + p3dword\n\n\n// C = m x n (tsrcdest), A = m x k (tsrc1), B = k x n (tsrc2)\ntsrc1_elements_per_row := tsrc1.colsb / 4\ntsrc2_elements_per_row := tsrc2.colsb / 4\ntsrcdest_elements_per_row := tsrcdest.colsb / 4\nfor m in 0 ... tsrcdest.rows-1:\n tmp := tsrcdest.row[m]\n for k in 0 ... tsrc1_elements_per_row-1:\n for n in 0 ... tsrcdest_elements_per_row-1:\n DPBD( tmp.dword[n], tsrc1.row[m].dword[k], tsrc2.row[k].dword[n] )\n write_row_and_zero(tsrcdest, m, tmp, tsrcdest.colsb)\nzero_upper_rows(tsrcdest, tsrcdest.rows)\nzero_tilecfg_start()\n", + "url": "https://www.felixcloutier.com/x86/tdpbssd:tdpbsud:tdpbusd:tdpbuud" + }, + "tdpbusd": { + "instruction": "TDPBUSD", + "title": "TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD\n\t\t— Dot Product of Signed/Unsigned Bytes with DwordAccumulation", + "opcode": "VEX.128.F2.0F38.W0 5E 11:rrr:bbb TDPBSSD tmm1, tmm2, tmm3", + "description": "For each possible combination of (row of tmm2, column of tmm3), the instruction performs a set of SIMD dot-products on all corresponding four byte elements, one from tmm2 and one from tmm3, adds the results of those dot-products, and then accumulates the result into the corresponding row and column of tmm1. Each dword in input tiles tmm2 and tmm3 is interpreted as four byte elements. These may be signed or unsigned. Each letter in the two-letter pattern SU, US, SS, UU indicates the signed/unsigned nature of the values in tmm2 and tmm3, respectively.\nAny attempt to execute the TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD instructions inside an Intel TSX transaction will result in a transaction abort.", + "operation": "define DPBD(c,x,y):// arguments are dwords\n if *x operand is signed*:\n extend_src1 := SIGN_EXTEND\n else:\n extend_src1 := ZERO_EXTEND\n if *y operand is signed*:\n extend_src2 := SIGN_EXTEND\n else:\n extend_src2 := ZERO_EXTEND\n p0dword := extend_src1(x.byte[0]) * extend_src2(y.byte[0])\n p1dword := extend_src1(x.byte[1]) * extend_src2(y.byte[1])\n p2dword := extend_src1(x.byte[2]) * extend_src2(y.byte[2])\n p3dword := extend_src1(x.byte[3]) * extend_src2(y.byte[3])\n c := c + p0dword + p1dword + p2dword + p3dword\n\n\n// C = m x n (tsrcdest), A = m x k (tsrc1), B = k x n (tsrc2)\ntsrc1_elements_per_row := tsrc1.colsb / 4\ntsrc2_elements_per_row := tsrc2.colsb / 4\ntsrcdest_elements_per_row := tsrcdest.colsb / 4\nfor m in 0 ... tsrcdest.rows-1:\n tmp := tsrcdest.row[m]\n for k in 0 ... tsrc1_elements_per_row-1:\n for n in 0 ... tsrcdest_elements_per_row-1:\n DPBD( tmp.dword[n], tsrc1.row[m].dword[k], tsrc2.row[k].dword[n] )\n write_row_and_zero(tsrcdest, m, tmp, tsrcdest.colsb)\nzero_upper_rows(tsrcdest, tsrcdest.rows)\nzero_tilecfg_start()\n", + "url": "https://www.felixcloutier.com/x86/tdpbssd:tdpbsud:tdpbusd:tdpbuud" + }, + "tdpbuud": { + "instruction": "TDPBUUD", + "title": "TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD\n\t\t— Dot Product of Signed/Unsigned Bytes with DwordAccumulation", + "opcode": "VEX.128.F2.0F38.W0 5E 11:rrr:bbb TDPBSSD tmm1, tmm2, tmm3", + "description": "For each possible combination of (row of tmm2, column of tmm3), the instruction performs a set of SIMD dot-products on all corresponding four byte elements, one from tmm2 and one from tmm3, adds the results of those dot-products, and then accumulates the result into the corresponding row and column of tmm1. Each dword in input tiles tmm2 and tmm3 is interpreted as four byte elements. These may be signed or unsigned. Each letter in the two-letter pattern SU, US, SS, UU indicates the signed/unsigned nature of the values in tmm2 and tmm3, respectively.\nAny attempt to execute the TDPBSSD/TDPBSUD/TDPBUSD/TDPBUUD instructions inside an Intel TSX transaction will result in a transaction abort.", + "operation": "define DPBD(c,x,y):// arguments are dwords\n if *x operand is signed*:\n extend_src1 := SIGN_EXTEND\n else:\n extend_src1 := ZERO_EXTEND\n if *y operand is signed*:\n extend_src2 := SIGN_EXTEND\n else:\n extend_src2 := ZERO_EXTEND\n p0dword := extend_src1(x.byte[0]) * extend_src2(y.byte[0])\n p1dword := extend_src1(x.byte[1]) * extend_src2(y.byte[1])\n p2dword := extend_src1(x.byte[2]) * extend_src2(y.byte[2])\n p3dword := extend_src1(x.byte[3]) * extend_src2(y.byte[3])\n c := c + p0dword + p1dword + p2dword + p3dword\n\n\n// C = m x n (tsrcdest), A = m x k (tsrc1), B = k x n (tsrc2)\ntsrc1_elements_per_row := tsrc1.colsb / 4\ntsrc2_elements_per_row := tsrc2.colsb / 4\ntsrcdest_elements_per_row := tsrcdest.colsb / 4\nfor m in 0 ... tsrcdest.rows-1:\n tmp := tsrcdest.row[m]\n for k in 0 ... tsrc1_elements_per_row-1:\n for n in 0 ... tsrcdest_elements_per_row-1:\n DPBD( tmp.dword[n], tsrc1.row[m].dword[k], tsrc2.row[k].dword[n] )\n write_row_and_zero(tsrcdest, m, tmp, tsrcdest.colsb)\nzero_upper_rows(tsrcdest, tsrcdest.rows)\nzero_tilecfg_start()\n", + "url": "https://www.felixcloutier.com/x86/tdpbssd:tdpbsud:tdpbusd:tdpbuud" + }, + "test": { + "instruction": "TEST", + "title": "TEST\n\t\t— Logical Compare", + "opcode": "A8 ib", + "description": "Computes the bit-wise logical AND of first operand (source 1 operand) and the second operand (source 2 operand) and sets the SF, ZF, and PF status flags according to the result. The result is then discarded.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "TEMP := SRC1 AND SRC2;\nSF := MSB(TEMP);\nIF TEMP = 0\n THEN ZF := 1;\n ELSE ZF := 0;\nFI:\nPF := BitwiseXNOR(TEMP[0:7]);\nCF := 0;\nOF := 0;\n(* AF is undefined *)\n", + "url": "https://www.felixcloutier.com/x86/test" + }, + "testui": { + "instruction": "TESTUI", + "title": "TESTUI\n\t\t— Determine User Interrupt Flag", + "opcode": "F3 0F 01 ED TESTUI", + "description": "", + "operation": "CF := UIF;\nZF := AF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/testui" + }, + "tileloadd": { + "instruction": "TILELOADD", + "title": "TILELOADD/TILELOADDT1\n\t\t— Load Tile", + "opcode": "VEX.128.F2.0F38.W0 4B !(11):rrr:100 TILELOADD tmm1, sibmem", + "description": "This instruction is required to use SIB addressing. The index register serves as a stride indicator. If the SIB encoding omits an index register, the value zero is assumed for the content of the index register.\nThis instruction loads a tile destination with rows and columns as specified by the tile configuration. The “T1” version provides a hint to the implementation that the data would be reused but does not need to be resident in the nearest cache levels.\nThe TILECFG.start_row in the TILECFG data should be initialized to '0' in order to load the entire tile and is set to zero on successful completion of the TILELOADD instruction. TILELOADD is a restartable instruction and the TILECFG.start_row will be non-zero when restartable events occur during the instruction execution.\nOnly memory operands are supported and they can only be accessed using a SIB addressing mode, similar to the V[P]GATHER*/V[P]SCATTER* instructions.\nAny attempt to execute the TILELOADD/TILELOADDT1 instructions inside an Intel TSX transaction will result in a transaction abort.", + "operation": "TILELOADD[,T1] tdest, tsib\nstart := tilecfg.start_row\nzero_upper_rows(tdest,start)\nmembegin := tsib.base + displacement\n// if no index register in the SIB encoding, the value zero is used.\nstride := tsib.index << tsib.scale\nnbytes := tdest.colsb\nwhile start < tdest.rows:\n memptr := membegin + start * stride\n write_row_and_zero(tdest, start, read_memory(memptr, nbytes), nbytes)\n start := start + 1\nzero_tilecfg_start()\n// In the case of a memory fault in the middle of an instruction, the tilecfg.start_row := start\n", + "url": "https://www.felixcloutier.com/x86/tileloadd:tileloaddt1" + }, + "tileloaddt1": { + "instruction": "TILELOADDT1", + "title": "TILELOADD/TILELOADDT1\n\t\t— Load Tile", + "opcode": "VEX.128.F2.0F38.W0 4B !(11):rrr:100 TILELOADD tmm1, sibmem", + "description": "This instruction is required to use SIB addressing. The index register serves as a stride indicator. If the SIB encoding omits an index register, the value zero is assumed for the content of the index register.\nThis instruction loads a tile destination with rows and columns as specified by the tile configuration. The “T1” version provides a hint to the implementation that the data would be reused but does not need to be resident in the nearest cache levels.\nThe TILECFG.start_row in the TILECFG data should be initialized to '0' in order to load the entire tile and is set to zero on successful completion of the TILELOADD instruction. TILELOADD is a restartable instruction and the TILECFG.start_row will be non-zero when restartable events occur during the instruction execution.\nOnly memory operands are supported and they can only be accessed using a SIB addressing mode, similar to the V[P]GATHER*/V[P]SCATTER* instructions.\nAny attempt to execute the TILELOADD/TILELOADDT1 instructions inside an Intel TSX transaction will result in a transaction abort.", + "operation": "TILELOADD[,T1] tdest, tsib\nstart := tilecfg.start_row\nzero_upper_rows(tdest,start)\nmembegin := tsib.base + displacement\n// if no index register in the SIB encoding, the value zero is used.\nstride := tsib.index << tsib.scale\nnbytes := tdest.colsb\nwhile start < tdest.rows:\n memptr := membegin + start * stride\n write_row_and_zero(tdest, start, read_memory(memptr, nbytes), nbytes)\n start := start + 1\nzero_tilecfg_start()\n// In the case of a memory fault in the middle of an instruction, the tilecfg.start_row := start\n", + "url": "https://www.felixcloutier.com/x86/tileloadd:tileloaddt1" + }, + "tilerelease": { + "instruction": "TILERELEASE", + "title": "TILERELEASE\n\t\t— Release Tile", + "opcode": "VEX.128.NP.0F38.W0 49 C0 TILERELEASE", + "description": "This instruction returns TILECFG and TILEDATA to the INIT state.\nAny attempt to execute the TILERELEASE instruction inside an Intel TSX transaction will result in a transaction abort.", + "operation": "zero_all_tile_data()\ntilecfg := 0// equivalent to 64B of zeros\nTILES_CONFIGURED := 0\n", + "url": "https://www.felixcloutier.com/x86/tilerelease" + }, + "tilestored": { + "instruction": "TILESTORED", + "title": "TILESTORED\n\t\t— Store Tile", + "opcode": "VEX.128.F3.0F38.W0 4B !(11):rrr:100 TILESTORED sibmem, tmm1", + "description": "This instruction is required to use SIB addressing. The index register serves as a stride indicator. If the SIB encoding omits an index register, the value zero is assumed for the content of the index register.\nThis instruction stores a tile source of rows and columns as specified by the tile configuration.\nThe TILECFG.start_row in the TILECFG data should be initialized to '0' in order to store the entire tile and are set to zero on successful completion of the TILESTORED instruction. TILESTORED is a restartable instruction and the TILECFG.start_row will be non-zero when restartable events occur during the instruction execution.\nOnly memory operands are supported and they can only be accessed using a SIB addressing mode, similar to the V[P]GATHER*/V[P]SCATTER* instructions.\nAny attempt to execute the TILESTORED instruction inside an Intel TSX transaction will result in a transaction abort.", + "operation": "TILESTORED tsib, tsrc\nstart := tilecfg.start_row\nmembegin := tsib.base + displacement\n// if no index register in the SIB encoding, the value zero is used.\nstride := tsib.index << tsib.scale\nwhile start < tdest.rows:\n memptr := membegin + start * stride\n write_memory(memptr, tsrc.colsb, tsrc.row[start])\n start := start + 1\nzero_tilecfg_start()\n// In the case of a memory fault in the middle of an instruction, the tilecfg.start_row := start\n", + "url": "https://www.felixcloutier.com/x86/tilestored" + }, + "tilezero": { + "instruction": "TILEZERO", + "title": "TILEZERO\n\t\t— Zero Tile", + "opcode": "VEX.128.F2.0F38.W0 49 11:rrr:000 TILEZERO tmm1", + "description": "This instruction zeroes the destination tile.\nAny attempt to execute the TILEZERO instruction inside an Intel TSX transaction will result in a transaction abort.", + "operation": "TILEZERO tdest\nnbytes := palette_table[palette_id].bytes_per_row\nfor i in 0 ... palette_table[palette_id].max_rows-1:\n for j in 0 ... nbytes-1:\n tdest.row[i].byte[j] := 0\nzero_tilecfg_start()\n", + "url": "https://www.felixcloutier.com/x86/tilezero" + }, + "tpause": { + "instruction": "TPAUSE", + "title": "TPAUSE\n\t\t— Timed PAUSE", + "opcode": "66 0F AE /6 TPAUSE r32, , ", + "description": "TPAUSE instructs the processor to enter an implementation-dependent optimized state. There are two such optimized states to choose from: light-weight power/performance optimized state, and improved power/performance optimized state. The selection between the two is governed by the explicit input register bit[0] source operand.\nTPAUSE is available when CPUID.7.0:ECX.WAITPKG[bit 5] is enumerated as 1. TPAUSE may be executed at any privilege level. This instruction’s operation is the same in non-64-bit modes and in 64-bit mode.\nUnlike PAUSE, the TPAUSE instruction will not cause an abort when used inside a transactional region, described in the chapter Chapter 16, “Programming with Intel® Transactional Synchronization Extensions,” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nThe input register contains information such as the preferred optimized state the processor should enter as described in the following table. Bits other than bit 0 are reserved and will result in #GP if non-zero.\nThe instruction execution wakes up when the time-stamp counter reaches or exceeds the implicit EDX:EAX 64-bit input value.\nPrior to executing the TPAUSE instruction, an operating system may specify the maximum delay it allows the processor to suspend its operation. It can do so by writing TSC-quanta value to the following 32-bit MSR (IA32_UMWAIT_CONTROL at MSR index E1H):\nIf the processor that executed a TPAUSE instruction wakes due to the expiration of the operating system time-limit, the instructions sets RFLAGS.CF; otherwise, that flag is cleared.\nThe following additional events cause the processor to exit the implementation-dependent optimized state: a store to the read-set range within the transactional region, an NMI or SMI, a debug exception, a machine check exception, the BINIT# signal, the INIT# signal, and the RESET# signal.\nOther implementation-dependent events may cause the processor to exit the implementation-dependent optimized state proceeding to the instruction following TPAUSE. In addition, an external interrupt causes the processor to exit the implementation-dependent optimized state regardless of whether maskable-interrupts are inhibited (EFLAGS.IF =0). It should be noted that if maskable-interrupts are inhibited execution will proceed to the instruction following TPAUSE.", + "operation": "os_deadline := TSC+(IA32_UMWAIT_CONTROL[31:2]<<2)\ninstr_deadline := UINT64(EDX:EAX)\nIF os_deadline < instr_deadline:\n deadline := os_deadline\n using_os_deadline := 1\nELSE:\n deadline := instr_deadline\n using_os_deadline := 0\nWHILE TSC < deadline:\n implementation_dependent_optimized_state(Source register, deadline, IA32_UMWAIT_CONTROL[0])\nIF using_os_deadline AND TSC ≥ deadline:\n RFLAGS.CF := 1\nELSE:\n RFLAGS.CF := 0\nRFLAGS.AF,PF,SF,ZF,OF := 0\n", + "url": "https://www.felixcloutier.com/x86/tpause" + }, + "tzcnt": { + "instruction": "TZCNT", + "title": "TZCNT\n\t\t— Count the Number of Trailing Zero Bits", + "opcode": "F3 0F BC /r TZCNT r16, r/m16", + "description": "TZCNT counts the number of trailing least significant zero bits in source operand (second operand) and returns the result in destination operand (first operand). TZCNT is an extension of the BSF instruction. The key difference between TZCNT and BSF instruction is that TZCNT provides operand size as output when source operand is zero while in the case of BSF instruction, if source operand is zero, the content of destination operand are undefined. On processors that do not support TZCNT, the instruction byte encoding is executed as BSF.", + "operation": "temp := 0\nDEST := 0\nDO WHILE ( (temp < OperandSize) and (SRC[ temp] = 0) )\n temp := temp +1\n DEST := DEST+ 1\nOD\nIF DEST = OperandSize\n CF := 1\nELSE\n CF := 0\nFI\nIF DEST = 0\n ZF := 1\nELSE\n ZF := 0\nFI\n", + "url": "https://www.felixcloutier.com/x86/tzcnt" + }, + "ucomisd": { + "instruction": "UCOMISD", + "title": "UCOMISD\n\t\t— Unordered Compare Scalar Double Precision Floating-Point Values and Set EFLAGS", + "opcode": "66 0F 2E /r UCOMISD xmm1, xmm2/m64", + "description": "Performs an unordered compare of the double precision floating-point values in the low quadwords of operand 1 (first operand) and operand 2 (second operand), and sets the ZF, PF, and CF flags in the EFLAGS register according to the result (unordered, greater than, less than, or equal). The OF, SF, and AF flags in the EFLAGS register are set to 0. The unordered result is returned if either source operand is a NaN (QNaN or SNaN).\nOperand 1 is an XMM register; operand 2 can be an XMM register or a 64 bit memory\nlocation.\nThe UCOMISD instruction differs from the COMISD instruction in that it signals a SIMD floating-point invalid operation exception (#I) only when a source operand is an SNaN. The COMISD instruction signals an invalid operation exception only if a source operand is either an SNaN or a QNaN.\nThe EFLAGS register is not updated if an unmasked SIMD floating-point exception is generated.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCOMISD is encoded with VEX.L=0. Encoding VCOMISD with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "RESULT := UnorderedCompare(DEST[63:0] <> SRC[63:0]) {\n(* Set EFLAGS *) CASE (RESULT) OF\n UNORDERED: ZF,PF,CF := 111;\n GREATER_THAN: ZF,PF,CF := 000;\n LESS_THAN: ZF,PF,CF := 001;\n EQUAL: ZF,PF,CF := 100;\nESAC;\nOF, AF, SF := 0; }\n", + "url": "https://www.felixcloutier.com/x86/ucomisd" + }, + "ucomiss": { + "instruction": "UCOMISS", + "title": "UCOMISS\n\t\t— Unordered Compare Scalar Single Precision Floating-Point Values and Set EFLAGS", + "opcode": "NP 0F 2E /r UCOMISS xmm1, xmm2/m32", + "description": "Compares the single precision floating-point values in the low doublewords of operand 1 (first operand) and operand 2 (second operand), and sets the ZF, PF, and CF flags in the EFLAGS register according to the result (unordered, greater than, less than, or equal). The OF, SF, and AF flags in the EFLAGS register are set to 0. The unordered result is returned if either source operand is a NaN (QNaN or SNaN).\nOperand 1 is an XMM register; operand 2 can be an XMM register or a 32 bit memory location.\nThe UCOMISS instruction differs from the COMISS instruction in that it signals a SIMD floating-point invalid operation exception (#I) only if a source operand is an SNaN. The COMISS instruction signals an invalid operation exception when a source operand is either a QNaN or SNaN.\nThe EFLAGS register is not updated if an unmasked SIMD floating-point exception is generated.\nNote: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b, otherwise instructions will #UD.\nSoftware should ensure VCOMISS is encoded with VEX.L=0. Encoding VCOMISS with VEX.L=1 may encounter unpredictable behavior across different processor generations.", + "operation": "RESULT := UnorderedCompare(DEST[31:0] <> SRC[31:0]) {\n(* Set EFLAGS *) CASE (RESULT) OF\n UNORDERED: ZF,PF,CF := 111;\n GREATER_THAN: ZF,PF,CF := 000;\n LESS_THAN: ZF,PF,CF := 001;\n EQUAL: ZF,PF,CF := 100;\nESAC;\nOF, AF, SF := 0; }\n", + "url": "https://www.felixcloutier.com/x86/ucomiss" + }, + "ud": { + "instruction": "UD", + "title": "UD\n\t\t— Undefined Instruction", + "opcode": "0F FF /r", + "description": "Generates an invalid opcode exception. This instruction is provided for software testing to explicitly generate an invalid opcode exception. The opcodes for this instruction are reserved for this purpose.\nOther than raising the invalid opcode exception, this instruction has no effect on processor state or memory.\nEven though it is the execution of the UD instruction that causes the invalid opcode exception, the instruction pointer saved by delivery of the exception references the UD instruction (and not the following instruction).\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "#UD (* Generates invalid opcode exception *);\n", + "url": "https://www.felixcloutier.com/x86/ud" + }, + "uiret": { + "instruction": "UIRET", + "title": "UIRET\n\t\t— User-Interrupt Return", + "opcode": "F3 0F 01 EC UIRET", + "description": "UIRET returns from the handling of a user interrupt. It can be executed regardless of CPL.\nExecution of UIRET inside a transactional region causes a transactional abort; the abort loads EAX as it would have had it been due to an execution of IRET.\nUIRET can be tracked by Architectural Last Branch Records (LBRs), Intel Processor Trace (Intel PT), and Performance Monitoring. For both Intel PT and LBRs, UIRET is recorded in precisely the same manner as IRET. Hence for LBRs, UIRETs fall into the OTHER_BRANCH category, which implies that IA32_LBR_CTL.OTHER_BRANCH[bit 22] must be set to record user-interrupt delivery, and that the IA32_LBR_x_INFO.BR_TYPE field will indicate OTHER_BRANCH for any recorded user interrupt. For Intel PT, control flow tracing must be enabled by setting IA32_RTIT_CTL.BranchEn[bit 13].\nUIRET will also increment performance counters for which counting BR_INST_RETIRED.FAR_BRANCH is enabled.", + "operation": "Pop tempRIP;\nPop tempRFLAGS; // see below for how this is used to load RFLAGS\nPop tempRSP;\nIF tempRIP is not canonical in current paging mode\n THEN #GP(0);\nFI;\nIF ShadowStackEnabled(CPL)\n THEN\n PopShadowStack SSRIP;\n IF SSRIP ≠ tempRIP\n THEN #CP (FAR-RET/IRET);\n FI;\nFI;\nRIP := tempRIP;\n// update in RFLAGS only CF, PF, AF, ZF, SF, TF, DF, OF, NT, RF, AC, and ID\nRFLAGS := (RFLAGS & ~254DD5H) | (tempRFLAGS & 254DD5H);\nRSP := tempRSP;\nUIF := 1;\nClear any cache-line monitoring established by MONITOR or UMONITOR;\n", + "url": "https://www.felixcloutier.com/x86/uiret" + }, + "umonitor": { + "instruction": "UMONITOR", + "title": "UMONITOR\n\t\t— User Level Set Up Monitor Address", + "opcode": "F3 0F AE /6 UMONITOR r16/r32/r64", + "description": "The UMONITOR instruction arms address monitoring hardware using an address specified in the source register (the address range that the monitoring hardware checks for store operations can be determined by using the CPUID monitor leaf function, EAX=05H). A store to an address within the specified address range triggers the monitoring hardware. The state of monitor hardware is used by UMWAIT.\nThe content of the source register is an effective address. By default, the DS segment is used to create a linear address that is monitored. Segment overrides can be used. The address range must use memory of the write-back type. Only write-back memory is guaranteed to correctly trigger the monitoring hardware. Additional information on determining what address range to use in order to prevent false wake-ups is described in Chapter 9, “MultipleProcessor Management‚” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nThe UMONITOR instruction is ordered as a load operation with respect to other memory transactions. The instruction is subject to the permission checking and faults associated with a byte load. Like a load, UMONITOR sets the A-bit but not the D-bit in page tables.\nUMONITOR and UMWAIT are available when CPUID.7.0:ECX.WAITPKG[bit 5] is enumerated as 1. UMONITOR and UMWAIT may be executed at any privilege level. Except for the width of the source register, the instruction’s operation is the same in non-64-bit modes and in 64-bit mode.\nUMONITOR does not interoperate with the legacy MWAIT instruction. If UMONITOR was executed prior to executing MWAIT and following the most recent execution of the legacy MONITOR instruction, MWAIT will not enter an optimized state. Execution will continue to the instruction following MWAIT.\nThe UMONITOR instruction causes a transactional abort when used inside a transactional region.\nThe width of the source register (16b, 32b or 64b) is determined by the effective addressing width, which is affected in the standard way by the machine mode settings and 67 prefix.", + "operation": "UMONITOR sets up an address range for the monitor hardware using the content of source register as an effective\naddress and puts the monitor hardware in armed state. A store to the specified address range will trigger the\nmonitor hardware.\n", + "url": "https://www.felixcloutier.com/x86/umonitor" + }, + "umwait": { + "instruction": "UMWAIT", + "title": "UMWAIT\n\t\t— User Level Monitor Wait", + "opcode": "F2 0F AE /6 UMWAIT r32, , ", + "description": "UMWAIT instructs the processor to enter an implementation-dependent optimized state while monitoring a range of addresses. The optimized state may be either a light-weight power/performance optimized state or an improved power/performance optimized state. The selection between the two states is governed by the explicit input register bit[0] source operand.\nUMWAIT is available when CPUID.7.0:ECX.WAITPKG[bit 5] is enumerated as 1. UMWAIT may be executed at any privilege level. This instruction’s operation is the same in non-64-bit modes and in 64-bit mode.\nThe input register contains information such as the preferred optimized state the processor should enter as described in the following table. Bits other than bit 0 are reserved and will result in #GP if nonzero.\nThe instruction wakes up when the time-stamp counter reaches or exceeds the implicit EDX:EAX 64-bit input value (if the monitoring hardware did not trigger beforehand).\nPrior to executing the UMWAIT instruction, an operating system may specify the maximum delay it allows the processor to suspend its operation. It can do so by writing TSC-quanta value to the following 32bit MSR (IA32_UM-WAIT_CONTROL at MSR index E1H):\nIf the processor that executed a UMWAIT instruction wakes due to the expiration of the operating system timelimit, the instructions sets RFLAGS.CF; otherwise, that flag is cleared.\nThe UMWAIT instruction causes a transactional abort when used inside a transactional region.\nThe UMWAIT instruction operates with the UMONITOR instruction. The two instructions allow the definition of an address at which to wait (UMONITOR) and an implementation-dependent optimized operation to perform while waiting (UMWAIT). The execution of UMWAIT is a hint to the processor that it can enter an implementation-dependent-optimized state while waiting for an event or a store operation to the address range armed by UMONITOR. The UMWAIT instruction will not wait (will not enter an implementation-dependent optimized state) if any of the\nfollowing instructions were executed before UMWAIT and after the most recent execution of UMONITOR: IRET, MONITOR, SYSEXIT, SYSRET, and far RET (the last if it is changing CPL).\nThe following additional events cause the processor to exit the implementation-dependent optimized state: a store to the address range armed by the UMONITOR instruction, an NMI or SMI, a debug exception, a machine check exception, the BINIT# signal, the INIT# signal, and the RESET# signal. Other implementation-dependent events may also cause the processor to exit the implementation-dependent optimized state.\nIn addition, an external interrupt causes the processor to exit the implementation-dependent optimized state regardless of whether maskable-interrupts are inhibited (EFLAGS.IF =0).\nFollowing exit from the implementation-dependent-optimized state, control passes to the instruction after the UMWAIT instruction. A pending interrupt that is not masked (including an NMI or an SMI) may be delivered before execution of that instruction.\nUnlike the HLT instruction, the UMWAIT instruction does not restart at the UMWAIT instruction following the handling of an SMI.\nIf the preceding UMONITOR instruction did not successfully arm an address range or if UMONITOR was not executed prior to executing UMWAIT and following the most recent execution of the legacy MONITOR instruction (UMWAIT does not interoperate with MONITOR), then the processor will not enter an optimized state. Execution will continue to the instruction following UMWAIT.\nA store to the address range armed by the UMONITOR instruction will cause the processor to exit UMWAIT if either the store was originated by other processor agents or the store was originated by a non-processor agent.", + "operation": "os_deadline := TSC+(IA32_UMWAIT_CONTROL[31:2]<<2)\ninstr_deadline := UINT64(EDX:EAX)\nIF os_deadline < instr_deadline:\n deadline := os_deadline\n using_os_deadline := 1\nELSE:\n deadline := instr_deadline\n using_os_deadline := 0\nWHILE monitor hardware armed AND TSC < deadline:\n implementation_dependent_optimized_state(Source register, deadline, IA32_UMWAIT_CONTROL[0] )\nIF using_os_deadline AND TSC ≥ deadline:\n RFLAGS.CF := 1\nELSE:\n RFLAGS.CF := 0\nRFLAGS.AF,PF,SF,ZF,OF := 0\n", + "url": "https://www.felixcloutier.com/x86/umwait" + }, + "unpckhpd": { + "instruction": "UNPCKHPD", + "title": "UNPCKHPD\n\t\t— Unpack and Interleave High Packed Double Precision Floating-Point Values", + "opcode": "66 0F 15 /r UNPCKHPD xmm1, xmm2/m128", + "description": "Performs an interleaved unpack of the high double precision floating-point values from the first source operand and the second source operand. See Figure 4-15 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified. When unpacking from a memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to 16-byte boundary and normal segment checking will still be enforced.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM register, conditionally updated using writemask k1.\nEVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register, a 256-bit memory location, or a 256-bit vector broadcasted from a 64-bit memory location. The destination operand is a YMM register, conditionally updated using writemask k1.\nEVEX.128 encoded version: The first source operand is a XMM register. The second source operand is a XMM register, a 128-bit memory location, or a 128-bit vector broadcasted from a 64-bit memory location. The destination operand is a XMM register, conditionally updated using writemask k1.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF VL >= 128\n TMP_DEST[63:0] := SRC1[127:64]\n TMP_DEST[127:64] := SRC2[127:64]\nFI;\nIF VL >= 256\n TMP_DEST[191:128] := SRC1[255:192]\n TMP_DEST[255:192] := SRC2[255:192]\nFI;\nIF VL >= 512\n TMP_DEST[319:256] := SRC1[383:320]\n TMP_DEST[383:320] := SRC2[383:320]\n TMP_DEST[447:384] := SRC1[511:448]\n TMP_DEST[511:448] := SRC2[511:448]\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL >= 128\n TMP_DEST[63:0] := SRC1[127:64]\n TMP_DEST[127:64] := TMP_SRC2[127:64]\nFI;\nIF VL >= 256\n TMP_DEST[191:128] := SRC1[255:192]\n TMP_DEST[255:192] := TMP_SRC2[255:192]\nFI;\nIF VL >= 512\n TMP_DEST[319:256] := SRC1[383:320]\n TMP_DEST[383:320] := TMP_SRC2[383:320]\n TMP_DEST[447:384] := SRC1[511:448]\n TMP_DEST[511:448] := TMP_SRC2[511:448]\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[191:128] := SRC1[255:192]\nDEST[255:192] := SRC2[255:192]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[127:64]\nDEST[127:64] := SRC2[127:64]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/unpckhpd" + }, + "unpckhps": { + "instruction": "UNPCKHPS", + "title": "UNPCKHPS\n\t\t— Unpack and Interleave High Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 15 /r UNPCKHPS xmm1, xmm2/m128", + "description": "Performs an interleaved unpack of the high single precision floating-point values from the first source operand and the second source operand.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified. When unpacking from a memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to 16-byte boundary and normal segment checking will still be enforced.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.256 encoded version: The second source operand is an YMM register or an 256-bit memory location. The first source operand and destination operands are YMM registers.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM register, conditionally updated using writemask k1.\nEVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register, a 256-bit memory location, or a 256-bit vector broadcasted from a 32-bit memory location. The destination operand is a YMM register, conditionally updated using writemask k1.\nEVEX.128 encoded version: The first source operand is a XMM register. The second source operand is a XMM register, a 128-bit memory location, or a 128-bit vector broadcasted from a 32-bit memory location. The destination operand is a XMM register, conditionally updated using writemask k1.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL >= 128\n TMP_DEST[31:0] := SRC1[95:64]\n TMP_DEST[63:32] := SRC2[95:64]\n TMP_DEST[95:64] := SRC1[127:96]\n TMP_DEST[127:96] := SRC2[127:96]\nFI;\nIF VL >= 256\n TMP_DEST[159:128] := SRC1[223:192]\n TMP_DEST[191:160] := SRC2[223:192]\n TMP_DEST[223:192] := SRC1[255:224]\n TMP_DEST[255:224] := SRC2[255:224]\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := SRC1[351:320]\n TMP_DEST[319:288] := SRC2[351:320]\n TMP_DEST[351:320] := SRC1[383:352]\n TMP_DEST[383:352] := SRC2[383:352]\n TMP_DEST[415:384] := SRC1[479:448]\n TMP_DEST[447:416] := SRC2[479:448]\n TMP_DEST[479:448] := SRC1[511:480]\n TMP_DEST[511:480] := SRC2[511:480]\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF (EVEX.b = 1)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL >= 128\n TMP_DEST[31:0] := SRC1[95:64]\n TMP_DEST[63:32] := TMP_SRC2[95:64]\n TMP_DEST[95:64] := SRC1[127:96]\n TMP_DEST[127:96] := TMP_SRC2[127:96]\nFI;\nIF VL >= 256\n TMP_DEST[159:128] := SRC1[223:192]\n TMP_DEST[191:160] := TMP_SRC2[223:192]\n TMP_DEST[223:192] := SRC1[255:224]\n TMP_DEST[255:224] := TMP_SRC2[255:224]\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := SRC1[351:320]\n TMP_DEST[319:288] := TMP_SRC2[351:320]\n TMP_DEST[351:320] := SRC1[383:352]\n TMP_DEST[383:352] := TMP_SRC2[383:352]\n TMP_DEST[415:384] := SRC1[479:448]\n TMP_DEST[447:416] := TMP_SRC2[479:448]\n TMP_DEST[479:448] := SRC1[511:480]\n TMP_DEST[511:480] := TMP_SRC2[511:480]\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI;\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[159:128] := SRC1[223:192]\nDEST[191:160] := SRC2[223:192]\nDEST[223:192] := SRC1[255:224]\nDEST[255:224] := SRC2[255:224]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[95:64]\nDEST[63:32] := SRC2[95:64]\nDEST[95:64] := SRC1[127:96]\nDEST[127:96] := SRC2[127:96]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/unpckhps" + }, + "unpcklpd": { + "instruction": "UNPCKLPD", + "title": "UNPCKLPD\n\t\t— Unpack and Interleave Low Packed Double Precision Floating-Point Values", + "opcode": "66 0F 14 /r UNPCKLPD xmm1, xmm2/m128", + "description": "Performs an interleaved unpack of the low double precision floating-point values from the first source operand and the second source operand.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified. When unpacking from a memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to 16-byte boundary and normal segment checking will still be enforced.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 64-bit memory location. The destination operand is a ZMM register, conditionally updated using writemask k1.\nEVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register, a 256-bit memory location, or a 256-bit vector broadcasted from a 64-bit memory location. The destination operand is a YMM register, conditionally updated using writemask k1.\nEVEX.128 encoded version: The first source operand is an XMM register. The second source operand is a XMM register, a 128-bit memory location, or a 128-bit vector broadcasted from a 64-bit memory location. The destination operand is a XMM register, conditionally updated using writemask k1.", + "operation": "(KL, VL) = (2, 128), (4, 256), (8, 512)\nIF VL >= 128\n TMP_DEST[63:0] := SRC1[63:0]\n TMP_DEST[127:64] := SRC2[63:0]\nFI;\nIF VL >= 256\n TMP_DEST[191:128] := SRC1[191:128]\n TMP_DEST[255:192] := SRC2[191:128]\nFI;\nIF VL >= 512\n TMP_DEST[319:256] := SRC1[319:256]\n TMP_DEST[383:320] := SRC2[319:256]\n TMP_DEST[447:384] := SRC1[447:384]\n TMP_DEST[511:448] := SRC2[447:384]\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF (EVEX.b = 1)\n THEN TMP_SRC2[i+63:i] := SRC2[63:0]\n ELSE TMP_SRC2[i+63:i] := SRC2[i+63:i]\n FI;\nENDFOR;\nIF VL >= 128\n TMP_DEST[63:0] := SRC1[63:0]\n TMP_DEST[127:64] := TMP_SRC2[63:0]\nFI;\nIF VL >= 256\n TMP_DEST[191:128] := SRC1[191:128]\n TMP_DEST[255:192] := TMP_SRC2[191:128]\nFI;\nIF VL >= 512\n TMP_DEST[319:256] := SRC1[319:256]\n TMP_DEST[383:320] := TMP_SRC2[319:256]\n TMP_DEST[447:384] := SRC1[447:384]\n TMP_DEST[511:448] := TMP_SRC2[447:384]\nFI;\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := TMP_DEST[i+63:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+63:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+63:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[191:128] := SRC1[191:128]\nDEST[255:192] := SRC2[191:128]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := SRC1[63:0]\nDEST[127:64] := SRC2[63:0]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/unpcklpd" + }, + "unpcklps": { + "instruction": "UNPCKLPS", + "title": "UNPCKLPS\n\t\t— Unpack and Interleave Low Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 14 /r UNPCKLPS xmm1, xmm2/m128", + "description": "Performs an interleaved unpack of the low single precision floating-point values from the first source operand and the second source operand.\n128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The destination is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding ZMM register destination are unmodified. When unpacking from a memory operand, an implementation may fetch only the appropriate 64 bits; however, alignment to 16-byte boundary and normal segment checking will still be enforced.\nVEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of the corresponding ZMM register destination are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM register or a 256-bit memory location. The destination operand is a YMM register.\nEVEX.512 encoded version: The first source operand is a ZMM register. The second source operand is a ZMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM register, conditionally updated using writemask k1.\nEVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register, a 256-bit memory location, or a 256-bit vector broadcasted from a 32-bit memory location. The destination operand is a YMM register, conditionally updated using writemask k1.\nEVEX.128 encoded version: The first source operand is an XMM register. The second source operand is a XMM register, a 128-bit memory location, or a 128-bit vector broadcasted from a 32-bit memory location. The destination operand is a XMM register, conditionally updated using writemask k1.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nIF VL >= 128\n TMP_DEST[31:0] := SRC1[31:0]\n TMP_DEST[63:32] := SRC2[31:0]\n TMP_DEST[95:64] := SRC1[63:32]\n TMP_DEST[127:96] := SRC2[63:32]\nFI;\nIF VL >= 256\n TMP_DEST[159:128] := SRC1[159:128]\n TMP_DEST[191:160] := SRC2[159:128]\n TMP_DEST[223:192] := SRC1[191:160]\n TMP_DEST[255:224] := SRC2[191:160]\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := SRC1[287:256]\n TMP_DEST[319:288] := SRC2[287:256]\n TMP_DEST[351:320] := SRC1[319:288]\n TMP_DEST[383:352] := SRC2[319:288]\n TMP_DEST[415:384] := SRC1[415:384]\n TMP_DEST[447:416] := SRC2[415:384]\n TMP_DEST[479:448] := SRC1[447:416]\n TMP_DEST[511:480] := SRC2[447:416]\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking*\n ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 31\n IF (EVEX.b = 1)\n THEN TMP_SRC2[i+31:i] := SRC2[31:0]\n ELSE TMP_SRC2[i+31:i] := SRC2[i+31:i]\n FI;\nENDFOR;\nIF VL >= 128\nTMP_DEST[31:0] := SRC1[31:0]\nTMP_DEST[63:32] := TMP_SRC2[31:0]\nTMP_DEST[95:64] := SRC1[63:32]\nTMP_DEST[127:96] := TMP_SRC2[63:32]\nFI;\nIF VL >= 256\n TMP_DEST[159:128] := SRC1[159:128]\n TMP_DEST[191:160] := TMP_SRC2[159:128]\n TMP_DEST[223:192] := SRC1[191:160]\n TMP_DEST[255:224] := TMP_SRC2[191:160]\nFI;\nIF VL >= 512\n TMP_DEST[287:256] := SRC1[287:256]\n TMP_DEST[319:288] := TMP_SRC2[287:256]\n TMP_DEST[351:320] := SRC1[319:288]\n TMP_DEST[383:352] := TMP_SRC2[319:288]\n TMP_DEST[415:384] := SRC1[415:384]\n TMP_DEST[447:416] := TMP_SRC2[415:384]\n TMP_DEST[479:448] := SRC1[447:416]\n TMP_DEST[511:480] := TMP_SRC2[447:416]\nFI;\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := TMP_DEST[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE *zeroing-masking* ; zeroing-masking\n DEST[i+31:i] := 0\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[159:128] := SRC1[159:128]\nDEST[191:160] := SRC2[159:128]\nDEST[223:192] := SRC1[191:160]\nDEST[255:224] := SRC2[191:160]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := SRC1[31:0]\nDEST[63:32] := SRC2[31:0]\nDEST[95:64] := SRC1[63:32]\nDEST[127:96] := SRC2[63:32]\nDEST[MAXVL-1:128] (Unmodified)\n", + "url": "https://www.felixcloutier.com/x86/unpcklps" + }, + "v4fmaddps": { + "instruction": "V4FMADDPS", + "title": "V4FMADDPS/V4FNMADDPS\n\t\t— Packed Single Precision Floating-Point Fused Multiply-Add(4-Iterations)", + "opcode": "EVEX.512.F2.0F38.W0 9A /r V4FMADDPS zmm1{k1}{z}, zmm2+3, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/v4fmaddps:v4fnmaddps" + }, + "v4fmaddss": { + "instruction": "V4FMADDSS", + "title": "V4FMADDSS/V4FNMADDSS\n\t\t— Scalar Single Precision Floating-Point Fused Multiply-Add(4-Iterations)", + "opcode": "EVEX.LLIG.F2.0F38.W0 9B /r V4FMADDSS xmm1{k1}{z}, xmm2+3, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/v4fmaddss:v4fnmaddss" + }, + "v4fnmaddps": { + "instruction": "V4FNMADDPS", + "title": "V4FMADDPS/V4FNMADDPS\n\t\t— Packed Single Precision Floating-Point Fused Multiply-Add(4-Iterations)", + "opcode": "EVEX.512.F2.0F38.W0 9A /r V4FMADDPS zmm1{k1}{z}, zmm2+3, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/v4fmaddps:v4fnmaddps" + }, + "v4fnmaddss": { + "instruction": "V4FNMADDSS", + "title": "V4FMADDSS/V4FNMADDSS\n\t\t— Scalar Single Precision Floating-Point Fused Multiply-Add(4-Iterations)", + "opcode": "EVEX.LLIG.F2.0F38.W0 9B /r V4FMADDSS xmm1{k1}{z}, xmm2+3, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/v4fmaddss:v4fnmaddss" + }, + "vaddph": { + "instruction": "VADDPH", + "title": "VADDPH\n\t\t— Add Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 58 /r VADDPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vaddph" + }, + "vaddsh": { + "instruction": "VADDSH", + "title": "VADDSH\n\t\t— Add Scalar FP16 Values", + "opcode": "EVEX.LLIG.F3.MAP5.W0 58 /r VADDSH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vaddsh" + }, + "valignd": { + "instruction": "VALIGND", + "title": "VALIGND/VALIGNQ\n\t\t— Align Doubleword/Quadword Vectors", + "opcode": "EVEX.128.66.0F3A.W0 03 /r ib VALIGND xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/valignd:valignq" + }, + "valignq": { + "instruction": "VALIGNQ", + "title": "VALIGND/VALIGNQ\n\t\t— Align Doubleword/Quadword Vectors", + "opcode": "EVEX.128.66.0F3A.W0 03 /r ib VALIGND xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/valignd:valignq" + }, + "vblendmpd": { + "instruction": "VBLENDMPD", + "title": "VBLENDMPD/VBLENDMPS\n\t\t— Blend Float64/Float32 Vectors Using an OpMask Control", + "opcode": "EVEX.128.66.0F38.W1 65 /r VBLENDMPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vblendmpd:vblendmps" + }, + "vblendmps": { + "instruction": "VBLENDMPS", + "title": "VBLENDMPD/VBLENDMPS\n\t\t— Blend Float64/Float32 Vectors Using an OpMask Control", + "opcode": "EVEX.128.66.0F38.W1 65 /r VBLENDMPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vblendmpd:vblendmps" + }, + "vbroadcast": { + "instruction": "VBROADCAST", + "title": "VBROADCAST\n\t\t— Load with Broadcast Floating-Point Data", + "opcode": "VEX.128.66.0F38.W0 18 /r VBROADCASTSS xmm1, m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vbroadcast" + }, + "vcmpph": { + "instruction": "VCMPPH", + "title": "VCMPPH\n\t\t— Compare Packed FP16 Values", + "opcode": "EVEX.128.NP.0F3A.W0 C2 /r /ib VCMPPH k1{k2}, xmm2, xmm3/m128/m16bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcmpph" + }, + "vcmpsh": { + "instruction": "VCMPSH", + "title": "VCMPSH\n\t\t— Compare Scalar FP16 Values", + "opcode": "EVEX.LLIG.F3.0F3A.W0 C2 /r /ib VCMPSH k1{k2}, xmm2, xmm3/m16 {sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcmpsh" + }, + "vcomish": { + "instruction": "VCOMISH", + "title": "VCOMISH\n\t\t— Compare Scalar Ordered FP16 Values and Set EFLAGS", + "opcode": "VCOMISH xmm1, xmm2/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcomish" + }, + "vcompresspd": { + "instruction": "VCOMPRESSPD", + "title": "VCOMPRESSPD\n\t\t— Store Sparse Packed Double Precision Floating-Point Values Into DenseMemory", + "opcode": "EVEX.128.66.0F38.W1 8A /r VCOMPRESSPD xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcompresspd" + }, + "vcompressps": { + "instruction": "VCOMPRESSPS", + "title": "VCOMPRESSPS\n\t\t— Store Sparse Packed Single Precision Floating-Point Values Into Dense Memory", + "opcode": "EVEX.128.66.0F38.W0 8A /r VCOMPRESSPS xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcompressps" + }, + "vcompressw": { + "instruction": "VCOMPRESSW", + "title": "VPCOMPRESSB/VCOMPRESSW\n\t\t— Store Sparse Packed Byte/Word Integer Values Into DenseMemory/Register", + "opcode": "EVEX.128.66.0F38.W0 63 /r VPCOMPRESSB m128{k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcompressb:vcompressw" + }, + "vcvtdq2ph": { + "instruction": "VCVTDQ2PH", + "title": "VCVTDQ2PH\n\t\t— Convert Packed Signed Doubleword Integers to Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 5B /r VCVTDQ2PH xmm1{k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtdq2ph" + }, + "vcvtne2ps2bf16": { + "instruction": "VCVTNE2PS2BF16", + "title": "VCVTNE2PS2BF16\n\t\t— Convert Two Packed Single Data to One Packed BF16 Data", + "opcode": "EVEX.128.F2.0F38.W0 72 /r VCVTNE2PS2BF16 xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtne2ps2bf16" + }, + "vcvtneps2bf16": { + "instruction": "VCVTNEPS2BF16", + "title": "VCVTNEPS2BF16\n\t\t— Convert Packed Single Data to Packed BF16 Data", + "opcode": "EVEX.128.F3.0F38.W0 72 /r VCVTNEPS2BF16 xmm1{k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtneps2bf16" + }, + "vcvtpd2ph": { + "instruction": "VCVTPD2PH", + "title": "VCVTPD2PH\n\t\t— Convert Packed Double Precision FP Values to Packed FP16 Values", + "opcode": "EVEX.128.66.MAP5.W1 5A /r VCVTPD2PH xmm1{k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtpd2ph" + }, + "vcvtpd2qq": { + "instruction": "VCVTPD2QQ", + "title": "VCVTPD2QQ\n\t\t— Convert Packed Double Precision Floating-Point Values to Packed QuadwordIntegers", + "opcode": "EVEX.128.66.0F.W1 7B /r VCVTPD2QQ xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtpd2qq" + }, + "vcvtpd2udq": { + "instruction": "VCVTPD2UDQ", + "title": "VCVTPD2UDQ\n\t\t— Convert Packed Double Precision Floating-Point Values to Packed UnsignedDoubleword Integers", + "opcode": "EVEX.128.0F.W1 79 /r VCVTPD2UDQ xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtpd2udq" + }, + "vcvtpd2uqq": { + "instruction": "VCVTPD2UQQ", + "title": "VCVTPD2UQQ\n\t\t— Convert Packed Double Precision Floating-Point Values to Packed UnsignedQuadword Integers", + "opcode": "EVEX.128.66.0F.W1 79 /r VCVTPD2UQQ xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtpd2uqq" + }, + "vcvtph2dq": { + "instruction": "VCVTPH2DQ", + "title": "VCVTPH2DQ\n\t\t— Convert Packed FP16 Values to Signed Doubleword Integers", + "opcode": "EVEX.128.66.MAP5.W0 5B /r VCVTPH2DQ xmm1{k1}{z}, xmm2/m64/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2dq" + }, + "vcvtph2pd": { + "instruction": "VCVTPH2PD", + "title": "VCVTPH2PD\n\t\t— Convert Packed FP16 Values to FP64 Values", + "opcode": "EVEX.128.NP.MAP5.W0 5A /r VCVTPH2PD xmm1{k1}{z}, xmm2/m32/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2pd" + }, + "vcvtph2ps": { + "instruction": "VCVTPH2PS", + "title": "VCVTPH2PS/VCVTPH2PSX\n\t\t— Convert Packed FP16 Values to Single Precision Floating-PointValues", + "opcode": "VEX.128.66.0F38.W0 13 /r VCVTPH2PS xmm1, xmm2/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2ps:vcvtph2psx" + }, + "vcvtph2psx": { + "instruction": "VCVTPH2PSX", + "title": "VCVTPH2PS/VCVTPH2PSX\n\t\t— Convert Packed FP16 Values to Single Precision Floating-PointValues", + "opcode": "VEX.128.66.0F38.W0 13 /r VCVTPH2PS xmm1, xmm2/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2ps:vcvtph2psx" + }, + "vcvtph2qq": { + "instruction": "VCVTPH2QQ", + "title": "VCVTPH2QQ\n\t\t— Convert Packed FP16 Values to Signed Quadword Integer Values", + "opcode": "EVEX.128.66.MAP5.W0 7B /r VCVTPH2QQ xmm1{k1}{z}, xmm2/m32/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2qq" + }, + "vcvtph2udq": { + "instruction": "VCVTPH2UDQ", + "title": "VCVTPH2UDQ\n\t\t— Convert Packed FP16 Values to Unsigned Doubleword Integers", + "opcode": "EVEX.128.NP.MAP5.W0 79 /r VCVTPH2UDQ xmm1{k1}{z}, xmm2/m64/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2udq" + }, + "vcvtph2uqq": { + "instruction": "VCVTPH2UQQ", + "title": "VCVTPH2UQQ\n\t\t— Convert Packed FP16 Values to Unsigned Quadword Integers", + "opcode": "EVEX.128.66.MAP5.W0 79 /r VCVTPH2UQQ xmm1{k1}{z}, xmm2/m32/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2uqq" + }, + "vcvtph2uw": { + "instruction": "VCVTPH2UW", + "title": "VCVTPH2UW\n\t\t— Convert Packed FP16 Values to Unsigned Word Integers", + "opcode": "EVEX.128.NP.MAP5.W0 7D /r VCVTPH2UW xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2uw" + }, + "vcvtph2w": { + "instruction": "VCVTPH2W", + "title": "VCVTPH2W\n\t\t— Convert Packed FP16 Values to Signed Word Integers", + "opcode": "EVEX.128.66.MAP5.W0 7D /r VCVTPH2W xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtph2w" + }, + "vcvtps2ph": { + "instruction": "VCVTPS2PH", + "title": "VCVTPS2PH\n\t\t— Convert Single-Precision FP Value to 16-bit FP Value", + "opcode": "VEX.128.66.0F3A.W0 1D /r ib VCVTPS2PH xmm1/m64, xmm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtps2ph" + }, + "vcvtps2phx": { + "instruction": "VCVTPS2PHX", + "title": "VCVTPS2PHX\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed FP16 Values", + "opcode": "EVEX.128.66.MAP5.W0 1D /r VCVTPS2PHX xmm1{k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtps2phx" + }, + "vcvtps2qq": { + "instruction": "VCVTPS2QQ", + "title": "VCVTPS2QQ\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed SignedQuadword Integer Values", + "opcode": "EVEX.128.66.0F.W0 7B /r VCVTPS2QQ xmm1 {k1}{z}, xmm2/m64/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtps2qq" + }, + "vcvtps2udq": { + "instruction": "VCVTPS2UDQ", + "title": "VCVTPS2UDQ\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed UnsignedDoubleword Integer Values", + "opcode": "EVEX.128.0F.W0 79 /r VCVTPS2UDQ xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtps2udq" + }, + "vcvtps2uqq": { + "instruction": "VCVTPS2UQQ", + "title": "VCVTPS2UQQ\n\t\t— Convert Packed Single Precision Floating-Point Values to Packed UnsignedQuadword Integer Values", + "opcode": "EVEX.128.66.0F.W0 79 /r VCVTPS2UQQ xmm1 {k1}{z}, xmm2/m64/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtps2uqq" + }, + "vcvtqq2pd": { + "instruction": "VCVTQQ2PD", + "title": "VCVTQQ2PD\n\t\t— Convert Packed Quadword Integers to Packed Double Precision Floating-PointValues", + "opcode": "EVEX.128.F3.0F.W1 E6 /r VCVTQQ2PD xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtqq2pd" + }, + "vcvtqq2ph": { + "instruction": "VCVTQQ2PH", + "title": "VCVTQQ2PH\n\t\t— Convert Packed Signed Quadword Integers to Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W1 5B /r VCVTQQ2PH xmm1{k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtqq2ph" + }, + "vcvtqq2ps": { + "instruction": "VCVTQQ2PS", + "title": "VCVTQQ2PS\n\t\t— Convert Packed Quadword Integers to Packed Single Precision Floating-PointValues", + "opcode": "EVEX.128.0F.W1 5B /r VCVTQQ2PS xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtqq2ps" + }, + "vcvtsd2sh": { + "instruction": "VCVTSD2SH", + "title": "VCVTSD2SH\n\t\t— Convert Low FP64 Value to an FP16 Value", + "opcode": "EVEX.LLIG.F2.MAP5.W1 5A /r VCVTSD2SH xmm1{k1}{z}, xmm2, xmm3/m64 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsd2sh" + }, + "vcvtsd2usi": { + "instruction": "VCVTSD2USI", + "title": "VCVTSD2USI\n\t\t— Convert Scalar Double Precision Floating-Point Value to Unsigned DoublewordInteger", + "opcode": "EVEX.LLIG.F2.0F.W0 79 /r VCVTSD2USI r32, xmm1/m64{er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsd2usi" + }, + "vcvtsh2sd": { + "instruction": "VCVTSH2SD", + "title": "VCVTSH2SD\n\t\t— Convert Low FP16 Value to an FP64 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 5A /r VCVTSH2SD xmm1{k1}{z}, xmm2, xmm3/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsh2sd" + }, + "vcvtsh2si": { + "instruction": "VCVTSH2SI", + "title": "VCVTSH2SI\n\t\t— Convert Low FP16 Value to Signed Integer", + "opcode": "EVEX.LLIG.F3.MAP5.W0 2D /r VCVTSH2SI r32, xmm1/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsh2si" + }, + "vcvtsh2ss": { + "instruction": "VCVTSH2SS", + "title": "VCVTSH2SS\n\t\t— Convert Low FP16 Value to FP32 Value", + "opcode": "EVEX.LLIG.NP.MAP6.W0 13 /r VCVTSH2SS xmm1{k1}{z}, xmm2, xmm3/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsh2ss" + }, + "vcvtsh2usi": { + "instruction": "VCVTSH2USI", + "title": "VCVTSH2USI\n\t\t— Convert Low FP16 Value to Unsigned Integer", + "opcode": "EVEX.LLIG.F3.MAP5.W0 79 /r VCVTSH2USI r32, xmm1/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsh2usi" + }, + "vcvtsi2sh": { + "instruction": "VCVTSI2SH", + "title": "VCVTSI2SH\n\t\t— Convert a Signed Doubleword/Quadword Integer to an FP16 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 2A /r VCVTSI2SH xmm1, xmm2, r32/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtsi2sh" + }, + "vcvtss2sh": { + "instruction": "VCVTSS2SH", + "title": "VCVTSS2SH\n\t\t— Convert Low FP32 Value to an FP16 Value", + "opcode": "EVEX.LLIG.NP.MAP5.W0 1D /r VCVTSS2SH xmm1{k1}{z}, xmm2, xmm3/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtss2sh" + }, + "vcvtss2usi": { + "instruction": "VCVTSS2USI", + "title": "VCVTSS2USI\n\t\t— Convert Scalar Single Precision Floating-Point Value to Unsigned DoublewordInteger", + "opcode": "EVEX.LLIG.F3.0F.W0 79 /r VCVTSS2USI r32, xmm1/m32{er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtss2usi" + }, + "vcvttpd2qq": { + "instruction": "VCVTTPD2QQ", + "title": "VCVTTPD2QQ\n\t\t— Convert With Truncation Packed Double Precision Floating-Point Values toPacked Quadword Integers", + "opcode": "EVEX.128.66.0F.W1 7A /r VCVTTPD2QQ xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttpd2qq" + }, + "vcvttpd2udq": { + "instruction": "VCVTTPD2UDQ", + "title": "VCVTTPD2UDQ\n\t\t— Convert With Truncation Packed Double Precision Floating-Point Values toPacked Unsigned Doubleword Integers", + "opcode": "EVEX.128.0F.W1 78 /r VCVTTPD2UDQ xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttpd2udq" + }, + "vcvttpd2uqq": { + "instruction": "VCVTTPD2UQQ", + "title": "VCVTTPD2UQQ\n\t\t— Convert With Truncation Packed Double Precision Floating-Point Values toPacked Unsigned Quadword Integers", + "opcode": "EVEX.128.66.0F.W1 78 /r VCVTTPD2UQQ xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttpd2uqq" + }, + "vcvttph2dq": { + "instruction": "VCVTTPH2DQ", + "title": "VCVTTPH2DQ\n\t\t— Convert with Truncation Packed FP16 Values to Signed Doubleword Integers", + "opcode": "EVEX.128.F3.MAP5.W0 5B /r VCVTTPH2DQ xmm1{k1}{z}, xmm2/m64/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttph2dq" + }, + "vcvttph2qq": { + "instruction": "VCVTTPH2QQ", + "title": "VCVTTPH2QQ\n\t\t— Convert with Truncation Packed FP16 Values to Signed Quadword Integers", + "opcode": "EVEX.128.66.MAP5.W0 7A /r VCVTTPH2QQ xmm1{k1}{z}, xmm2/m32/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttph2qq" + }, + "vcvttph2udq": { + "instruction": "VCVTTPH2UDQ", + "title": "VCVTTPH2UDQ\n\t\t— Convert with Truncation Packed FP16 Values to Unsigned DoublewordIntegers", + "opcode": "EVEX.128.NP.MAP5.W0 78 /r VCVTTPH2UDQ xmm1{k1}{z}, xmm2/m64/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttph2udq" + }, + "vcvttph2uqq": { + "instruction": "VCVTTPH2UQQ", + "title": "VCVTTPH2UQQ\n\t\t— Convert with Truncation Packed FP16 Values to Unsigned Quadword Integers", + "opcode": "EVEX.128.66.MAP5.W0 78 /r VCVTTPH2UQQ xmm1{k1}{z}, xmm2/m32/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttph2uqq" + }, + "vcvttph2uw": { + "instruction": "VCVTTPH2UW", + "title": "VCVTTPH2UW\n\t\t— Convert Packed FP16 Values to Unsigned Word Integers", + "opcode": "EVEX.128.NP.MAP5.W0 7C /r VCVTTPH2UW xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttph2uw" + }, + "vcvttph2w": { + "instruction": "VCVTTPH2W", + "title": "VCVTTPH2W\n\t\t— Convert Packed FP16 Values to Signed Word Integers", + "opcode": "EVEX.128.66.MAP5.W0 7C /r VCVTTPH2W xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttph2w" + }, + "vcvttps2qq": { + "instruction": "VCVTTPS2QQ", + "title": "VCVTTPS2QQ\n\t\t— Convert With Truncation Packed Single Precision Floating-Point Values toPacked Signed Quadword Integer Values", + "opcode": "EVEX.128.66.0F.W0 7A /r VCVTTPS2QQ xmm1 {k1}{z}, xmm2/m64/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttps2qq" + }, + "vcvttps2udq": { + "instruction": "VCVTTPS2UDQ", + "title": "VCVTTPS2UDQ\n\t\t— Convert With Truncation Packed Single Precision Floating-Point Values toPacked Unsigned Doubleword Integer Values", + "opcode": "EVEX.128.0F.W0 78 /r VCVTTPS2UDQ xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttps2udq" + }, + "vcvttps2uqq": { + "instruction": "VCVTTPS2UQQ", + "title": "VCVTTPS2UQQ\n\t\t— Convert With Truncation Packed Single Precision Floating-Point Values toPacked Unsigned Quadword Integer Values", + "opcode": "EVEX.128.66.0F.W0 78 /r VCVTTPS2UQQ xmm1 {k1}{z}, xmm2/m64/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttps2uqq" + }, + "vcvttsd2usi": { + "instruction": "VCVTTSD2USI", + "title": "VCVTTSD2USI\n\t\t— Convert With Truncation Scalar Double Precision Floating-Point Value toUnsigned Integer", + "opcode": "EVEX.LLIG.F2.0F.W0 78 /r VCVTTSD2USI r32, xmm1/m64{sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttsd2usi" + }, + "vcvttsh2si": { + "instruction": "VCVTTSH2SI", + "title": "VCVTTSH2SI\n\t\t— Convert with Truncation Low FP16 Value to a Signed Integer", + "opcode": "EVEX.LLIG.F3.MAP5.W0 2C /r VCVTTSH2SI r32, xmm1/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttsh2si" + }, + "vcvttsh2usi": { + "instruction": "VCVTTSH2USI", + "title": "VCVTTSH2USI\n\t\t— Convert with Truncation Low FP16 Value to an Unsigned Integer", + "opcode": "EVEX.LLIG.F3.MAP5.W0 78 /r VCVTTSH2USI r32, xmm1/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttsh2usi" + }, + "vcvttss2usi": { + "instruction": "VCVTTSS2USI", + "title": "VCVTTSS2USI\n\t\t— Convert With Truncation Scalar Single Precision Floating-Point Value toUnsigned Integer", + "opcode": "EVEX.LLIG.F3.0F.W0 78 /r VCVTTSS2USI r32, xmm1/m32{sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvttss2usi" + }, + "vcvtudq2pd": { + "instruction": "VCVTUDQ2PD", + "title": "VCVTUDQ2PD\n\t\t— Convert Packed Unsigned Doubleword Integers to Packed Double PrecisionFloating-Point Values", + "opcode": "EVEX.128.F3.0F.W0 7A /r VCVTUDQ2PD xmm1 {k1}{z}, xmm2/m64/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtudq2pd" + }, + "vcvtudq2ph": { + "instruction": "VCVTUDQ2PH", + "title": "VCVTUDQ2PH\n\t\t— Convert Packed Unsigned Doubleword Integers to Packed FP16 Values", + "opcode": "EVEX.128.F2.MAP5.W0 7A /r VCVTUDQ2PH xmm1{k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtudq2ph" + }, + "vcvtudq2ps": { + "instruction": "VCVTUDQ2PS", + "title": "VCVTUDQ2PS\n\t\t— Convert Packed Unsigned Doubleword Integers to Packed Single PrecisionFloating-Point Values", + "opcode": "EVEX.128.F2.0F.W0 7A /r VCVTUDQ2PS xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtudq2ps" + }, + "vcvtuqq2pd": { + "instruction": "VCVTUQQ2PD", + "title": "VCVTUQQ2PD\n\t\t— Convert Packed Unsigned Quadword Integers to Packed Double PrecisionFloating-Point Values", + "opcode": "EVEX.128.F3.0F.W1 7A /r VCVTUQQ2PD xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtuqq2pd" + }, + "vcvtuqq2ph": { + "instruction": "VCVTUQQ2PH", + "title": "VCVTUQQ2PH\n\t\t— Convert Packed Unsigned Quadword Integers to Packed FP16 Values", + "opcode": "EVEX.128.F2.MAP5.W1 7A /r VCVTUQQ2PH xmm1{k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtuqq2ph" + }, + "vcvtuqq2ps": { + "instruction": "VCVTUQQ2PS", + "title": "VCVTUQQ2PS\n\t\t— Convert Packed Unsigned Quadword Integers to Packed Single PrecisionFloating-Point Values", + "opcode": "EVEX.128.F2.0F.W1 7A /r VCVTUQQ2PS xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtuqq2ps" + }, + "vcvtusi2sd": { + "instruction": "VCVTUSI2SD", + "title": "VCVTUSI2SD\n\t\t— Convert Unsigned Integer to Scalar Double Precision Floating-Point Value", + "opcode": "EVEX.LLIG.F2.0F.W0 7B /r VCVTUSI2SD xmm1, xmm2, r/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtusi2sd" + }, + "vcvtusi2sh": { + "instruction": "VCVTUSI2SH", + "title": "VCVTUSI2SH\n\t\t— Convert Unsigned Doubleword Integer to an FP16 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 7B /r VCVTUSI2SH xmm1, xmm2, r32/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtusi2sh" + }, + "vcvtusi2ss": { + "instruction": "VCVTUSI2SS", + "title": "VCVTUSI2SS\n\t\t— Convert Unsigned Integer to Scalar Single Precision Floating-Point Value", + "opcode": "EVEX.LLIG.F3.0F.W0 7B /r VCVTUSI2SS xmm1, xmm2, r/m32{er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtusi2ss" + }, + "vcvtuw2ph": { + "instruction": "VCVTUW2PH", + "title": "VCVTUW2PH\n\t\t— Convert Packed Unsigned Word Integers to FP16 Values", + "opcode": "EVEX.128.F2.MAP5.W0 7D /r VCVTUW2PH xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtuw2ph" + }, + "vcvtw2ph": { + "instruction": "VCVTW2PH", + "title": "VCVTW2PH\n\t\t— Convert Packed Signed Word Integers to FP16 Values", + "opcode": "EVEX.128.F3.MAP5.W0 7D /r VCVTW2PH xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vcvtw2ph" + }, + "vdbpsadbw": { + "instruction": "VDBPSADBW", + "title": "VDBPSADBW\n\t\t— Double Block Packed Sum-Absolute-Differences (SAD) on Unsigned Bytes", + "opcode": "EVEX.128.66.0F3A.W0 42 /r ib VDBPSADBW xmm1 {k1}{z}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vdbpsadbw" + }, + "vdivph": { + "instruction": "VDIVPH", + "title": "VDIVPH\n\t\t— Divide Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 5E /r VDIVPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vdivph" + }, + "vdivsh": { + "instruction": "VDIVSH", + "title": "VDIVSH\n\t\t— Divide Scalar FP16 Values", + "opcode": "EVEX.LLIG.F3.MAP5.W0 5E /r VDIVSH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vdivsh" + }, + "vdpbf16ps": { + "instruction": "VDPBF16PS", + "title": "VDPBF16PS\n\t\t— Dot Product of BF16 Pairs Accumulated Into Packed Single Precision", + "opcode": "EVEX.128.F3.0F38.W0 52 /r VDPBF16PS xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vdpbf16ps" + }, + "verr": { + "instruction": "VERR", + "title": "VERR/VERW\n\t\t— Verify a Segment for Reading or Writing", + "opcode": "0F 00 /4 VERR r/m16", + "description": "Verifies whether the code or data segment specified with the source operand is readable (VERR) or writable (VERW) from the current privilege level (CPL). The source operand is a 16-bit register or a memory location that contains the segment selector for the segment to be verified. If the segment is accessible and readable (VERR) or writable (VERW), the ZF flag is set; otherwise, the ZF flag is cleared. Code segments are never verified as writable. This check cannot be performed on system segments.\nTo set the ZF flag, the following conditions must be met:\nThe validation performed is the same as is performed when a segment selector is loaded into the DS, ES, FS, or GS register, and the indicated access (read or write) is performed. The segment selector's value cannot result in a protection exception, enabling the software to anticipate possible segment access problems.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode. The operand size is fixed at 16 bits.", + "operation": "IF SRC(Offset) > (GDTR(Limit) or (LDTR(Limit))\n THEN ZF := 0; FI;\nRead segment descriptor;\nIF SegmentDescriptor(DescriptorType) = 0 (* System segment *)\nor (SegmentDescriptor(Type) ≠ conforming code segment)\nand (CPL > DPL) or (RPL > DPL)\n THEN\n ZF := 0;\n ELSE\n IF ((Instruction = VERR) and (Segment readable))\n or ((Instruction = VERW) and (Segment writable))\n THEN\n ZF := 1;\n ELSE\n ZF := 0;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/verr:verw" + }, + "verw": { + "instruction": "VERW", + "title": "VERR/VERW\n\t\t— Verify a Segment for Reading or Writing", + "opcode": "0F 00 /4 VERR r/m16", + "description": "Verifies whether the code or data segment specified with the source operand is readable (VERR) or writable (VERW) from the current privilege level (CPL). The source operand is a 16-bit register or a memory location that contains the segment selector for the segment to be verified. If the segment is accessible and readable (VERR) or writable (VERW), the ZF flag is set; otherwise, the ZF flag is cleared. Code segments are never verified as writable. This check cannot be performed on system segments.\nTo set the ZF flag, the following conditions must be met:\nThe validation performed is the same as is performed when a segment selector is loaded into the DS, ES, FS, or GS register, and the indicated access (read or write) is performed. The segment selector's value cannot result in a protection exception, enabling the software to anticipate possible segment access problems.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode. The operand size is fixed at 16 bits.", + "operation": "IF SRC(Offset) > (GDTR(Limit) or (LDTR(Limit))\n THEN ZF := 0; FI;\nRead segment descriptor;\nIF SegmentDescriptor(DescriptorType) = 0 (* System segment *)\nor (SegmentDescriptor(Type) ≠ conforming code segment)\nand (CPL > DPL) or (RPL > DPL)\n THEN\n ZF := 0;\n ELSE\n IF ((Instruction = VERR) and (Segment readable))\n or ((Instruction = VERW) and (Segment writable))\n THEN\n ZF := 1;\n ELSE\n ZF := 0;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/verr:verw" + }, + "vexp2pd": { + "instruction": "VEXP2PD", + "title": "VEXP2PD\n\t\t— Approximation to the Exponential 2^x of Packed Double Precision Floating-PointValues With Less Than 2^-23 Relative Error", + "opcode": "EVEX.512.66.0F38.W1 C8 /r VEXP2PD zmm1 {k1}{z}, zmm2/m512/m64bcst {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vexp2pd" + }, + "vexp2ps": { + "instruction": "VEXP2PS", + "title": "VEXP2PS\n\t\t— Approximation to the Exponential 2^x of Packed Single Precision Floating-PointValues With Less Than 2^-23 Relative Error", + "opcode": "EVEX.512.66.0F38.W0 C8 /r VEXP2PS zmm1 {k1}{z}, zmm2/m512/m32bcst {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vexp2ps" + }, + "vexpandpd": { + "instruction": "VEXPANDPD", + "title": "VEXPANDPD\n\t\t— Load Sparse Packed Double Precision Floating-Point Values From Dense Memory", + "opcode": "EVEX.128.66.0F38.W1 88 /r VEXPANDPD xmm1 {k1}{z}, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vexpandpd" + }, + "vexpandps": { + "instruction": "VEXPANDPS", + "title": "VEXPANDPS\n\t\t— Load Sparse Packed Single Precision Floating-Point Values From Dense Memory", + "opcode": "EVEX.128.66.0F38.W0 88 /r VEXPANDPS xmm1 {k1}{z}, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vexpandps" + }, + "vextractf128": { + "instruction": "VEXTRACTF128", + "title": "VEXTRACTF128/VEXTRACTF32x4/VEXTRACTF64x2/VEXTRACTF32x8/VEXTRACTF64x4\n\t\t— Extract Packed Floating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 19 /r ib VEXTRACTF128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextractf128:vextractf32x4:vextractf64x2:vextractf32x8:vextractf64x4" + }, + "vextractf32x4": { + "instruction": "VEXTRACTF32X4", + "title": "VEXTRACTF128/VEXTRACTF32x4/VEXTRACTF64x2/VEXTRACTF32x8/VEXTRACTF64x4\n\t\t— Extract Packed Floating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 19 /r ib VEXTRACTF128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextractf128:vextractf32x4:vextractf64x2:vextractf32x8:vextractf64x4" + }, + "vextractf32x8": { + "instruction": "VEXTRACTF32X8", + "title": "VEXTRACTF128/VEXTRACTF32x4/VEXTRACTF64x2/VEXTRACTF32x8/VEXTRACTF64x4\n\t\t— Extract Packed Floating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 19 /r ib VEXTRACTF128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextractf128:vextractf32x4:vextractf64x2:vextractf32x8:vextractf64x4" + }, + "vextractf64x2": { + "instruction": "VEXTRACTF64X2", + "title": "VEXTRACTF128/VEXTRACTF32x4/VEXTRACTF64x2/VEXTRACTF32x8/VEXTRACTF64x4\n\t\t— Extract Packed Floating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 19 /r ib VEXTRACTF128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextractf128:vextractf32x4:vextractf64x2:vextractf32x8:vextractf64x4" + }, + "vextractf64x4": { + "instruction": "VEXTRACTF64X4", + "title": "VEXTRACTF128/VEXTRACTF32x4/VEXTRACTF64x2/VEXTRACTF32x8/VEXTRACTF64x4\n\t\t— Extract Packed Floating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 19 /r ib VEXTRACTF128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextractf128:vextractf32x4:vextractf64x2:vextractf32x8:vextractf64x4" + }, + "vextracti128": { + "instruction": "VEXTRACTI128", + "title": "VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4\n\t\t— ExtractPacked Integer Values", + "opcode": "VEX.256.66.0F3A.W0 39 /r ib VEXTRACTI128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextracti128:vextracti32x4:vextracti64x2:vextracti32x8:vextracti64x4" + }, + "vextracti32x4": { + "instruction": "VEXTRACTI32X4", + "title": "VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4\n\t\t— ExtractPacked Integer Values", + "opcode": "VEX.256.66.0F3A.W0 39 /r ib VEXTRACTI128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextracti128:vextracti32x4:vextracti64x2:vextracti32x8:vextracti64x4" + }, + "vextracti32x8": { + "instruction": "VEXTRACTI32X8", + "title": "VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4\n\t\t— ExtractPacked Integer Values", + "opcode": "VEX.256.66.0F3A.W0 39 /r ib VEXTRACTI128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextracti128:vextracti32x4:vextracti64x2:vextracti32x8:vextracti64x4" + }, + "vextracti64x2": { + "instruction": "VEXTRACTI64X2", + "title": "VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4\n\t\t— ExtractPacked Integer Values", + "opcode": "VEX.256.66.0F3A.W0 39 /r ib VEXTRACTI128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextracti128:vextracti32x4:vextracti64x2:vextracti32x8:vextracti64x4" + }, + "vextracti64x4": { + "instruction": "VEXTRACTI64X4", + "title": "VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4\n\t\t— ExtractPacked Integer Values", + "opcode": "VEX.256.66.0F3A.W0 39 /r ib VEXTRACTI128 xmm1/m128, ymm2, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vextracti128:vextracti32x4:vextracti64x2:vextracti32x8:vextracti64x4" + }, + "vfcmaddcph": { + "instruction": "VFCMADDCPH", + "title": "VFCMADDCPH/VFMADDCPH\n\t\t— Complex Multiply and Accumulate FP16 Values", + "opcode": "EVEX.128.F2.MAP6.W0 56 /r VFCMADDCPH xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmaddcph:vfmaddcph" + }, + "vfcmaddcsh": { + "instruction": "VFCMADDCSH", + "title": "VFCMADDCSH/VFMADDCSH\n\t\t— Complex Multiply and Accumulate Scalar FP16 Values", + "opcode": "EVEX.LLIG.F2.MAP6.W0 57 /r VFCMADDCSH xmm1{k1}{z}, xmm2, xmm3/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmaddcsh:vfmaddcsh" + }, + "vfcmulcph": { + "instruction": "VFCMULCPH", + "title": "VFCMULCPH/VFMULCPH\n\t\t— Complex Multiply FP16 Values", + "opcode": "EVEX.128.F2.MAP6.W0 D6 /r VFCMULCPH xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmulcph:vfmulcph" + }, + "vfcmulcsh": { + "instruction": "VFCMULCSH", + "title": "VFCMULCSH/VFMULCSH\n\t\t— Complex Multiply Scalar FP16 Values", + "opcode": "EVEX.LLIG.F2.MAP6.W0 D7 /r VFCMULCSH xmm1{k1}{z}, xmm2, xmm3/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmulcsh:vfmulcsh" + }, + "vfixupimmpd": { + "instruction": "VFIXUPIMMPD", + "title": "VFIXUPIMMPD\n\t\t— Fix Up Special Packed Float64 Values", + "opcode": "EVEX.128.66.0F3A.W1 54 /r ib VFIXUPIMMPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfixupimmpd" + }, + "vfixupimmps": { + "instruction": "VFIXUPIMMPS", + "title": "VFIXUPIMMPS\n\t\t— Fix Up Special Packed Float32 Values", + "opcode": "EVEX.128.66.0F3A.W0 54 /r VFIXUPIMMPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfixupimmps" + }, + "vfixupimmsd": { + "instruction": "VFIXUPIMMSD", + "title": "VFIXUPIMMSD\n\t\t— Fix Up Special Scalar Float64 Value", + "opcode": "EVEX.LLIG.66.0F3A.W1 55 /r ib VFIXUPIMMSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfixupimmsd" + }, + "vfixupimmss": { + "instruction": "VFIXUPIMMSS", + "title": "VFIXUPIMMSS\n\t\t— Fix Up Special Scalar Float32 Value", + "opcode": "EVEX.LLIG.66.0F3A.W0 55 /r ib VFIXUPIMMSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfixupimmss" + }, + "vfmadd132pd": { + "instruction": "VFMADD132PD", + "title": "VFMADD132PD/VFMADD213PD/VFMADD231PD\n\t\t— Fused Multiply-Add of Packed DoublePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 98 /r VFMADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132pd:vfmadd213pd:vfmadd231pd" + }, + "vfmadd132ph": { + "instruction": "VFMADD132PH", + "title": "VFMADD132PH/VFNMADD132PH/VFMADD213PH/VFNMADD213PH/VFMADD231PH/VFNMADD231PH\n\t\t— Fused Multiply-Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 98 /r VFMADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ph:vfnmadd132ph:vfmadd213ph:vfnmadd213ph:vfmadd231ph:vfnmadd231ph" + }, + "vfmadd132ps": { + "instruction": "VFMADD132PS", + "title": "VFMADD132PS/VFMADD213PS/VFMADD231PS\n\t\t— Fused Multiply-Add of Packed SinglePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 98 /r VFMADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ps:vfmadd213ps:vfmadd231ps" + }, + "vfmadd132sd": { + "instruction": "VFMADD132SD", + "title": "VFMADD132SD/VFMADD213SD/VFMADD231SD\n\t\t— Fused Multiply-Add of Scalar DoublePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 99 /r VFMADD132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sd:vfmadd213sd:vfmadd231sd" + }, + "vfmadd132sh": { + "instruction": "VFMADD132SH", + "title": "VFMADD132SH/VFNMADD132SH/VFMADD213SH/VFNMADD213SH/VFMADD231SH/VFNMADD231SH\n\t\t— Fused Multiply-Add of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sh:vfnmadd132sh:vfmadd213sh:vfnmadd213sh:vfmadd231sh:vfnmadd231sh" + }, + "vfmadd132ss": { + "instruction": "VFMADD132SS", + "title": "VFMADD132SS/VFMADD213SS/VFMADD231SS\n\t\t— Fused Multiply-Add of Scalar Single PrecisionFloating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 99 /r VFMADD132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ss:vfmadd213ss:vfmadd231ss" + }, + "vfmadd213pd": { + "instruction": "VFMADD213PD", + "title": "VFMADD132PD/VFMADD213PD/VFMADD231PD\n\t\t— Fused Multiply-Add of Packed DoublePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 98 /r VFMADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132pd:vfmadd213pd:vfmadd231pd" + }, + "vfmadd213ph": { + "instruction": "VFMADD213PH", + "title": "VFMADD132PH/VFNMADD132PH/VFMADD213PH/VFNMADD213PH/VFMADD231PH/VFNMADD231PH\n\t\t— Fused Multiply-Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 98 /r VFMADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ph:vfnmadd132ph:vfmadd213ph:vfnmadd213ph:vfmadd231ph:vfnmadd231ph" + }, + "vfmadd213ps": { + "instruction": "VFMADD213PS", + "title": "VFMADD132PS/VFMADD213PS/VFMADD231PS\n\t\t— Fused Multiply-Add of Packed SinglePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 98 /r VFMADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ps:vfmadd213ps:vfmadd231ps" + }, + "vfmadd213sd": { + "instruction": "VFMADD213SD", + "title": "VFMADD132SD/VFMADD213SD/VFMADD231SD\n\t\t— Fused Multiply-Add of Scalar DoublePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 99 /r VFMADD132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sd:vfmadd213sd:vfmadd231sd" + }, + "vfmadd213sh": { + "instruction": "VFMADD213SH", + "title": "VFMADD132SH/VFNMADD132SH/VFMADD213SH/VFNMADD213SH/VFMADD231SH/VFNMADD231SH\n\t\t— Fused Multiply-Add of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sh:vfnmadd132sh:vfmadd213sh:vfnmadd213sh:vfmadd231sh:vfnmadd231sh" + }, + "vfmadd213ss": { + "instruction": "VFMADD213SS", + "title": "VFMADD132SS/VFMADD213SS/VFMADD231SS\n\t\t— Fused Multiply-Add of Scalar Single PrecisionFloating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 99 /r VFMADD132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ss:vfmadd213ss:vfmadd231ss" + }, + "vfmadd231pd": { + "instruction": "VFMADD231PD", + "title": "VFMADD132PD/VFMADD213PD/VFMADD231PD\n\t\t— Fused Multiply-Add of Packed DoublePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 98 /r VFMADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132pd:vfmadd213pd:vfmadd231pd" + }, + "vfmadd231ph": { + "instruction": "VFMADD231PH", + "title": "VFMADD132PH/VFNMADD132PH/VFMADD213PH/VFNMADD213PH/VFMADD231PH/VFNMADD231PH\n\t\t— Fused Multiply-Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 98 /r VFMADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ph:vfnmadd132ph:vfmadd213ph:vfnmadd213ph:vfmadd231ph:vfnmadd231ph" + }, + "vfmadd231ps": { + "instruction": "VFMADD231PS", + "title": "VFMADD132PS/VFMADD213PS/VFMADD231PS\n\t\t— Fused Multiply-Add of Packed SinglePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 98 /r VFMADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ps:vfmadd213ps:vfmadd231ps" + }, + "vfmadd231sd": { + "instruction": "VFMADD231SD", + "title": "VFMADD132SD/VFMADD213SD/VFMADD231SD\n\t\t— Fused Multiply-Add of Scalar DoublePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 99 /r VFMADD132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sd:vfmadd213sd:vfmadd231sd" + }, + "vfmadd231sh": { + "instruction": "VFMADD231SH", + "title": "VFMADD132SH/VFNMADD132SH/VFMADD213SH/VFNMADD213SH/VFMADD231SH/VFNMADD231SH\n\t\t— Fused Multiply-Add of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sh:vfnmadd132sh:vfmadd213sh:vfnmadd213sh:vfmadd231sh:vfnmadd231sh" + }, + "vfmadd231ss": { + "instruction": "VFMADD231SS", + "title": "VFMADD132SS/VFMADD213SS/VFMADD231SS\n\t\t— Fused Multiply-Add of Scalar Single PrecisionFloating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 99 /r VFMADD132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ss:vfmadd213ss:vfmadd231ss" + }, + "vfmaddcph": { + "instruction": "VFMADDCPH", + "title": "VFCMADDCPH/VFMADDCPH\n\t\t— Complex Multiply and Accumulate FP16 Values", + "opcode": "EVEX.128.F2.MAP6.W0 56 /r VFCMADDCPH xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmaddcph:vfmaddcph" + }, + "vfmaddcsh": { + "instruction": "VFMADDCSH", + "title": "VFCMADDCSH/VFMADDCSH\n\t\t— Complex Multiply and Accumulate Scalar FP16 Values", + "opcode": "EVEX.LLIG.F2.MAP6.W0 57 /r VFCMADDCSH xmm1{k1}{z}, xmm2, xmm3/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmaddcsh:vfmaddcsh" + }, + "vfmaddrnd231pd": { + "instruction": "VFMADDRND231PD", + "title": "VFMADDRND231PD\n\t\t— Fused Multiply-Add of Packed Double-Precision Floating-Point Valueswith rounding control", + "opcode": "", + "description": "Multiplies the two or four packed double-precision floating-point values from the second source operand to the two or four packed double-precision floating-point values in the third source operand, adds the infinite precision intermediate result to the two or four packed double-precision floating-point values in the first source operand, performs rounding and stores the resulting two or four packed double-precision floating-point values to the destination operand (first source operand).\nThe immediate byte defines several bit fields that control rounding, DAZ, FTZ, and exception suppression (SeeTable 5-3).The rounding mode specified in MXCSR.RC may be bypassed if the immediate bit called MS1 (MXCSR.RC Override) is set. Likewise, the MXCSR.FTZ and MXCSR.DAZ may also be bypassed if the immediate bit called MS2 (MXCSR.FTZ/DAZ Override) is set. In case SAE (Suppress All Exceptions) bit is set (i.e. imm8[3] = 1), the status flags in MXCSR are not updated and no SIMD floating-point exceptions are raised. When SAE bit is not set (i.e. imm8[3] = 0) then SIMD floating-point exceptions are signaled according to the MXCSR. If any result operand is an SNaN then it will be converted to a QNaN.\nVEX.256 encoded version: The destination operand (also first source operand) is a YMM register and encoded in reg_field. The second source operand is a YMM register and encoded in VEX.vvvv. The third source operand is a YMM register or a 256-bit memory location and encoded in rm_field.\nVEX.128 encoded version: The destination operand (also first source operand) is a XMM register and encoded in reg_field. The second source operand is a XMM register and encoded in VEX.vvvv. The third source operand is a XMM register or a 128-bit memory location and encoded in rm_field. The upper 128 bits of the YMM destination register are zeroed.\nCompiler tools may optionally support the complementary mnemonic VMADDRND321PD. The behavior of the complementary mnemonic in situations involving NANs are governed by the definition of the instruction mnemonic defined in the opcode/instruction column. See also Section 2.3.1, “FMA Instruction Operand Order and Arithmetic Behavior”", + "operation": "In the operations below, “+” and “*” symbols represent multiplication and addition with infinite precision inputs and outputs (no rounding)\n\n\nIF (VEX.128) THEN\n MAXVL =2\nELSEIF (VEX.256)\n MAXVL = 4\nFI\nIF (imm8[3] = 1) THEN\n Suppress_SIMD_Exception_Signaling_Reporting();\nFI\nFor i = 0 to MAXVL-1 {\n n = 64*i;\n DEST[n+63:n]←RoundFPControl_Imm((SRC2[n+63:n]*SRC3[n+63:n] + DEST[n+63:n]), imm8)\n}\nIF (VEX.128) THEN\nDEST[255:128] ← 0\nFI\nIF (imm8[3] = 1) THEN\n Resume_SIMD_Exception_Signaling_Reporting();\nFI\n", + "url": "https://www.felixcloutier.com/x86/vfmaddrnd231pd" + }, + "vfmaddsub132pd": { + "instruction": "VFMADDSUB132PD", + "title": "VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 96 /r VFMADDSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132pd:vfmaddsub213pd:vfmaddsub231pd" + }, + "vfmaddsub132ph": { + "instruction": "VFMADDSUB132PH", + "title": "VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 96 /r VFMADDSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132ph:vfmaddsub213ph:vfmaddsub231ph" + }, + "vfmaddsub132ps": { + "instruction": "VFMADDSUB132PS", + "title": "VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 96 /r VFMADDSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132ps:vfmaddsub213ps:vfmaddsub231ps" + }, + "vfmaddsub213pd": { + "instruction": "VFMADDSUB213PD", + "title": "VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 96 /r VFMADDSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132pd:vfmaddsub213pd:vfmaddsub231pd" + }, + "vfmaddsub213ph": { + "instruction": "VFMADDSUB213PH", + "title": "VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 96 /r VFMADDSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132ph:vfmaddsub213ph:vfmaddsub231ph" + }, + "vfmaddsub213ps": { + "instruction": "VFMADDSUB213PS", + "title": "VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 96 /r VFMADDSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132ps:vfmaddsub213ps:vfmaddsub231ps" + }, + "vfmaddsub231pd": { + "instruction": "VFMADDSUB231PD", + "title": "VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 96 /r VFMADDSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132pd:vfmaddsub213pd:vfmaddsub231pd" + }, + "vfmaddsub231ph": { + "instruction": "VFMADDSUB231PH", + "title": "VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 96 /r VFMADDSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132ph:vfmaddsub213ph:vfmaddsub231ph" + }, + "vfmaddsub231ps": { + "instruction": "VFMADDSUB231PS", + "title": "VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS\n\t\t— Fused Multiply-AlternatingAdd/Subtract of Packed Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 96 /r VFMADDSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmaddsub132ps:vfmaddsub213ps:vfmaddsub231ps" + }, + "vfmsub132pd": { + "instruction": "VFMSUB132PD", + "title": "VFMSUB132PD/VFMSUB213PD/VFMSUB231PD\n\t\t— Fused Multiply-Subtract of Packed DoublePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9A /r VFMSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132pd:vfmsub213pd:vfmsub231pd" + }, + "vfmsub132ph": { + "instruction": "VFMSUB132PH", + "title": "VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH\n\t\t— Fused Multiply-Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ph:vfnmsub132ph:vfmsub213ph:vfnmsub213ph:vfmsub231ph:vfnmsub231ph" + }, + "vfmsub132ps": { + "instruction": "VFMSUB132PS", + "title": "VFMSUB132PS/VFMSUB213PS/VFMSUB231PS\n\t\t— Fused Multiply-Subtract of Packed SinglePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9A /r VFMSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ps:vfmsub213ps:vfmsub231ps" + }, + "vfmsub132sd": { + "instruction": "VFMSUB132SD", + "title": "VFMSUB132SD/VFMSUB213SD/VFMSUB231SD\n\t\t— Fused Multiply-Subtract of Scalar DoublePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9B /r VFMSUB132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sd:vfmsub213sd:vfmsub231sd" + }, + "vfmsub132sh": { + "instruction": "VFMSUB132SH", + "title": "VFMSUB132SH/VFNMSUB132SH/VFMSUB213SH/VFNMSUB213SH/VFMSUB231SH/VFNMSUB231SH\n\t\t— Fused Multiply-Subtract of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 9B /r VFMSUB132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sh:vfnmsub132sh:vfmsub213sh:vfnmsub213sh:vfmsub231sh:vfnmsub231sh" + }, + "vfmsub132ss": { + "instruction": "VFMSUB132SS", + "title": "VFMSUB132SS/VFMSUB213SS/VFMSUB231SS\n\t\t— Fused Multiply-Subtract of Scalar SinglePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9B /r VFMSUB132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ss:vfmsub213ss:vfmsub231ss" + }, + "vfmsub213pd": { + "instruction": "VFMSUB213PD", + "title": "VFMSUB132PD/VFMSUB213PD/VFMSUB231PD\n\t\t— Fused Multiply-Subtract of Packed DoublePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9A /r VFMSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132pd:vfmsub213pd:vfmsub231pd" + }, + "vfmsub213ph": { + "instruction": "VFMSUB213PH", + "title": "VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH\n\t\t— Fused Multiply-Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ph:vfnmsub132ph:vfmsub213ph:vfnmsub213ph:vfmsub231ph:vfnmsub231ph" + }, + "vfmsub213ps": { + "instruction": "VFMSUB213PS", + "title": "VFMSUB132PS/VFMSUB213PS/VFMSUB231PS\n\t\t— Fused Multiply-Subtract of Packed SinglePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9A /r VFMSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ps:vfmsub213ps:vfmsub231ps" + }, + "vfmsub213sd": { + "instruction": "VFMSUB213SD", + "title": "VFMSUB132SD/VFMSUB213SD/VFMSUB231SD\n\t\t— Fused Multiply-Subtract of Scalar DoublePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9B /r VFMSUB132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sd:vfmsub213sd:vfmsub231sd" + }, + "vfmsub213sh": { + "instruction": "VFMSUB213SH", + "title": "VFMSUB132SH/VFNMSUB132SH/VFMSUB213SH/VFNMSUB213SH/VFMSUB231SH/VFNMSUB231SH\n\t\t— Fused Multiply-Subtract of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 9B /r VFMSUB132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sh:vfnmsub132sh:vfmsub213sh:vfnmsub213sh:vfmsub231sh:vfnmsub231sh" + }, + "vfmsub213ss": { + "instruction": "VFMSUB213SS", + "title": "VFMSUB132SS/VFMSUB213SS/VFMSUB231SS\n\t\t— Fused Multiply-Subtract of Scalar SinglePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9B /r VFMSUB132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ss:vfmsub213ss:vfmsub231ss" + }, + "vfmsub231pd": { + "instruction": "VFMSUB231PD", + "title": "VFMSUB132PD/VFMSUB213PD/VFMSUB231PD\n\t\t— Fused Multiply-Subtract of Packed DoublePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9A /r VFMSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132pd:vfmsub213pd:vfmsub231pd" + }, + "vfmsub231ph": { + "instruction": "VFMSUB231PH", + "title": "VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH\n\t\t— Fused Multiply-Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ph:vfnmsub132ph:vfmsub213ph:vfnmsub213ph:vfmsub231ph:vfnmsub231ph" + }, + "vfmsub231ps": { + "instruction": "VFMSUB231PS", + "title": "VFMSUB132PS/VFMSUB213PS/VFMSUB231PS\n\t\t— Fused Multiply-Subtract of Packed SinglePrecision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9A /r VFMSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ps:vfmsub213ps:vfmsub231ps" + }, + "vfmsub231sd": { + "instruction": "VFMSUB231SD", + "title": "VFMSUB132SD/VFMSUB213SD/VFMSUB231SD\n\t\t— Fused Multiply-Subtract of Scalar DoublePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9B /r VFMSUB132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sd:vfmsub213sd:vfmsub231sd" + }, + "vfmsub231sh": { + "instruction": "VFMSUB231SH", + "title": "VFMSUB132SH/VFNMSUB132SH/VFMSUB213SH/VFNMSUB213SH/VFMSUB231SH/VFNMSUB231SH\n\t\t— Fused Multiply-Subtract of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 9B /r VFMSUB132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sh:vfnmsub132sh:vfmsub213sh:vfnmsub213sh:vfmsub231sh:vfnmsub231sh" + }, + "vfmsub231ss": { + "instruction": "VFMSUB231SS", + "title": "VFMSUB132SS/VFMSUB213SS/VFMSUB231SS\n\t\t— Fused Multiply-Subtract of Scalar SinglePrecision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9B /r VFMSUB132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ss:vfmsub213ss:vfmsub231ss" + }, + "vfmsubadd132pd": { + "instruction": "VFMSUBADD132PD", + "title": "VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 97 /r VFMSUBADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132pd:vfmsubadd213pd:vfmsubadd231pd" + }, + "vfmsubadd132ph": { + "instruction": "VFMSUBADD132PH", + "title": "VFMSUBADD132PH/VFMSUBADD213PH/VFMSUBADD231PH\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 97 /r VFMSUBADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132ph:vfmsubadd213ph:vfmsubadd231ph" + }, + "vfmsubadd132ps": { + "instruction": "VFMSUBADD132PS", + "title": "VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 97 /r VFMSUBADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132ps:vfmsubadd213ps:vfmsubadd231ps" + }, + "vfmsubadd213pd": { + "instruction": "VFMSUBADD213PD", + "title": "VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 97 /r VFMSUBADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132pd:vfmsubadd213pd:vfmsubadd231pd" + }, + "vfmsubadd213ph": { + "instruction": "VFMSUBADD213PH", + "title": "VFMSUBADD132PH/VFMSUBADD213PH/VFMSUBADD231PH\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 97 /r VFMSUBADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132ph:vfmsubadd213ph:vfmsubadd231ph" + }, + "vfmsubadd213ps": { + "instruction": "VFMSUBADD213PS", + "title": "VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 97 /r VFMSUBADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132ps:vfmsubadd213ps:vfmsubadd231ps" + }, + "vfmsubadd231pd": { + "instruction": "VFMSUBADD231PD", + "title": "VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 97 /r VFMSUBADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132pd:vfmsubadd213pd:vfmsubadd231pd" + }, + "vfmsubadd231ph": { + "instruction": "VFMSUBADD231PH", + "title": "VFMSUBADD132PH/VFMSUBADD213PH/VFMSUBADD231PH\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 97 /r VFMSUBADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132ph:vfmsubadd213ph:vfmsubadd231ph" + }, + "vfmsubadd231ps": { + "instruction": "VFMSUBADD231PS", + "title": "VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS\n\t\t— Fused Multiply-AlternatingSubtract/Add of Packed Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 97 /r VFMSUBADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsubadd132ps:vfmsubadd213ps:vfmsubadd231ps" + }, + "vfmulcph": { + "instruction": "VFMULCPH", + "title": "VFCMULCPH/VFMULCPH\n\t\t— Complex Multiply FP16 Values", + "opcode": "EVEX.128.F2.MAP6.W0 D6 /r VFCMULCPH xmm1{k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmulcph:vfmulcph" + }, + "vfmulcsh": { + "instruction": "VFMULCSH", + "title": "VFCMULCSH/VFMULCSH\n\t\t— Complex Multiply Scalar FP16 Values", + "opcode": "EVEX.LLIG.F2.MAP6.W0 D7 /r VFCMULCSH xmm1{k1}{z}, xmm2, xmm3/m32 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfcmulcsh:vfmulcsh" + }, + "vfnmadd132pd": { + "instruction": "VFNMADD132PD", + "title": "VFNMADD132PD/VFNMADD213PD/VFNMADD231PD\n\t\t— Fused Negative Multiply-Add of PackedDouble Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9C /r VFNMADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132pd:vfnmadd213pd:vfnmadd231pd" + }, + "vfnmadd132ph": { + "instruction": "VFNMADD132PH", + "title": "VFMADD132PH/VFNMADD132PH/VFMADD213PH/VFNMADD213PH/VFMADD231PH/VFNMADD231PH\n\t\t— Fused Multiply-Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 98 /r VFMADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ph:vfnmadd132ph:vfmadd213ph:vfnmadd213ph:vfmadd231ph:vfnmadd231ph" + }, + "vfnmadd132ps": { + "instruction": "VFNMADD132PS", + "title": "VFNMADD132PS/VFNMADD213PS/VFNMADD231PS\n\t\t— Fused Negative Multiply-Add of PackedSingle Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9C /r VFNMADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132ps:vfnmadd213ps:vfnmadd231ps" + }, + "vfnmadd132sd": { + "instruction": "VFNMADD132SD", + "title": "VFNMADD132SD/VFNMADD213SD/VFNMADD231SD\n\t\t— Fused Negative Multiply-Add of ScalarDouble Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9D /r VFNMADD132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132sd:vfnmadd213sd:vfnmadd231sd" + }, + "vfnmadd132sh": { + "instruction": "VFNMADD132SH", + "title": "VFMADD132SH/VFNMADD132SH/VFMADD213SH/VFNMADD213SH/VFMADD231SH/VFNMADD231SH\n\t\t— Fused Multiply-Add of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sh:vfnmadd132sh:vfmadd213sh:vfnmadd213sh:vfmadd231sh:vfnmadd231sh" + }, + "vfnmadd132ss": { + "instruction": "VFNMADD132SS", + "title": "VFNMADD132SS/VFNMADD213SS/VFNMADD231SS\n\t\t— Fused Negative Multiply-Add of ScalarSingle Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9D /r VFNMADD132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132ss:vfnmadd213ss:vfnmadd231ss" + }, + "vfnmadd213pd": { + "instruction": "VFNMADD213PD", + "title": "VFNMADD132PD/VFNMADD213PD/VFNMADD231PD\n\t\t— Fused Negative Multiply-Add of PackedDouble Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9C /r VFNMADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132pd:vfnmadd213pd:vfnmadd231pd" + }, + "vfnmadd213ph": { + "instruction": "VFNMADD213PH", + "title": "VFMADD132PH/VFNMADD132PH/VFMADD213PH/VFNMADD213PH/VFMADD231PH/VFNMADD231PH\n\t\t— Fused Multiply-Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 98 /r VFMADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ph:vfnmadd132ph:vfmadd213ph:vfnmadd213ph:vfmadd231ph:vfnmadd231ph" + }, + "vfnmadd213ps": { + "instruction": "VFNMADD213PS", + "title": "VFNMADD132PS/VFNMADD213PS/VFNMADD231PS\n\t\t— Fused Negative Multiply-Add of PackedSingle Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9C /r VFNMADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132ps:vfnmadd213ps:vfnmadd231ps" + }, + "vfnmadd213sd": { + "instruction": "VFNMADD213SD", + "title": "VFNMADD132SD/VFNMADD213SD/VFNMADD231SD\n\t\t— Fused Negative Multiply-Add of ScalarDouble Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9D /r VFNMADD132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132sd:vfnmadd213sd:vfnmadd231sd" + }, + "vfnmadd213sh": { + "instruction": "VFNMADD213SH", + "title": "VFMADD132SH/VFNMADD132SH/VFMADD213SH/VFNMADD213SH/VFMADD231SH/VFNMADD231SH\n\t\t— Fused Multiply-Add of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sh:vfnmadd132sh:vfmadd213sh:vfnmadd213sh:vfmadd231sh:vfnmadd231sh" + }, + "vfnmadd213ss": { + "instruction": "VFNMADD213SS", + "title": "VFNMADD132SS/VFNMADD213SS/VFNMADD231SS\n\t\t— Fused Negative Multiply-Add of ScalarSingle Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9D /r VFNMADD132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132ss:vfnmadd213ss:vfnmadd231ss" + }, + "vfnmadd231pd": { + "instruction": "VFNMADD231PD", + "title": "VFNMADD132PD/VFNMADD213PD/VFNMADD231PD\n\t\t— Fused Negative Multiply-Add of PackedDouble Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9C /r VFNMADD132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132pd:vfnmadd213pd:vfnmadd231pd" + }, + "vfnmadd231ph": { + "instruction": "VFNMADD231PH", + "title": "VFMADD132PH/VFNMADD132PH/VFMADD213PH/VFNMADD213PH/VFMADD231PH/VFNMADD231PH\n\t\t— Fused Multiply-Add of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 98 /r VFMADD132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132ph:vfnmadd132ph:vfmadd213ph:vfnmadd213ph:vfmadd231ph:vfnmadd231ph" + }, + "vfnmadd231ps": { + "instruction": "VFNMADD231PS", + "title": "VFNMADD132PS/VFNMADD213PS/VFNMADD231PS\n\t\t— Fused Negative Multiply-Add of PackedSingle Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9C /r VFNMADD132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132ps:vfnmadd213ps:vfnmadd231ps" + }, + "vfnmadd231sd": { + "instruction": "VFNMADD231SD", + "title": "VFNMADD132SD/VFNMADD213SD/VFNMADD231SD\n\t\t— Fused Negative Multiply-Add of ScalarDouble Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9D /r VFNMADD132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132sd:vfnmadd213sd:vfnmadd231sd" + }, + "vfnmadd231sh": { + "instruction": "VFNMADD231SH", + "title": "VFMADD132SH/VFNMADD132SH/VFMADD213SH/VFNMADD213SH/VFMADD231SH/VFNMADD231SH\n\t\t— Fused Multiply-Add of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmadd132sh:vfnmadd132sh:vfmadd213sh:vfnmadd213sh:vfmadd231sh:vfnmadd231sh" + }, + "vfnmadd231ss": { + "instruction": "VFNMADD231SS", + "title": "VFNMADD132SS/VFNMADD213SS/VFNMADD231SS\n\t\t— Fused Negative Multiply-Add of ScalarSingle Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9D /r VFNMADD132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmadd132ss:vfnmadd213ss:vfnmadd231ss" + }, + "vfnmsub132pd": { + "instruction": "VFNMSUB132PD", + "title": "VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD\n\t\t— Fused Negative Multiply-Subtract ofPacked Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9E /r VFNMSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132pd:vfnmsub213pd:vfnmsub231pd" + }, + "vfnmsub132ph": { + "instruction": "VFNMSUB132PH", + "title": "VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH\n\t\t— Fused Multiply-Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ph:vfnmsub132ph:vfmsub213ph:vfnmsub213ph:vfmsub231ph:vfnmsub231ph" + }, + "vfnmsub132ps": { + "instruction": "VFNMSUB132PS", + "title": "VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS\n\t\t— Fused Negative Multiply-Subtract ofPacked Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9E /r VFNMSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132ps:vfnmsub213ps:vfnmsub231ps" + }, + "vfnmsub132sd": { + "instruction": "VFNMSUB132SD", + "title": "VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD\n\t\t— Fused Negative Multiply-Subtract ofScalar Double Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9F /r VFNMSUB132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132sd:vfnmsub213sd:vfnmsub231sd" + }, + "vfnmsub132sh": { + "instruction": "VFNMSUB132SH", + "title": "VFMSUB132SH/VFNMSUB132SH/VFMSUB213SH/VFNMSUB213SH/VFMSUB231SH/VFNMSUB231SH\n\t\t— Fused Multiply-Subtract of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 9B /r VFMSUB132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sh:vfnmsub132sh:vfmsub213sh:vfnmsub213sh:vfmsub231sh:vfnmsub231sh" + }, + "vfnmsub132ss": { + "instruction": "VFNMSUB132SS", + "title": "VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS\n\t\t— Fused Negative Multiply-Subtract ofScalar Single Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9F /r VFNMSUB132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132ss:vfnmsub213ss:vfnmsub231ss" + }, + "vfnmsub213pd": { + "instruction": "VFNMSUB213PD", + "title": "VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD\n\t\t— Fused Negative Multiply-Subtract ofPacked Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9E /r VFNMSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132pd:vfnmsub213pd:vfnmsub231pd" + }, + "vfnmsub213ph": { + "instruction": "VFNMSUB213PH", + "title": "VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH\n\t\t— Fused Multiply-Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ph:vfnmsub132ph:vfmsub213ph:vfnmsub213ph:vfmsub231ph:vfnmsub231ph" + }, + "vfnmsub213ps": { + "instruction": "VFNMSUB213PS", + "title": "VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS\n\t\t— Fused Negative Multiply-Subtract ofPacked Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9E /r VFNMSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132ps:vfnmsub213ps:vfnmsub231ps" + }, + "vfnmsub213sd": { + "instruction": "VFNMSUB213SD", + "title": "VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD\n\t\t— Fused Negative Multiply-Subtract ofScalar Double Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9F /r VFNMSUB132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132sd:vfnmsub213sd:vfnmsub231sd" + }, + "vfnmsub213sh": { + "instruction": "VFNMSUB213SH", + "title": "VFMSUB132SH/VFNMSUB132SH/VFMSUB213SH/VFNMSUB213SH/VFMSUB231SH/VFNMSUB231SH\n\t\t— Fused Multiply-Subtract of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 9B /r VFMSUB132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sh:vfnmsub132sh:vfmsub213sh:vfnmsub213sh:vfmsub231sh:vfnmsub231sh" + }, + "vfnmsub213ss": { + "instruction": "VFNMSUB213SS", + "title": "VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS\n\t\t— Fused Negative Multiply-Subtract ofScalar Single Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9F /r VFNMSUB132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132ss:vfnmsub213ss:vfnmsub231ss" + }, + "vfnmsub231pd": { + "instruction": "VFNMSUB231PD", + "title": "VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD\n\t\t— Fused Negative Multiply-Subtract ofPacked Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W1 9E /r VFNMSUB132PD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132pd:vfnmsub213pd:vfnmsub231pd" + }, + "vfnmsub231ph": { + "instruction": "VFNMSUB231PH", + "title": "VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH\n\t\t— Fused Multiply-Subtract of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132ph:vfnmsub132ph:vfmsub213ph:vfnmsub213ph:vfmsub231ph:vfnmsub231ph" + }, + "vfnmsub231ps": { + "instruction": "VFNMSUB231PS", + "title": "VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS\n\t\t— Fused Negative Multiply-Subtract ofPacked Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 9E /r VFNMSUB132PS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132ps:vfnmsub213ps:vfnmsub231ps" + }, + "vfnmsub231sd": { + "instruction": "VFNMSUB231SD", + "title": "VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD\n\t\t— Fused Negative Multiply-Subtract ofScalar Double Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W1 9F /r VFNMSUB132SD xmm1, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132sd:vfnmsub213sd:vfnmsub231sd" + }, + "vfnmsub231sh": { + "instruction": "VFNMSUB231SH", + "title": "VFMSUB132SH/VFNMSUB132SH/VFMSUB213SH/VFNMSUB213SH/VFMSUB231SH/VFNMSUB231SH\n\t\t— Fused Multiply-Subtract of Scalar FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 9B /r VFMSUB132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfmsub132sh:vfnmsub132sh:vfmsub213sh:vfnmsub213sh:vfmsub231sh:vfnmsub231sh" + }, + "vfnmsub231ss": { + "instruction": "VFNMSUB231SS", + "title": "VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS\n\t\t— Fused Negative Multiply-Subtract ofScalar Single Precision Floating-Point Values", + "opcode": "VEX.LIG.66.0F38.W0 9F /r VFNMSUB132SS xmm1, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfnmsub132ss:vfnmsub213ss:vfnmsub231ss" + }, + "vfpclasspd": { + "instruction": "VFPCLASSPD", + "title": "VFPCLASSPD\n\t\t— Tests Types of Packed Float64 Values", + "opcode": "EVEX.128.66.0F3A.W1 66 /r ib VFPCLASSPD k2 {k1}, xmm2/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfpclasspd" + }, + "vfpclassph": { + "instruction": "VFPCLASSPH", + "title": "VFPCLASSPH\n\t\t— Test Types of Packed FP16 Values", + "opcode": "EVEX.128.NP.0F3A.W0 66 /r /ib VFPCLASSPH k1{k2}, xmm1/m128/m16bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfpclassph" + }, + "vfpclassps": { + "instruction": "VFPCLASSPS", + "title": "VFPCLASSPS\n\t\t— Tests Types of Packed Float32 Values", + "opcode": "EVEX.128.66.0F3A.W0 66 /r ib VFPCLASSPS k2 {k1}, xmm2/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfpclassps" + }, + "vfpclasssd": { + "instruction": "VFPCLASSSD", + "title": "VFPCLASSSD\n\t\t— Tests Type of a Scalar Float64 Value", + "opcode": "EVEX.LLIG.66.0F3A.W1 67 /r ib VFPCLASSSD k2 {k1}, xmm2/m64, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfpclasssd" + }, + "vfpclasssh": { + "instruction": "VFPCLASSSH", + "title": "VFPCLASSSH\n\t\t— Test Types of Scalar FP16 Values", + "opcode": "EVEX.LLIG.NP.0F3A.W0 67 /r /ib VFPCLASSSH k1{k2}, xmm1/m16, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfpclasssh" + }, + "vfpclassss": { + "instruction": "VFPCLASSSS", + "title": "VFPCLASSSS\n\t\t— Tests Type of a Scalar Float32 Value", + "opcode": "EVEX.LLIG.66.0F3A.W0 67 /r VFPCLASSSS k2 {k1}, xmm2/m32, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vfpclassss" + }, + "vgatherdpd": { + "instruction": "VGATHERDPD", + "title": "VGATHERDPS/VGATHERDPD\n\t\t— Gather Packed Single, Packed Double with Signed Dword Indices", + "opcode": "EVEX.128.66.0F38.W0 92 /vsib VGATHERDPS xmm1 {k1}, vm32x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherdps:vgatherdpd" + }, + "vgatherdps": { + "instruction": "VGATHERDPS", + "title": "VGATHERDPS/VGATHERDPD\n\t\t— Gather Packed Single, Packed Double with Signed Dword Indices", + "opcode": "EVEX.128.66.0F38.W0 92 /vsib VGATHERDPS xmm1 {k1}, vm32x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherdps:vgatherdpd" + }, + "vgatherpf0dpd": { + "instruction": "VGATHERPF0DPD", + "title": "VGATHERPF0DPS/VGATHERPF0QPS/VGATHERPF0DPD/VGATHERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T0 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /1 /vsib VGATHERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf0dps:vgatherpf0qps:vgatherpf0dpd:vgatherpf0qpd" + }, + "vgatherpf0dps": { + "instruction": "VGATHERPF0DPS", + "title": "VGATHERPF0DPS/VGATHERPF0QPS/VGATHERPF0DPD/VGATHERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T0 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /1 /vsib VGATHERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf0dps:vgatherpf0qps:vgatherpf0dpd:vgatherpf0qpd" + }, + "vgatherpf0qpd": { + "instruction": "VGATHERPF0QPD", + "title": "VGATHERPF0DPS/VGATHERPF0QPS/VGATHERPF0DPD/VGATHERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T0 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /1 /vsib VGATHERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf0dps:vgatherpf0qps:vgatherpf0dpd:vgatherpf0qpd" + }, + "vgatherpf0qps": { + "instruction": "VGATHERPF0QPS", + "title": "VGATHERPF0DPS/VGATHERPF0QPS/VGATHERPF0DPD/VGATHERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T0 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /1 /vsib VGATHERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf0dps:vgatherpf0qps:vgatherpf0dpd:vgatherpf0qpd" + }, + "vgatherpf1dpd": { + "instruction": "VGATHERPF1DPD", + "title": "VGATHERPF1DPS/VGATHERPF1QPS/VGATHERPF1DPD/VGATHERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /2 /vsib VGATHERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf1dps:vgatherpf1qps:vgatherpf1dpd:vgatherpf1qpd" + }, + "vgatherpf1dps": { + "instruction": "VGATHERPF1DPS", + "title": "VGATHERPF1DPS/VGATHERPF1QPS/VGATHERPF1DPD/VGATHERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /2 /vsib VGATHERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf1dps:vgatherpf1qps:vgatherpf1dpd:vgatherpf1qpd" + }, + "vgatherpf1qpd": { + "instruction": "VGATHERPF1QPD", + "title": "VGATHERPF1DPS/VGATHERPF1QPS/VGATHERPF1DPD/VGATHERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /2 /vsib VGATHERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf1dps:vgatherpf1qps:vgatherpf1dpd:vgatherpf1qpd" + }, + "vgatherpf1qps": { + "instruction": "VGATHERPF1QPS", + "title": "VGATHERPF1DPS/VGATHERPF1QPS/VGATHERPF1DPD/VGATHERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint", + "opcode": "EVEX.512.66.0F38.W0 C6 /2 /vsib VGATHERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherpf1dps:vgatherpf1qps:vgatherpf1dpd:vgatherpf1qpd" + }, + "vgatherqpd": { + "instruction": "VGATHERQPD", + "title": "VGATHERQPS/VGATHERQPD\n\t\t— Gather Packed Single, Packed Double with Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 93 /vsib VGATHERQPS xmm1 {k1}, vm64x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherqps:vgatherqpd" + }, + "vgatherqps": { + "instruction": "VGATHERQPS", + "title": "VGATHERQPS/VGATHERQPD\n\t\t— Gather Packed Single, Packed Double with Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 93 /vsib VGATHERQPS xmm1 {k1}, vm64x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgatherqps:vgatherqpd" + }, + "vgetexppd": { + "instruction": "VGETEXPPD", + "title": "VGETEXPPD\n\t\t— Convert Exponents of Packed Double Precision Floating-Point Values to DoublePrecision Floating-Point Values", + "opcode": "EVEX.128.66.0F38.W1 42 /r VGETEXPPD xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetexppd" + }, + "vgetexpph": { + "instruction": "VGETEXPPH", + "title": "VGETEXPPH\n\t\t— Convert Exponents of Packed FP16 Values to FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 42 /r VGETEXPPH xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetexpph" + }, + "vgetexpps": { + "instruction": "VGETEXPPS", + "title": "VGETEXPPS\n\t\t— Convert Exponents of Packed Single Precision Floating-Point Values to SinglePrecision Floating-Point Values", + "opcode": "EVEX.128.66.0F38.W0 42 /r VGETEXPPS xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetexpps" + }, + "vgetexpsd": { + "instruction": "VGETEXPSD", + "title": "VGETEXPSD\n\t\t— Convert Exponents of Scalar Double Precision Floating-Point Value to DoublePrecision Floating-Point Value", + "opcode": "EVEX.LLIG.66.0F38.W1 43 /r VGETEXPSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetexpsd" + }, + "vgetexpsh": { + "instruction": "VGETEXPSH", + "title": "VGETEXPSH\n\t\t— Convert Exponents of Scalar FP16 Values to FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 43 /r VGETEXPSH xmm1{k1}{z}, xmm2, xmm3/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetexpsh" + }, + "vgetexpss": { + "instruction": "VGETEXPSS", + "title": "VGETEXPSS\n\t\t— Convert Exponents of Scalar Single Precision Floating-Point Value to SinglePrecision Floating-Point Value", + "opcode": "EVEX.LLIG.66.0F38.W0 43 /r VGETEXPSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetexpss" + }, + "vgetmantpd": { + "instruction": "VGETMANTPD", + "title": "VGETMANTPD\n\t\t— Extract Float64 Vector of Normalized Mantissas From Float64 Vector", + "opcode": "EVEX.128.66.0F3A.W1 26 /r ib VGETMANTPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetmantpd" + }, + "vgetmantph": { + "instruction": "VGETMANTPH", + "title": "VGETMANTPH\n\t\t— Extract FP16 Vector of Normalized Mantissas from FP16 Vector", + "opcode": "EVEX.128.NP.0F3A.W0 26 /r /ib VGETMANTPH xmm1{k1}{z}, xmm2/m128/m16bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetmantph" + }, + "vgetmantps": { + "instruction": "VGETMANTPS", + "title": "VGETMANTPS\n\t\t— Extract Float32 Vector of Normalized Mantissas From Float32 Vector", + "opcode": "EVEX.128.66.0F3A.W0 26 /r ib VGETMANTPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetmantps" + }, + "vgetmantsd": { + "instruction": "VGETMANTSD", + "title": "VGETMANTSD\n\t\t— Extract Float64 of Normalized Mantissa From Float64 Scalar", + "opcode": "EVEX.LLIG.66.0F3A.W1 27 /r ib VGETMANTSD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetmantsd" + }, + "vgetmantsh": { + "instruction": "VGETMANTSH", + "title": "VGETMANTSH\n\t\t— Extract FP16 of Normalized Mantissa from FP16 Scalar", + "opcode": "EVEX.LLIG.NP.0F3A.W0 27 /r /ib VGETMANTSH xmm1{k1}{z}, xmm2, xmm3/m16 {sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetmantsh" + }, + "vgetmantss": { + "instruction": "VGETMANTSS", + "title": "VGETMANTSS\n\t\t— Extract Float32 Vector of Normalized Mantissa From Float32 Scalar", + "opcode": "EVEX.LLIG.66.0F3A.W0 27 /r ib VGETMANTSS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vgetmantss" + }, + "vinsertf128": { + "instruction": "VINSERTF128", + "title": "VINSERTF128/VINSERTF32x4/VINSERTF64x2/VINSERTF32x8/VINSERTF64x4\n\t\t— Insert PackedFloating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 18 /r ib VINSERTF128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinsertf128:vinsertf32x4:vinsertf64x2:vinsertf32x8:vinsertf64x4" + }, + "vinsertf32x4": { + "instruction": "VINSERTF32X4", + "title": "VINSERTF128/VINSERTF32x4/VINSERTF64x2/VINSERTF32x8/VINSERTF64x4\n\t\t— Insert PackedFloating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 18 /r ib VINSERTF128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinsertf128:vinsertf32x4:vinsertf64x2:vinsertf32x8:vinsertf64x4" + }, + "vinsertf32x8": { + "instruction": "VINSERTF32X8", + "title": "VINSERTF128/VINSERTF32x4/VINSERTF64x2/VINSERTF32x8/VINSERTF64x4\n\t\t— Insert PackedFloating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 18 /r ib VINSERTF128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinsertf128:vinsertf32x4:vinsertf64x2:vinsertf32x8:vinsertf64x4" + }, + "vinsertf64x2": { + "instruction": "VINSERTF64X2", + "title": "VINSERTF128/VINSERTF32x4/VINSERTF64x2/VINSERTF32x8/VINSERTF64x4\n\t\t— Insert PackedFloating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 18 /r ib VINSERTF128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinsertf128:vinsertf32x4:vinsertf64x2:vinsertf32x8:vinsertf64x4" + }, + "vinsertf64x4": { + "instruction": "VINSERTF64X4", + "title": "VINSERTF128/VINSERTF32x4/VINSERTF64x2/VINSERTF32x8/VINSERTF64x4\n\t\t— Insert PackedFloating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 18 /r ib VINSERTF128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinsertf128:vinsertf32x4:vinsertf64x2:vinsertf32x8:vinsertf64x4" + }, + "vinserti128": { + "instruction": "VINSERTI128", + "title": "VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4\n\t\t— Insert PackedInteger Values", + "opcode": "VEX.256.66.0F3A.W0 38 /r ib VINSERTI128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinserti128:vinserti32x4:vinserti64x2:vinserti32x8:vinserti64x4" + }, + "vinserti32x4": { + "instruction": "VINSERTI32X4", + "title": "VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4\n\t\t— Insert PackedInteger Values", + "opcode": "VEX.256.66.0F3A.W0 38 /r ib VINSERTI128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinserti128:vinserti32x4:vinserti64x2:vinserti32x8:vinserti64x4" + }, + "vinserti32x8": { + "instruction": "VINSERTI32X8", + "title": "VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4\n\t\t— Insert PackedInteger Values", + "opcode": "VEX.256.66.0F3A.W0 38 /r ib VINSERTI128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinserti128:vinserti32x4:vinserti64x2:vinserti32x8:vinserti64x4" + }, + "vinserti64x2": { + "instruction": "VINSERTI64X2", + "title": "VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4\n\t\t— Insert PackedInteger Values", + "opcode": "VEX.256.66.0F3A.W0 38 /r ib VINSERTI128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinserti128:vinserti32x4:vinserti64x2:vinserti32x8:vinserti64x4" + }, + "vinserti64x4": { + "instruction": "VINSERTI64X4", + "title": "VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4\n\t\t— Insert PackedInteger Values", + "opcode": "VEX.256.66.0F3A.W0 38 /r ib VINSERTI128 ymm1, ymm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vinserti128:vinserti32x4:vinserti64x2:vinserti32x8:vinserti64x4" + }, + "vmaskmov": { + "instruction": "VMASKMOV", + "title": "VMASKMOV\n\t\t— Conditional SIMD Packed Loads and Stores", + "opcode": "VEX.128.66.0F38.W0 2C /r VMASKMOVPS xmm1, xmm2, m128", + "description": "Conditionally moves packed data elements from the second source operand into the corresponding data element of the destination operand, depending on the mask bits associated with each data element. The mask bits are specified in the first source operand.\nThe mask bit for each data element is the most significant bit of that element in the first source operand. If a mask is 1, the corresponding data element is copied from the second source operand to the destination operand. If the mask is 0, the corresponding data element is set to zero in the load form of these instructions, and unmodified in the store form.\nThe second source operand is a memory address for the load form of these instruction. The destination operand is a memory address for the store form of these instructions. The other operands are both XMM registers (for VEX.128 version) or YMM registers (for VEX.256 version).\nFaults occur only due to mask-bit required memory accesses that caused the faults. Faults will not occur due to referencing any memory location if the corresponding mask bit for that memory location is 0. For example, no faults will be detected if the mask bits are all zero.\nUnlike previous MASKMOV instructions (MASKMOVQ and MASKMOVDQU), a nontemporal hint is not applied to these instructions.\nInstruction behavior on alignment check reporting with mask bits of less than all 1s are the same as with mask bits of all 1s.\nVMASKMOV should not be used to access memory mapped I/O and un-cached memory as the access and the ordering of the individual loads or stores it does is implementation specific.\nIn cases where mask bits indicate data should not be loaded or stored paging A and D bits will be set in an implementation dependent way. However, A and D bits are always set for pages where data is actually loaded/stored.\nNote: for load forms, the first source (the mask) is encoded in VEX.vvvv; the second source is encoded in rm_field, and the destination register is encoded in reg_field.\nNote: for store forms, the first source (the mask) is encoded in VEX.vvvv; the second source register is encoded in reg_field, and the destination memory location is encoded in rm_field.", + "operation": "DEST[31:0] := IF (SRC1[31]) Load_32(mem) ELSE 0\nDEST[63:32] := IF (SRC1[63]) Load_32(mem + 4) ELSE 0\nDEST[95:64] := IF (SRC1[95]) Load_32(mem + 8) ELSE 0\nDEST[127:97] := IF (SRC1[127]) Load_32(mem + 12) ELSE 0\nDEST[MAXVL-1:128] := 0\n\n\nDEST[31:0] := IF (SRC1[31]) Load_32(mem) ELSE 0\nDEST[63:32] := IF (SRC1[63]) Load_32(mem + 4) ELSE 0\nDEST[95:64] := IF (SRC1[95]) Load_32(mem + 8) ELSE 0\nDEST[127:96] := IF (SRC1[127]) Load_32(mem + 12) ELSE 0\nDEST[159:128] := IF (SRC1[159]) Load_32(mem + 16) ELSE 0\nDEST[191:160] := IF (SRC1[191]) Load_32(mem + 20) ELSE 0\nDEST[223:192] := IF (SRC1[223]) Load_32(mem + 24) ELSE 0\nDEST[255:224] := IF (SRC1[255]) Load_32(mem + 28) ELSE 0\n\n\nDEST[63:0] := IF (SRC1[63]) Load_64(mem) ELSE 0\nDEST[127:64] := IF (SRC1[127]) Load_64(mem + 16) ELSE 0\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := IF (SRC1[63]) Load_64(mem) ELSE 0\nDEST[127:64] := IF (SRC1[127]) Load_64(mem + 8) ELSE 0\nDEST[195:128] := IF (SRC1[191]) Load_64(mem + 16) ELSE 0\nDEST[255:196] := IF (SRC1[255]) Load_64(mem + 24) ELSE 0\n\n\nIF (SRC1[31]) DEST[31:0] := SRC2[31:0]\nIF (SRC1[63]) DEST[63:32] := SRC2[63:32]\nIF (SRC1[95]) DEST[95:64] := SRC2[95:64]\nIF (SRC1[127]) DEST[127:96] := SRC2[127:96]\n\n\nIF (SRC1[31]) DEST[31:0] := SRC2[31:0]\nIF (SRC1[63]) DEST[63:32] := SRC2[63:32]\nIF (SRC1[95]) DEST[95:64] := SRC2[95:64]\nIF (SRC1[127]) DEST[127:96] := SRC2[127:96]\nIF (SRC1[159]) DEST[159:128] :=SRC2[159:128]\nIF (SRC1[191]) DEST[191:160] := SRC2[191:160]\nIF (SRC1[223]) DEST[223:192] := SRC2[223:192]\nIF (SRC1[255]) DEST[255:224] := SRC2[255:224]\n\n\nIF (SRC1[63]) DEST[63:0] := SRC2[63:0]\nIF (SRC1[127]) DEST[127:64] := SRC2[127:64]\n\n\nIF (SRC1[63]) DEST[63:0] := SRC2[63:0]\nIF (SRC1[127]) DEST[127:64] := SRC2[127:64]\nIF (SRC1[191]) DEST[191:128] := SRC2[191:128]\nIF (SRC1[255]) DEST[255:192] := SRC2[255:192]\n", + "url": "https://www.felixcloutier.com/x86/vmaskmov" + }, + "vmaxph": { + "instruction": "VMAXPH", + "title": "VMAXPH\n\t\t— Return Maximum of Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 5F /r VMAXPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmaxph" + }, + "vmaxsh": { + "instruction": "VMAXSH", + "title": "VMAXSH\n\t\t— Return Maximum of Scalar FP16 Values", + "opcode": "EVEX.LLIG.F3.MAP5.W0 5F /r VMAXSH xmm1{k1}{z}, xmm2, xmm3/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmaxsh" + }, + "vmcall": { + "instruction": "VMCALL", + "title": "VMCALL\n\t\t— Call to VM Monitor", + "opcode": "0F 01 C1 VMCALL", + "description": "This instruction allows guest software can make a call for service into an underlying VM monitor. The details of the programming interface for such calls are VMM-specific; this instruction does nothing more than cause a VM exit, registering the appropriate exit reason.\nUse of this instruction in VMX root operation invokes an SMM monitor (see Section 32.15.2). This invocation will activate the dual-monitor treatment of system-management interrupts (SMIs) and system-management mode (SMM) if it is not already active (see Section 32.15.6).", + "operation": "IF not in VMX operation\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VM exit;\nELSIF (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF CPL > 0\n THEN #GP(0);\nELSIF in SMM or the logical processor does not support the dual-monitor treatment of SMIs and SMM or the valid bit in the\nIA32_SMM_MONITOR_CTL MSR is clear\n THEN VMfail (VMCALL executed in VMX root operation);\nELSIF dual-monitor treatment of SMIs and SMM is active\n THEN perform an SMM VM exit (see Section 32.15.2);\nELSIF current-VMCS pointer is not valid\n THEN VMfailInvalid;\nELSIF launch state of current VMCS is not clear\n THEN VMfailValid(VMCALL with non-clear VMCS);\nELSIF VM-exit control fields are not valid (see Section 32.15.6.1)\n THEN VMfailValid (VMCALL with invalid VM-exit control fields);\nELSE\n enter SMM;\n read revision identifier in MSEG;\n IF revision identifier does not match that supported by processor\n THEN\n leave SMM;\n VMfailValid(VMCALL with incorrect MSEG revision identifier);\n ELSE\n read SMM-monitor features field in MSEG (see Section 32.15.6.1);\n IF features field is invalid\n THEN\n leave SMM;\n VMfailValid(VMCALL with invalid SMM-monitor features);\n ELSE activate dual-monitor treatment of SMIs and SMM (see Section 32.15.6);\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmcall" + }, + "vmclear": { + "instruction": "VMCLEAR", + "title": "VMCLEAR\n\t\t— Clear Virtual-Machine Control Structure", + "opcode": "66 0F C7 /6 VMCLEAR m64", + "description": "This instruction applies to the VMCS whose VMCS region resides at the physical address contained in the instruction operand. The instruction ensures that VMCS data for that VMCS (some of these data may be currently maintained on the processor) are copied to the VMCS region in memory. It also initializes parts of the VMCS region (for example, it sets the launch state of that VMCS to clear). See Chapter 25, “Virtual Machine Control Structures.”\nThe operand of this instruction is always 64 bits and is always in memory. If the operand is the current-VMCS pointer, then that pointer is made invalid (set to FFFFFFFF_FFFFFFFFH).\nNote that the VMCLEAR instruction might not explicitly write any VMCS data to memory; the data may be already resident in memory before the VMCLEAR is executed.", + "operation": "IF (register operand) or (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VM exit;\nELSIF CPL > 0\n THEN #GP(0);\n ELSE\n addr := contents of 64-bit in-memory operand;\n IF addr is not 4KB-aligned OR\n addr sets any bits beyond the physical-address width1\n THEN VMfail(VMCLEAR with invalid physical address);\n ELSIF addr = VMXON pointer\n THEN VMfail(VMCLEAR with VMXON pointer);\n ELSE\n ensure that data for VMCS referenced by the operand is in memory;\n initialize implementation-specific data in VMCS region;\n launch state of VMCS referenced by the operand := “clear”\n IF operand addr = current-VMCS pointer\n THEN current-VMCS pointer := FFFFFFFF_FFFFFFFFH;\n FI;\n VMsucceed;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmclear" + }, + "vmfunc": { + "instruction": "VMFUNC", + "title": "VMFUNC\n\t\t— Invoke VM function", + "opcode": "NP 0F 01 D4 VMFUNC", + "description": "This instruction allows software in VMX non-root operation to invoke a VM function, which is processor functionality enabled and configured by software in VMX root operation. The value of EAX selects the specific VM function being invoked.\nThe behavior of each VM function (including any additional fault checking) is specified in Section 26.5.6, “VM Functions.”", + "operation": "Perform functionality of the VM function specified in EAX;\n", + "url": "https://www.felixcloutier.com/x86/vmfunc" + }, + "vminph": { + "instruction": "VMINPH", + "title": "VMINPH\n\t\t— Return Minimum of Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 5D /r VMINPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vminph" + }, + "vminsh": { + "instruction": "VMINSH", + "title": "VMINSH\n\t\t— Return Minimum Scalar FP16 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 5D /r VMINSH xmm1{k1}{z}, xmm2, xmm3/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vminsh" + }, + "vmlaunch": { + "instruction": "VMLAUNCH", + "title": "VMLAUNCH/VMRESUME\n\t\t— Launch/Resume Virtual Machine", + "opcode": "0F 01 C2 VMLAUNCH", + "description": "Effects a VM entry managed by the current VMCS.\nIf VM entry is attempted, the logical processor performs a series of consistency checks as detailed in Chapter 27, “VM Entries.” Failure to pass checks on the VMX controls or on the host-state area passes control to the instruction following the VMLAUNCH or VMRESUME instruction. If these pass but checks on the guest-state area fail, the logical processor loads state from the host-state area of the VMCS, passing control to the instruction referenced by the RIP field in the host-state area.\nVM entry is not allowed when events are blocked by MOV SS or POP SS. Neither VMLAUNCH nor VMRESUME should be used immediately after either MOV to SS or POP to SS.", + "operation": "IF (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\nELSIF current-VMCS pointer is not valid\n THEN VMfailInvalid;\nELSIF events are being blocked by MOV SS\n THEN VMfailValid(VM entry with events blocked by MOV SS);\nELSIF (VMLAUNCH and launch state of current VMCS is not “clear”)\n THEN VMfailValid(VMLAUNCH with non-clear VMCS);\nELSIF (VMRESUME and launch state of current VMCS is not “launched”)\n THEN VMfailValid(VMRESUME with non-launched VMCS);\n ELSE\n Check settings of VMX controls and host-state area;\n IF invalid settings\n THEN VMfailValid(VM entry with invalid VMX-control field(s)) or\n VMfailValid(VM entry with invalid host-state field(s)) or\n VMfailValid(VM entry with invalid executive-VMCS pointer)) or\n VMfailValid(VM entry with non-launched executive VMCS) or\n VMfailValid(VM entry with executive-VMCS pointer not VMXON pointer) or\n VMfailValid(VM entry with invalid VM-execution control fields in executive\n VMCS)\n as appropriate;\n ELSE\n Attempt to load guest state and PDPTRs as appropriate;\n clear address-range monitoring;\n IF failure in checking guest state or PDPTRs\n THEN VM entry fails (see Section 27.8);\n ELSE\n Attempt to load MSRs from VM-entry MSR-load area;\n IF failure\n THEN VM entry fails\n (see Section 27.8);\n ELSE\n IF VMLAUNCH\n THEN launch state of VMCS := “launched”;\n FI;\n IF in SMM and “entry to SMM” VM-entry control is 0\n THEN\n IF “deactivate dual-monitor treatment” VM-entry\n control is 0\n THEN SMM-transfer VMCS pointer :=\n current-VMCS pointer;\n FI;\n IF executive-VMCS pointer is VMXON pointer\n THEN current-VMCS pointer :=\n VMCS-link pointer;\n ELSE current-VMCS pointer :=\n executive-VMCS pointer;\n FI;\n leave SMM;\n FI;\n VM entry succeeds;\n FI;\n FI;\n FI;\nFI;\nFurther details of the operation of the VM-entry appear in Chapter 27.\n", + "url": "https://www.felixcloutier.com/x86/vmlaunch:vmresume" + }, + "vmovdqa32": { + "instruction": "VMOVDQA32", + "title": "MOVDQA/VMOVDQA32/VMOVDQA64\n\t\t— Move Aligned Packed Integer Values", + "opcode": "66 0F 6F /r MOVDQA xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed doubleword/quadword integer values from the source operand (the second operand) to the destination operand (the first operand). This instruction can be used to load a vector register from an int32/int64 memory location, to store the contents of a vector register into an int32/int64 memory location, or to move data between two ZMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16 (EVEX.128)/32(EVEX.256)/64(EVEX.512)-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction.\nThe destination operand is updated at 32-bit (VMOVDQA32) or 64-bit (VMOVDQA64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 32-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction. Bits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqa:vmovdqa32:vmovdqa64" + }, + "vmovdqa64": { + "instruction": "VMOVDQA64", + "title": "MOVDQA/VMOVDQA32/VMOVDQA64\n\t\t— Move Aligned Packed Integer Values", + "opcode": "66 0F 6F /r MOVDQA xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed doubleword/quadword integer values from the source operand (the second operand) to the destination operand (the first operand). This instruction can be used to load a vector register from an int32/int64 memory location, to store the contents of a vector register into an int32/int64 memory location, or to move data between two ZMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16 (EVEX.128)/32(EVEX.256)/64(EVEX.512)-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction.\nThe destination operand is updated at 32-bit (VMOVDQA32) or 64-bit (VMOVDQA64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 32-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction. Bits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\nWhen the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated. To move integer data to and from unaligned memory locations, use the VMOVDQU instruction.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding ZMM destination register remain unchanged.\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqa:vmovdqa32:vmovdqa64" + }, + "vmovdqu16": { + "instruction": "VMOVDQU16", + "title": "MOVDQU/VMOVDQU8/VMOVDQU16/VMOVDQU32/VMOVDQU64\n\t\t— Move Unaligned Packed Integer Values", + "opcode": "F3 0F 6F /r MOVDQU xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed byte/word/doubleword/quadword integer values from the source operand (the second operand) to the destination operand (first operand). This instruction can be used to load a vector register from a memory location, to store the contents of a vector register into a memory location, or to move data between two vector registers.\nThe destination operand is updated at 8-bit (VMOVDQU8), 16-bit (VMOVDQU16), 32-bit (VMOVDQU32), or 64-bit (VMOVDQU64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nBits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned to any alignment without causing a general-protection exception (#GP) to be generated\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] :=\n SRC[i+7:i]\n ELSE *DEST[i+7:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] :=\n SRC[i+15:i]\n ELSE *DEST[i+15:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\nVMOVDQU (VEX.128 encoded version)\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqu:vmovdqu8:vmovdqu16:vmovdqu32:vmovdqu64" + }, + "vmovdqu32": { + "instruction": "VMOVDQU32", + "title": "MOVDQU/VMOVDQU8/VMOVDQU16/VMOVDQU32/VMOVDQU64\n\t\t— Move Unaligned Packed Integer Values", + "opcode": "F3 0F 6F /r MOVDQU xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed byte/word/doubleword/quadword integer values from the source operand (the second operand) to the destination operand (first operand). This instruction can be used to load a vector register from a memory location, to store the contents of a vector register into a memory location, or to move data between two vector registers.\nThe destination operand is updated at 8-bit (VMOVDQU8), 16-bit (VMOVDQU16), 32-bit (VMOVDQU32), or 64-bit (VMOVDQU64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nBits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned to any alignment without causing a general-protection exception (#GP) to be generated\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] :=\n SRC[i+7:i]\n ELSE *DEST[i+7:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] :=\n SRC[i+15:i]\n ELSE *DEST[i+15:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\nVMOVDQU (VEX.128 encoded version)\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqu:vmovdqu8:vmovdqu16:vmovdqu32:vmovdqu64" + }, + "vmovdqu64": { + "instruction": "VMOVDQU64", + "title": "MOVDQU/VMOVDQU8/VMOVDQU16/VMOVDQU32/VMOVDQU64\n\t\t— Move Unaligned Packed Integer Values", + "opcode": "F3 0F 6F /r MOVDQU xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed byte/word/doubleword/quadword integer values from the source operand (the second operand) to the destination operand (first operand). This instruction can be used to load a vector register from a memory location, to store the contents of a vector register into a memory location, or to move data between two vector registers.\nThe destination operand is updated at 8-bit (VMOVDQU8), 16-bit (VMOVDQU16), 32-bit (VMOVDQU32), or 64-bit (VMOVDQU64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nBits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned to any alignment without causing a general-protection exception (#GP) to be generated\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] :=\n SRC[i+7:i]\n ELSE *DEST[i+7:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] :=\n SRC[i+15:i]\n ELSE *DEST[i+15:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\nVMOVDQU (VEX.128 encoded version)\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqu:vmovdqu8:vmovdqu16:vmovdqu32:vmovdqu64" + }, + "vmovdqu8": { + "instruction": "VMOVDQU8", + "title": "MOVDQU/VMOVDQU8/VMOVDQU16/VMOVDQU32/VMOVDQU64\n\t\t— Move Unaligned Packed Integer Values", + "opcode": "F3 0F 6F /r MOVDQU xmm1, xmm2/m128", + "description": "Note: VEX.vvvv and EVEX.vvvv are reserved and must be 1111b otherwise instructions will #UD.\nEVEX encoded versions:\nMoves 128, 256 or 512 bits of packed byte/word/doubleword/quadword integer values from the source operand (the second operand) to the destination operand (first operand). This instruction can be used to load a vector register from a memory location, to store the contents of a vector register into a memory location, or to move data between two vector registers.\nThe destination operand is updated at 8-bit (VMOVDQU8), 16-bit (VMOVDQU16), 32-bit (VMOVDQU32), or 64-bit (VMOVDQU64) granularity according to the writemask.\nVEX.256 encoded version:\nMoves 256 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load a YMM register from a 256-bit memory location, to store the contents of a YMM register into a 256-bit memory location, or to move data between two YMM registers.\nBits (MAXVL-1:256) of the destination register are zeroed.\n128-bit versions:\nMoves 128 bits of packed integer values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers.\n128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding destination register remain unchanged.\nWhen the source or destination operand is a memory operand, the operand may be unaligned to any alignment without causing a general-protection exception (#GP) to be generated\nVEX.128 encoded version: Bits (MAXVL-1:128) of the destination register are zeroed.", + "operation": "(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] :=\n SRC[i+7:i]\n ELSE *DEST[i+7:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (16, 128), (32, 256), (64, 512)\nFOR j := 0 TO KL-1\n i := j * 8\n IF k1[j] OR *no writemask*\n THEN DEST[i+7:i] := SRC[i+7:i]\n ELSE\n IF *merging-masking*\n ; merging-masking\n THEN *DEST[i+7:i] remains unchanged*\n ELSE DEST[i+7:i] := 0\n ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] :=\n SRC[i+15:i]\n ELSE *DEST[i+15:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (8, 128), (16, 256), (32, 512)\nFOR j := 0 TO KL-1\n i := j * 16\n IF k1[j] OR *no writemask*\n THEN DEST[i+15:i] := SRC[i+15:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+15:i] remains unchanged*\n ELSE DEST[i+15:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] :=\n SRC[i+31:i]\n ELSE *DEST[i+31:i] remains unchanged*\n ; merging-masking\n I\n ;\nENDFOR;\n\n\n(KL, VL) = (4, 128), (8, 256), (16, 512)\nFOR j := 0 TO KL-1\n i := j * 32\n IF k1[j] OR *no writemask*\n THEN DEST[i+31:i] := SRC[i+31:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+31:i] remains unchanged*\n ELSE DEST[i+31:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE *DEST[i+63:i] remains unchanged*\n ; merging-masking\n FI;\nENDFOR;\n\n\n(KL, VL) = (2, 128), (4, 256), (8, 512)\nFOR j := 0 TO KL-1\n i := j * 64\n IF k1[j] OR *no writemask*\n THEN DEST[i+63:i] := SRC[i+63:i]\n ELSE\n IF *merging-masking*\n THEN *DEST[i+63:i] remains unchanged*\n ELSE DEST[i+63:i] := 0 ; zeroing-masking\n FI\n FI;\nENDFOR\nDEST[MAXVL-1:VL] := 0\n\n\nDEST[255:0] := SRC[255:0]\nDEST[MAXVL-1:256] := 0\n\n\nDEST[255:0] := SRC[255:0]\nVMOVDQU (VEX.128 encoded version)\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] := 0\n\n\nDEST[127:0] := SRC[127:0]\nDEST[MAXVL-1:128] (Unmodified)\n\n\nDEST[127:0] := SRC[127:0]\n", + "url": "https://www.felixcloutier.com/x86/movdqu:vmovdqu8:vmovdqu16:vmovdqu32:vmovdqu64" + }, + "vmovsh": { + "instruction": "VMOVSH", + "title": "VMOVSH\n\t\t— Move Scalar FP16 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 10 /r VMOVSH xmm1{k1}{z}, m16", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmovsh" + }, + "vmovw": { + "instruction": "VMOVW", + "title": "VMOVW\n\t\t— Move Word", + "opcode": "EVEX.128.66.MAP5.WIG 6E /r VMOVW xmm1, reg/m16", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmovw" + }, + "vmptrld": { + "instruction": "VMPTRLD", + "title": "VMPTRLD\n\t\t— Load Pointer to Virtual-Machine Control Structure", + "opcode": "NP 0F C7 /6 VMPTRLD m64", + "description": "Marks the current-VMCS pointer valid and loads it with the physical address in the instruction operand. The instruction fails if its operand is not properly aligned, sets unsupported physical-address bits, or is equal to the VMXON pointer. In addition, the instruction fails if the 32 bits in memory referenced by the operand do not match the VMCS revision identifier supported by this processor.1\nThe operand of this instruction is always 64 bits and is always in memory.", + "operation": "IF (register operand) or (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\n ELSE\n addr := contents of 64-bit in-memory source operand;\n IF addr is not 4KB-aligned OR\n addr sets any bits beyond the physical-address width2\n THEN VMfail(VMPTRLD with invalid physical address);\n ELSIF addr = VMXON pointer\n THEN VMfail(VMPTRLD with VMXON pointer);\n ELSE\n rev := 32 bits located at physical address addr;\n IF rev[30:0] ≠ VMCS revision identifier supported by processor OR\n rev[31] = 1 AND processor does not support 1-setting of “VMCS shadowing”\n THEN VMfail(VMPTRLD with incorrect VMCS revision identifier);\n ELSE\n current-VMCS pointer := addr;\n VMsucceed;\n FI;\n FI;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmptrld" + }, + "vmptrst": { + "instruction": "VMPTRST", + "title": "VMPTRST\n\t\t— Store Pointer to Virtual-Machine Control Structure", + "opcode": "NP 0F C7 /7 VMPTRST m64", + "description": "Stores the current-VMCS pointer into a specified memory address. The operand of this instruction is always 64 bits and is always in memory.", + "operation": "IF (register operand) or (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\n ELSE\n 64-bit in-memory destination operand := current-VMCS pointer;\n VMsucceed;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmptrst" + }, + "vmread": { + "instruction": "VMREAD", + "title": "VMREAD\n\t\t— Read Field from Virtual-Machine Control Structure", + "opcode": "NP 0F 78 VMREAD r/m64, r64", + "description": "Reads a specified field from a VMCS and stores it into a specified destination operand (register or memory). In VMX root operation, the instruction reads from the current VMCS. If executed in VMX non-root operation, the instruction reads from the VMCS referenced by the VMCS link pointer field in the current VMCS.\nThe VMCS field is specified by the VMCS-field encoding contained in the register source operand. Outside IA-32e mode, the source operand has 32 bits, regardless of the value of CS.D. In 64-bit mode, the source operand has 64 bits.\nThe effective size of the destination operand, which may be a register or in memory, is always 32 bits outside IA-32e mode (the setting of CS.D is ignored with respect to operand size) and 64 bits in 64-bit mode. If the VMCS field specified by the source operand is shorter than this effective operand size, the high bits of the destination operand are cleared to 0. If the VMCS field is longer, then the high bits of the field are not read.\nNote that any faults resulting from accessing a memory destination operand can occur only after determining, in the operation section below, that the relevant VMCS pointer is valid and that the specified VMCS field is supported.", + "operation": "IF (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation AND (“VMCS shadowing” is 0 OR source operand sets bits in range 63:15 OR\nVMREAD bit corresponding to bits 14:0 of source operand is 1)1\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\nELSIF (in VMX root operation AND current-VMCS pointer is not valid) OR\n(in VMX non-root operation AND VMCS link pointer is not valid)\n THEN VMfailInvalid;\nELSIF source operand does not correspond to any VMCS field\n THEN VMfailValid(VMREAD/VMWRITE from/to unsupported VMCS component);\n ELSE\n IF in VMX root operation\n THEN destination operand := contents of field indexed by source operand in current VMCS;\n ELSE destination operand := contents of field indexed by source operand in VMCS referenced by VMCS link pointer;\n FI;\n VMsucceed;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmread" + }, + "vmresume": { + "instruction": "VMRESUME", + "title": "VMRESUME\n\t\t— Resume Virtual Machine", + "opcode": "", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmresume" + }, + "vmulph": { + "instruction": "VMULPH", + "title": "VMULPH\n\t\t— Multiply Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 59 /r VMULPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmulph" + }, + "vmulsh": { + "instruction": "VMULSH", + "title": "VMULSH\n\t\t— Multiply Scalar FP16 Values", + "opcode": "EVEX.LLIG.F3.MAP5.W0 59 /r VMULSH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vmulsh" + }, + "vmwrite": { + "instruction": "VMWRITE", + "title": "VMWRITE\n\t\t— Write Field to Virtual-Machine Control Structure", + "opcode": "NP 0F 79 VMWRITE r64, r/m64", + "description": "Writes the contents of a primary source operand (register or memory) to a specified field in a VMCS. In VMX root operation, the instruction writes to the current VMCS. If executed in VMX non-root operation, the instruction writes to the VMCS referenced by the VMCS link pointer field in the current VMCS.\nThe VMCS field is specified by the VMCS-field encoding contained in the register secondary source operand. Outside IA-32e mode, the secondary source operand is always 32 bits, regardless of the value of CS.D. In 64-bit mode, the secondary source operand has 64 bits.\nThe effective size of the primary source operand, which may be a register or in memory, is always 32 bits outside IA-32e mode (the setting of CS.D is ignored with respect to operand size) and 64 bits in 64-bit mode. If the VMCS field specified by the secondary source operand is shorter than this effective operand size, the high bits of the primary source operand are ignored. If the VMCS field is longer, then the high bits of the field are cleared to 0.\nNote that any faults resulting from accessing a memory source operand occur after determining, in the operation section below, that the relevant VMCS pointer is valid but before determining if the destination VMCS field is supported.", + "operation": "IF (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation AND (“VMCS shadowing” is 0 OR secondary source operand sets bits in range 63:15 OR\nVMWRITE bit corresponding to bits 14:0 of secondary source operand is 1)1\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\nELSIF (in VMX root operation AND current-VMCS pointer is not valid) OR\n(in VMX non-root operation AND VMCS-link pointer is not valid)\n THEN VMfailInvalid;\nELSIF secondary source operand does not correspond to any VMCS field\n THEN VMfailValid(VMREAD/VMWRITE from/to unsupported VMCS component);\nELSIF VMCS field indexed by secondary source operand is a VM-exit information field AND\nprocessor does not support writing to such fields2\n THEN VMfailValid(VMWRITE to read-only VMCS component);\n ELSE\n\n\n IF in VMX root operation\n THEN field indexed by secondary source operand in current VMCS := primary source operand;\n ELSE field indexed by secondary source operand in VMCS referenced by VMCS link pointer := primary source operand;\n FI;\n VMsucceed;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmwrite" + }, + "vmxoff": { + "instruction": "VMXOFF", + "title": "VMXOFF\n\t\t— Leave VMX Operation", + "opcode": "0F 01 C4 VMXOFF", + "description": "Takes the logical processor out of VMX operation, unblocks INIT signals, conditionally re-enables A20M, and clears any address-range monitoring.1", + "operation": "IF (not in VMX operation) or (CR0.PE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF in VMX non-root operation\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\nELSIF dual-monitor treatment of SMIs and SMM is active\n THEN VMfail(VMXOFF under dual-monitor treatment of SMIs and SMM);\n ELSE\n leave VMX operation;\n unblock INIT;\n IF IA32_SMM_MONITOR_CTL[2] = 02\n THEN unblock SMIs;\n IF outside SMX operation3\n THEN unblock and enable A20M;\n FI;\n clear address-range monitoring;\n VMsucceed;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmxoff" + }, + "vmxon": { + "instruction": "VMXON", + "title": "VMXON\n\t\t— Enter VMX Operation", + "opcode": "F3 0F C7 /6 VMXON m64", + "description": "Puts the logical processor in VMX operation with no current VMCS, blocks INIT signals, disables A20M, and clears any address-range monitoring established by the MONITOR instruction.1\nThe operand of this instruction is a 4KB-aligned physical address (the VMXON pointer) that references the VMXON region, which the logical processor may use to support VMX operation. This operand is always 64 bits and is always in memory.", + "operation": "IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)\n THEN #UD;\nELSIF not in VMX operation\n THEN\n IF (CPL > 0) or (in A20M mode) or\n (the values of CR0 and CR4 are not supported in VMX operation; see Section 24.8) or\n (bit 0 (lock bit) of IA32_FEATURE_CONTROL MSR is clear) or\n (in SMX operation2 and bit 1 of IA32_FEATURE_CONTROL MSR is clear) or\n (outside SMX operation and bit 2 of IA32_FEATURE_CONTROL MSR is clear)\n THEN #GP(0);\n ELSE\n addr := contents of 64-bit in-memory source operand;\n IF addr is not 4KB-aligned or\n addr sets any bits beyond the physical-address width3\n THEN VMfailInvalid;\n ELSE\n rev := 32 bits located at physical address addr;\n IF rev[30:0] ≠ VMCS revision identifier supported by processor OR rev[31] = 1\n THEN VMfailInvalid;\n ELSE\n current-VMCS pointer := FFFFFFFF_FFFFFFFFH;\n enter VMX operation;\n block INIT signals;\n block and disable A20M;\n\n\n clear address-range monitoring;\n IF the processor supports Intel PT but does not allow it to be used in VMX operation1\n THEN IA32_RTIT_CTL.TraceEn := 0;\n FI;\n VMsucceed;\n FI;\n FI;\n FI;\nELSIF in VMX non-root operation\n THEN VMexit;\nELSIF CPL > 0\n THEN #GP(0);\n ELSE VMfail(“VMXON executed in VMX root operation”);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/vmxon" + }, + "vp2intersectd": { + "instruction": "VP2INTERSECTD", + "title": "VP2INTERSECTD/VP2INTERSECTQ\n\t\t— Compute Intersection Between DWORDS/QUADWORDS to aPair of Mask Registers", + "opcode": "EVEX.NDS.128.F2.0F38.W0 68 /r VP2INTERSECTD k1+1, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vp2intersectd:vp2intersectq" + }, + "vp2intersectq": { + "instruction": "VP2INTERSECTQ", + "title": "VP2INTERSECTD/VP2INTERSECTQ\n\t\t— Compute Intersection Between DWORDS/QUADWORDS to aPair of Mask Registers", + "opcode": "EVEX.NDS.128.F2.0F38.W0 68 /r VP2INTERSECTD k1+1, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vp2intersectd:vp2intersectq" + }, + "vp4dpwssd": { + "instruction": "VP4DPWSSD", + "title": "VP4DPWSSD\n\t\t— Dot Product of Signed Words With Dword Accumulation (4-Iterations)", + "opcode": "EVEX.512.F2.0F38.W0 52 /r VP4DPWSSD zmm1{k1}{z}, zmm2+3, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vp4dpwssd" + }, + "vp4dpwssds": { + "instruction": "VP4DPWSSDS", + "title": "VP4DPWSSDS\n\t\t— Dot Product of Signed Words With Dword Accumulation and Saturation(4-Iterations)", + "opcode": "EVEX.512.F2.0F38.W0 53 /r VP4DPWSSDS zmm1{k1}{z}, zmm2+3, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vp4dpwssds" + }, + "vpblendd": { + "instruction": "VPBLENDD", + "title": "VPBLENDD\n\t\t— Blend Packed Dwords", + "opcode": "VEX.128.66.0F3A.W0 02 /r ib VPBLENDD xmm1, xmm2, xmm3/m128, imm8", + "description": "Dword elements from the source operand (second operand) are conditionally written to the destination operand (first operand) depending on bits in the immediate operand (third operand). The immediate bits (bits 7:0) form a mask that determines whether the corresponding dword in the destination is copied from the source. If a bit in the mask, corresponding to a dword, is “1\", then the dword is copied, else the dword is unchanged.\nVEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register are zeroed.\nVEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register or a 256-bit memory location. The destination operand is a YMM register.", + "operation": "IF (imm8[0] == 1) THEN DEST[31:0] := SRC2[31:0]\nELSE DEST[31:0] := SRC1[31:0]\nIF (imm8[1] == 1) THEN DEST[63:32] := SRC2[63:32]\nELSE DEST[63:32] := SRC1[63:32]\nIF (imm8[2] == 1) THEN DEST[95:64] := SRC2[95:64]\nELSE DEST[95:64] := SRC1[95:64]\nIF (imm8[3] == 1) THEN DEST[127:96] := SRC2[127:96]\nELSE DEST[127:96] := SRC1[127:96]\nIF (imm8[4] == 1) THEN DEST[159:128] := SRC2[159:128]\nELSE DEST[159:128] := SRC1[159:128]\nIF (imm8[5] == 1) THEN DEST[191:160] := SRC2[191:160]\nELSE DEST[191:160] := SRC1[191:160]\nIF (imm8[6] == 1) THEN DEST[223:192] := SRC2[223:192]\nELSE DEST[223:192] := SRC1[223:192]\nIF (imm8[7] == 1) THEN DEST[255:224] := SRC2[255:224]\nELSE DEST[255:224] := SRC1[255:224]\n\n\nIF (imm8[0] == 1) THEN DEST[31:0] := SRC2[31:0]\nELSE DEST[31:0] := SRC1[31:0]\nIF (imm8[1] == 1) THEN DEST[63:32] := SRC2[63:32]\nELSE DEST[63:32] := SRC1[63:32]\nIF (imm8[2] == 1) THEN DEST[95:64] := SRC2[95:64]\nELSE DEST[95:64] := SRC1[95:64]\nIF (imm8[3] == 1) THEN DEST[127:96] := SRC2[127:96]\nELSE DEST[127:96] := SRC1[127:96]\nDEST[MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/vpblendd" + }, + "vpblendmb": { + "instruction": "VPBLENDMB", + "title": "VPBLENDMB/VPBLENDMW\n\t\t— Blend Byte/Word Vectors Using an Opmask Control", + "opcode": "EVEX.128.66.0F38.W0 66 /r VPBLENDMB xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpblendmb:vpblendmw" + }, + "vpblendmd": { + "instruction": "VPBLENDMD", + "title": "VPBLENDMD/VPBLENDMQ\n\t\t— Blend Int32/Int64 Vectors Using an OpMask Control", + "opcode": "EVEX.128.66.0F38.W0 64 /r VPBLENDMD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpblendmd:vpblendmq" + }, + "vpblendmq": { + "instruction": "VPBLENDMQ", + "title": "VPBLENDMD/VPBLENDMQ\n\t\t— Blend Int32/Int64 Vectors Using an OpMask Control", + "opcode": "EVEX.128.66.0F38.W0 64 /r VPBLENDMD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpblendmd:vpblendmq" + }, + "vpblendmw": { + "instruction": "VPBLENDMW", + "title": "VPBLENDMB/VPBLENDMW\n\t\t— Blend Byte/Word Vectors Using an Opmask Control", + "opcode": "EVEX.128.66.0F38.W0 66 /r VPBLENDMB xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpblendmb:vpblendmw" + }, + "vpbroadcast": { + "instruction": "VPBROADCAST", + "title": "VPBROADCAST\n\t\t— Load Integer and Broadcast", + "opcode": "VEX.128.66.0F38.W0 78 /r VPBROADCASTB xmm1, xmm2/m8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpbroadcast" + }, + "vpbroadcastb": { + "instruction": "VPBROADCASTB", + "title": "VPBROADCASTB/VPBROADCASTW/VPBROADCASTD/VPBROADCASTQ\n\t\t— Load With Broadcast Integer Data From General Purpose Register", + "opcode": "EVEX.128.66.0F38.W0 7A /r VPBROADCASTB xmm1 {k1}{z}, reg", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpbroadcastb:vpbroadcastw:vpbroadcastd:vpbroadcastq" + }, + "vpbroadcastd": { + "instruction": "VPBROADCASTD", + "title": "VPBROADCASTB/VPBROADCASTW/VPBROADCASTD/VPBROADCASTQ\n\t\t— Load With Broadcast Integer Data From General Purpose Register", + "opcode": "EVEX.128.66.0F38.W0 7A /r VPBROADCASTB xmm1 {k1}{z}, reg", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpbroadcastb:vpbroadcastw:vpbroadcastd:vpbroadcastq" + }, + "vpbroadcastm": { + "instruction": "VPBROADCASTM", + "title": "VPBROADCASTM\n\t\t— Broadcast Mask to Vector Register", + "opcode": "EVEX.128.F3.0F38.W1 2A /r VPBROADCASTMB2Q xmm1, k1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpbroadcastm" + }, + "vpbroadcastq": { + "instruction": "VPBROADCASTQ", + "title": "VPBROADCASTB/VPBROADCASTW/VPBROADCASTD/VPBROADCASTQ\n\t\t— Load With Broadcast Integer Data From General Purpose Register", + "opcode": "EVEX.128.66.0F38.W0 7A /r VPBROADCASTB xmm1 {k1}{z}, reg", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpbroadcastb:vpbroadcastw:vpbroadcastd:vpbroadcastq" + }, + "vpbroadcastw": { + "instruction": "VPBROADCASTW", + "title": "VPBROADCASTB/VPBROADCASTW/VPBROADCASTD/VPBROADCASTQ\n\t\t— Load With Broadcast Integer Data From General Purpose Register", + "opcode": "EVEX.128.66.0F38.W0 7A /r VPBROADCASTB xmm1 {k1}{z}, reg", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpbroadcastb:vpbroadcastw:vpbroadcastd:vpbroadcastq" + }, + "vpcmpb": { + "instruction": "VPCMPB", + "title": "VPCMPB/VPCMPUB\n\t\t— Compare Packed Byte Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W0 3F /r ib VPCMPB k1 {k2}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpb:vpcmpub" + }, + "vpcmpd": { + "instruction": "VPCMPD", + "title": "VPCMPD/VPCMPUD\n\t\t— Compare Packed Integer Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W0 1F /r ib VPCMPD k1 {k2}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpd:vpcmpud" + }, + "vpcmpq": { + "instruction": "VPCMPQ", + "title": "VPCMPQ/VPCMPUQ\n\t\t— Compare Packed Integer Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W1 1F /r ib VPCMPQ k1 {k2}, xmm2, xmm3/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpq:vpcmpuq" + }, + "vpcmpub": { + "instruction": "VPCMPUB", + "title": "VPCMPB/VPCMPUB\n\t\t— Compare Packed Byte Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W0 3F /r ib VPCMPB k1 {k2}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpb:vpcmpub" + }, + "vpcmpud": { + "instruction": "VPCMPUD", + "title": "VPCMPD/VPCMPUD\n\t\t— Compare Packed Integer Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W0 1F /r ib VPCMPD k1 {k2}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpd:vpcmpud" + }, + "vpcmpuq": { + "instruction": "VPCMPUQ", + "title": "VPCMPQ/VPCMPUQ\n\t\t— Compare Packed Integer Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W1 1F /r ib VPCMPQ k1 {k2}, xmm2, xmm3/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpq:vpcmpuq" + }, + "vpcmpuw": { + "instruction": "VPCMPUW", + "title": "VPCMPW/VPCMPUW\n\t\t— Compare Packed Word Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W1 3F /r ib VPCMPW k1 {k2}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpw:vpcmpuw" + }, + "vpcmpw": { + "instruction": "VPCMPW", + "title": "VPCMPW/VPCMPUW\n\t\t— Compare Packed Word Values Into Mask", + "opcode": "EVEX.128.66.0F3A.W1 3F /r ib VPCMPW k1 {k2}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcmpw:vpcmpuw" + }, + "vpcompressb": { + "instruction": "VPCOMPRESSB", + "title": "VPCOMPRESSB/VCOMPRESSW\n\t\t— Store Sparse Packed Byte/Word Integer Values Into DenseMemory/Register", + "opcode": "EVEX.128.66.0F38.W0 63 /r VPCOMPRESSB m128{k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcompressb:vcompressw" + }, + "vpcompressd": { + "instruction": "VPCOMPRESSD", + "title": "VPCOMPRESSD\n\t\t— Store Sparse Packed Doubleword Integer Values Into Dense Memory/Register", + "opcode": "EVEX.128.66.0F38.W0 8B /r VPCOMPRESSD xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcompressd" + }, + "vpcompressq": { + "instruction": "VPCOMPRESSQ", + "title": "VPCOMPRESSQ\n\t\t— Store Sparse Packed Quadword Integer Values Into Dense Memory/Register", + "opcode": "EVEX.128.66.0F38.W1 8B /r VPCOMPRESSQ xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpcompressq" + }, + "vpconflictd": { + "instruction": "VPCONFLICTD", + "title": "VPCONFLICTD/VPCONFLICTQ\n\t\t— Detect Conflicts Within a Vector of Packed Dword/Qword Values Into DenseMemory/ Register", + "opcode": "EVEX.128.66.0F38.W0 C4 /r VPCONFLICTD xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpconflictd:vpconflictq" + }, + "vpconflictq": { + "instruction": "VPCONFLICTQ", + "title": "VPCONFLICTD/VPCONFLICTQ\n\t\t— Detect Conflicts Within a Vector of Packed Dword/Qword Values Into DenseMemory/ Register", + "opcode": "EVEX.128.66.0F38.W0 C4 /r VPCONFLICTD xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpconflictd:vpconflictq" + }, + "vpdpbusd": { + "instruction": "VPDPBUSD", + "title": "VPDPBUSD\n\t\t— Multiply and Add Unsigned and Signed Bytes", + "opcode": "VEX.128.66.0F38.W0 50 /r VPDPBUSD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpdpbusd" + }, + "vpdpbusds": { + "instruction": "VPDPBUSDS", + "title": "VPDPBUSDS\n\t\t— Multiply and Add Unsigned and Signed Bytes With Saturation", + "opcode": "VEX.128.66.0F38.W0 51 /r VPDPBUSDS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpdpbusds" + }, + "vpdpwssd": { + "instruction": "VPDPWSSD", + "title": "VPDPWSSD\n\t\t— Multiply and Add Signed Word Integers", + "opcode": "VEX.128.66.0F38.W0 52 /r VPDPWSSD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpdpwssd" + }, + "vpdpwssds": { + "instruction": "VPDPWSSDS", + "title": "VPDPWSSDS\n\t\t— Multiply and Add Signed Word Integers With Saturation", + "opcode": "VEX.128.66.0F38.W0 53 /r VPDPWSSDS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpdpwssds" + }, + "vperm2f128": { + "instruction": "VPERM2F128", + "title": "VPERM2F128\n\t\t— Permute Floating-Point Values", + "opcode": "VEX.256.66.0F3A.W0 06 /r ib VPERM2F128 ymm1, ymm2, ymm3/m256, imm8", + "description": "Permute 128 bit floating-point-containing fields from the first source operand (second operand) and second source operand (third operand) using bits in the 8-bit immediate and store results in the destination operand (first operand). The first source operand is a YMM register, the second source operand is a YMM register or a 256-bit memory location, and the destination operand is a YMM register.\nImm8[1:0] select the source for the first destination 128-bit field, imm8[5:4] select the source for the second destination field. If imm8[3] is set, the low 128-bit field is zeroed. If imm8[7] is set, the high 128-bit field is zeroed.\nVEX.L must be 1, otherwise the instruction will #UD.", + "operation": "CASE IMM8[1:0] of\n0: DEST[127:0] := SRC1[127:0]\n1: DEST[127:0] := SRC1[255:128]\n2: DEST[127:0] := SRC2[127:0]\n3: DEST[127:0] := SRC2[255:128]\nESAC\nCASE IMM8[5:4] of\n0: DEST[255:128] := SRC1[127:0]\n1: DEST[255:128] := SRC1[255:128]\n2: DEST[255:128] := SRC2[127:0]\n3: DEST[255:128] := SRC2[255:128]\nESAC\nIF (imm8[3])\nDEST[127:0] := 0\nFI\nIF (imm8[7])\nDEST[MAXVL-1:128] := 0\nFI\n", + "url": "https://www.felixcloutier.com/x86/vperm2f128" + }, + "vperm2i128": { + "instruction": "VPERM2I128", + "title": "VPERM2I128\n\t\t— Permute Integer Values", + "opcode": "VEX.256.66.0F3A.W0 46 /r ib VPERM2I128 ymm1, ymm2, ymm3/m256, imm8", + "description": "Permute 128 bit integer data from the first source operand (second operand) and second source operand (third operand) using bits in the 8-bit immediate and store results in the destination operand (first operand). The first source operand is a YMM register, the second source operand is a YMM register or a 256-bit memory location, and the destination operand is a YMM register.\nImm8[1:0] select the source for the first destination 128-bit field, imm8[5:4] select the source for the second destination field. If imm8[3] is set, the low 128-bit field is zeroed. If imm8[7] is set, the high 128-bit field is zeroed.\nVEX.L must be 1, otherwise the instruction will #UD.", + "operation": "CASE IMM8[1:0] of\n0: DEST[127:0] := SRC1[127:0]\n1: DEST[127:0] := SRC1[255:128]\n2: DEST[127:0] := SRC2[127:0]\n3: DEST[127:0] := SRC2[255:128]\nESAC\nCASE IMM8[5:4] of\n0: DEST[255:128] := SRC1[127:0]\n1: DEST[255:128] := SRC1[255:128]\n2: DEST[255:128] := SRC2[127:0]\n3: DEST[255:128] := SRC2[255:128]\nESAC\nIF (imm8[3])\nDEST[127:0] := 0\nFI\nIF (imm8[7])\nDEST[255:128] := 0\nFI\n", + "url": "https://www.felixcloutier.com/x86/vperm2i128" + }, + "vpermb": { + "instruction": "VPERMB", + "title": "VPERMB\n\t\t— Permute Packed Bytes Elements", + "opcode": "EVEX.128.66.0F38.W0 8D /r VPERMB xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermb" + }, + "vpermd": { + "instruction": "VPERMD", + "title": "VPERMD/VPERMW\n\t\t— Permute Packed Doubleword/Word Elements", + "opcode": "VEX.256.66.0F38.W0 36 /r VPERMD ymm1, ymm2, ymm3/m256", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermd:vpermw" + }, + "vpermi2b": { + "instruction": "VPERMI2B", + "title": "VPERMI2B\n\t\t— Full Permute of Bytes From Two Tables Overwriting the Index", + "opcode": "EVEX.128.66.0F38.W0 75 /r VPERMI2B xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermi2b" + }, + "vpermi2d": { + "instruction": "VPERMI2D", + "title": "VPERMI2W/VPERMI2D/VPERMI2Q/VPERMI2PS/VPERMI2PD\n\t\t— Full Permute From Two Tables Overwriting the Index", + "opcode": "EVEX.128.66.0F38.W1 75 /r VPERMI2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermi2w:vpermi2d:vpermi2q:vpermi2ps:vpermi2pd" + }, + "vpermi2pd": { + "instruction": "VPERMI2PD", + "title": "VPERMI2W/VPERMI2D/VPERMI2Q/VPERMI2PS/VPERMI2PD\n\t\t— Full Permute From Two Tables Overwriting the Index", + "opcode": "EVEX.128.66.0F38.W1 75 /r VPERMI2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermi2w:vpermi2d:vpermi2q:vpermi2ps:vpermi2pd" + }, + "vpermi2ps": { + "instruction": "VPERMI2PS", + "title": "VPERMI2W/VPERMI2D/VPERMI2Q/VPERMI2PS/VPERMI2PD\n\t\t— Full Permute From Two Tables Overwriting the Index", + "opcode": "EVEX.128.66.0F38.W1 75 /r VPERMI2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermi2w:vpermi2d:vpermi2q:vpermi2ps:vpermi2pd" + }, + "vpermi2q": { + "instruction": "VPERMI2Q", + "title": "VPERMI2W/VPERMI2D/VPERMI2Q/VPERMI2PS/VPERMI2PD\n\t\t— Full Permute From Two Tables Overwriting the Index", + "opcode": "EVEX.128.66.0F38.W1 75 /r VPERMI2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermi2w:vpermi2d:vpermi2q:vpermi2ps:vpermi2pd" + }, + "vpermi2w": { + "instruction": "VPERMI2W", + "title": "VPERMI2W/VPERMI2D/VPERMI2Q/VPERMI2PS/VPERMI2PD\n\t\t— Full Permute From Two Tables Overwriting the Index", + "opcode": "EVEX.128.66.0F38.W1 75 /r VPERMI2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermi2w:vpermi2d:vpermi2q:vpermi2ps:vpermi2pd" + }, + "vpermilpd": { + "instruction": "VPERMILPD", + "title": "VPERMILPD\n\t\t— Permute In-Lane of Pairs of Double Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 0D /r VPERMILPD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermilpd" + }, + "vpermilps": { + "instruction": "VPERMILPS", + "title": "VPERMILPS\n\t\t— Permute In-Lane of Quadruples of Single Precision Floating-Point Values", + "opcode": "VEX.128.66.0F38.W0 0C /r VPERMILPS xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermilps" + }, + "vpermpd": { + "instruction": "VPERMPD", + "title": "VPERMPD\n\t\t— Permute Double Precision Floating-Point Elements", + "opcode": "VEX.256.66.0F3A.W1 01 /r ib VPERMPD ymm1, ymm2/m256, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermpd" + }, + "vpermps": { + "instruction": "VPERMPS", + "title": "VPERMPS\n\t\t— Permute Single Precision Floating-Point Elements", + "opcode": "VEX.256.66.0F38.W0 16 /r VPERMPS ymm1, ymm2, ymm3/m256", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermps" + }, + "vpermq": { + "instruction": "VPERMQ", + "title": "VPERMQ\n\t\t— Qwords Element Permutation", + "opcode": "VEX.256.66.0F3A.W1 00 /r ib VPERMQ ymm1, ymm2/m256, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermq" + }, + "vpermt2b": { + "instruction": "VPERMT2B", + "title": "VPERMT2B\n\t\t— Full Permute of Bytes From Two Tables Overwriting a Table", + "opcode": "EVEX.128.66.0F38.W0 7D /r VPERMT2B xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermt2b" + }, + "vpermt2d": { + "instruction": "VPERMT2D", + "title": "VPERMT2W/VPERMT2D/VPERMT2Q/VPERMT2PS/VPERMT2PD\n\t\t— Full Permute From Two Tables Overwriting One Table", + "opcode": "EVEX.128.66.0F38.W1 7D /r VPERMT2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd" + }, + "vpermt2pd": { + "instruction": "VPERMT2PD", + "title": "VPERMT2W/VPERMT2D/VPERMT2Q/VPERMT2PS/VPERMT2PD\n\t\t— Full Permute From Two Tables Overwriting One Table", + "opcode": "EVEX.128.66.0F38.W1 7D /r VPERMT2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd" + }, + "vpermt2ps": { + "instruction": "VPERMT2PS", + "title": "VPERMT2W/VPERMT2D/VPERMT2Q/VPERMT2PS/VPERMT2PD\n\t\t— Full Permute From Two Tables Overwriting One Table", + "opcode": "EVEX.128.66.0F38.W1 7D /r VPERMT2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd" + }, + "vpermt2q": { + "instruction": "VPERMT2Q", + "title": "VPERMT2W/VPERMT2D/VPERMT2Q/VPERMT2PS/VPERMT2PD\n\t\t— Full Permute From Two Tables Overwriting One Table", + "opcode": "EVEX.128.66.0F38.W1 7D /r VPERMT2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd" + }, + "vpermt2w": { + "instruction": "VPERMT2W", + "title": "VPERMT2W/VPERMT2D/VPERMT2Q/VPERMT2PS/VPERMT2PD\n\t\t— Full Permute From Two Tables Overwriting One Table", + "opcode": "EVEX.128.66.0F38.W1 7D /r VPERMT2W xmm1 {k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd" + }, + "vpermw": { + "instruction": "VPERMW", + "title": "VPERMD/VPERMW\n\t\t— Permute Packed Doubleword/Word Elements", + "opcode": "VEX.256.66.0F38.W0 36 /r VPERMD ymm1, ymm2, ymm3/m256", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpermd:vpermw" + }, + "vpexpandb": { + "instruction": "VPEXPANDB", + "title": "VPEXPANDB/VPEXPANDW\n\t\t— Expand Byte/Word Values", + "opcode": "EVEX.128.66.0F38.W0 62 /r VPEXPANDB xmm1{k1}{z}, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpexpandb:vpexpandw" + }, + "vpexpandd": { + "instruction": "VPEXPANDD", + "title": "VPEXPANDD\n\t\t— Load Sparse Packed Doubleword Integer Values From Dense Memory/Register", + "opcode": "EVEX.128.66.0F38.W0 89 /r VPEXPANDD xmm1 {k1}{z}, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpexpandd" + }, + "vpexpandq": { + "instruction": "VPEXPANDQ", + "title": "VPEXPANDQ\n\t\t— Load Sparse Packed Quadword Integer Values From Dense Memory/Register", + "opcode": "EVEX.128.66.0F38.W1 89 /r VPEXPANDQ xmm1 {k1}{z}, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpexpandq" + }, + "vpexpandw": { + "instruction": "VPEXPANDW", + "title": "VPEXPANDB/VPEXPANDW\n\t\t— Expand Byte/Word Values", + "opcode": "EVEX.128.66.0F38.W0 62 /r VPEXPANDB xmm1{k1}{z}, m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpexpandb:vpexpandw" + }, + "vpgatherdd": { + "instruction": "VPGATHERDD", + "title": "VPGATHERDD/VPGATHERDQ\n\t\t— Gather Packed Dword, Packed Qword With Signed Dword Indices", + "opcode": "EVEX.128.66.0F38.W0 90 /vsib VPGATHERDD xmm1 {k1}, vm32x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpgatherdd:vpgatherdq" + }, + "vpgatherdq": { + "instruction": "VPGATHERDQ", + "title": "VPGATHERDQ/VPGATHERQQ\n\t\t— Gather Packed Qword Values Using Signed Dword/Qword Indices", + "opcode": "VEX.128.66.0F38.W1 90 /r VPGATHERDQ xmm1, vm32x, xmm2", + "description": "The instruction conditionally loads up to 2 or 4 qword values from memory addresses specified by the memory operand (the second operand) and using qword indices. The memory operand uses the VSIB form of the SIB byte to specify a general purpose register operand as the common base, a vector register for an array of indices relative to the base and a constant scale factor.\nThe mask operand (the third operand) specifies the conditional load operation from each memory address and the corresponding update of each data element of the destination operand (the first operand). Conditionality is specified by the most significant bit of each data element of the mask register. If an element’s mask bit is not set, the corresponding element of the destination register is left unchanged. The width of data element in the destination register and mask register are identical. The entire mask register will be set to zero by this instruction unless the instruction causes an exception.\nUsing dword indices in the lower half of the mask register, the instruction conditionally loads up to 2 or 4 qword values from the VSIB addressing memory operand, and updates the destination register.\nThis instruction can be suspended by an exception if at least one element is already gathered (i.e., if the exception is triggered by an element other than the rightmost one with its mask bit set). When this happens, the destination register and the mask operand are partially updated; those elements that have been gathered are placed into the destination register and have their mask bits set to zero. If any traps or interrupts are pending from already gathered elements, they will be delivered in lieu of the exception; in this case, EFLAG.RF is set to one so an instruction breakpoint is not re-triggered when the instruction is continued.\nIf the data size and index size are different, part of the destination register and part of the mask register do not correspond to any elements being gathered. This instruction sets those parts to zero. It may do this to one or both of those registers even if the instruction triggers an exception, and even if the instruction triggers the exception before gathering any elements.\nVEX.128 version: The instruction will gather two qword values. For dword indices, only the lower two indices in the vector index register are used.\nVEX.256 version: The instruction will gather four qword values. For dword indices, only the lower four indices in the vector index register are used.\nNote that:", + "operation": "DEST := SRC1;\nBASE_ADDR: base register encoded in VSIB addressing;\nVINDEX: the vector index register encoded by VSIB addressing;\nSCALE: scale factor encoded by SIB:[7:6];\nDISP: optional 1, 4 byte displacement;\nMASK := SRC3;\n\n\nMASK[MAXVL-1:128] := 0;\nFOR j := 0 to 1\n i := j * 64;\n IF MASK[63+i] THEN\n MASK[i +63:i] := FFFFFFFF_FFFFFFFFH; // extend from most significant bit\n ELSE\n MASK[i +63:i] := 0;\n FI;\nENDFOR\nFOR j := 0 to 1\n k := j * 32;\n i := j * 64;\n DATA_ADDR := BASE_ADDR + (SignExtend(VINDEX[k+31:k])*SCALE + DISP);\n IF MASK[63+i] THEN\n DEST[i +63:i] := FETCH_64BITS(DATA_ADDR); // a fault exits the instruction\n FI;\n MASK[i +63:i] := 0;\nENDFOR\nDEST[MAXVL-1:128] := 0;\n\n\nMASK[MAXVL-1:128] := 0;\nFOR j := 0 to 1\n i := j * 64;\n IF MASK[63+i] THEN\n MASK[i +63:i] := FFFFFFFF_FFFFFFFFH; // extend from most significant bit\n ELSE\n MASK[i +63:i] := 0;\n FI;\nENDFOR\nFOR j := 0 to 1\n i := j * 64;\n DATA_ADDR := BASE_ADDR + (SignExtend(VINDEX1[i+63:i])*SCALE + DISP);\n IF MASK[63+i] THEN\n DEST[i +63:i] := FETCH_64BITS(DATA_ADDR); // a fault exits the instruction\n FI;\n MASK[i +63:i] := 0;\nENDFOR\nDEST[MAXVL-1:128] := 0;\n\n\nMASK[MAXVL-1:256] := 0;\nFOR j := 0 to 3\n i := j * 64;\n IF MASK[63+i] THEN\n MASK[i +63:i] := FFFFFFFF_FFFFFFFFH; // extend from most significant bit\n ELSE\n MASK[i +63:i] := 0;\n FI;\nENDFOR\nFOR j := 0 to 3\n i := j * 64;\n DATA_ADDR := BASE_ADDR + (SignExtend(VINDEX1[i+63:i])*SCALE + DISP);\n IF MASK[63+i] THEN\n DEST[i +63:i] := FETCH_64BITS(DATA_ADDR); // a fault exits the instruction\n FI;\n MASK[i +63:i] := 0;\nENDFOR\nDEST[MAXVL-1:256] := 0;\n\n\nMASK[MAXVL-1:256] := 0;\nFOR j := 0 to 3\n i := j * 64;\n IF MASK[63+i] THEN\n MASK[i +63:i] := FFFFFFFF_FFFFFFFFH; // extend from most significant bit\n ELSE\n MASK[i +63:i] := 0;\n FI;\nENDFOR\nFOR j := 0 to 3\n k := j * 32;\n i := j * 64;\n DATA_ADDR := BASE_ADDR + (SignExtend(VINDEX1[k+31:k])*SCALE + DISP);\n IF MASK[63+i] THEN\n DEST[i +63:i] := FETCH_64BITS(DATA_ADDR); // a fault exits the instruction\n FI;\n MASK[i +63:i] := 0;\nENDFOR\nDEST[MAXVL-1:256] := 0;\n", + "url": "https://www.felixcloutier.com/x86/vpgatherdq:vpgatherqq" + }, + "vpgatherqd": { + "instruction": "VPGATHERQD", + "title": "VPGATHERQD/VPGATHERQQ\n\t\t— Gather Packed Dword, Packed Qword with Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 91 /vsib VPGATHERQD xmm1 {k1}, vm64x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpgatherqd:vpgatherqq" + }, + "vpgatherqq": { + "instruction": "VPGATHERQQ", + "title": "VPGATHERQD/VPGATHERQQ\n\t\t— Gather Packed Dword, Packed Qword with Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 91 /vsib VPGATHERQD xmm1 {k1}, vm64x", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpgatherqd:vpgatherqq" + }, + "vplzcntd": { + "instruction": "VPLZCNTD", + "title": "VPLZCNTD/VPLZCNTQ\n\t\t— Count the Number of Leading Zero Bits for Packed Dword, Packed Qword Values", + "opcode": "EVEX.128.66.0F38.W0 44 /r VPLZCNTD xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vplzcntd:vplzcntq" + }, + "vplzcntq": { + "instruction": "VPLZCNTQ", + "title": "VPLZCNTD/VPLZCNTQ\n\t\t— Count the Number of Leading Zero Bits for Packed Dword, Packed Qword Values", + "opcode": "EVEX.128.66.0F38.W0 44 /r VPLZCNTD xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vplzcntd:vplzcntq" + }, + "vpmadd52huq": { + "instruction": "VPMADD52HUQ", + "title": "VPMADD52HUQ\n\t\t— Packed Multiply of Unsigned 52-Bit Unsigned Integers and Add High 52-BitProducts to 64-Bit Accumulators", + "opcode": "EVEX.128.66.0F38.W1 B5 /r VPMADD52HUQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmadd52huq" + }, + "vpmadd52luq": { + "instruction": "VPMADD52LUQ", + "title": "VPMADD52LUQ\n\t\t— Packed Multiply of Unsigned 52-Bit Integers and Add the Low 52-Bit Productsto Qword Accumulators", + "opcode": "EVEX.128.66.0F38.W1 B4 /r VPMADD52LUQ xmm1 {k1}{z}, xmm2,xmm3/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmadd52luq" + }, + "vpmaskmov": { + "instruction": "VPMASKMOV", + "title": "VPMASKMOV\n\t\t— Conditional SIMD Integer Packed Loads and Stores", + "opcode": "VEX.128.66.0F38.W0 8C /r VPMASKMOVD xmm1, xmm2, m128", + "description": "Conditionally moves packed data elements from the second source operand into the corresponding data element of the destination operand, depending on the mask bits associated with each data element. The mask bits are specified in the first source operand.\nThe mask bit for each data element is the most significant bit of that element in the first source operand. If a mask is 1, the corresponding data element is copied from the second source operand to the destination operand. If the mask is 0, the corresponding data element is set to zero in the load form of these instructions, and unmodified in the store form.\nThe second source operand is a memory address for the load form of these instructions. The destination operand is a memory address for the store form of these instructions. The other operands are either XMM registers (for VEX.128 version) or YMM registers (for VEX.256 version).\nFaults occur only due to mask-bit required memory accesses that caused the faults. Faults will not occur due to referencing any memory location if the corresponding mask bit for that memory location is 0. For example, no faults will be detected if the mask bits are all zero.\nUnlike previous MASKMOV instructions (MASKMOVQ and MASKMOVDQU), a nontemporal hint is not applied to these instructions.\nInstruction behavior on alignment check reporting with mask bits of less than all 1s are the same as with mask bits of all 1s.\nVMASKMOV should not be used to access memory mapped I/O as the ordering of the individual loads or stores it does is implementation specific.\nIn cases where mask bits indicate data should not be loaded or stored paging A and D bits will be set in an implementation dependent way. However, A and D bits are always set for pages where data is actually loaded/stored.\nNote: for load forms, the first source (the mask) is encoded in VEX.vvvv; the second source is encoded in rm_field, and the destination register is encoded in reg_field.\nNote: for store forms, the first source (the mask) is encoded in VEX.vvvv; the second source register is encoded in reg_field, and the destination memory location is encoded in rm_field.", + "operation": "DEST[31:0] := IF (SRC1[31]) Load_32(mem) ELSE 0\nDEST[63:32] := IF (SRC1[63]) Load_32(mem + 4) ELSE 0\nDEST[95:64] := IF (SRC1[95]) Load_32(mem + 8) ELSE 0\nDEST[127:96] := IF (SRC1[127]) Load_32(mem + 12) ELSE 0\nDEST[159:128] := IF (SRC1[159]) Load_32(mem + 16) ELSE 0\nDEST[191:160] := IF (SRC1[191]) Load_32(mem + 20) ELSE 0\nDEST[223:192] := IF (SRC1[223]) Load_32(mem + 24) ELSE 0\nDEST[255:224] := IF (SRC1[255]) Load_32(mem + 28) ELSE 0\n\n\nDEST[31:0] := IF (SRC1[31]) Load_32(mem) ELSE 0\nDEST[63:32] := IF (SRC1[63]) Load_32(mem + 4) ELSE 0\nDEST[95:64] := IF (SRC1[95]) Load_32(mem + 8) ELSE 0\nDEST[127:97] := IF (SRC1[127]) Load_32(mem + 12) ELSE 0\nDEST[MAXVL-1:128] := 0\n\n\nDEST[63:0] := IF (SRC1[63]) Load_64(mem) ELSE 0\nDEST[127:64] := IF (SRC1[127]) Load_64(mem + 8) ELSE 0\nDEST[195:128] := IF (SRC1[191]) Load_64(mem + 16) ELSE 0\nDEST[255:196] := IF (SRC1[255]) Load_64(mem + 24) ELSE 0\n\n\nDEST[63:0] := IF (SRC1[63]) Load_64(mem) ELSE 0\nDEST[127:64] := IF (SRC1[127]) Load_64(mem + 16) ELSE 0\nDEST[MAXVL-1:128] := 0\n\n\nIF (SRC1[31]) DEST[31:0] := SRC2[31:0]\nIF (SRC1[63]) DEST[63:32] := SRC2[63:32]\nIF (SRC1[95]) DEST[95:64] := SRC2[95:64]\nIF (SRC1[127]) DEST[127:96] := SRC2[127:96]\nIF (SRC1[159]) DEST[159:128] :=SRC2[159:128]\nIF (SRC1[191]) DEST[191:160] := SRC2[191:160]\nIF (SRC1[223]) DEST[223:192] := SRC2[223:192]\nIF (SRC1[255]) DEST[255:224] := SRC2[255:224]\n\n\nIF (SRC1[31]) DEST[31:0] := SRC2[31:0]\nIF (SRC1[63]) DEST[63:32] := SRC2[63:32]\nIF (SRC1[95]) DEST[95:64] := SRC2[95:64]\nIF (SRC1[127]) DEST[127:96] := SRC2[127:96]\n\n\nIF (SRC1[63]) DEST[63:0] := SRC2[63:0]\nIF (SRC1[127]) DEST[127:64] :=SRC2[127:64]\nIF (SRC1[191]) DEST[191:128] := SRC2[191:128]\nIF (SRC1[255]) DEST[255:192] := SRC2[255:192]\n\n\nIF (SRC1[63]) DEST[63:0] := SRC2[63:0]\nIF (SRC1[127]) DEST[127:64] :=SRC2[127:64]\n", + "url": "https://www.felixcloutier.com/x86/vpmaskmov" + }, + "vpmovb2m": { + "instruction": "VPMOVB2M", + "title": "VPMOVB2M/VPMOVW2M/VPMOVD2M/VPMOVQ2M\n\t\t— Convert a Vector Register to a Mask", + "opcode": "EVEX.128.F3.0F38.W0 29 /r VPMOVB2M k1, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovb2m:vpmovw2m:vpmovd2m:vpmovq2m" + }, + "vpmovd2m": { + "instruction": "VPMOVD2M", + "title": "VPMOVB2M/VPMOVW2M/VPMOVD2M/VPMOVQ2M\n\t\t— Convert a Vector Register to a Mask", + "opcode": "EVEX.128.F3.0F38.W0 29 /r VPMOVB2M k1, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovb2m:vpmovw2m:vpmovd2m:vpmovq2m" + }, + "vpmovdb": { + "instruction": "VPMOVDB", + "title": "VPMOVDB/VPMOVSDB/VPMOVUSDB\n\t\t— Down Convert DWord to Byte", + "opcode": "EVEX.128.F3.0F38.W0 31 /r VPMOVDB xmm1/m32 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovdb:vpmovsdb:vpmovusdb" + }, + "vpmovdw": { + "instruction": "VPMOVDW", + "title": "VPMOVDW/VPMOVSDW/VPMOVUSDW\n\t\t— Down Convert DWord to Word", + "opcode": "EVEX.128.F3.0F38.W0 33 /r VPMOVDW xmm1/m64 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovdw:vpmovsdw:vpmovusdw" + }, + "vpmovm2b": { + "instruction": "VPMOVM2B", + "title": "VPMOVM2B/VPMOVM2W/VPMOVM2D/VPMOVM2Q\n\t\t— Convert a Mask Register to a VectorRegister", + "opcode": "EVEX.128.F3.0F38.W0 28 /r VPMOVM2B xmm1, k1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovm2b:vpmovm2w:vpmovm2d:vpmovm2q" + }, + "vpmovm2d": { + "instruction": "VPMOVM2D", + "title": "VPMOVM2B/VPMOVM2W/VPMOVM2D/VPMOVM2Q\n\t\t— Convert a Mask Register to a VectorRegister", + "opcode": "EVEX.128.F3.0F38.W0 28 /r VPMOVM2B xmm1, k1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovm2b:vpmovm2w:vpmovm2d:vpmovm2q" + }, + "vpmovm2q": { + "instruction": "VPMOVM2Q", + "title": "VPMOVM2B/VPMOVM2W/VPMOVM2D/VPMOVM2Q\n\t\t— Convert a Mask Register to a VectorRegister", + "opcode": "EVEX.128.F3.0F38.W0 28 /r VPMOVM2B xmm1, k1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovm2b:vpmovm2w:vpmovm2d:vpmovm2q" + }, + "vpmovm2w": { + "instruction": "VPMOVM2W", + "title": "VPMOVM2B/VPMOVM2W/VPMOVM2D/VPMOVM2Q\n\t\t— Convert a Mask Register to a VectorRegister", + "opcode": "EVEX.128.F3.0F38.W0 28 /r VPMOVM2B xmm1, k1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovm2b:vpmovm2w:vpmovm2d:vpmovm2q" + }, + "vpmovq2m": { + "instruction": "VPMOVQ2M", + "title": "VPMOVB2M/VPMOVW2M/VPMOVD2M/VPMOVQ2M\n\t\t— Convert a Vector Register to a Mask", + "opcode": "EVEX.128.F3.0F38.W0 29 /r VPMOVB2M k1, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovb2m:vpmovw2m:vpmovd2m:vpmovq2m" + }, + "vpmovqb": { + "instruction": "VPMOVQB", + "title": "VPMOVQB/VPMOVSQB/VPMOVUSQB\n\t\t— Down Convert QWord to Byte", + "opcode": "EVEX.128.F3.0F38.W0 32 /r VPMOVQB xmm1/m16 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqb:vpmovsqb:vpmovusqb" + }, + "vpmovqd": { + "instruction": "VPMOVQD", + "title": "VPMOVQD/VPMOVSQD/VPMOVUSQD\n\t\t— Down Convert QWord to DWord", + "opcode": "EVEX.128.F3.0F38.W0 35 /r VPMOVQD xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqd:vpmovsqd:vpmovusqd" + }, + "vpmovqw": { + "instruction": "VPMOVQW", + "title": "VPMOVQW/VPMOVSQW/VPMOVUSQW\n\t\t— Down Convert QWord to Word", + "opcode": "EVEX.128.F3.0F38.W0 34 /r VPMOVQW xmm1/m32 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqw:vpmovsqw:vpmovusqw" + }, + "vpmovsdb": { + "instruction": "VPMOVSDB", + "title": "VPMOVDB/VPMOVSDB/VPMOVUSDB\n\t\t— Down Convert DWord to Byte", + "opcode": "EVEX.128.F3.0F38.W0 31 /r VPMOVDB xmm1/m32 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovdb:vpmovsdb:vpmovusdb" + }, + "vpmovsdw": { + "instruction": "VPMOVSDW", + "title": "VPMOVDW/VPMOVSDW/VPMOVUSDW\n\t\t— Down Convert DWord to Word", + "opcode": "EVEX.128.F3.0F38.W0 33 /r VPMOVDW xmm1/m64 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovdw:vpmovsdw:vpmovusdw" + }, + "vpmovsqb": { + "instruction": "VPMOVSQB", + "title": "VPMOVQB/VPMOVSQB/VPMOVUSQB\n\t\t— Down Convert QWord to Byte", + "opcode": "EVEX.128.F3.0F38.W0 32 /r VPMOVQB xmm1/m16 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqb:vpmovsqb:vpmovusqb" + }, + "vpmovsqd": { + "instruction": "VPMOVSQD", + "title": "VPMOVQD/VPMOVSQD/VPMOVUSQD\n\t\t— Down Convert QWord to DWord", + "opcode": "EVEX.128.F3.0F38.W0 35 /r VPMOVQD xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqd:vpmovsqd:vpmovusqd" + }, + "vpmovsqw": { + "instruction": "VPMOVSQW", + "title": "VPMOVQW/VPMOVSQW/VPMOVUSQW\n\t\t— Down Convert QWord to Word", + "opcode": "EVEX.128.F3.0F38.W0 34 /r VPMOVQW xmm1/m32 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqw:vpmovsqw:vpmovusqw" + }, + "vpmovswb": { + "instruction": "VPMOVSWB", + "title": "VPMOVWB/VPMOVSWB/VPMOVUSWB\n\t\t— Down Convert Word to Byte", + "opcode": "EVEX.128.F3.0F38.W0 30 /r VPMOVWB xmm1/m64 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovwb:vpmovswb:vpmovuswb" + }, + "vpmovusdb": { + "instruction": "VPMOVUSDB", + "title": "VPMOVDB/VPMOVSDB/VPMOVUSDB\n\t\t— Down Convert DWord to Byte", + "opcode": "EVEX.128.F3.0F38.W0 31 /r VPMOVDB xmm1/m32 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovdb:vpmovsdb:vpmovusdb" + }, + "vpmovusdw": { + "instruction": "VPMOVUSDW", + "title": "VPMOVDW/VPMOVSDW/VPMOVUSDW\n\t\t— Down Convert DWord to Word", + "opcode": "EVEX.128.F3.0F38.W0 33 /r VPMOVDW xmm1/m64 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovdw:vpmovsdw:vpmovusdw" + }, + "vpmovusqb": { + "instruction": "VPMOVUSQB", + "title": "VPMOVQB/VPMOVSQB/VPMOVUSQB\n\t\t— Down Convert QWord to Byte", + "opcode": "EVEX.128.F3.0F38.W0 32 /r VPMOVQB xmm1/m16 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqb:vpmovsqb:vpmovusqb" + }, + "vpmovusqd": { + "instruction": "VPMOVUSQD", + "title": "VPMOVQD/VPMOVSQD/VPMOVUSQD\n\t\t— Down Convert QWord to DWord", + "opcode": "EVEX.128.F3.0F38.W0 35 /r VPMOVQD xmm1/m128 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqd:vpmovsqd:vpmovusqd" + }, + "vpmovusqw": { + "instruction": "VPMOVUSQW", + "title": "VPMOVQW/VPMOVSQW/VPMOVUSQW\n\t\t— Down Convert QWord to Word", + "opcode": "EVEX.128.F3.0F38.W0 34 /r VPMOVQW xmm1/m32 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovqw:vpmovsqw:vpmovusqw" + }, + "vpmovuswb": { + "instruction": "VPMOVUSWB", + "title": "VPMOVWB/VPMOVSWB/VPMOVUSWB\n\t\t— Down Convert Word to Byte", + "opcode": "EVEX.128.F3.0F38.W0 30 /r VPMOVWB xmm1/m64 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovwb:vpmovswb:vpmovuswb" + }, + "vpmovw2m": { + "instruction": "VPMOVW2M", + "title": "VPMOVB2M/VPMOVW2M/VPMOVD2M/VPMOVQ2M\n\t\t— Convert a Vector Register to a Mask", + "opcode": "EVEX.128.F3.0F38.W0 29 /r VPMOVB2M k1, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovb2m:vpmovw2m:vpmovd2m:vpmovq2m" + }, + "vpmovwb": { + "instruction": "VPMOVWB", + "title": "VPMOVWB/VPMOVSWB/VPMOVUSWB\n\t\t— Down Convert Word to Byte", + "opcode": "EVEX.128.F3.0F38.W0 30 /r VPMOVWB xmm1/m64 {k1}{z}, xmm2", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmovwb:vpmovswb:vpmovuswb" + }, + "vpmultishiftqb": { + "instruction": "VPMULTISHIFTQB", + "title": "VPMULTISHIFTQB\n\t\t— Select Packed Unaligned Bytes From Quadword Sources", + "opcode": "EVEX.128.66.0F38.W1 83 /r VPMULTISHIFTQB xmm1 {k1}{z}, xmm2,xmm3/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpmultishiftqb" + }, + "vpopcnt": { + "instruction": "VPOPCNT", + "title": "VPOPCNT\n\t\t— Return the Count of Number of Bits Set to 1 in BYTE/WORD/DWORD/QWORD", + "opcode": "EVEX.128.66.0F38.W0 54 /r VPOPCNTB xmm1{k1}{z}, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpopcnt" + }, + "vprold": { + "instruction": "VPROLD", + "title": "VPROLD/VPROLVD/VPROLQ/VPROLVQ\n\t\t— Bit Rotate Left", + "opcode": "EVEX.128.66.0F38.W0 15 /r VPROLVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprold:vprolvd:vprolq:vprolvq" + }, + "vprolq": { + "instruction": "VPROLQ", + "title": "VPROLD/VPROLVD/VPROLQ/VPROLVQ\n\t\t— Bit Rotate Left", + "opcode": "EVEX.128.66.0F38.W0 15 /r VPROLVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprold:vprolvd:vprolq:vprolvq" + }, + "vprolvd": { + "instruction": "VPROLVD", + "title": "VPROLD/VPROLVD/VPROLQ/VPROLVQ\n\t\t— Bit Rotate Left", + "opcode": "EVEX.128.66.0F38.W0 15 /r VPROLVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprold:vprolvd:vprolq:vprolvq" + }, + "vprolvq": { + "instruction": "VPROLVQ", + "title": "VPROLD/VPROLVD/VPROLQ/VPROLVQ\n\t\t— Bit Rotate Left", + "opcode": "EVEX.128.66.0F38.W0 15 /r VPROLVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprold:vprolvd:vprolq:vprolvq" + }, + "vprord": { + "instruction": "VPRORD", + "title": "VPRORD/VPRORVD/VPRORQ/VPRORVQ\n\t\t— Bit Rotate Right", + "opcode": "EVEX.128.66.0F38.W0 14 /r VPRORVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprord:vprorvd:vprorq:vprorvq" + }, + "vprorq": { + "instruction": "VPRORQ", + "title": "VPRORD/VPRORVD/VPRORQ/VPRORVQ\n\t\t— Bit Rotate Right", + "opcode": "EVEX.128.66.0F38.W0 14 /r VPRORVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprord:vprorvd:vprorq:vprorvq" + }, + "vprorvd": { + "instruction": "VPRORVD", + "title": "VPRORD/VPRORVD/VPRORQ/VPRORVQ\n\t\t— Bit Rotate Right", + "opcode": "EVEX.128.66.0F38.W0 14 /r VPRORVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprord:vprorvd:vprorq:vprorvq" + }, + "vprorvq": { + "instruction": "VPRORVQ", + "title": "VPRORD/VPRORVD/VPRORQ/VPRORVQ\n\t\t— Bit Rotate Right", + "opcode": "EVEX.128.66.0F38.W0 14 /r VPRORVD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vprord:vprorvd:vprorq:vprorvq" + }, + "vpscatterdd": { + "instruction": "VPSCATTERDD", + "title": "VPSCATTERDD/VPSCATTERDQ/VPSCATTERQD/VPSCATTERQQ\n\t\t— Scatter Packed Dword, PackedQword with Signed Dword, Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A0 /vsib VPSCATTERDD vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpscatterdd:vpscatterdq:vpscatterqd:vpscatterqq" + }, + "vpscatterdq": { + "instruction": "VPSCATTERDQ", + "title": "VPSCATTERDD/VPSCATTERDQ/VPSCATTERQD/VPSCATTERQQ\n\t\t— Scatter Packed Dword, PackedQword with Signed Dword, Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A0 /vsib VPSCATTERDD vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpscatterdd:vpscatterdq:vpscatterqd:vpscatterqq" + }, + "vpscatterqd": { + "instruction": "VPSCATTERQD", + "title": "VPSCATTERDD/VPSCATTERDQ/VPSCATTERQD/VPSCATTERQQ\n\t\t— Scatter Packed Dword, PackedQword with Signed Dword, Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A0 /vsib VPSCATTERDD vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpscatterdd:vpscatterdq:vpscatterqd:vpscatterqq" + }, + "vpscatterqq": { + "instruction": "VPSCATTERQQ", + "title": "VPSCATTERDD/VPSCATTERDQ/VPSCATTERQD/VPSCATTERQQ\n\t\t— Scatter Packed Dword, PackedQword with Signed Dword, Signed Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A0 /vsib VPSCATTERDD vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpscatterdd:vpscatterdq:vpscatterqd:vpscatterqq" + }, + "vpshld": { + "instruction": "VPSHLD", + "title": "VPSHLD\n\t\t— Concatenate and Shift Packed Data Left Logical", + "opcode": "EVEX.128.66.0F3A.W1 70 /r /ib VPSHLDW xmm1{k1}{z}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpshld" + }, + "vpshldv": { + "instruction": "VPSHLDV", + "title": "VPSHLDV\n\t\t— Concatenate and Variable Shift Packed Data Left Logical", + "opcode": "EVEX.128.66.0F38.W1 70 /r VPSHLDVW xmm1{k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpshldv" + }, + "vpshrd": { + "instruction": "VPSHRD", + "title": "VPSHRD\n\t\t— Concatenate and Shift Packed Data Right Logical", + "opcode": "EVEX.128.66.0F3A.W1 72 /r /ib VPSHRDW xmm1{k1}{z}, xmm2, xmm3/m128, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpshrd" + }, + "vpshrdv": { + "instruction": "VPSHRDV", + "title": "VPSHRDV\n\t\t— Concatenate and Variable Shift Packed Data Right Logical", + "opcode": "EVEX.128.66.0F38.W1 72 /r VPSHRDVW xmm1{k1}{z}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpshrdv" + }, + "vpshufbitqmb": { + "instruction": "VPSHUFBITQMB", + "title": "VPSHUFBITQMB\n\t\t— Shuffle Bits From Quadword Elements Using Byte Indexes Into Mask", + "opcode": "EVEX.128.66.0F38.W0 8F /r VPSHUFBITQMB k1{k2}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpshufbitqmb" + }, + "vpsllvd": { + "instruction": "VPSLLVD", + "title": "VPSLLVW/VPSLLVD/VPSLLVQ\n\t\t— Variable Bit Shift Left Logical", + "opcode": "VEX.128.66.0F38.W0 47 /r VPSLLVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsllvw:vpsllvd:vpsllvq" + }, + "vpsllvq": { + "instruction": "VPSLLVQ", + "title": "VPSLLVW/VPSLLVD/VPSLLVQ\n\t\t— Variable Bit Shift Left Logical", + "opcode": "VEX.128.66.0F38.W0 47 /r VPSLLVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsllvw:vpsllvd:vpsllvq" + }, + "vpsllvw": { + "instruction": "VPSLLVW", + "title": "VPSLLVW/VPSLLVD/VPSLLVQ\n\t\t— Variable Bit Shift Left Logical", + "opcode": "VEX.128.66.0F38.W0 47 /r VPSLLVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsllvw:vpsllvd:vpsllvq" + }, + "vpsravd": { + "instruction": "VPSRAVD", + "title": "VPSRAVW/VPSRAVD/VPSRAVQ\n\t\t— Variable Bit Shift Right Arithmetic", + "opcode": "VEX.128.66.0F38.W0 46 /r VPSRAVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsravw:vpsravd:vpsravq" + }, + "vpsravq": { + "instruction": "VPSRAVQ", + "title": "VPSRAVW/VPSRAVD/VPSRAVQ\n\t\t— Variable Bit Shift Right Arithmetic", + "opcode": "VEX.128.66.0F38.W0 46 /r VPSRAVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsravw:vpsravd:vpsravq" + }, + "vpsravw": { + "instruction": "VPSRAVW", + "title": "VPSRAVW/VPSRAVD/VPSRAVQ\n\t\t— Variable Bit Shift Right Arithmetic", + "opcode": "VEX.128.66.0F38.W0 46 /r VPSRAVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsravw:vpsravd:vpsravq" + }, + "vpsrlvd": { + "instruction": "VPSRLVD", + "title": "VPSRLVW/VPSRLVD/VPSRLVQ\n\t\t— Variable Bit Shift Right Logical", + "opcode": "VEX.128.66.0F38.W0 45 /r VPSRLVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsrlvw:vpsrlvd:vpsrlvq" + }, + "vpsrlvq": { + "instruction": "VPSRLVQ", + "title": "VPSRLVW/VPSRLVD/VPSRLVQ\n\t\t— Variable Bit Shift Right Logical", + "opcode": "VEX.128.66.0F38.W0 45 /r VPSRLVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsrlvw:vpsrlvd:vpsrlvq" + }, + "vpsrlvw": { + "instruction": "VPSRLVW", + "title": "VPSRLVW/VPSRLVD/VPSRLVQ\n\t\t— Variable Bit Shift Right Logical", + "opcode": "VEX.128.66.0F38.W0 45 /r VPSRLVD xmm1, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpsrlvw:vpsrlvd:vpsrlvq" + }, + "vpternlogd": { + "instruction": "VPTERNLOGD", + "title": "VPTERNLOGD/VPTERNLOGQ\n\t\t— Bitwise Ternary Logic", + "opcode": "EVEX.128.66.0F3A.W0 25 /r ib VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpternlogd:vpternlogq" + }, + "vpternlogq": { + "instruction": "VPTERNLOGQ", + "title": "VPTERNLOGD/VPTERNLOGQ\n\t\t— Bitwise Ternary Logic", + "opcode": "EVEX.128.66.0F3A.W0 25 /r ib VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vpternlogd:vpternlogq" + }, + "vptestmb": { + "instruction": "VPTESTMB", + "title": "VPTESTMB/VPTESTMW/VPTESTMD/VPTESTMQ\n\t\t— Logical AND and Set Mask", + "opcode": "EVEX.128.66.0F38.W0 26 /r VPTESTMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestmb:vptestmw:vptestmd:vptestmq" + }, + "vptestmd": { + "instruction": "VPTESTMD", + "title": "VPTESTMB/VPTESTMW/VPTESTMD/VPTESTMQ\n\t\t— Logical AND and Set Mask", + "opcode": "EVEX.128.66.0F38.W0 26 /r VPTESTMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestmb:vptestmw:vptestmd:vptestmq" + }, + "vptestmq": { + "instruction": "VPTESTMQ", + "title": "VPTESTMB/VPTESTMW/VPTESTMD/VPTESTMQ\n\t\t— Logical AND and Set Mask", + "opcode": "EVEX.128.66.0F38.W0 26 /r VPTESTMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestmb:vptestmw:vptestmd:vptestmq" + }, + "vptestmw": { + "instruction": "VPTESTMW", + "title": "VPTESTMB/VPTESTMW/VPTESTMD/VPTESTMQ\n\t\t— Logical AND and Set Mask", + "opcode": "EVEX.128.66.0F38.W0 26 /r VPTESTMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestmb:vptestmw:vptestmd:vptestmq" + }, + "vptestnmb": { + "instruction": "VPTESTNMB", + "title": "VPTESTNMB/VPTESTNMW/VPTESTNMD/VPTESTNMQ\n\t\t— Logical NAND and Set", + "opcode": "EVEX.128.F3.0F38.W0 26 /r VPTESTNMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestnmb:vptestnmw:vptestnmd:vptestnmq" + }, + "vptestnmd": { + "instruction": "VPTESTNMD", + "title": "VPTESTNMB/VPTESTNMW/VPTESTNMD/VPTESTNMQ\n\t\t— Logical NAND and Set", + "opcode": "EVEX.128.F3.0F38.W0 26 /r VPTESTNMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestnmb:vptestnmw:vptestnmd:vptestnmq" + }, + "vptestnmq": { + "instruction": "VPTESTNMQ", + "title": "VPTESTNMB/VPTESTNMW/VPTESTNMD/VPTESTNMQ\n\t\t— Logical NAND and Set", + "opcode": "EVEX.128.F3.0F38.W0 26 /r VPTESTNMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestnmb:vptestnmw:vptestnmd:vptestnmq" + }, + "vptestnmw": { + "instruction": "VPTESTNMW", + "title": "VPTESTNMB/VPTESTNMW/VPTESTNMD/VPTESTNMQ\n\t\t— Logical NAND and Set", + "opcode": "EVEX.128.F3.0F38.W0 26 /r VPTESTNMB k2 {k1}, xmm2, xmm3/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vptestnmb:vptestnmw:vptestnmd:vptestnmq" + }, + "vrangepd": { + "instruction": "VRANGEPD", + "title": "VRANGEPD\n\t\t— Range Restriction Calculation for Packed Pairs of Float64 Values", + "opcode": "EVEX.128.66.0F3A.W1 50 /r ib VRANGEPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrangepd" + }, + "vrangeps": { + "instruction": "VRANGEPS", + "title": "VRANGEPS\n\t\t— Range Restriction Calculation for Packed Pairs of Float32 Values", + "opcode": "EVEX.128.66.0F3A.W0 50 /r ib VRANGEPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrangeps" + }, + "vrangesd": { + "instruction": "VRANGESD", + "title": "VRANGESD\n\t\t— Range Restriction Calculation From a Pair of Scalar Float64 Values", + "opcode": "EVEX.LLIG.66.0F3A.W1 51 /r VRANGESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrangesd" + }, + "vrangess": { + "instruction": "VRANGESS", + "title": "VRANGESS\n\t\t— Range Restriction Calculation From a Pair of Scalar Float32 Values", + "opcode": "EVEX.LLIG.66.0F3A.W0 51 /r VRANGESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrangess" + }, + "vrcp14pd": { + "instruction": "VRCP14PD", + "title": "VRCP14PD\n\t\t— Compute Approximate Reciprocals of Packed Float64 Values", + "opcode": "EVEX.128.66.0F38.W1 4C /r VRCP14PD xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp14pd" + }, + "vrcp14ps": { + "instruction": "VRCP14PS", + "title": "VRCP14PS\n\t\t— Compute Approximate Reciprocals of Packed Float32 Values", + "opcode": "EVEX.128.66.0F38.W0 4C /r VRCP14PS xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp14ps" + }, + "vrcp14sd": { + "instruction": "VRCP14SD", + "title": "VRCP14SD\n\t\t— Compute Approximate Reciprocal of Scalar Float64 Value", + "opcode": "EVEX.LLIG.66.0F38.W1 4D /r VRCP14SD xmm1 {k1}{z}, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp14sd" + }, + "vrcp14ss": { + "instruction": "VRCP14SS", + "title": "VRCP14SS\n\t\t— Compute Approximate Reciprocal of Scalar Float32 Value", + "opcode": "EVEX.LLIG.66.0F38.W0 4D /r VRCP14SS xmm1 {k1}{z}, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp14ss" + }, + "vrcp28pd": { + "instruction": "VRCP28PD", + "title": "VRCP28PD\n\t\t— Approximation to the Reciprocal of Packed Double Precision Floating-Point ValuesWith Less Than 2^-28 Relative Error", + "opcode": "EVEX.512.66.0F38.W1 CA /r VRCP28PD zmm1 {k1}{z}, zmm2/m512/m64bcst {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp28pd" + }, + "vrcp28ps": { + "instruction": "VRCP28PS", + "title": "VRCP28PS\n\t\t— Approximation to the Reciprocal of Packed Single Precision Floating-Point ValuesWith Less Than 2^-28 Relative Error", + "opcode": "EVEX.512.66.0F38.W0 CA /r VRCP28PS zmm1 {k1}{z}, zmm2/m512/m32bcst {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp28ps" + }, + "vrcp28sd": { + "instruction": "VRCP28SD", + "title": "VRCP28SD\n\t\t— Approximation to the Reciprocal of Scalar Double Precision Floating-Point ValueWith Less Than 2^-28 Relative Error", + "opcode": "EVEX.LLIG.66.0F38.W1 CB /r VRCP28SD xmm1 {k1}{z}, xmm2, xmm3/m64 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp28sd" + }, + "vrcp28ss": { + "instruction": "VRCP28SS", + "title": "VRCP28SS\n\t\t— Approximation to the Reciprocal of Scalar Single Precision Floating-Point ValueWith Less Than 2^-28 Relative Error", + "opcode": "EVEX.LLIG.66.0F38.W0 CB /r VRCP28SS xmm1 {k1}{z}, xmm2, xmm3/m32 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcp28ss" + }, + "vrcpph": { + "instruction": "VRCPPH", + "title": "VRCPPH\n\t\t— Compute Reciprocals of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 4C /r VRCPPH xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcpph" + }, + "vrcpsh": { + "instruction": "VRCPSH", + "title": "VRCPSH\n\t\t— Compute Reciprocal of Scalar FP16 Value", + "opcode": "EVEX.LLIG.66.MAP6.W0 4D /r VRCPSH xmm1{k1}{z}, xmm2, xmm3/m16", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrcpsh" + }, + "vreducepd": { + "instruction": "VREDUCEPD", + "title": "VREDUCEPD\n\t\t— Perform Reduction Transformation on Packed Float64 Values", + "opcode": "EVEX.128.66.0F3A.W1 56 /r ib VREDUCEPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vreducepd" + }, + "vreduceph": { + "instruction": "VREDUCEPH", + "title": "VREDUCEPH\n\t\t— Perform Reduction Transformation on Packed FP16 Values", + "opcode": "EVEX.128.NP.0F3A.W0 56 /r /ib VREDUCEPH xmm1{k1}{z}, xmm2/m128/m16bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vreduceph" + }, + "vreduceps": { + "instruction": "VREDUCEPS", + "title": "VREDUCEPS\n\t\t— Perform Reduction Transformation on Packed Float32 Values", + "opcode": "EVEX.128.66.0F3A.W0 56 /r ib VREDUCEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vreduceps" + }, + "vreducesd": { + "instruction": "VREDUCESD", + "title": "VREDUCESD\n\t\t— Perform a Reduction Transformation on a Scalar Float64 Value", + "opcode": "EVEX.LLIG.66.0F3A.W1 57 VREDUCESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8/r", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vreducesd" + }, + "vreducesh": { + "instruction": "VREDUCESH", + "title": "VREDUCESH\n\t\t— Perform Reduction Transformation on Scalar FP16 Value", + "opcode": "EVEX.LLIG.NP.0F3A.W0 57 /r /ib VREDUCESH xmm1{k1}{z}, xmm2, xmm3/m16 {sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vreducesh" + }, + "vreducess": { + "instruction": "VREDUCESS", + "title": "VREDUCESS\n\t\t— Perform a Reduction Transformation on a Scalar Float32 Value", + "opcode": "EVEX.LLIG.66.0F3A.W0 57 /r /ib VREDUCESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vreducess" + }, + "vrndscalepd": { + "instruction": "VRNDSCALEPD", + "title": "VRNDSCALEPD\n\t\t— Round Packed Float64 Values to Include a Given Number of Fraction Bits", + "opcode": "EVEX.128.66.0F3A.W1 09 /r ib VRNDSCALEPD xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrndscalepd" + }, + "vrndscaleph": { + "instruction": "VRNDSCALEPH", + "title": "VRNDSCALEPH\n\t\t— Round Packed FP16 Values to Include a Given Number of Fraction Bits", + "opcode": "EVEX.128.NP.0F3A.W0 08 /r /ib VRNDSCALEPH xmm1{k1}{z}, xmm2/m128/m16bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrndscaleph" + }, + "vrndscaleps": { + "instruction": "VRNDSCALEPS", + "title": "VRNDSCALEPS\n\t\t— Round Packed Float32 Values to Include a Given Number of Fraction Bits", + "opcode": "EVEX.128.66.0F3A.W0 08 /r ib VRNDSCALEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrndscaleps" + }, + "vrndscalesd": { + "instruction": "VRNDSCALESD", + "title": "VRNDSCALESD\n\t\t— Round Scalar Float64 Value to Include a Given Number of Fraction Bits", + "opcode": "EVEX.LLIG.66.0F3A.W1 0B /r ib VRNDSCALESD xmm1 {k1}{z}, xmm2, xmm3/m64{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrndscalesd" + }, + "vrndscalesh": { + "instruction": "VRNDSCALESH", + "title": "VRNDSCALESH\n\t\t— Round Scalar FP16 Value to Include a Given Number of Fraction Bits", + "opcode": "EVEX.LLIG.NP.0F3A.W0 0A /r /ib VRNDSCALESH xmm1{k1}{z}, xmm2, xmm3/m16 {sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrndscalesh" + }, + "vrndscaless": { + "instruction": "VRNDSCALESS", + "title": "VRNDSCALESS\n\t\t— Round Scalar Float32 Value to Include a Given Number of Fraction Bits", + "opcode": "EVEX.LLIG.66.0F3A.W0 0A /r ib VRNDSCALESS xmm1 {k1}{z}, xmm2, xmm3/m32{sae}, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrndscaless" + }, + "vrsqrt14pd": { + "instruction": "VRSQRT14PD", + "title": "VRSQRT14PD\n\t\t— Compute Approximate Reciprocals of Square Roots of Packed Float64 Values", + "opcode": "EVEX.128.66.0F38.W1 4E /r VRSQRT14PD xmm1 {k1}{z}, xmm2/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt14pd" + }, + "vrsqrt14ps": { + "instruction": "VRSQRT14PS", + "title": "VRSQRT14PS\n\t\t— Compute Approximate Reciprocals of Square Roots of Packed Float32 Values", + "opcode": "EVEX.128.66.0F38.W0 4E /r VRSQRT14PS xmm1 {k1}{z}, xmm2/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt14ps" + }, + "vrsqrt14sd": { + "instruction": "VRSQRT14SD", + "title": "VRSQRT14SD\n\t\t— Compute Approximate Reciprocal of Square Root of Scalar Float64 Value", + "opcode": "EVEX.LLIG.66.0F38.W1 4F /r VRSQRT14SD xmm1 {k1}{z}, xmm2, xmm3/m64", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt14sd" + }, + "vrsqrt14ss": { + "instruction": "VRSQRT14SS", + "title": "VRSQRT14SS\n\t\t— Compute Approximate Reciprocal of Square Root of Scalar Float32 Value", + "opcode": "EVEX.LLIG.66.0F38.W0 4F /r VRSQRT14SS xmm1 {k1}{z}, xmm2, xmm3/m32", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt14ss" + }, + "vrsqrt28pd": { + "instruction": "VRSQRT28PD", + "title": "VRSQRT28PD\n\t\t— Approximation to the Reciprocal Square Root of Packed Double PrecisionFloating-Point Values With Less Than 2^-28 Relative Error", + "opcode": "EVEX.512.66.0F38.W1 CC /r VRSQRT28PD zmm1 {k1}{z}, zmm2/m512/m64bcst {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt28pd" + }, + "vrsqrt28ps": { + "instruction": "VRSQRT28PS", + "title": "VRSQRT28PS\n\t\t— Approximation to the Reciprocal Square Root of Packed Single PrecisionFloating-Point Values With Less Than 2^-28 Relative Error", + "opcode": "EVEX.512.66.0F38.W0 CC /r VRSQRT28PS zmm1 {k1}{z}, zmm2/m512/m32bcst {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt28ps" + }, + "vrsqrt28sd": { + "instruction": "VRSQRT28SD", + "title": "VRSQRT28SD\n\t\t— Approximation to the Reciprocal Square Root of Scalar Double PrecisionFloating-Point Value With Less Than 2^-28 Relative Error", + "opcode": "EVEX.LLIG.66.0F38.W1 CD /r VRSQRT28SD xmm1 {k1}{z}, xmm2, xmm3/m64 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt28sd" + }, + "vrsqrt28ss": { + "instruction": "VRSQRT28SS", + "title": "VRSQRT28SS\n\t\t— Approximation to the Reciprocal Square Root of Scalar Single Precision Floating-Point Value With Less Than 2^-28 Relative Error", + "opcode": "EVEX.LLIG.66.0F38.W0 CD /r VRSQRT28SS xmm1 {k1}{z}, xmm2, xmm3/m32 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrt28ss" + }, + "vrsqrtph": { + "instruction": "VRSQRTPH", + "title": "VRSQRTPH\n\t\t— Compute Reciprocals of Square Roots of Packed FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 4E /r VRSQRTPH xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrtph" + }, + "vrsqrtsh": { + "instruction": "VRSQRTSH", + "title": "VRSQRTSH\n\t\t— Compute Approximate Reciprocal of Square Root of Scalar FP16 Value", + "opcode": "EVEX.LLIG.66.MAP6.W0 4F /r VRSQRTSH xmm1{k1}{z}, xmm2, xmm3/m16", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vrsqrtsh" + }, + "vscalefpd": { + "instruction": "VSCALEFPD", + "title": "VSCALEFPD\n\t\t— Scale Packed Float64 Values With Float64 Values", + "opcode": "EVEX.128.66.0F38.W1 2C /r VSCALEFPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscalefpd" + }, + "vscalefph": { + "instruction": "VSCALEFPH", + "title": "VSCALEFPH\n\t\t— Scale Packed FP16 Values with FP16 Values", + "opcode": "EVEX.128.66.MAP6.W0 2C /r VSCALEFPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscalefph" + }, + "vscalefps": { + "instruction": "VSCALEFPS", + "title": "VSCALEFPS\n\t\t— Scale Packed Float32 Values With Float32 Values", + "opcode": "EVEX.128.66.0F38.W0 2C /r VSCALEFPS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscalefps" + }, + "vscalefsd": { + "instruction": "VSCALEFSD", + "title": "VSCALEFSD\n\t\t— Scale Scalar Float64 Values With Float64 Values", + "opcode": "EVEX.LLIG.66.0F38.W1 2D /r VSCALEFSD xmm1 {k1}{z}, xmm2, xmm3/m64{er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscalefsd" + }, + "vscalefsh": { + "instruction": "VSCALEFSH", + "title": "VSCALEFSH\n\t\t— Scale Scalar FP16 Values with FP16 Values", + "opcode": "EVEX.LLIG.66.MAP6.W0 2D /r VSCALEFSH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscalefsh" + }, + "vscalefss": { + "instruction": "VSCALEFSS", + "title": "VSCALEFSS\n\t\t— Scale Scalar Float32 Value With Float32 Value", + "opcode": "EVEX.LLIG.66.0F38.W0 2D /r VSCALEFSS xmm1 {k1}{z}, xmm2, xmm3/m32{er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscalefss" + }, + "vscatterdpd": { + "instruction": "VSCATTERDPD", + "title": "VSCATTERDPS/VSCATTERDPD/VSCATTERQPS/VSCATTERQPD\n\t\t— Scatter Packed Single, PackedDouble with Signed Dword and Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A2 /vsib VSCATTERDPS vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterdps:vscatterdpd:vscatterqps:vscatterqpd" + }, + "vscatterdps": { + "instruction": "VSCATTERDPS", + "title": "VSCATTERDPS/VSCATTERDPD/VSCATTERQPS/VSCATTERQPD\n\t\t— Scatter Packed Single, PackedDouble with Signed Dword and Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A2 /vsib VSCATTERDPS vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterdps:vscatterdpd:vscatterqps:vscatterqpd" + }, + "vscatterpf0dpd": { + "instruction": "VSCATTERPF0DPD", + "title": "VSCATTERPF0DPS/VSCATTERPF0QPS/VSCATTERPF0DPD/VSCATTERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values with Signed Dword, Signed Qword Indices Using T0 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /5 /vsib VSCATTERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf0dps:vscatterpf0qps:vscatterpf0dpd:vscatterpf0qpd" + }, + "vscatterpf0dps": { + "instruction": "VSCATTERPF0DPS", + "title": "VSCATTERPF0DPS/VSCATTERPF0QPS/VSCATTERPF0DPD/VSCATTERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values with Signed Dword, Signed Qword Indices Using T0 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /5 /vsib VSCATTERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf0dps:vscatterpf0qps:vscatterpf0dpd:vscatterpf0qpd" + }, + "vscatterpf0qpd": { + "instruction": "VSCATTERPF0QPD", + "title": "VSCATTERPF0DPS/VSCATTERPF0QPS/VSCATTERPF0DPD/VSCATTERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values with Signed Dword, Signed Qword Indices Using T0 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /5 /vsib VSCATTERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf0dps:vscatterpf0qps:vscatterpf0dpd:vscatterpf0qpd" + }, + "vscatterpf0qps": { + "instruction": "VSCATTERPF0QPS", + "title": "VSCATTERPF0DPS/VSCATTERPF0QPS/VSCATTERPF0DPD/VSCATTERPF0QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values with Signed Dword, Signed Qword Indices Using T0 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /5 /vsib VSCATTERPF0DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf0dps:vscatterpf0qps:vscatterpf0dpd:vscatterpf0qpd" + }, + "vscatterpf1dpd": { + "instruction": "VSCATTERPF1DPD", + "title": "VSCATTERPF1DPS/VSCATTERPF1QPS/VSCATTERPF1DPD/VSCATTERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /6 /vsib VSCATTERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf1dps:vscatterpf1qps:vscatterpf1dpd:vscatterpf1qpd" + }, + "vscatterpf1dps": { + "instruction": "VSCATTERPF1DPS", + "title": "VSCATTERPF1DPS/VSCATTERPF1QPS/VSCATTERPF1DPD/VSCATTERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /6 /vsib VSCATTERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf1dps:vscatterpf1qps:vscatterpf1dpd:vscatterpf1qpd" + }, + "vscatterpf1qpd": { + "instruction": "VSCATTERPF1QPD", + "title": "VSCATTERPF1DPS/VSCATTERPF1QPS/VSCATTERPF1DPD/VSCATTERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /6 /vsib VSCATTERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf1dps:vscatterpf1qps:vscatterpf1dpd:vscatterpf1qpd" + }, + "vscatterpf1qps": { + "instruction": "VSCATTERPF1QPS", + "title": "VSCATTERPF1DPS/VSCATTERPF1QPS/VSCATTERPF1DPD/VSCATTERPF1QPD\n\t\t— Sparse PrefetchPacked SP/DP Data Values With Signed Dword, Signed Qword Indices Using T1 Hint With Intentto Write", + "opcode": "EVEX.512.66.0F38.W0 C6 /6 /vsib VSCATTERPF1DPS vm32z {k1}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterpf1dps:vscatterpf1qps:vscatterpf1dpd:vscatterpf1qpd" + }, + "vscatterqpd": { + "instruction": "VSCATTERQPD", + "title": "VSCATTERDPS/VSCATTERDPD/VSCATTERQPS/VSCATTERQPD\n\t\t— Scatter Packed Single, PackedDouble with Signed Dword and Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A2 /vsib VSCATTERDPS vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterdps:vscatterdpd:vscatterqps:vscatterqpd" + }, + "vscatterqps": { + "instruction": "VSCATTERQPS", + "title": "VSCATTERDPS/VSCATTERDPD/VSCATTERQPS/VSCATTERQPD\n\t\t— Scatter Packed Single, PackedDouble with Signed Dword and Qword Indices", + "opcode": "EVEX.128.66.0F38.W0 A2 /vsib VSCATTERDPS vm32x {k1}, xmm1", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vscatterdps:vscatterdpd:vscatterqps:vscatterqpd" + }, + "vshuff32x4": { + "instruction": "VSHUFF32X4", + "title": "VSHUFF32x4/VSHUFF64x2/VSHUFI32x4/VSHUFI64x2\n\t\t— Shuffle Packed Values at 128-BitGranularity", + "opcode": "EVEX.256.66.0F3A.W0 23 /r ib VSHUFF32X4 ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vshuff32x4:vshuff64x2:vshufi32x4:vshufi64x2" + }, + "vshuff64x2": { + "instruction": "VSHUFF64X2", + "title": "VSHUFF32x4/VSHUFF64x2/VSHUFI32x4/VSHUFI64x2\n\t\t— Shuffle Packed Values at 128-BitGranularity", + "opcode": "EVEX.256.66.0F3A.W0 23 /r ib VSHUFF32X4 ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vshuff32x4:vshuff64x2:vshufi32x4:vshufi64x2" + }, + "vshufi32x4": { + "instruction": "VSHUFI32X4", + "title": "VSHUFF32x4/VSHUFF64x2/VSHUFI32x4/VSHUFI64x2\n\t\t— Shuffle Packed Values at 128-BitGranularity", + "opcode": "EVEX.256.66.0F3A.W0 23 /r ib VSHUFF32X4 ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vshuff32x4:vshuff64x2:vshufi32x4:vshufi64x2" + }, + "vshufi64x2": { + "instruction": "VSHUFI64X2", + "title": "VSHUFF32x4/VSHUFF64x2/VSHUFI32x4/VSHUFI64x2\n\t\t— Shuffle Packed Values at 128-BitGranularity", + "opcode": "EVEX.256.66.0F3A.W0 23 /r ib VSHUFF32X4 ymm1{k1}{z}, ymm2, ymm3/m256/m32bcst, imm8", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vshuff32x4:vshuff64x2:vshufi32x4:vshufi64x2" + }, + "vsqrtph": { + "instruction": "VSQRTPH", + "title": "VSQRTPH\n\t\t— Compute Square Root of Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 51 /r VSQRTPH xmm1{k1}{z}, xmm2/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vsqrtph" + }, + "vsqrtsh": { + "instruction": "VSQRTSH", + "title": "VSQRTSH\n\t\t— Compute Square Root of Scalar FP16 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 51 /r VSQRTSH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vsqrtsh" + }, + "vsubph": { + "instruction": "VSUBPH", + "title": "VSUBPH\n\t\t— Subtract Packed FP16 Values", + "opcode": "EVEX.128.NP.MAP5.W0 5C /r VSUBPH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vsubph" + }, + "vsubsh": { + "instruction": "VSUBSH", + "title": "VSUBSH\n\t\t— Subtract Scalar FP16 Value", + "opcode": "EVEX.LLIG.F3.MAP5.W0 5C /r VSUBSH xmm1{k1}{z}, xmm2, xmm3/m16 {er}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vsubsh" + }, + "vtestpd": { + "instruction": "VTESTPD", + "title": "VTESTPD/VTESTPS\n\t\t— Packed Bit Test", + "opcode": "VEX.128.66.0F38.W0 0E /r VTESTPS xmm1, xmm2/m128", + "description": "VTESTPS performs a bitwise comparison of all the sign bits of the packed single-precision elements in the first source operation and corresponding sign bits in the second source operand. If the AND of the source sign bits with the dest sign bits produces all zeros, the ZF is set else the ZF is clear. If the AND of the source sign bits with the inverted dest sign bits produces all zeros the CF is set else the CF is clear. An attempt to execute VTESTPS with VEX.W=1 will cause #UD.\nVTESTPD performs a bitwise comparison of all the sign bits of the double precision elements in the first source operation and corresponding sign bits in the second source operand. If the AND of the source sign bits with the dest sign bits produces all zeros, the ZF is set else the ZF is clear. If the AND the source sign bits with the inverted dest sign bits produces all zeros the CF is set else the CF is clear. An attempt to execute VTESTPS with VEX.W=1 will cause #UD.\nThe first source register is specified by the ModR/M reg field.\n128-bit version: The first source register is an XMM register. The second source register can be an XMM register or a 128-bit memory location. The destination register is not modified.\nVEX.256 encoded version: The first source register is a YMM register. The second source register can be a YMM register or a 256-bit memory location. The destination register is not modified.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "TEMP[127:0] := SRC[127:0] AND DEST[127:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[127:0] := SRC[127:0] AND NOT DEST[127:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nTEMP[255:0] := SRC[255:0] AND DEST[255:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127]= TEMP[160] =TEMP[191] = TEMP[224] = TEMP[255] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[255:0] := SRC[255:0] AND NOT DEST[255:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127]= TEMP[160] =TEMP[191] = TEMP[224] = TEMP[255] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nTEMP[127:0] := SRC[127:0] AND DEST[127:0]\nIF ( TEMP[63] = TEMP[127] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[127:0] := SRC[127:0] AND NOT DEST[127:0]\nIF ( TEMP[63] = TEMP[127] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nTEMP[255:0] := SRC[255:0] AND DEST[255:0]\nIF (TEMP[63] = TEMP[127] = TEMP[191] = TEMP[255] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[255:0] := SRC[255:0] AND NOT DEST[255:0]\nIF (TEMP[63] = TEMP[127] = TEMP[191] = TEMP[255] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/vtestpd:vtestps" + }, + "vtestps": { + "instruction": "VTESTPS", + "title": "VTESTPD/VTESTPS\n\t\t— Packed Bit Test", + "opcode": "VEX.128.66.0F38.W0 0E /r VTESTPS xmm1, xmm2/m128", + "description": "VTESTPS performs a bitwise comparison of all the sign bits of the packed single-precision elements in the first source operation and corresponding sign bits in the second source operand. If the AND of the source sign bits with the dest sign bits produces all zeros, the ZF is set else the ZF is clear. If the AND of the source sign bits with the inverted dest sign bits produces all zeros the CF is set else the CF is clear. An attempt to execute VTESTPS with VEX.W=1 will cause #UD.\nVTESTPD performs a bitwise comparison of all the sign bits of the double precision elements in the first source operation and corresponding sign bits in the second source operand. If the AND of the source sign bits with the dest sign bits produces all zeros, the ZF is set else the ZF is clear. If the AND the source sign bits with the inverted dest sign bits produces all zeros the CF is set else the CF is clear. An attempt to execute VTESTPS with VEX.W=1 will cause #UD.\nThe first source register is specified by the ModR/M reg field.\n128-bit version: The first source register is an XMM register. The second source register can be an XMM register or a 128-bit memory location. The destination register is not modified.\nVEX.256 encoded version: The first source register is a YMM register. The second source register can be a YMM register or a 256-bit memory location. The destination register is not modified.\nNote: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.", + "operation": "TEMP[127:0] := SRC[127:0] AND DEST[127:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[127:0] := SRC[127:0] AND NOT DEST[127:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nTEMP[255:0] := SRC[255:0] AND DEST[255:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127]= TEMP[160] =TEMP[191] = TEMP[224] = TEMP[255] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[255:0] := SRC[255:0] AND NOT DEST[255:0]\nIF (TEMP[31] = TEMP[63] = TEMP[95] = TEMP[127]= TEMP[160] =TEMP[191] = TEMP[224] = TEMP[255] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nTEMP[127:0] := SRC[127:0] AND DEST[127:0]\nIF ( TEMP[63] = TEMP[127] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[127:0] := SRC[127:0] AND NOT DEST[127:0]\nIF ( TEMP[63] = TEMP[127] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n\n\nTEMP[255:0] := SRC[255:0] AND DEST[255:0]\nIF (TEMP[63] = TEMP[127] = TEMP[191] = TEMP[255] = 0)\n THEN ZF := 1;\n ELSE ZF := 0;\nTEMP[255:0] := SRC[255:0] AND NOT DEST[255:0]\nIF (TEMP[63] = TEMP[127] = TEMP[191] = TEMP[255] = 0)\n THEN CF := 1;\n ELSE CF := 0;\nDEST (unmodified)\nAF := OF := PF := SF := 0;\n", + "url": "https://www.felixcloutier.com/x86/vtestpd:vtestps" + }, + "vucomish": { + "instruction": "VUCOMISH", + "title": "VUCOMISH\n\t\t— Unordered Compare Scalar FP16 Values and Set EFLAGS", + "opcode": "VUCOMISH xmm1, xmm2/m16 {sae}", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/vucomish" + }, + "vzeroall": { + "instruction": "VZEROALL", + "title": "VZEROALL\n\t\t— Zero XMM, YMM, and ZMM Registers", + "opcode": "VEX.256.0F.WIG 77 VZEROALL", + "description": "In 64-bit mode, the instruction zeroes XMM0-XMM15, YMM0-YMM15, and ZMM0-ZMM15. Outside 64-bit mode, it zeroes only XMM0-XMM7, YMM0-YMM7, and ZMM0-ZMM7. VZEROALL does not modify ZMM16-ZMM31.\nNote: VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD. In Compatibility and legacy 32-bit mode only the lower 8 registers are modified.", + "operation": "simd_reg_file[][] is a two dimensional array representing the SIMD register file containing all the overlapping xmm, ymm, and zmm\nregisters present in that implementation. The major dimension is the register number: 0 for xmm0, ymm0, and zmm0; 1 for xmm1,\nymm1, and zmm1; etc. The minor dimension size is the width of the implemented SIMD state measured in bits. On a machine\nsupporting Intel AVX-512, the width is 512.\n\n\nIF (64-bit mode)\n limit :=15\nELSE\n limit := 7\nFOR i in 0 .. limit:\n simd_reg_file[i][MAXVL-1:0] := 0\n", + "url": "https://www.felixcloutier.com/x86/vzeroall" + }, + "vzeroupper": { + "instruction": "VZEROUPPER", + "title": "VZEROUPPER\n\t\t— Zero Upper Bits of YMM and ZMM Registers", + "opcode": "VEX.128.0F.WIG 77 VZEROUPPER", + "description": "In 64-bit mode, the instruction zeroes the bits in positions 128 and higher in YMM0-YMM15 and ZMM0-ZMM15. Outside 64-bit mode, it zeroes those bits only in YMM0-YMM7 and ZMM0-ZMM7. VZEROUPPER does not modify the lower 128 bits of these registers and it does not modify ZMM16-ZMM31.\nThis instruction is recommended when transitioning between AVX and legacy SSE code; it will eliminate performance penalties caused by false dependencies.\nNote: VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD. In Compatibility and legacy 32-bit mode only the lower 8 registers are modified.", + "operation": "simd_reg_file[][] is a two dimensional array representing the SIMD register file containing all the overlapping xmm, ymm, and zmm\nregisters present in that implementation. The major dimension is the register number: 0 for xmm0, ymm0, and zmm0; 1 for xmm1,\nymm1, and zmm1; etc. The minor dimension size is the width of the implemented SIMD state measured in bits.\n\n\nIF (64-bit mode)\n limit :=15\nELSE\n limit := 7\nFOR i in 0 .. limit:\n simd_reg_file[i][MAXVL-1:128] := 0\n", + "url": "https://www.felixcloutier.com/x86/vzeroupper" + }, + "wait": { + "instruction": "WAIT", + "title": "WAIT/FWAIT\n\t\t— Wait", + "opcode": "9B", + "description": "Causes the processor to check for and handle pending, unmasked, floating-point exceptions before proceeding. (FWAIT is an alternate mnemonic for WAIT.)\nThis instruction is useful for synchronizing exceptions in critical sections of code. Coding a WAIT instruction after a floating-point instruction ensures that any unmasked floating-point exceptions the instruction may raise are handled before the processor can modify the instruction’s results. See the section titled “Floating-Point Exception Synchronization” in Chapter 8 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more information on using the WAIT/FWAIT instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "CheckForPendingUnmaskedFloatingPointExceptions;\n", + "url": "https://www.felixcloutier.com/x86/wait:fwait" + }, + "wakeup": { + "instruction": "WAKEUP", + "title": "GETSEC[WAKEUP]\n\t\t— Wake Up Sleeping Processors in Measured Environment", + "opcode": "NP 0F 37 (EAX=8)", + "description": "The GETSEC[WAKEUP] leaf function broadcasts a wake-up message to all logical processors currently in the SENTER sleep state. This GETSEC leaf must be executed only by the ILP, in order to wake-up the RLPs. Responding logical processors (RLPs) enter the SENTER sleep state after completion of the SENTER rendezvous sequence.\nThe GETSEC[WAKEUP] instruction may only be executed:\nIf these conditions are not met, attempts to execute GETSEC[WAKEUP] result in a general protection violation.\nAn RLP exits the SENTER sleep state and start execution in response to a WAKEUP signal initiated by ILP’s execution of GETSEC[WAKEUP]. The RLP retrieves a pointer to a data structure that contains information to enable execution from a defined entry point. This data structure is located using a physical address held in the Intel® TXT-capable chipset configuration register LT.MLE.JOIN. The register is publicly writable in the chipset by all processors and is not restricted by the Intel® TXT-capable chipset configuration register lock status. The format of this data structure is defined in Table 7-12.\nThe MLE JOIN data structure contains the information necessary to initialize RLP processor state and permit the processor to join the measured environment. The GDTR, LIP, and CS, DS, SS, and ES selector values are initialized using this data structure. The CS selector index is derived directly from the segment selector initializer field; DS, SS, and ES selectors are initialized to CS+8. The segment descriptor fields are initialized implicitly with BASE = 0, LIMIT = FFFFFH, G = 1, D = 1, P = 1, S = 1; read/write/access for DS, SS, and ES; and execute/read/access for CS. It is the responsibility of external software to establish a GDT pointed to by the MLE JOIN data structure that contains descriptor entries consistent with the implicit settings initialized by the processor (see Table 7-6). Certain states from the content of Table 7-12 are checked for consistency by the processor prior to execution. A failure of any consistency check results in the RLP aborting entry into the protected environment and signaling an Intel® TXT shutdown condition. The specific checks performed are documented later in this section. After successful completion of processor consistency checks and subsequent initialization, RLP execution in the measured environment begins from the entry point at offset 12 (as indicated in Table 7-12).", + "operation": "(* The state of the internal flag ACMODEFLAG and SENTERFLAG persist across instruction boundary *)\nIF (CR4.SMXE=0)\n THEN #UD;\nELSE IF (in VMX non-root operation)\n THEN VM Exit (reason=”GETSEC instruction”);\nELSE IF (GETSEC leaf unsupported)\n THEN #UD;\nELSE IF ((CR0.PE=0) or (CPL>0) or (EFLAGS.VM=1) or (SENTERFLAG=0) or (ACMODEFLAG=1) or (IN_SMM=0) or (in VMX operation) or\n(IA32_APIC_BASE.BSP=0) or (TXT chipset not present))\n THEN #GP(0);\nELSE\n SignalTXTMsg(WAKEUP);\nEND;\n\n\nWHILE (no SignalWAKEUP event);\nIF (IA32_SMM_MONITOR_CTL[0] ≠ ILP.IA32_SMM_MONITOR_CTL[0])\n THEN TXT-SHUTDOWN(#IllegalEvent)\nIF (IA32_SMM_MONITOR_CTL[0] = 0)\n THEN Unmask SMI pin event;\nELSE\n Mask SMI pin event;\nMask A20M, and NMI external pin events (unmask INIT);\nMask SignalWAKEUP event;\nInvalidate processor TLB(s);\nDrain outgoing transactions;\nTempGDTRLIMIT := LOAD(LT.MLE.JOIN);\nTempGDTRBASE := LOAD(LT.MLE.JOIN+4);\nTempSegSel := LOAD(LT.MLE.JOIN+8);\nTempEIP := LOAD(LT.MLE.JOIN+12);\nIF (TempGDTLimit & FFFF0000h)\n THEN TXT-SHUTDOWN(#BadJOINFormat);\nIF ((TempSegSel > TempGDTRLIMIT-15) or (TempSegSel < 8))\n THEN TXT-SHUTDOWN(#BadJOINFormat);\nIF ((TempSegSel.TI=1) or (TempSegSel.RPL≠0))\n THEN TXT-SHUTDOWN(#BadJOINFormat);\nCR0.[PG,CD,NW,AM,WP] := 0;\nCR0.[NE,PE] := 1;\nCR4 := 00004000h;\nEFLAGS := 00000002h;\nIA32_EFER := 0;\nGDTR.BASE := TempGDTRBASE;\nGDTR.LIMIT := TempGDTRLIMIT;\nCS.SEL := TempSegSel;\nCS.BASE := 0;\nCS.LIMIT := FFFFFh;\nCS.G := 1;\nCS.D := 1;\nCS.AR := 9Bh;\nDS.SEL := TempSegSel+8;\nDS.BASE := 0;\nDS.LIMIT := FFFFFh;\nDS.G := 1;\nDS.D := 1;\nDS.AR := 93h;\nSS := DS;\nES := DS;\nDR7 := 00000400h;\nIA32_DEBUGCTL := 0;\nEIP := TempEIP;\nEND;\n", + "url": "https://www.felixcloutier.com/x86/wakeup" + }, + "wbinvd": { + "instruction": "WBINVD", + "title": "WBINVD\n\t\t— Write Back and Invalidate Cache", + "opcode": "0F 09", + "description": "Writes back all modified cache lines in the processor’s internal cache to main memory and invalidates (flushes) the internal caches. The instruction then issues a special-function bus cycle that directs external caches to also write back modified data and another bus cycle to indicate that the external caches should be invalidated.\nAfter executing this instruction, the processor does not wait for the external caches to complete their write-back and flushing operations before proceeding with instruction execution. It is the responsibility of hardware to respond to the cache write-back and flush signals. The amount of time or cycles for WBINVD to complete will vary due to size and other factors of different cache hierarchies. As a consequence, the use of the WBINVD instruction can have an impact on logical processor interrupt/event response time. Additional information of WBINVD behavior in a cache hierarchy with hierarchical sharing topology can be found in Chapter 2 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.\nThe WBINVD instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a program or procedure must be 0 to execute this instruction. This instruction is also a serializing instruction (see “Serializing Instructions” in Chapter 9 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A).\nIn situations where cache coherency with main memory is not a concern, software can use the INVD instruction.\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "WriteBack(InternalCaches);\nFlush(InternalCaches);\nSignalWriteBack(ExternalCaches);\nSignalFlush(ExternalCaches);\nContinue; (* Continue execution *)\n\n\nWBINVD void _wbinvd(void);\n", + "url": "https://www.felixcloutier.com/x86/wbinvd" + }, + "wbnoinvd": { + "instruction": "WBNOINVD", + "title": "WBNOINVD\n\t\t— Write Back and Do Not Invalidate Cache", + "opcode": "F3 0F 09 WBNOINVD", + "description": "The WBNOINVD instruction writes back all modified cache lines in the processor’s internal cache to main memory but does not invalidate (flush) the internal caches.\nAfter executing this instruction, the processor does not wait for the external caches to complete their write-back operation before proceeding with instruction execution. It is the responsibility of hardware to respond to the cache write-back signal. The amount of time or cycles for WBNOINVD to complete will vary due to size and other factors of different cache hierarchies. As a consequence, the use of the WBNOINVD instruction can have an impact on logical processor interrupt/event response time.\nThe WBNOINVD instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a program or procedure must be 0 to execute this instruction. This instruction is also a serializing instruction (see “Serializing Instructions” in Chapter 9 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A).\nThis instruction’s operation is the same in non-64-bit modes and 64-bit mode.", + "operation": "WriteBack(InternalCaches);\nContinue; (* Continue execution *)\n\n\nWBNOINVD void _wbnoinvd(void);\n", + "url": "https://www.felixcloutier.com/x86/wbnoinvd" + }, + "wrfsbase": { + "instruction": "WRFSBASE", + "title": "WRFSBASE/WRGSBASE\n\t\t— Write FS/GS Segment Base", + "opcode": "F3 0F AE /2 WRFSBASE r32", + "description": "Loads the FS or GS segment base address with the general-purpose register indicated by the modR/M:r/m field.\nThe source operand may be either a 32-bit or a 64-bit general-purpose register. The REX.W prefix indicates the operand size is 64 bits. If no REX.W prefix is used, the operand size is 32 bits; the upper 32 bits of the source register are ignored and upper 32 bits of the base address (for FS or GS) are cleared.\nThis instruction is supported only in 64-bit mode.", + "operation": "FS/GS segment base address := SRC;\n", + "url": "https://www.felixcloutier.com/x86/wrfsbase:wrgsbase" + }, + "wrgsbase": { + "instruction": "WRGSBASE", + "title": "WRFSBASE/WRGSBASE\n\t\t— Write FS/GS Segment Base", + "opcode": "F3 0F AE /2 WRFSBASE r32", + "description": "Loads the FS or GS segment base address with the general-purpose register indicated by the modR/M:r/m field.\nThe source operand may be either a 32-bit or a 64-bit general-purpose register. The REX.W prefix indicates the operand size is 64 bits. If no REX.W prefix is used, the operand size is 32 bits; the upper 32 bits of the source register are ignored and upper 32 bits of the base address (for FS or GS) are cleared.\nThis instruction is supported only in 64-bit mode.", + "operation": "FS/GS segment base address := SRC;\n", + "url": "https://www.felixcloutier.com/x86/wrfsbase:wrgsbase" + }, + "wrmsr": { + "instruction": "WRMSR", + "title": "WRMSR\n\t\t— Write to Model Specific Register", + "opcode": "0F 30", + "description": "Writes the contents of registers EDX:EAX into the 64-bit model specific register (MSR) specified in the ECX register. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The contents of the EDX register are copied to high-order 32 bits of the selected MSR and the contents of the EAX register are copied to low-order 32 bits of the MSR. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are ignored.) Undefined or reserved bits in an MSR should be set to values previously read.\nThis instruction must be executed at privilege level 0 or in real-address mode; otherwise, a general protection exception #GP(0) is generated. Specifying a reserved or unimplemented MSR address in ECX will also cause a general protection exception. The processor will also generate a general protection exception if software attempts to write to bits in a reserved MSR.\nWhen the WRMSR instruction is used to write to an MTRR, the TLBs are invalidated. This includes global entries (see “Translation Lookaside Buffers (TLBs)” in Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A).\nMSRs control functions for testability, execution tracing, performance-monitoring and machine check errors. Chapter 2, “Model-Specific Registers (MSRs),” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 4, lists all MSRs that can be written with this instruction and their addresses. Note that each processor family has its own set of MSRs.\nThe WRMSR instruction is a serializing instruction (see “Serializing Instructions” in Chapter 9 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A). Note that WRMSR to the IA32_TSC_DEADLINE MSR (MSR index 6E0H) and the X2APIC MSRs (MSR indices 802H to 83FH) are not serializing.\nThe CPUID instruction should be used to determine whether MSRs are supported (CPUID.01H:EDX[5] = 1) before using this instruction.", + "operation": "MSR[ECX] := EDX:EAX;\n", + "url": "https://www.felixcloutier.com/x86/wrmsr" + }, + "wrpkru": { + "instruction": "WRPKRU", + "title": "WRPKRU\n\t\t— Write Data to User Page Key Register", + "opcode": "NP 0F 01 EF WRPKRU", + "description": "Writes the value of EAX into PKRU. ECX and EDX must be 0 when WRPKRU is executed; otherwise, a general-protection exception (#GP) occurs.\nWRPKRU can be executed only if CR4.PKE = 1; otherwise, an invalid-opcode exception (#UD) occurs. Software can discover the value of CR4.PKE by examining CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4].\nOn processors that support the Intel 64 Architecture, the high-order 32-bits of RCX, RDX, and RAX are ignored.\nWRPKRU will never execute speculatively. Memory accesses affected by PKRU register will not execute (even speculatively) until all prior executions of WRPKRU have completed execution and updated the PKRU register.", + "operation": "IF (ECX = 0 AND EDX = 0)\n THEN PKRU := EAX;\n ELSE #GP(0);\nFI;\n", + "url": "https://www.felixcloutier.com/x86/wrpkru" + }, + "wrssd": { + "instruction": "WRSSD", + "title": "WRSSD/WRSSQ\n\t\t— Write to Shadow Stack", + "opcode": "0F 38 F6 !(11):rrr:bbb WRSSD m32, r32", + "description": "Writes bytes in register source to the shadow stack.", + "operation": "IF CPL = 3\n IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0\n THEN #UD; FI;\n IF (IA32_U_CET.WR_SHSTK_EN) = 0\n THEN #UD; FI;\nELSE\n IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0\n THEN #UD; FI;\n IF (IA32_S_CET.WR_SHSTK_EN) = 0\n THEN #UD; FI;\nFI;\nDEST_LA = Linear_Address(mem operand)\nIF (operand size is 64 bit)\n THEN\n (* Destination not 8B aligned *)\n IF DEST_LA[2:0]\n THEN GP(0); FI;\n Shadow_stack_store 8 bytes of SRC to DEST_LA;\n ELSE\n (* Destination not 4B aligned *)\n IF DEST_LA[1:0]\n THEN GP(0); FI;\n Shadow_stack_store 4 bytes of SRC[31:0] to DEST_LA;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/wrssd:wrssq" + }, + "wrssq": { + "instruction": "WRSSQ", + "title": "WRSSD/WRSSQ\n\t\t— Write to Shadow Stack", + "opcode": "0F 38 F6 !(11):rrr:bbb WRSSD m32, r32", + "description": "Writes bytes in register source to the shadow stack.", + "operation": "IF CPL = 3\n IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0\n THEN #UD; FI;\n IF (IA32_U_CET.WR_SHSTK_EN) = 0\n THEN #UD; FI;\nELSE\n IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0\n THEN #UD; FI;\n IF (IA32_S_CET.WR_SHSTK_EN) = 0\n THEN #UD; FI;\nFI;\nDEST_LA = Linear_Address(mem operand)\nIF (operand size is 64 bit)\n THEN\n (* Destination not 8B aligned *)\n IF DEST_LA[2:0]\n THEN GP(0); FI;\n Shadow_stack_store 8 bytes of SRC to DEST_LA;\n ELSE\n (* Destination not 4B aligned *)\n IF DEST_LA[1:0]\n THEN GP(0); FI;\n Shadow_stack_store 4 bytes of SRC[31:0] to DEST_LA;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/wrssd:wrssq" + }, + "wrussd": { + "instruction": "WRUSSD", + "title": "WRUSSD/WRUSSQ\n\t\t— Write to User Shadow Stack", + "opcode": "66 0F 38 F5 !(11):rrr:bbb WRUSSD m32, r32", + "description": "Writes bytes in register source to a user shadow stack page. The WRUSS instruction can be executed only if CPL = 0, however the processor treats its shadow-stack accesses as user accesses.", + "operation": "IF CR4.CET = 0\n THEN #UD; FI;\nIF CPL > 0\n THEN #GP(0); FI;\nDEST_LA = Linear_Address(mem operand)\nIF (operand size is 64 bit)\n THEN\n (* Destination not 8B aligned *)\n IF DEST_LA[2:0]\n THEN GP(0); FI;\n Shadow_stack_store 8 bytes of SRC to DEST_LA as user-mode access;\n ELSE\n (* Destination not 4B aligned *)\n IF DEST_LA[1:0]\n THEN GP(0); FI;\n Shadow_stack_store 4 bytes of SRC[31:0] to DEST_LA as user-mode access;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/wrussd:wrussq" + }, + "wrussq": { + "instruction": "WRUSSQ", + "title": "WRUSSD/WRUSSQ\n\t\t— Write to User Shadow Stack", + "opcode": "66 0F 38 F5 !(11):rrr:bbb WRUSSD m32, r32", + "description": "Writes bytes in register source to a user shadow stack page. The WRUSS instruction can be executed only if CPL = 0, however the processor treats its shadow-stack accesses as user accesses.", + "operation": "IF CR4.CET = 0\n THEN #UD; FI;\nIF CPL > 0\n THEN #GP(0); FI;\nDEST_LA = Linear_Address(mem operand)\nIF (operand size is 64 bit)\n THEN\n (* Destination not 8B aligned *)\n IF DEST_LA[2:0]\n THEN GP(0); FI;\n Shadow_stack_store 8 bytes of SRC to DEST_LA as user-mode access;\n ELSE\n (* Destination not 4B aligned *)\n IF DEST_LA[1:0]\n THEN GP(0); FI;\n Shadow_stack_store 4 bytes of SRC[31:0] to DEST_LA as user-mode access;\nFI;\n", + "url": "https://www.felixcloutier.com/x86/wrussd:wrussq" + }, + "xabort": { + "instruction": "XABORT", + "title": "XABORT\n\t\t— Transactional Abort", + "opcode": "C6 F8 ib XABORT imm8", + "description": "XABORT forces an RTM abort. Following an RTM abort, the logical processor resumes execution at the fallback address computed through the outermost XBEGIN instruction. The EAX register is updated to reflect an XABORT instruction caused the abort, and the imm8 argument will be provided in bits 31:24 of EAX.", + "operation": "IF RTM_ACTIVE = 0\n THEN\n Treat as NOP;\n ELSE\n GOTO RTM_ABORT_PROCESSING;\nFI;\n(* For any RTM abort condition encountered during RTM execution *)\nRTM_ABORT_PROCESSING:\n Restore architectural register state;\n Discard memory updates performed in transaction;\n Update EAX with status and XABORT argument;\n RTM_NEST_COUNT:= 0;\n RTM_ACTIVE:= 0;\n SUSLDTRK_ACTIVE := 0;\n IF 64-bit Mode\n THEN\n RIP:= fallbackRIP;\n ELSE\n EIP := fallbackEIP;\n FI;\nEND\n", + "url": "https://www.felixcloutier.com/x86/xabort" + }, + "xacquire": { + "instruction": "XACQUIRE", + "title": "XACQUIRE/XRELEASE\n\t\t— Hardware Lock Elision Prefix Hints", + "opcode": "F2 XACQUIRE", + "description": "The XACQUIRE prefix is a hint to start lock elision on the memory address specified by the instruction and the XRELEASE prefix is a hint to end lock elision on the memory address specified by the instruction.\nThe XACQUIRE prefix hint can only be used with the following instructions (these instructions are also referred to as XACQUIRE-enabled when used with the XACQUIRE prefix):\nThe XRELEASE prefix hint can only be used with the following instructions (also referred to as XRELEASE-enabled when used with the XRELEASE prefix):\nThe lock variables must satisfy the guidelines described in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, Section 16.3.3, for elision to be successful, otherwise an HLE abort may be signaled.\nIf an encoded byte sequence that meets XACQUIRE/XRELEASE requirements includes both prefixes, then the HLE semantic is determined by the prefix byte that is placed closest to the instruction opcode. For example, an F3F2C6 will not be treated as a XRELEASE-enabled instruction since the F2H (XACQUIRE) is closest to the instruction opcode C6. Similarly, an F2F3F0 prefixed instruction will be treated as a XRELEASE-enabled instruction since F3H (XRELEASE) is closest to the instruction opcode.\nIntel 64 and IA-32 Compatibility\nThe effect of the XACQUIRE/XRELEASE prefix hint is the same in non-64-bit modes and in 64-bit mode.\nFor instructions that do not support the XACQUIRE hint, the presence of the F2H prefix behaves the same way as prior hardware, according to\nFor instructions that do not support the XRELEASE hint, the presence of the F3H prefix behaves the same way as in prior hardware, according to", + "operation": "IF XACQUIRE-enabled instruction\n THEN\n IF (HLE_NEST_COUNT < MAX_HLE_NEST_COUNT) THEN\n HLE_NEST_COUNT++\n IF (HLE_NEST_COUNT = 1) THEN\n HLE_ACTIVE := 1\n IF 64-bit mode\n THEN\n restartRIP := instruction pointer of the XACQUIRE-enabled instruction\n ELSE\n restartEIP := instruction pointer of the XACQUIRE-enabled instruction\n FI;\n Enter HLE Execution (* record register state, start tracking memory state *)\n FI; (* HLE_NEST_COUNT = 1*)\n IF ElisionBufferAvailable\n THEN\n Allocate elision buffer\n Record address and data for forwarding and commit checking\n Perform elision\n ELSE\n Perform lock acquire operation transactionally but without elision\n FI;\n ELSE (* HLE_NEST_COUNT = MAX_HLE_NEST_COUNT*)\n GOTO HLE_ABORT_PROCESSING\n FI;\n ELSE\n Treat instruction as non-XACQUIRE F2H prefixed legacy instruction\nFI;\n\n\nIF XRELEASE-enabled instruction\n THEN\n IF (HLE_NEST_COUNT > 0)\n THEN\n HLE_NEST_COUNT--\n IF lock address matches in elision buffer THEN\n IF lock satisfies address and value requirements THEN\n Deallocate elision buffer\n ELSE\n GOTO HLE_ABORT_PROCESSING\n FI;\n FI;\n IF (HLE_NEST_COUNT = 0)\n THEN\n IF NoAllocatedElisionBuffer\n THEN\n Try to commit transactional execution\n IF fail to commit transactional execution\n THEN\n GOTO HLE_ABORT_PROCESSING;\n ELSE (* commit success *)\n HLE_ACTIVE := 0\n FI;\n ELSE\n GOTO HLE_ABORT_PROCESSING\n FI;\n FI;\n FI; (* HLE_NEST_COUNT > 0 *)\n ELSE\n Treat instruction as non-XRELEASE F3H prefixed legacy instruction\nFI;\n(* For any HLE abort condition encountered during HLE execution *)\nHLE_ABORT_PROCESSING:\n HLE_ACTIVE := 0\n HLE_NEST_COUNT := 0\n Restore architectural register state\n Discard memory updates performed in transaction\n Free any allocated lock elision buffers\n IF 64-bit mode\n THEN\n RIP := restartRIP\n ELSE\n EIP := restartEIP\n FI;\n Execute and retire instruction at RIP (or EIP) and ignore any HLE hint\nEND\n", + "url": "https://www.felixcloutier.com/x86/xacquire:xrelease" + }, + "xadd": { + "instruction": "XADD", + "title": "XADD\n\t\t— Exchange and Add", + "opcode": "0F C0 /r", + "description": "Exchanges the first operand (destination operand) with the second operand (source operand), then loads the sum of the two values into the destination operand. The destination operand can be a register or a memory location; the source operand is a register.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.", + "operation": "TEMP := SRC + DEST;\nSRC := DEST;\nDEST := TEMP;\n", + "url": "https://www.felixcloutier.com/x86/xadd" + }, + "xbegin": { + "instruction": "XBEGIN", + "title": "XBEGIN\n\t\t— Transactional Begin", + "opcode": "C7 F8 XBEGIN rel16", + "description": "The XBEGIN instruction specifies the start of an RTM code region. If the logical processor was not already in transactional execution, then the XBEGIN instruction causes the logical processor to transition into transactional execution. The XBEGIN instruction that transitions the logical processor into transactional execution is referred to as the outermost XBEGIN instruction. The instruction also specifies a relative offset to compute the address of the fallback code path following a transactional abort. (Use of the 16-bit operand size does not cause this address to be truncated to 16 bits, unlike a near jump to a relative offset.)\nOn an RTM abort, the logical processor discards all architectural register and memory updates performed during the RTM execution and restores architectural state to that corresponding to the outermost XBEGIN instruction. The fallback address following an abort is computed from the outermost XBEGIN instruction.\nExecution of XBEGIN while in a suspend read address tracking region causes a transactional abort.", + "operation": "IF RTM_NEST_COUNT < MAX_RTM_NEST_COUNT AND SUSLDTRK_ACTIVE = 0\n THEN\n RTM_NEST_COUNT++\n IF RTM_NEST_COUNT = 1 THEN\n IF 64-bit Mode\n THEN\n IF OperandSize = 16\n THEN fallbackRIP := RIP + SignExtend64(rel16);\n ELSE fallbackRIP := RIP + SignExtend64(rel32);\n FI;\n IF fallbackRIP is not canonical\n THEN #GP(0);\n FI;\n ELSE\n IF OperandSize = 16\n THEN fallbackEIP := EIP + SignExtend32(rel16);\n ELSE fallbackEIP := EIP + rel32;\n FI;\n IF fallbackEIP outside code segment limit\n THEN #GP(0);\n FI;\n FI;\n RTM_ACTIVE := 1\n Enter RTM Execution (* record register state, start tracking memory state*)\n FI; (* RTM_NEST_COUNT = 1 *)\n ELSE (* RTM_NEST_COUNT = MAX_RTM_NEST_COUNT OR SUSLDTRK_ACTIVE = 1 *)\n GOTO RTM_ABORT_PROCESSING\nFI;\n(* For any RTM abort condition encountered during RTM execution *)\nRTM_ABORT_PROCESSING:\n Restore architectural register state\n Discard memory updates performed in transaction\n Update EAX with status\n RTM_NEST_COUNT := 0\n RTM_ACTIVE := 0\n SUSLDTRK_ACTIVE := 0\n IF 64-bit mode\n THEN\n RIP := fallbackRIP\n ELSE\n EIP := fallbackEIP\n FI;\nEND\n", + "url": "https://www.felixcloutier.com/x86/xbegin" + }, + "xchg": { + "instruction": "XCHG", + "title": "XCHG\n\t\t— Exchange Register/Memory With Register", + "opcode": "90+rw", + "description": "Exchanges the contents of the destination (first) and source (second) operands. The operands can be two general-purpose registers or a register and a memory location. If a memory operand is referenced, the processor’s locking protocol is automatically implemented for the duration of the exchange operation, regardless of the presence or absence of the LOCK prefix or of the value of the IOPL. (See the LOCK prefix description in this chapter for more information on the locking protocol.)\nThis instruction is useful for implementing semaphores or similar data structures for process synchronization. (See “Bus Locking” in Chapter 9 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for more information on bus locking.)\nThe XCHG instruction can also be used instead of the BSWAP instruction for 16-bit operands.\nIn 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "TEMP := DEST;\nDEST := SRC;\nSRC := TEMP;\n", + "url": "https://www.felixcloutier.com/x86/xchg" + }, + "xend": { + "instruction": "XEND", + "title": "XEND\n\t\t— Transactional End", + "opcode": "NP 0F 01 D5 XEND", + "description": "The instruction marks the end of an RTM code region. If this corresponds to the outermost scope (that is, including this XEND instruction, the number of XBEGIN instructions is the same as number of XEND instructions), the logical processor will attempt to commit the logical processor state atomically. If the commit fails, the logical processor will rollback all architectural register and memory updates performed during the RTM execution. The logical processor will resume execution at the fallback address computed from the outermost XBEGIN instruction. The EAX register is updated to reflect RTM abort information.\nExecution of XEND outside a transactional region causes a general-protection exception (#GP). Execution of XEND while in a suspend read address tracking region causes a transactional abort.", + "operation": "IF (RTM_ACTIVE = 0) THEN\n SIGNAL #GP\nELSE\n IF SUSLDTRK_ACTIVE = 1\n THEN GOTO RTM_ABORT_PROCESSING;\n FI;\n RTM_NEST_COUNT--\n IF (RTM_NEST_COUNT = 0) THEN\n Try to commit transaction\n IF fail to commit transactional execution\n THEN\n GOTO RTM_ABORT_PROCESSING;\n ELSE (* commit success *)\n RTM_ACTIVE := 0\n FI;\n FI;\nFI;\n(* For any RTM abort condition encountered during RTM execution *)\nRTM_ABORT_PROCESSING:\n Restore architectural register state\n Discard memory updates performed in transaction\n Update EAX with status\n RTM_NEST_COUNT := 0\n RTM_ACTIVE := 0\n SUSLDTRK_ACTIVE := 0\n IF 64-bit Mode\n THEN\n RIP := fallbackRIP\n ELSE\n EIP := fallbackEIP\n FI;\nEND\n", + "url": "https://www.felixcloutier.com/x86/xend" + }, + "xgetbv": { + "instruction": "XGETBV", + "title": "XGETBV\n\t\t— Get Value of Extended Control Register", + "opcode": "NP 0F 01 D0", + "description": "Reads the contents of the extended control register (XCR) specified in the ECX register into registers EDX:EAX. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The EDX register is loaded with the high-order 32 bits of the XCR and the EAX register is loaded with the low-order 32 bits. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.) If fewer than 64 bits are implemented in the XCR being read, the values returned to EDX:EAX in unimplemented bit locations are undefined.\nXCR0 is supported on any processor that supports the XGETBV instruction. If CPUID.(EAX=0DH,ECX=1):EAX.XG1[bit 2] = 1, executing XGETBV with ECX = 1 returns in EDX:EAX the logicalAND of XCR0 and the current value of the XINUSE state-component bitmap. This allows software to discover the state of the init optimization used by XSAVEOPT and XSAVES. See Chapter 13, “Managing State Using the XSAVE Feature Set‚” in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nUse of any other value for ECX results in a general-protection (#GP) exception.", + "operation": "EDX:EAX := XCR[ECX];\n", + "url": "https://www.felixcloutier.com/x86/xgetbv" + }, + "xlat": { + "instruction": "XLAT", + "title": "XLAT/XLATB\n\t\t— Table Look-up Translation", + "opcode": "D7", + "description": "Locates a byte entry in a table in memory, using the contents of the AL register as a table index, then copies the contents of the table entry back into the AL register. The index in the AL register is treated as an unsigned integer. The XLAT and XLATB instructions get the base address of the table in memory from either the DS:EBX or the DS:BX registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). (The DS segment may be overridden with a segment override prefix.)\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operand” form and the “no-operand” form. The explicit-operand form (specified with the XLAT mnemonic) allows the base address of the table to be specified explicitly with a symbol. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the symbol does not have to specify the correct base address. The base address is always specified by the DS:(E)BX registers, which must be loaded correctly before the XLAT instruction is executed.\nThe no-operands form (XLATB) provides a “short form” of the XLAT instructions. Here also the processor assumes that the DS:(E)BX registers contain the base address of the table.\nIn 64-bit mode, operation is similar to that in legacy or compatibility mode. AL is used to specify the table index (the operand size is fixed at 8 bits). RBX, however, is used to specify the table’s base address. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF AddressSize = 16\n THEN\n AL := (DS:BX + ZeroExtend(AL));\n ELSE IF (AddressSize = 32)\n AL := (DS:EBX + ZeroExtend(AL)); FI;\n ELSE (AddressSize = 64)\n AL := (RBX + ZeroExtend(AL));\nFI;\n", + "url": "https://www.felixcloutier.com/x86/xlat:xlatb" + }, + "xlatb": { + "instruction": "XLATB", + "title": "XLAT/XLATB\n\t\t— Table Look-up Translation", + "opcode": "D7", + "description": "Locates a byte entry in a table in memory, using the contents of the AL register as a table index, then copies the contents of the table entry back into the AL register. The index in the AL register is treated as an unsigned integer. The XLAT and XLATB instructions get the base address of the table in memory from either the DS:EBX or the DS:BX registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). (The DS segment may be overridden with a segment override prefix.)\nAt the assembly-code level, two forms of this instruction are allowed: the “explicit-operand” form and the “no-operand” form. The explicit-operand form (specified with the XLAT mnemonic) allows the base address of the table to be specified explicitly with a symbol. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the symbol does not have to specify the correct base address. The base address is always specified by the DS:(E)BX registers, which must be loaded correctly before the XLAT instruction is executed.\nThe no-operands form (XLATB) provides a “short form” of the XLAT instructions. Here also the processor assumes that the DS:(E)BX registers contain the base address of the table.\nIn 64-bit mode, operation is similar to that in legacy or compatibility mode. AL is used to specify the table index (the operand size is fixed at 8 bits). RBX, however, is used to specify the table’s base address. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "IF AddressSize = 16\n THEN\n AL := (DS:BX + ZeroExtend(AL));\n ELSE IF (AddressSize = 32)\n AL := (DS:EBX + ZeroExtend(AL)); FI;\n ELSE (AddressSize = 64)\n AL := (RBX + ZeroExtend(AL));\nFI;\n", + "url": "https://www.felixcloutier.com/x86/xlat:xlatb" + }, + "xor": { + "instruction": "XOR", + "title": "XOR\n\t\t— Logical Exclusive OR", + "opcode": "34 ib", + "description": "Performs a bitwise exclusive OR (XOR) operation on the destination (first) and source (second) operands and stores the result in the destination operand location. The source operand can be an immediate, a register, or a memory location; the destination operand can be a register or a memory location. (However, two memory operands cannot be used in one instruction.) Each bit of the result is 1 if the corresponding bits of the operands are different; each bit is 0 if the corresponding bits are the same.\nThis instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.\nIn 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits. See the summary chart at the beginning of this section for encoding data and limits.", + "operation": "DEST := DEST XOR SRC;\n", + "url": "https://www.felixcloutier.com/x86/xor" + }, + "xorpd": { + "instruction": "XORPD", + "title": "XORPD\n\t\t— Bitwise Logical XOR of Packed Double Precision Floating-Point Values", + "opcode": "66 0F 57/r XORPD xmm1, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/xorpd" + }, + "xorps": { + "instruction": "XORPS", + "title": "XORPS\n\t\t— Bitwise Logical XOR of Packed Single Precision Floating-Point Values", + "opcode": "NP 0F 57 /r XORPS xmm1, xmm2/m128", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/xorps" + }, + "xrelease": { + "instruction": "XRELEASE", + "title": "XACQUIRE/XRELEASE\n\t\t— Hardware Lock Elision Prefix Hints", + "opcode": "F2 XACQUIRE", + "description": "The XACQUIRE prefix is a hint to start lock elision on the memory address specified by the instruction and the XRELEASE prefix is a hint to end lock elision on the memory address specified by the instruction.\nThe XACQUIRE prefix hint can only be used with the following instructions (these instructions are also referred to as XACQUIRE-enabled when used with the XACQUIRE prefix):\nThe XRELEASE prefix hint can only be used with the following instructions (also referred to as XRELEASE-enabled when used with the XRELEASE prefix):\nThe lock variables must satisfy the guidelines described in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, Section 16.3.3, for elision to be successful, otherwise an HLE abort may be signaled.\nIf an encoded byte sequence that meets XACQUIRE/XRELEASE requirements includes both prefixes, then the HLE semantic is determined by the prefix byte that is placed closest to the instruction opcode. For example, an F3F2C6 will not be treated as a XRELEASE-enabled instruction since the F2H (XACQUIRE) is closest to the instruction opcode C6. Similarly, an F2F3F0 prefixed instruction will be treated as a XRELEASE-enabled instruction since F3H (XRELEASE) is closest to the instruction opcode.\nIntel 64 and IA-32 Compatibility\nThe effect of the XACQUIRE/XRELEASE prefix hint is the same in non-64-bit modes and in 64-bit mode.\nFor instructions that do not support the XACQUIRE hint, the presence of the F2H prefix behaves the same way as prior hardware, according to\nFor instructions that do not support the XRELEASE hint, the presence of the F3H prefix behaves the same way as in prior hardware, according to", + "operation": "IF XACQUIRE-enabled instruction\n THEN\n IF (HLE_NEST_COUNT < MAX_HLE_NEST_COUNT) THEN\n HLE_NEST_COUNT++\n IF (HLE_NEST_COUNT = 1) THEN\n HLE_ACTIVE := 1\n IF 64-bit mode\n THEN\n restartRIP := instruction pointer of the XACQUIRE-enabled instruction\n ELSE\n restartEIP := instruction pointer of the XACQUIRE-enabled instruction\n FI;\n Enter HLE Execution (* record register state, start tracking memory state *)\n FI; (* HLE_NEST_COUNT = 1*)\n IF ElisionBufferAvailable\n THEN\n Allocate elision buffer\n Record address and data for forwarding and commit checking\n Perform elision\n ELSE\n Perform lock acquire operation transactionally but without elision\n FI;\n ELSE (* HLE_NEST_COUNT = MAX_HLE_NEST_COUNT*)\n GOTO HLE_ABORT_PROCESSING\n FI;\n ELSE\n Treat instruction as non-XACQUIRE F2H prefixed legacy instruction\nFI;\n\n\nIF XRELEASE-enabled instruction\n THEN\n IF (HLE_NEST_COUNT > 0)\n THEN\n HLE_NEST_COUNT--\n IF lock address matches in elision buffer THEN\n IF lock satisfies address and value requirements THEN\n Deallocate elision buffer\n ELSE\n GOTO HLE_ABORT_PROCESSING\n FI;\n FI;\n IF (HLE_NEST_COUNT = 0)\n THEN\n IF NoAllocatedElisionBuffer\n THEN\n Try to commit transactional execution\n IF fail to commit transactional execution\n THEN\n GOTO HLE_ABORT_PROCESSING;\n ELSE (* commit success *)\n HLE_ACTIVE := 0\n FI;\n ELSE\n GOTO HLE_ABORT_PROCESSING\n FI;\n FI;\n FI; (* HLE_NEST_COUNT > 0 *)\n ELSE\n Treat instruction as non-XRELEASE F3H prefixed legacy instruction\nFI;\n(* For any HLE abort condition encountered during HLE execution *)\nHLE_ABORT_PROCESSING:\n HLE_ACTIVE := 0\n HLE_NEST_COUNT := 0\n Restore architectural register state\n Discard memory updates performed in transaction\n Free any allocated lock elision buffers\n IF 64-bit mode\n THEN\n RIP := restartRIP\n ELSE\n EIP := restartEIP\n FI;\n Execute and retire instruction at RIP (or EIP) and ignore any HLE hint\nEND\n", + "url": "https://www.felixcloutier.com/x86/xacquire:xrelease" + }, + "xresldtrk": { + "instruction": "XRESLDTRK", + "title": "XRESLDTRK\n\t\t— Resume Tracking Load Addresses", + "opcode": "F2 0F 01 E9 XRESLDTRK", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/xresldtrk" + }, + "xrstor": { + "instruction": "XRSTOR", + "title": "XRSTOR\n\t\t— Restore Processor Extended States", + "opcode": "NP 0F AE /5 XRSTOR mem", + "description": "Performs a full or partial restore of processor state components from the XSAVE area located at the memory address specified by the source operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components restored correspond to the bits set in the requested-feature bitmap (RFBM), which is the logical-AND of EDX:EAX and XCR0.\nThe format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nSection 13.8, “Operation of XRSTOR,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 provides a detailed description of the operation of the XRSTOR instruction. The following items provide a highlevel outline:\nUse of a source operand not aligned to 64-byte boundary (for 64-bit and 32-bit modes) results in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.\nSee Section 13.6, “Processor Tracking of XSAVE-Managed State,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 for discussion of the bitmaps XINUSE and XMODIFIED and of the quantity XRSTOR_INFO.", + "operation": "RFBM := XCR0 AND EDX:EAX; /* bitwise logical AND */\nCOMPMASK := XCOMP_BV field from XSAVE header;\nRSTORMASK := XSTATE_BV field from XSAVE header;\nIF COMPMASK[63] = 0\n THEN\n /* Standard form of XRSTOR */\n TO_BE_RESTORED := RFBM AND RSTORMASK;\n TO_BE_INITIALIZED := RFBM AND NOT RSTORMASK;\n IF TO_BE_RESTORED[0] = 1\n THEN\n XINUSE[0] := 1;\n load x87 state from legacy region of XSAVE area;\n ELSIF TO_BE_INITIALIZED[0] = 1\n THEN\n XINUSE[0] := 0;\n initialize x87 state;\n FI;\n IF RFBM[1] = 1 OR RFBM[2] = 1\n THEN load MXCSR from legacy region of XSAVE area;\n FI;\n IF TO_BE_RESTORED[1] = 1\n THEN\n XINUSE[1] := 1;\n load XMM registers from legacy region of XSAVE area; // this step does not load MXCSR\n ELSIF TO_BE_INITIALIZED[1] = 1\n THEN\n XINUSE[1] := 0;\n set all XMM registers to 0; // this step does not initialize MXCSR\n FI;\n FOR i := 2 TO 62\n IF TO_BE_RESTORED[i] = 1\n THEN\n XINUSE[i] := 1;\n load XSAVE state component i at offset n from base of XSAVE area;\n // n enumerated by CPUID(EAX=0DH,ECX=i):EBX)\n ELSIF TO_BE_INITIALIZED[i] = 1\n THEN\n XINUSE[i] := 0;\n initialize XSAVE state component i;\n FI;\n ENDFOR;\n ELSE\n /* Compacted form of XRSTOR */\n IF CPUID.(EAX=0DH,ECX=1):EAX.XSAVEC[bit 1] = 0\n THEN /* compacted form not supported */\n #GP(0);\n FI;\n FORMAT = COMPMASK AND 7FFFFFFF_FFFFFFFFH;\n RESTORE_FEATURES = FORMAT AND RFBM;\n TO_BE_RESTORED := RESTORE_FEATURES AND RSTORMASK;\n FORCE_INIT := RFBM AND NOT FORMAT;\n TO_BE_INITIALIZED = (RFBM AND NOT RSTORMASK) OR FORCE_INIT;\n IF TO_BE_RESTORED[0] = 1\n THEN\n XINUSE[0] := 1;\n load x87 state from legacy region of XSAVE area;\n ELSIF TO_BE_INITIALIZED[0] = 1\n THEN\n XINUSE[0] := 0;\n initialize x87 state;\n FI;\n IF TO_BE_RESTORED[1] = 1\n THEN\n XINUSE[1] := 1;\n load SSE state from legacy region of XSAVE area; // this step loads the XMM registers and MXCSR\n ELSIF TO_BE_INITIALIZED[1] = 1\n THEN\n set all XMM registers to 0;\n XINUSE[1] := 0;\n MXCSR := 1F80H;\n FI;\n NEXT_FEATURE_OFFSET = 576;\n // Legacy area and XSAVE header consume 576 bytes\n FOR i := 2 TO 62\n IF FORMAT[i] = 1\n THEN\n IF TO_BE_RESTORED[i] = 1\n THEN\n XINUSE[i] := 1;\n load XSAVE state component i at offset NEXT_FEATURE_OFFSET from base of XSAVE area;\n FI;\n NEXT_FEATURE_OFFSET = NEXT_FEATURE_OFFSET + n (n enumerated by CPUID(EAX=0DH,ECX=i):EAX);\n FI;\n IF TO_BE_INITIALIZED[i] = 1\n THEN\n XINUSE[i] := 0;\n initialize XSAVE state component i;\n FI;\n ENDFOR;\nFI;\nXMODIFIED := NOT RFBM;\nIF in VMX non-root operation\n THEN VMXNR := 1;\n ELSE VMXNR := 0;\nFI;\nLAXA := linear address of XSAVE area;\nXRSTOR_INFO := CPL,VMXNR,LAXA,COMPMASK;\n", + "url": "https://www.felixcloutier.com/x86/xrstor" + }, + "xrstors": { + "instruction": "XRSTORS", + "title": "XRSTORS\n\t\t— Restore Processor Extended States Supervisor", + "opcode": "NP 0F C7 /3 XRSTORS mem", + "description": "Performs a full or partial restore of processor state components from the XSAVE area located at the memory address specified by the source operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components restored correspond to the bits set in the requested-feature bitmap (RFBM), which is the logical-AND of EDX:EAX and the logical-OR of XCR0 with the IA32_XSS MSR. XRSTORS may be executed only if CPL = 0.\nThe format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nSection 13.12, “Operation of XRSTORS,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 provides a detailed description of the operation of the XRSTOR instruction. The following items provide a high-level outline:\nUse of a source operand not aligned to 64-byte boundary (for 64-bit and 32-bit modes) results in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.\nSee Section 13.6, “Processor Tracking of XSAVE-Managed State,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 for discussion of the bitmaps XINUSE and XMODIFIED and of the quantity XRSTOR_INFO.", + "operation": "RFBM := (XCR0 OR IA32_XSS) AND EDX:EAX;\n /* bitwise logical OR and AND */\nCOMPMASK := XCOMP_BV field from XSAVE header;\nRSTORMASK := XSTATE_BV field from XSAVE header;\nFORMAT = COMPMASK AND 7FFFFFFF_FFFFFFFFH;\nRESTORE_FEATURES = FORMAT AND RFBM;\nTO_BE_RESTORED := RESTORE_FEATURES AND RSTORMASK;\nFORCE_INIT := RFBM AND NOT FORMAT;\nTO_BE_INITIALIZED = (RFBM AND NOT RSTORMASK) OR FORCE_INIT;\nIF TO_BE_RESTORED[0] = 1\n THEN\n XINUSE[0] := 1;\n load x87 state from legacy region of XSAVE area;\nELSIF TO_BE_INITIALIZED[0] = 1\n THEN\n XINUSE[0] := 0;\n initialize x87 state;\nFI;\nIF TO_BE_RESTORED[1] = 1\n THEN\n XINUSE[1] := 1;\n load SSE state from legacy region of XSAVE area; // this step loads the XMM registers and MXCSR\nELSIF TO_BE_INITIALIZED[1] = 1\n THEN\n set all XMM registers to 0;\n XINUSE[1] := 0;\n MXCSR := 1F80H;\nFI;\nNEXT_FEATURE_OFFSET = 576;\n // Legacy area and XSAVE header consume 576 bytes\nFOR i := 2 TO 62\n IF FORMAT[i] = 1\n THEN\n IF TO_BE_RESTORED[i] = 1\n THEN\n XINUSE[i] := 1;\n load XSAVE state component i at offset NEXT_FEATURE_OFFSET from base of XSAVE area;\n FI;\n NEXT_FEATURE_OFFSET = NEXT_FEATURE_OFFSET + n (n enumerated by CPUID(EAX=0DH,ECX=i):EAX);\n FI;\n IF TO_BE_INITIALIZED[i] = 1\n THEN\n XINUSE[i] := 0;\n initialize XSAVE state component i;\n FI;\nENDFOR;\nXMODIFIED := NOT RFBM;\nIF in VMX non-root operation\n THEN VMXNR := 1;\n ELSE VMXNR := 0;\nFI;\nLAXA := linear address of XSAVE area;\nXRSTOR_INFO := CPL,VMXNR,LAXA,COMPMASK;\n", + "url": "https://www.felixcloutier.com/x86/xrstors" + }, + "xsave": { + "instruction": "XSAVE", + "title": "XSAVE\n\t\t— Save Processor Extended States", + "opcode": "NP 0F AE /4 XSAVE mem", + "description": "Performs a full or partial save of processor state components to the XSAVE area located at the memory address specified by the destination operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components saved correspond to the bits set in the requested-feature bitmap (RFBM), which is the logical-AND of EDX:EAX and XCR0.\nThe format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nSection 13.7, “Operation of XSAVE,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 provides a detailed description of the operation of the XSAVE instruction. The following items provide a high-level outline:\nUse of a destination operand not aligned to 64-byte boundary (in either 64-bit or 32-bit modes) results in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.", + "operation": "RFBM := XCR0 AND EDX:EAX; /* bitwise logical AND */\nOLD_BV := XSTATE_BV field from XSAVE header;\nIF RFBM[0] = 1\n THEN store x87 state into legacy region of XSAVE area;\nFI;\nIF RFBM[1] = 1\n THEN store XMM registers into legacy region of XSAVE area; // this step does not save MXCSR or MXCSR_MASK\nFI;\nIF RFBM[1] = 1 OR RFBM[2] = 1\n THEN store MXCSR and MXCSR_MASK into legacy region of XSAVE area;\nFI;\nFOR i := 2 TO 62\n IF RFBM[i] = 1\n THEN save XSAVE state component i at offset n from base of XSAVE area (n enumerated by CPUID(EAX=0DH,ECX=i):EBX);\n FI;\nENDFOR;\nXSTATE_BV field in XSAVE header := (OLD_BV AND NOT RFBM) OR (XINUSE AND RFBM);\n", + "url": "https://www.felixcloutier.com/x86/xsave" + }, + "xsavec": { + "instruction": "XSAVEC", + "title": "XSAVEC\n\t\t— Save Processor Extended States With Compaction", + "opcode": "NP 0F C7 /4 XSAVEC mem", + "description": "Performs a full or partial save of processor state components to the XSAVE area located at the memory address specified by the destination operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components saved correspond to the bits set in the requested-feature bitmap (RFBM), which is the logical-AND of EDX:EAX and XCR0.\nThe format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nSection 13.10, “Operation of XSAVEC,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 provides a detailed description of the operation of the XSAVEC instruction. The following items provide a highlevel outline:\nUse of a destination operand not aligned to 64-byte boundary (in either 64-bit or 32-bit modes) results in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.", + "operation": "RFBM := XCR0 AND EDX:EAX;\n /* bitwise logical AND */\nTO_BE_SAVED := RFBM AND XINUSE;\n /* bitwise logical AND */\nIf MXCSR ≠ 1F80H AND RFBM[1]\n TO_BE_SAVED[1] = 1;\nFI;\nIF TO_BE_SAVED[0] = 1\n THEN store x87 state into legacy region of XSAVE area;\nFI;\nIF TO_BE_SAVED[1] = 1\n THEN store SSE state into legacy region of XSAVE area; // this step saves the XMM registers, MXCSR, and MXCSR_MASK\nFI;\nNEXT_FEATURE_OFFSET = 576;\n // Legacy area and XSAVE header consume 576 bytes\nFOR i := 2 TO 62\n IF RFBM[i] = 1\n THEN\n IF TO_BE_SAVED[i]\n THEN save XSAVE state component i at offset NEXT_FEATURE_OFFSET from base of XSAVE area;\n FI;\n NEXT_FEATURE_OFFSET = NEXT_FEATURE_OFFSET + n (n enumerated by CPUID(EAX=0DH,ECX=i):EAX);\n FI;\nENDFOR;\nXSTATE_BV field in XSAVE header := TO_BE_SAVED;\nXCOMP_BV field in XSAVE header := RFBM OR 80000000_00000000H;\n", + "url": "https://www.felixcloutier.com/x86/xsavec" + }, + "xsaveopt": { + "instruction": "XSAVEOPT", + "title": "XSAVEOPT\n\t\t— Save Processor Extended States Optimized", + "opcode": "NP 0F AE /6 XSAVEOPT mem", + "description": "Performs a full or partial save of processor state components to the XSAVE area located at the memory address specified by the destination operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components saved correspond to the bits set in the requested-feature bitmap (RFBM), which is the logical-AND of EDX:EAX and XCR0.\nThe format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nSection 13.9, “Operation of XSAVEOPT,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 provides a detailed description of the operation of the XSAVEOPT instruction. The following items provide a highlevel outline:\nUse of a destination operand not aligned to 64-byte boundary (in either 64-bit or 32-bit modes) will result in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.\nSee Section 13.6, “Processor Tracking of XSAVE-Managed State,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 for discussion of the bitmap XMODIFIED and of the quantity XRSTOR_INFO.", + "operation": "RFBM := XCR0 AND EDX:EAX; /* bitwise logical AND */\nOLD_BV := XSTATE_BV field from XSAVE header;\nTO_BE_SAVED := RFBM AND XINUSE;\nIF in VMX non-root operation\n THEN VMXNR := 1;\n ELSE VMXNR := 0;\nFI;\nLAXA := linear address of XSAVE area;\nIF XRSTOR_INFO = CPL,VMXNR,LAXA,00000000_00000000H\n THEN TO_BE_SAVED := TO_BE_SAVED AND XMODIFIED;\nFI;\nIF TO_BE_SAVED[0] = 1\n THEN store x87 state into legacy region of XSAVE area;\nFI;\nIF TO_BE_SAVED[1]\n THEN store XMM registers into legacy region of XSAVE area; // this step does not save MXCSR or MXCSR_MASK\nFI;\nIF RFBM[1] = 1 or RFBM[2] = 1\n THEN store MXCSR and MXCSR_MASK into legacy region of XSAVE area;\nFI;\nFOR i := 2 TO 62\n IF TO_BE_SAVED[i] = 1\n THEN save XSAVE state component i at offset n from base of XSAVE area (n enumerated by CPUID(EAX=0DH,ECX=i):EBX);\n FI;\nENDFOR;\nXSTATE_BV field in XSAVE header := (OLD_BV AND NOT RFBM) OR (XINUSE AND RFBM);\n", + "url": "https://www.felixcloutier.com/x86/xsaveopt" + }, + "xsaves": { + "instruction": "XSAVES", + "title": "XSAVES\n\t\t— Save Processor Extended States Supervisor", + "opcode": "NP 0F C7 /5 XSAVES mem", + "description": "Performs a full or partial save of processor state components to the XSAVE area located at the memory address specified by the destination operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components saved correspond to the bits set in the requested-feature bitmap (RFBM), the logicalAND of EDX:EAX and the logical-OR of XCR0 with the IA32_XSS MSR. XSAVES may be executed only if CPL = 0.\nThe format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State,” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.\nSection 13.11, “Operation of XSAVES,” of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 provides a detailed description of the operation of the XSAVES instruction. The following items provide a high-level outline:\nUse of a destination operand not aligned to 64-byte boundary (in either 64-bit or 32-bit modes) results in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.\nSee Section 13.6, “Processor Tracking of XSAVE-Managed State,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 for discussion of the bitmap XMODIFIED and of the quantity XRSTOR_INFO.", + "operation": "RFBM := (XCR0 OR IA32_XSS) AND EDX:EAX;\n /* bitwise logical OR and AND */\nIF in VMX non-root operation\n THEN VMXNR := 1;\n ELSE VMXNR := 0;\nFI;\nLAXA := linear address of XSAVE area;\nCOMPMASK := RFBM OR 80000000_00000000H;\nTO_BE_SAVED := RFBM AND XINUSE;\nIF XRSTOR_INFO = CPL,VMXNR,LAXA,COMPMASK\n THEN TO_BE_SAVED := TO_BE_SAVED AND XMODIFIED;\nFI;\nIF MXCSR ≠ 1F80H AND RFBM[1]\n THEN TO_BE_SAVED[1] = 1;\nFI;\nIF TO_BE_SAVED[0] = 1\n THEN store x87 state into legacy region of XSAVE area;\nFI;\nIF TO_BE_SAVED[1] = 1\n THEN store SSE state into legacy region of XSAVE area; // this step saves the XMM registers, MXCSR, and MXCSR_MASK\nFI;\nNEXT_FEATURE_OFFSET = 576;\n // Legacy area and XSAVE header consume 576 bytes\nFOR i := 2 TO 62\n IF RFBM[i] = 1\n THEN\n IF TO_BE_SAVED[i]\n THEN\n save XSAVE state component i at offset NEXT_FEATURE_OFFSET from base of XSAVE area;\n IF i = 8 // state component 8 is for PT state\n THEN IA32_RTIT_CTL.TraceEn[bit 0] := 0;\n FI;\n FI;\n NEXT_FEATURE_OFFSET = NEXT_FEATURE_OFFSET + n (n enumerated by CPUID(EAX=0DH,ECX=i):EAX);\n FI;\nENDFOR;\nNEW_HEADER := RFBM AND XINUSE;\nIF MXCSR ≠ 1F80H AND RFBM[1]\n THEN NEW_HEADER[1] = 1;\nFI;\nXSTATE_BV field in XSAVE header := NEW_HEADER;\nXCOMP_BV field in XSAVE header := COMPMASK;\n", + "url": "https://www.felixcloutier.com/x86/xsaves" + }, + "xsetbv": { + "instruction": "XSETBV", + "title": "XSETBV\n\t\t— Set Extended Control Register", + "opcode": "NP 0F 01 D1", + "description": "Writes the contents of registers EDX:EAX into the 64-bit extended control register (XCR) specified in the ECX register. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The contents of the EDX register are copied to high-order 32 bits of the selected XCR and the contents of the EAX register are copied to low-order 32 bits of the XCR. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are ignored.) Undefined or reserved bits in an XCR should be set to values previously read.\nThis instruction must be executed at privilege level 0 or in real-address mode; otherwise, a general protection exception #GP(0) is generated. Specifying a reserved or unimplemented XCR in ECX will also cause a general protection exception. The processor will also generate a general protection exception if software attempts to write to reserved bits in an XCR.\nCurrently, only XCR0 is supported. Thus, all other values of ECX are reserved and will cause a #GP(0). Note that bit 0 of XCR0 (corresponding to x87 state) must be set to 1; the instruction will cause a #GP(0) if an attempt is made to clear this bit. In addition, the instruction causes a #GP(0) if an attempt is made to set XCR0[2] (AVX state) while clearing XCR0[1] (SSE state); it is necessary to set both bits to use AVX instructions; Section 13.3, “Enabling the XSAVE Feature Set and XSAVE-Enabled Features,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.", + "operation": "XCR[ECX] := EDX:EAX;\n", + "url": "https://www.felixcloutier.com/x86/xsetbv" + }, + "xsusldtrk": { + "instruction": "XSUSLDTRK", + "title": "XSUSLDTRK\n\t\t— Suspend Tracking Load Addresses", + "opcode": "F2 0F 01 E8 XSUSLDTRK", + "description": "", + "operation": "", + "url": "https://www.felixcloutier.com/x86/xsusldtrk" + }, + "xtest": { + "instruction": "XTEST", + "title": "XTEST\n\t\t— Test if in Transactional Execution", + "opcode": "NP 0F 01 D6 XTEST", + "description": "The XTEST instruction queries the transactional execution status. If the instruction executes inside a transactionally executing RTM region or a transactionally executing HLE region, then the ZF flag is cleared, else it is set.", + "operation": "IF (RTM_ACTIVE = 1 OR HLE_ACTIVE = 1)\n THEN\n ZF := 0\n ELSE\n ZF := 1\nFI;\n", + "url": "https://www.felixcloutier.com/x86/xtest" + } +} \ No newline at end of file