# This file is auto-generated by /codegen/x86_64.py
# Instruction data is based on package opcodes 0.3.14

import inspect

import peachpy.stream
import peachpy.x86_64.options
import peachpy.x86_64.isa
from peachpy.util import is_sint8, is_sint32
from peachpy.x86_64.encoding import rex, optional_rex, vex2, vex3, evex, modrm_sib_disp
from peachpy.x86_64.instructions import Instruction, BranchInstruction
from peachpy.x86_64.operand import is_al, is_ax, is_eax, is_rax, is_cl, is_xmm0, is_r8, is_r8rex, is_r16, is_r32, is_r64, \
    is_mm, is_xmm, is_ymm, is_m, is_m8, is_m16, is_m32, is_m64, is_m80, is_m128, is_m256, is_m512, \
    is_evex_xmm, is_xmmk, is_xmmkz, is_evex_ymm, is_ymmk, is_ymmkz, is_zmm, is_zmmk, is_zmmkz, is_k, is_kk, \
    is_m32k, is_m64k, is_m16kz, is_m32kz, is_m64kz, is_m128kz, is_m256kz, is_m512kz, \
    is_m64_m32bcst, is_m128_m32bcst, is_m256_m32bcst, is_m512_m32bcst, \
    is_m128_m64bcst, is_m256_m64bcst, is_m512_m64bcst, \
    is_vmx, is_vmy, is_evex_vmx, is_evex_vmy, is_vmz, is_vmxk, is_vmyk, is_vmzk, \
    is_imm, is_imm4, is_imm8, is_imm16, is_imm32, is_imm64, \
    is_rel8, is_rel32, is_label, is_er, is_sae, check_operand, format_operand_type


class ADD(Instruction):
    """Add"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ADD(r16, r16/m16)
            * ADD(r16/m16, imm16)
            * ADD(r16/m16, r16)
            * ADD(r32, r32/m32)
            * ADD(r32/m32, imm32)
            * ADD(r32/m32, r32)
            * ADD(r64, r64/m64)
            * ADD(r64/m64, imm32)
            * ADD(r64/m64, r64)
            * ADD(r8, r8/m8)
            * ADD(r8/m8, imm8)
            * ADD(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ADD, self).__init__("ADD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"ADD\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ADDB"
            self._gas_name = "addb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x04, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ADDB"
            self._gas_name = "addb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x00, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x02, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "ADDB"
            self._gas_name = "addb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x02]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ADDW"
            self._gas_name = "addw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x05, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ADDW"
            self._gas_name = "addw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x01, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x03, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "ADDW"
            self._gas_name = "addw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x03]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADDL"
            self._gas_name = "addl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x05, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ADDL"
            self._gas_name = "addl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x01, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x03, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "ADDL"
            self._gas_name = "addl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x03]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADDQ"
            self._gas_name = "addq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x05, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ADDQ"
            self._gas_name = "addq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x01, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x03, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "ADDQ"
            self._gas_name = "addq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x03]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ADDB"
            self._gas_name = "addb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ADDB"
            self._gas_name = "addb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x00]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ADDW"
            self._gas_name = "addw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ADDW"
            self._gas_name = "addw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x01]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADDL"
            self._gas_name = "addl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ADDL"
            self._gas_name = "addl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x01]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADDQ"
            self._gas_name = "addq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ADDQ"
            self._gas_name = "addq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x01]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: ADD " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SUB(Instruction):
    """Subtract"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SUB(r16, r16/m16)
            * SUB(r16/m16, imm16)
            * SUB(r16/m16, r16)
            * SUB(r32, r32/m32)
            * SUB(r32/m32, imm32)
            * SUB(r32/m32, r32)
            * SUB(r64, r64/m64)
            * SUB(r64/m64, imm32)
            * SUB(r64/m64, r64)
            * SUB(r8, r8/m8)
            * SUB(r8/m8, imm8)
            * SUB(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SUB, self).__init__("SUB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"SUB\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SUBB"
            self._gas_name = "subb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x2C, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "SUBB"
            self._gas_name = "subb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x28, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x2A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "SUBB"
            self._gas_name = "subb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x2A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "SUBW"
            self._gas_name = "subw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x2D, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xE8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "SUBW"
            self._gas_name = "subw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x29, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x2B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "SUBW"
            self._gas_name = "subw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x2B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SUBL"
            self._gas_name = "subl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x2D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xE8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "SUBL"
            self._gas_name = "subl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x29, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x2B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "SUBL"
            self._gas_name = "subl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x2B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SUBQ"
            self._gas_name = "subq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x2D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xE8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "SUBQ"
            self._gas_name = "subq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x29, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x2B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "SUBQ"
            self._gas_name = "subq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x2B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SUBB"
            self._gas_name = "subb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "SUBB"
            self._gas_name = "subb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x28]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "SUBW"
            self._gas_name = "subw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "SUBW"
            self._gas_name = "subw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x29]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SUBL"
            self._gas_name = "subl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "SUBL"
            self._gas_name = "subl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x29]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SUBQ"
            self._gas_name = "subq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "SUBQ"
            self._gas_name = "subq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x29]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: SUB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class ADC(Instruction):
    """Add with Carry"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ADC(r16, r16/m16)
            * ADC(r16/m16, imm16)
            * ADC(r16/m16, r16)
            * ADC(r32, r32/m32)
            * ADC(r32/m32, imm32)
            * ADC(r32/m32, r32)
            * ADC(r64, r64/m64)
            * ADC(r64/m64, imm32)
            * ADC(r64/m64, r64)
            * ADC(r8, r8/m8)
            * ADC(r8/m8, imm8)
            * ADC(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ADC, self).__init__("ADC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"ADC\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ADCB"
            self._gas_name = "adcb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x14, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ADCB"
            self._gas_name = "adcb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x10, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x12, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "ADCB"
            self._gas_name = "adcb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x12]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ADCW"
            self._gas_name = "adcw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x15, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xD0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ADCW"
            self._gas_name = "adcw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x11, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x13, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "ADCW"
            self._gas_name = "adcw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x13]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADCL"
            self._gas_name = "adcl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x15, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xD0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ADCL"
            self._gas_name = "adcl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x11, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x13, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "ADCL"
            self._gas_name = "adcl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x13]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADCQ"
            self._gas_name = "adcq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x15, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xD0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ADCQ"
            self._gas_name = "adcq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x11, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x13, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "ADCQ"
            self._gas_name = "adcq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x13]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ADCB"
            self._gas_name = "adcb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ADCB"
            self._gas_name = "adcb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x10]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ADCW"
            self._gas_name = "adcw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ADCW"
            self._gas_name = "adcw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x11]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADCL"
            self._gas_name = "adcl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ADCL"
            self._gas_name = "adcl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x11]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ADCQ"
            self._gas_name = "adcq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ADCQ"
            self._gas_name = "adcq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x11]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: ADC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SBB(Instruction):
    """Subtract with Borrow"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SBB(r16, r16/m16)
            * SBB(r16/m16, imm16)
            * SBB(r16/m16, r16)
            * SBB(r32, r32/m32)
            * SBB(r32/m32, imm32)
            * SBB(r32/m32, r32)
            * SBB(r64, r64/m64)
            * SBB(r64/m64, imm32)
            * SBB(r64/m64, r64)
            * SBB(r8, r8/m8)
            * SBB(r8/m8, imm8)
            * SBB(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SBB, self).__init__("SBB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"SBB\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SBBB"
            self._gas_name = "sbbb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x1C, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "SBBB"
            self._gas_name = "sbbb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x18, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x1A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "SBBB"
            self._gas_name = "sbbb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x1A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "SBBW"
            self._gas_name = "sbbw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x1D, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xD8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "SBBW"
            self._gas_name = "sbbw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x19, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x1B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "SBBW"
            self._gas_name = "sbbw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x1B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SBBL"
            self._gas_name = "sbbl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x1D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xD8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "SBBL"
            self._gas_name = "sbbl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x19, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x1B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "SBBL"
            self._gas_name = "sbbl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x1B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SBBQ"
            self._gas_name = "sbbq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x1D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xD8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "SBBQ"
            self._gas_name = "sbbq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x19, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x1B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "SBBQ"
            self._gas_name = "sbbq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x1B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SBBB"
            self._gas_name = "sbbb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "SBBB"
            self._gas_name = "sbbb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x18]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "SBBW"
            self._gas_name = "sbbw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "SBBW"
            self._gas_name = "sbbw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x19]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SBBL"
            self._gas_name = "sbbl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "SBBL"
            self._gas_name = "sbbl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x19]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "SBBQ"
            self._gas_name = "sbbq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "SBBQ"
            self._gas_name = "sbbq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x19]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: SBB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class ADCX(Instruction):
    """Unsigned Integer Addition of Two Operands with Carry Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ADCX(r32, r32/m32)    [ADX]
            * ADCX(r64, r64/m64)    [ADX]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ADCX, self).__init__("ADCX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"ADCX\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.adx])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "adcxl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x38, 0xF6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "adcxl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "adcxq"
            self.encodings.append((0x00, lambda op: bytearray([0x66, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x38, 0xF6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "adcxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0x66]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x38, 0xF6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: ADCX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class ADOX(Instruction):
    """Unsigned Integer Addition of Two Operands with Overflow Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ADOX(r32, r32/m32)    [ADX]
            * ADOX(r64, r64/m64)    [ADX]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ADOX, self).__init__("ADOX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"ADOX\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.adx])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "adoxl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x38, 0xF6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "adoxl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "adoxq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x38, 0xF6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "adoxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x38, 0xF6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: ADOX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class AND(Instruction):
    """Logical AND"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * AND(r16, r16/m16)
            * AND(r16/m16, imm16)
            * AND(r16/m16, r16)
            * AND(r32, r32/m32)
            * AND(r32/m32, imm32)
            * AND(r32/m32, r32)
            * AND(r64, r64/m64)
            * AND(r64/m64, imm32)
            * AND(r64/m64, r64)
            * AND(r8, r8/m8)
            * AND(r8/m8, imm8)
            * AND(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(AND, self).__init__("AND", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"AND\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ANDB"
            self._gas_name = "andb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x24, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ANDB"
            self._gas_name = "andb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x20, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x22, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "ANDB"
            self._gas_name = "andb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x22]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ANDW"
            self._gas_name = "andw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x25, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xE0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ANDW"
            self._gas_name = "andw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x21, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x23, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "ANDW"
            self._gas_name = "andw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x23]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ANDL"
            self._gas_name = "andl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x25, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xE0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ANDL"
            self._gas_name = "andl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x21, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x23, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "ANDL"
            self._gas_name = "andl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x23]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ANDQ"
            self._gas_name = "andq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x25, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xE0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ANDQ"
            self._gas_name = "andq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x21, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x23, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "ANDQ"
            self._gas_name = "andq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x23]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ANDB"
            self._gas_name = "andb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ANDB"
            self._gas_name = "andb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x20]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ANDW"
            self._gas_name = "andw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ANDW"
            self._gas_name = "andw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x21]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ANDL"
            self._gas_name = "andl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ANDL"
            self._gas_name = "andl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x21]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ANDQ"
            self._gas_name = "andq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ANDQ"
            self._gas_name = "andq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x21]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: AND " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class OR(Instruction):
    """Logical Inclusive OR"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * OR(r16, r16/m16)
            * OR(r16/m16, imm16)
            * OR(r16/m16, r16)
            * OR(r32, r32/m32)
            * OR(r32/m32, imm32)
            * OR(r32/m32, r32)
            * OR(r64, r64/m64)
            * OR(r64/m64, imm32)
            * OR(r64/m64, r64)
            * OR(r8, r8/m8)
            * OR(r8/m8, imm8)
            * OR(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(OR, self).__init__("OR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"OR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ORB"
            self._gas_name = "orb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x0C, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ORB"
            self._gas_name = "orb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x08, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x0A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "ORB"
            self._gas_name = "orb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x0A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ORW"
            self._gas_name = "orw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x0D, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xC8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ORW"
            self._gas_name = "orw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x09, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "ORW"
            self._gas_name = "orw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ORL"
            self._gas_name = "orl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x0D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xC8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ORL"
            self._gas_name = "orl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x09, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "ORL"
            self._gas_name = "orl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ORQ"
            self._gas_name = "orq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x0D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xC8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ORQ"
            self._gas_name = "orq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x09, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "ORQ"
            self._gas_name = "orq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ORB"
            self._gas_name = "orb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "ORB"
            self._gas_name = "orb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x08]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "ORW"
            self._gas_name = "orw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "ORW"
            self._gas_name = "orw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x09]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ORL"
            self._gas_name = "orl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "ORL"
            self._gas_name = "orl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x09]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "ORQ"
            self._gas_name = "orq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "ORQ"
            self._gas_name = "orq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x09]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: OR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class XOR(Instruction):
    """Logical Exclusive OR"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * XOR(r16, r16/m16)
            * XOR(r16/m16, imm16)
            * XOR(r16/m16, r16)
            * XOR(r32, r32/m32)
            * XOR(r32/m32, imm32)
            * XOR(r32/m32, r32)
            * XOR(r64, r64/m64)
            * XOR(r64/m64, imm32)
            * XOR(r64/m64, r64)
            * XOR(r8, r8/m8)
            * XOR(r8/m8, imm8)
            * XOR(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(XOR, self).__init__("XOR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"XOR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "XORB"
            self._gas_name = "xorb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x34, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "XORB"
            self._gas_name = "xorb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x30, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x32, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "XORB"
            self._gas_name = "xorb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x32]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "XORW"
            self._gas_name = "xorw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x35, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xF0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "XORW"
            self._gas_name = "xorw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x31, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x33, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "XORW"
            self._gas_name = "xorw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x33]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "XORL"
            self._gas_name = "xorl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x35, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xF0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "XORL"
            self._gas_name = "xorl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x31, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x33, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "XORL"
            self._gas_name = "xorl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x33]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "XORQ"
            self._gas_name = "xorq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x35, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xF0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "XORQ"
            self._gas_name = "xorq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x31, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x33, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self._cancelling_inputs = True
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "XORQ"
            self._gas_name = "xorq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x33]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "XORB"
            self._gas_name = "xorb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "XORB"
            self._gas_name = "xorb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x30]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "XORW"
            self._gas_name = "xorw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "XORW"
            self._gas_name = "xorw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x31]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "XORL"
            self._gas_name = "xorl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "XORL"
            self._gas_name = "xorl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x31]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "XORQ"
            self._gas_name = "xorq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "XORQ"
            self._gas_name = "xorq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x31]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: XOR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class ANDN(Instruction):
    """Logical AND NOT"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ANDN(r32, r32, r32/m32)    [BMI]
            * ANDN(r64, r64, r64/m64)    [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ANDN, self).__init__("ANDN", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"ANDN\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "andnl"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0x78 ^ (op[1].hlcode << 3), 0xF2, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
            self._cancelling_inputs = True
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_m32(self.operands[2]):
            self._gas_name = "andnl"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x00, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF2]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "andnq"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0xF8 ^ (op[1].hlcode << 3), 0xF2, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
            self._cancelling_inputs = True
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_m64(self.operands[2]):
            self._gas_name = "andnq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x80, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF2]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: ANDN " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class NOT(Instruction):
    """One's Complement Negation"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * NOT(r16/m16)
            * NOT(r32/m32)
            * NOT(r64/m64)
            * NOT(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(NOT, self).__init__("NOT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"NOT\" requires 1 operands")
        self.in_regs = (True,)
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.go_name = "NOTB"
            self._gas_name = "notb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xD0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r16(self.operands[0]):
            self.go_name = "NOTW"
            self._gas_name = "notw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xD0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r32(self.operands[0]):
            self.go_name = "NOTL"
            self._gas_name = "notl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xD0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r64(self.operands[0]):
            self.go_name = "NOTQ"
            self._gas_name = "notq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xD0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.go_name = "NOTB"
            self._gas_name = "notb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m16(self.operands[0]):
            self.go_name = "NOTW"
            self._gas_name = "notw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m32(self.operands[0]):
            self.go_name = "NOTL"
            self._gas_name = "notl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m64(self.operands[0]):
            self.go_name = "NOTQ"
            self._gas_name = "notq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: NOT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class NEG(Instruction):
    """Two's Complement Negation"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * NEG(r16/m16)
            * NEG(r32/m32)
            * NEG(r64/m64)
            * NEG(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(NEG, self).__init__("NEG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"NEG\" requires 1 operands")
        self.in_regs = (True,)
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.go_name = "NEGB"
            self._gas_name = "negb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xD8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r16(self.operands[0]):
            self.go_name = "NEGW"
            self._gas_name = "negw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xD8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r32(self.operands[0]):
            self.go_name = "NEGL"
            self._gas_name = "negl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xD8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r64(self.operands[0]):
            self.go_name = "NEGQ"
            self._gas_name = "negq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xD8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.go_name = "NEGB"
            self._gas_name = "negb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m16(self.operands[0]):
            self.go_name = "NEGW"
            self._gas_name = "negw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m32(self.operands[0]):
            self.go_name = "NEGL"
            self._gas_name = "negl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m64(self.operands[0]):
            self.go_name = "NEGQ"
            self._gas_name = "negq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: NEG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class INC(Instruction):
    """Increment by 1"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * INC(r16/m16)
            * INC(r32/m32)
            * INC(r64/m64)
            * INC(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(INC, self).__init__("INC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"INC\" requires 1 operands")
        self.in_regs = (True,)
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.go_name = "INCB"
            self._gas_name = "incb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xFE, 0xC0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r16(self.operands[0]):
            self.go_name = "INCW"
            self._gas_name = "incw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xFF, 0xC0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r32(self.operands[0]):
            self.go_name = "INCL"
            self._gas_name = "incl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xFF, 0xC0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r64(self.operands[0]):
            self.go_name = "INCQ"
            self._gas_name = "incq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xFF, 0xC0 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.go_name = "INCB"
            self._gas_name = "incb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFE]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m16(self.operands[0]):
            self.go_name = "INCW"
            self._gas_name = "incw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m32(self.operands[0]):
            self.go_name = "INCL"
            self._gas_name = "incl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m64(self.operands[0]):
            self.go_name = "INCQ"
            self._gas_name = "incq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xFF]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: INC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class DEC(Instruction):
    """Decrement by 1"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * DEC(r16/m16)
            * DEC(r32/m32)
            * DEC(r64/m64)
            * DEC(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(DEC, self).__init__("DEC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"DEC\" requires 1 operands")
        self.in_regs = (True,)
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.go_name = "DECB"
            self._gas_name = "decb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xFE, 0xC8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r16(self.operands[0]):
            self.go_name = "DECW"
            self._gas_name = "decw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xFF, 0xC8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r32(self.operands[0]):
            self.go_name = "DECL"
            self._gas_name = "decl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xFF, 0xC8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_r64(self.operands[0]):
            self.go_name = "DECQ"
            self._gas_name = "decq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xFF, 0xC8 | op[0].lcode])))
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.go_name = "DECB"
            self._gas_name = "decb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFE]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m16(self.operands[0]):
            self.go_name = "DECW"
            self._gas_name = "decw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m32(self.operands[0]):
            self.go_name = "DECL"
            self._gas_name = "decl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        elif is_m64(self.operands[0]):
            self.go_name = "DECQ"
            self._gas_name = "decq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xFF]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: DEC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class TEST(Instruction):
    """Logical Compare"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * TEST(r16/m16, imm16)
            * TEST(r16/m16, r16)
            * TEST(r32/m32, imm32)
            * TEST(r32/m32, r32)
            * TEST(r64/m64, imm32)
            * TEST(r64/m64, r64)
            * TEST(r8/m8, imm8)
            * TEST(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(TEST, self).__init__("TEST", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"TEST\" requires 2 operands")
        self.out_regs = (False, False)
        self.out_operands = (False, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "TESTB"
            self._gas_name = "testb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0xA8, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "TESTB"
            self._gas_name = "testb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x84, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "TESTW"
            self._gas_name = "testw"
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0xA9, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "TESTW"
            self._gas_name = "testw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x85, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "TESTL"
            self._gas_name = "testl"
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0xA9, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "TESTL"
            self._gas_name = "testl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x85, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "TESTQ"
            self._gas_name = "testq"
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0xA9, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "TESTQ"
            self._gas_name = "testq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x85, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "TESTB"
            self._gas_name = "testb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "TESTB"
            self._gas_name = "testb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x84]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "TESTW"
            self._gas_name = "testw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "TESTW"
            self._gas_name = "testw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x85]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "TESTL"
            self._gas_name = "testl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "TESTL"
            self._gas_name = "testl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x85]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "TESTQ"
            self._gas_name = "testq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "TESTQ"
            self._gas_name = "testq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x85]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        else:
            raise SyntaxError("Invalid operand types: TEST " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMP(Instruction):
    """Compare Two Operands"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMP(r16, r16/m16)
            * CMP(r16/m16, imm16)
            * CMP(r16/m16, r16)
            * CMP(r32, r32/m32)
            * CMP(r32/m32, imm32)
            * CMP(r32/m32, r32)
            * CMP(r64, r64/m64)
            * CMP(r64/m64, imm32)
            * CMP(r64/m64, r64)
            * CMP(r8, r8/m8)
            * CMP(r8/m8, imm8)
            * CMP(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMP, self).__init__("CMP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMP\" requires 2 operands")
        self.out_regs = (False, False)
        self.out_operands = (False, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "CMPB"
            self._gas_name = "cmpb"
            if is_al(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x3C, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x80, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "CMPB"
            self._gas_name = "cmpb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x38, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x3A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self._cancelling_inputs = True
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "CMPB"
            self._gas_name = "cmpb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x3A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "CMPW"
            self._gas_name = "cmpw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x83, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x66, 0x3D, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x81, 0xF8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "CMPW"
            self._gas_name = "cmpw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x39, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x3B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self._cancelling_inputs = True
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "CMPW"
            self._gas_name = "cmpw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x3B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "CMPL"
            self._gas_name = "cmpl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x83, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x3D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x81, 0xF8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "CMPL"
            self._gas_name = "cmpl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x39, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x3B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self._cancelling_inputs = True
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "CMPL"
            self._gas_name = "cmpl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x3B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "CMPQ"
            self._gas_name = "cmpq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x83, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48, 0x3D, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x81, 0xF8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "CMPQ"
            self._gas_name = "cmpq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x39, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x3B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (True, True)
            self._cancelling_inputs = True
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "CMPQ"
            self._gas_name = "cmpq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x3B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "CMPB"
            self._gas_name = "cmpb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x80]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "CMPB"
            self._gas_name = "cmpb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x38]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "CMPW"
            self._gas_name = "cmpw"
            if is_imm8(self.operands[1], ext_size=2):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "CMPW"
            self._gas_name = "cmpw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x39]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "CMPL"
            self._gas_name = "cmpl"
            if is_imm8(self.operands[1], ext_size=4):
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x83]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x81]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "CMPL"
            self._gas_name = "cmpl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x39]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "CMPQ"
            self._gas_name = "cmpq"
            if is_imm8(self.operands[1], ext_size=8):
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x83]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x81]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "CMPQ"
            self._gas_name = "cmpq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x39]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        else:
            raise SyntaxError("Invalid operand types: CMP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MOV(Instruction):
    """Move"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MOV(m64, imm32)
            * MOV(r16, r16/m16)
            * MOV(r16/m16, imm16)
            * MOV(r16/m16, r16)
            * MOV(r32, r32/m32)
            * MOV(r32/m32, imm32)
            * MOV(r32/m32, r32)
            * MOV(r64, imm64)
            * MOV(r64, r64/m64)
            * MOV(r64/m64, r64)
            * MOV(r8, r8/m8)
            * MOV(r8/m8, imm8)
            * MOV(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MOV, self).__init__("MOV", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"MOV\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "MOVB"
            self._gas_name = "movb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC6, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xB0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (False, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVB"
            self._gas_name = "movb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x88, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x8A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVB"
            self._gas_name = "movb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x8A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "MOVW"
            self._gas_name = "movw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC7, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xB8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (False, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "MOVW"
            self._gas_name = "movw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x89, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x8B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "MOVW"
            self._gas_name = "movw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x8B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "MOVL"
            self._gas_name = "movl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC7, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xB8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (False, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "MOVL"
            self._gas_name = "movl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x89, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x8B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "MOVL"
            self._gas_name = "movl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x8B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm64(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm64")
            self.go_name = "MOVQ"
            self._gas_name = "movq"
            if is_imm32(self.operands[1], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC7, 0xC0 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xB8 | op[0].lcode, op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF, (op[1] >> 32) & 0xFF, (op[1] >> 40) & 0xFF, (op[1] >> 48) & 0xFF, (op[1] >> 56) & 0xFF])))
            self.in_regs = (False, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "MOVQ"
            self._gas_name = "movq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x89, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x8B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "MOVQ"
            self._gas_name = "movq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x8B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "MOVB"
            self._gas_name = "movb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC6]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVB"
            self._gas_name = "movb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x88]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm16(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm16")
            self.go_name = "MOVW"
            self._gas_name = "movw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC7]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "MOVW"
            self._gas_name = "movw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x89]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "MOVL"
            self._gas_name = "movl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC7]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "MOVL"
            self._gas_name = "movl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x89]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm32(self.operands[1], ext_size=8):
                raise ValueError("Argument #1 can not be encoded as imm32")
            self.go_name = "MOVQ"
            self._gas_name = "movq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC7]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF, (op[1] >> 8) & 0xFF, (op[1] >> 16) & 0xFF, (op[1] >> 24) & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "MOVQ"
            self._gas_name = "movq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x89]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: MOV " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MOVZX(Instruction):
    """Move with Zero-Extend"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MOVZX(r16, r8/m8)
            * MOVZX(r32, r16/m16)
            * MOVZX(r32, r8/m8)
            * MOVZX(r64, r16/m16)
            * MOVZX(r64, r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MOVZX, self).__init__("MOVZX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"MOVZX\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVBWZX"
            self._gas_name = "movzbw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[1])) + bytearray([0x0F, 0xB6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVBWZX"
            self._gas_name = "movzbw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVBLZX"
            self._gas_name = "movzbl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[1])) + bytearray([0x0F, 0xB6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "MOVWLZX"
            self._gas_name = "movzwl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xB7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVBLZX"
            self._gas_name = "movzbl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "MOVWLZX"
            self._gas_name = "movzwl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVBQZX"
            self._gas_name = "movzbq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xB6, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "MOVWQZX"
            self._gas_name = "movzwq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xB7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVBQZX"
            self._gas_name = "movzbq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xB6]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "MOVWQZX"
            self._gas_name = "movzwq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xB7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: MOVZX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MOVSX(Instruction):
    """Move with Sign-Extension"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MOVSX(r16, r8/m8)
            * MOVSX(r32, r16/m16)
            * MOVSX(r32, r8/m8)
            * MOVSX(r64, r16/m16)
            * MOVSX(r64, r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MOVSX, self).__init__("MOVSX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"MOVSX\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVBWSX"
            self._gas_name = "movsbw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[1])) + bytearray([0x0F, 0xBE, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVBWSX"
            self._gas_name = "movsbw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBE]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVBLSX"
            self._gas_name = "movsbl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[1])) + bytearray([0x0F, 0xBE, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "MOVWLSX"
            self._gas_name = "movswl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBF, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVBLSX"
            self._gas_name = "movsbl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBE]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "MOVWLSX"
            self._gas_name = "movswl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBF]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "MOVBQSX"
            self._gas_name = "movsbq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBE, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "MOVWQSX"
            self._gas_name = "movswq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBF, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "MOVBQSX"
            self._gas_name = "movsbq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBE]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "MOVWQSX"
            self._gas_name = "movswq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBF]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: MOVSX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MOVSXD(Instruction):
    """Move Doubleword to Quadword with Sign-Extension"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MOVSXD(r64, r32/m32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MOVSXD, self).__init__("MOVSXD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"MOVSXD\" requires 2 operands")
        self.go_name = "MOVLQSX"
        self._gas_name = "movslq"
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        if is_r64(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x63, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x63]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: MOVSXD " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MOVBE(Instruction):
    """Move Data After Swapping Bytes"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MOVBE(m16, r16)    [MOVBE]
            * MOVBE(m32, r32)    [MOVBE]
            * MOVBE(m64, r64)    [MOVBE]
            * MOVBE(r16, m16)    [MOVBE]
            * MOVBE(r32, m32)    [MOVBE]
            * MOVBE(r64, m64)    [MOVBE]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MOVBE, self).__init__("MOVBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"MOVBE\" requires 2 operands")
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.movbe])
        if is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "movbew"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "movbel"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "movbeq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x38, 0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True)
            self.out_regs = (True, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "movbew"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0x38, 0xF1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "movbel"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0x38, 0xF1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "movbeq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0x38, 0xF1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: MOVBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MOVNTI(Instruction):
    """Store Doubleword Using Non-Temporal Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MOVNTI(m32, r32)    [SSE2]
            * MOVNTI(m64, r64)    [SSE2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MOVNTI, self).__init__("MOVNTI", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"MOVNTI\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (False, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.sse2])
        if is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "MOVNTIL"
            self._gas_name = "movntil"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xC3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "MOVNTIQ"
            self._gas_name = "movntiq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xC3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: MOVNTI " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BT(Instruction):
    """Bit Test"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BT(r16/m16, imm8)
            * BT(r16/m16, r16)
            * BT(r32/m32, imm8)
            * BT(r32/m32, r32)
            * BT(r64/m64, imm8)
            * BT(r64/m64, r64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BT, self).__init__("BT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BT\" requires 2 operands")
        self.out_regs = (False, False)
        self.out_operands = (False, False)
        if is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTW"
            self._gas_name = "btw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTW"
            self._gas_name = "btw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xA3, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTL"
            self._gas_name = "btl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTL"
            self._gas_name = "btl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xA3, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTQ"
            self._gas_name = "btq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x0F, 0xBA, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTQ"
            self._gas_name = "btq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xA3, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTW"
            self._gas_name = "btw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTW"
            self._gas_name = "btw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xA3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTL"
            self._gas_name = "btl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTL"
            self._gas_name = "btl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xA3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTQ"
            self._gas_name = "btq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTQ"
            self._gas_name = "btq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xA3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
        else:
            raise SyntaxError("Invalid operand types: BT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BTS(Instruction):
    """Bit Test and Set"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BTS(r16/m16, imm8)
            * BTS(r16/m16, r16)
            * BTS(r32/m32, imm8)
            * BTS(r32/m32, r32)
            * BTS(r64/m64, imm8)
            * BTS(r64/m64, r64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BTS, self).__init__("BTS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BTS\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTSW"
            self._gas_name = "btsw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTSW"
            self._gas_name = "btsw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xAB, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTSL"
            self._gas_name = "btsl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTSL"
            self._gas_name = "btsl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xAB, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTSQ"
            self._gas_name = "btsq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x0F, 0xBA, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTSQ"
            self._gas_name = "btsq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xAB, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTSW"
            self._gas_name = "btsw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTSW"
            self._gas_name = "btsw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xAB]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTSL"
            self._gas_name = "btsl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTSL"
            self._gas_name = "btsl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xAB]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTSQ"
            self._gas_name = "btsq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTSQ"
            self._gas_name = "btsq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xAB]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: BTS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BTR(Instruction):
    """Bit Test and Reset"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BTR(r16/m16, imm8)
            * BTR(r16/m16, r16)
            * BTR(r32/m32, imm8)
            * BTR(r32/m32, r32)
            * BTR(r64/m64, imm8)
            * BTR(r64/m64, r64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BTR, self).__init__("BTR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BTR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTRW"
            self._gas_name = "btrw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTRW"
            self._gas_name = "btrw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xB3, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTRL"
            self._gas_name = "btrl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTRL"
            self._gas_name = "btrl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xB3, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTRQ"
            self._gas_name = "btrq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x0F, 0xBA, 0xF0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTRQ"
            self._gas_name = "btrq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xB3, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTRW"
            self._gas_name = "btrw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTRW"
            self._gas_name = "btrw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xB3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTRL"
            self._gas_name = "btrl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTRL"
            self._gas_name = "btrl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xB3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTRQ"
            self._gas_name = "btrq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(6, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTRQ"
            self._gas_name = "btrq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xB3]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: BTR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BTC(Instruction):
    """Bit Test and Complement"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BTC(r16/m16, imm8)
            * BTC(r16/m16, r16)
            * BTC(r32/m32, imm8)
            * BTC(r32/m32, r32)
            * BTC(r64/m64, imm8)
            * BTC(r64/m64, r64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BTC, self).__init__("BTC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BTC\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTCW"
            self._gas_name = "btcw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTCW"
            self._gas_name = "btcw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xBB, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTCL"
            self._gas_name = "btcl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x0F, 0xBA, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTCL"
            self._gas_name = "btcl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xBB, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTCQ"
            self._gas_name = "btcq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x0F, 0xBA, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTCQ"
            self._gas_name = "btcq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xBB, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTCW"
            self._gas_name = "btcw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BTCW"
            self._gas_name = "btcw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xBB]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTCL"
            self._gas_name = "btcl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BTCL"
            self._gas_name = "btcl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xBB]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "BTCQ"
            self._gas_name = "btcq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x0F, 0xBA]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BTCQ"
            self._gas_name = "btcq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xBB]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: BTC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class POPCNT(Instruction):
    """Count of Number of Bits Set to 1"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * POPCNT(r16, r16/m16)    [POPCNT]
            * POPCNT(r32, r32/m32)    [POPCNT]
            * POPCNT(r64, r64/m64)    [POPCNT]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(POPCNT, self).__init__("POPCNT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"POPCNT\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.popcnt])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "popcntw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xB8, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "popcntw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB8]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "popcntl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xB8, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "popcntl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB8]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "popcntq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xB8, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "popcntq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xB8]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: POPCNT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BSWAP(Instruction):
    """Byte Swap"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BSWAP(r32)
            * BSWAP(r64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BSWAP, self).__init__("BSWAP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"BSWAP\" requires 1 operands")
        self.in_regs = (True,)
        self.out_regs = (True,)
        self.out_operands = (True,)
        if is_r32(self.operands[0]):
            self.go_name = "BSWAPL"
            self._gas_name = "bswapl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x0F, 0xC8 | op[0].lcode])))
        elif is_r64(self.operands[0]):
            self.go_name = "BSWAPQ"
            self._gas_name = "bswapq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0x0F, 0xC8 | op[0].lcode])))
        else:
            raise SyntaxError("Invalid operand types: BSWAP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BSF(Instruction):
    """Bit Scan Forward"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BSF(r16, r16/m16)
            * BSF(r32, r32/m32)
            * BSF(r64, r64/m64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BSF, self).__init__("BSF", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BSF\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BSFW"
            self._gas_name = "bsfw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "BSFW"
            self._gas_name = "bsfw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BSFL"
            self._gas_name = "bsfl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "BSFL"
            self._gas_name = "bsfl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BSFQ"
            self._gas_name = "bsfq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "BSFQ"
            self._gas_name = "bsfq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BSF " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BSR(Instruction):
    """Bit Scan Reverse"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BSR(r16, r16/m16)
            * BSR(r32, r32/m32)
            * BSR(r64, r64/m64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BSR, self).__init__("BSR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BSR\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "BSRW"
            self._gas_name = "bsrw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "BSRW"
            self._gas_name = "bsrw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "BSRL"
            self._gas_name = "bsrl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "BSRL"
            self._gas_name = "bsrl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "BSRQ"
            self._gas_name = "bsrq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "BSRQ"
            self._gas_name = "bsrq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BSR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class LZCNT(Instruction):
    """Count the Number of Leading Zero Bits"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * LZCNT(r16, r16/m16)    [LZCNT]
            * LZCNT(r32, r32/m32)    [LZCNT]
            * LZCNT(r64, r64/m64)    [LZCNT]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(LZCNT, self).__init__("LZCNT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"LZCNT\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.lzcnt])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "lzcntw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "lzcntw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "lzcntl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "lzcntl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "lzcntq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "lzcntq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: LZCNT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class TZCNT(Instruction):
    """Count the Number of Trailing Zero Bits"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * TZCNT(r16, r16/m16)    [BMI]
            * TZCNT(r32, r32/m32)    [BMI]
            * TZCNT(r64, r64/m64)    [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(TZCNT, self).__init__("TZCNT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"TZCNT\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "tzcntw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "tzcntw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "tzcntl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "tzcntl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "tzcntq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "tzcntq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: TZCNT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SHR(Instruction):
    """Logical Shift Right"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SHR(r16/m16, cl)
            * SHR(r16/m16, imm8)
            * SHR(r32/m32, cl)
            * SHR(r32/m32, imm8)
            * SHR(r64/m64, cl)
            * SHR(r64/m64, imm8)
            * SHR(r8/m8, cl)
            * SHR(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SHR, self).__init__("SHR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"SHR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRB"
            self._gas_name = "shrb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xE8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRB"
            self._gas_name = "shrb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xE8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRW"
            self._gas_name = "shrw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xE8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRW"
            self._gas_name = "shrw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xE8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRL"
            self._gas_name = "shrl"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xE8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRL"
            self._gas_name = "shrl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xE8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRQ"
            self._gas_name = "shrq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xE8 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xE8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRQ"
            self._gas_name = "shrq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xE8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRB"
            self._gas_name = "shrb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRB"
            self._gas_name = "shrb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRW"
            self._gas_name = "shrw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRW"
            self._gas_name = "shrw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRL"
            self._gas_name = "shrl"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRL"
            self._gas_name = "shrl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHRQ"
            self._gas_name = "shrq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(5, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHRQ"
            self._gas_name = "shrq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: SHR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SAR(Instruction):
    """Arithmetic Shift Right"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SAR(r16/m16, cl)
            * SAR(r16/m16, imm8)
            * SAR(r32/m32, cl)
            * SAR(r32/m32, imm8)
            * SAR(r64/m64, cl)
            * SAR(r64/m64, imm8)
            * SAR(r8/m8, cl)
            * SAR(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SAR, self).__init__("SAR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"SAR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARB"
            self._gas_name = "sarb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xF8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARB"
            self._gas_name = "sarb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xF8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARW"
            self._gas_name = "sarw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xF8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARW"
            self._gas_name = "sarw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xF8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARL"
            self._gas_name = "sarl"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xF8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARL"
            self._gas_name = "sarl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xF8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARQ"
            self._gas_name = "sarq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xF8 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xF8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARQ"
            self._gas_name = "sarq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xF8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARB"
            self._gas_name = "sarb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARB"
            self._gas_name = "sarb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARW"
            self._gas_name = "sarw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARW"
            self._gas_name = "sarw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARL"
            self._gas_name = "sarl"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARL"
            self._gas_name = "sarl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SARQ"
            self._gas_name = "sarq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(7, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SARQ"
            self._gas_name = "sarq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: SAR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SHL(Instruction):
    """Logical Shift Left"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SHL(r16/m16, cl)
            * SHL(r16/m16, imm8)
            * SHL(r32/m32, cl)
            * SHL(r32/m32, imm8)
            * SHL(r64/m64, cl)
            * SHL(r64/m64, imm8)
            * SHL(r8/m8, cl)
            * SHL(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SHL, self).__init__("SHL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"SHL\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLB"
            self._gas_name = "shlb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xE0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLB"
            self._gas_name = "shlb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLW"
            self._gas_name = "shlw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xE0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLW"
            self._gas_name = "shlw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLL"
            self._gas_name = "shll"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xE0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLL"
            self._gas_name = "shll"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLQ"
            self._gas_name = "shlq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xE0 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLQ"
            self._gas_name = "shlq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLB"
            self._gas_name = "shlb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLB"
            self._gas_name = "shlb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLW"
            self._gas_name = "shlw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLW"
            self._gas_name = "shlw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLL"
            self._gas_name = "shll"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLL"
            self._gas_name = "shll"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SHLQ"
            self._gas_name = "shlq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SHLQ"
            self._gas_name = "shlq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: SHL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SAL(Instruction):
    """Arithmetic Shift Left"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SAL(r16/m16, cl)
            * SAL(r16/m16, imm8)
            * SAL(r32/m32, cl)
            * SAL(r32/m32, imm8)
            * SAL(r64/m64, cl)
            * SAL(r64/m64, imm8)
            * SAL(r8/m8, cl)
            * SAL(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SAL, self).__init__("SAL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"SAL\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALB"
            self._gas_name = "salb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xE0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALB"
            self._gas_name = "salb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALW"
            self._gas_name = "salw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xE0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALW"
            self._gas_name = "salw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALL"
            self._gas_name = "sall"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xE0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALL"
            self._gas_name = "sall"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALQ"
            self._gas_name = "salq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xE0 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xE0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALQ"
            self._gas_name = "salq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xE0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALB"
            self._gas_name = "salb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALB"
            self._gas_name = "salb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALW"
            self._gas_name = "salw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALW"
            self._gas_name = "salw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALL"
            self._gas_name = "sall"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALL"
            self._gas_name = "sall"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "SALQ"
            self._gas_name = "salq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(4, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "SALQ"
            self._gas_name = "salq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: SAL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SHRX(Instruction):
    """Logical Shift Right Without Affecting Flags"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SHRX(r32, r32/m32, r32)    [BMI2]
            * SHRX(r64, r64/m64, r64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SHRX, self).__init__("SHRX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"SHRX\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "shrxl"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x7B ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "shrxl"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x03, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "shrxq"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xFB ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "shrxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x83, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: SHRX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SARX(Instruction):
    """Arithmetic Shift Right Without Affecting Flags"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SARX(r32, r32/m32, r32)    [BMI2]
            * SARX(r64, r64/m64, r64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SARX, self).__init__("SARX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"SARX\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "sarxl"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x7A ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "sarxl"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x02, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "sarxq"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xFA ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "sarxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x82, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: SARX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SHLX(Instruction):
    """Logical Shift Left Without Affecting Flags"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SHLX(r32, r32/m32, r32)    [BMI2]
            * SHLX(r64, r64/m64, r64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SHLX, self).__init__("SHLX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"SHLX\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "shlxl"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x79 ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "shlxl"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x01, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "shlxq"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xF9 ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "shlxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x81, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: SHLX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SHRD(Instruction):
    """Integer Double Precision Shift Right"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SHRD(r16/m16, r16, cl)
            * SHRD(r16/m16, r16, imm8)
            * SHRD(r32/m32, r32, cl)
            * SHRD(r32/m32, r32, imm8)
            * SHRD(r64/m64, r64, cl)
            * SHRD(r64/m64, r64, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SHRD, self).__init__("SHRD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"SHRD\" requires 3 operands")
        self.out_operands = (True, False, False)
        if is_r16(self.operands[0]) and is_r16(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shrdw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xAC, 0xC0 | op[1].lcode << 3 | op[0].lcode, op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (True, False, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shrdw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xAD, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True, True)
            self.out_regs = (True, False, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shrdl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xAC, 0xC0 | op[1].lcode << 3 | op[0].lcode, op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (True, False, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shrdl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xAD, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True, True)
            self.out_regs = (True, False, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shrdq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xAC, 0xC0 | op[1].lcode << 3 | op[0].lcode, op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (True, False, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shrdq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xAD, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True, True)
            self.out_regs = (True, False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shrdw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xAC]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (False, False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shrdw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xAD]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True, True)
            self.out_regs = (False, False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shrdl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xAC]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (False, False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shrdl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xAD]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True, True)
            self.out_regs = (False, False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shrdq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xAC]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (False, False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shrdq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xAD]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True, True)
            self.out_regs = (False, False, False)
        else:
            raise SyntaxError("Invalid operand types: SHRD " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SHLD(Instruction):
    """Integer Double Precision Shift Left"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SHLD(r16/m16, r16, cl)
            * SHLD(r16/m16, r16, imm8)
            * SHLD(r32/m32, r32, cl)
            * SHLD(r32/m32, r32, imm8)
            * SHLD(r64/m64, r64, cl)
            * SHLD(r64/m64, r64, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SHLD, self).__init__("SHLD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"SHLD\" requires 3 operands")
        self.out_operands = (True, False, False)
        if is_r16(self.operands[0]) and is_r16(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shldw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xA4, 0xC0 | op[1].lcode << 3 | op[0].lcode, op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (True, False, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shldw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xA5, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True, True)
            self.out_regs = (True, False, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shldl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xA4, 0xC0 | op[1].lcode << 3 | op[0].lcode, op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (True, False, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shldl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xA5, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True, True)
            self.out_regs = (True, False, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shldq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xA4, 0xC0 | op[1].lcode << 3 | op[0].lcode, op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (True, False, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shldq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xA5, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.in_regs = (True, True, True)
            self.out_regs = (True, False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shldw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xA4]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (False, False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shldw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xA5]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True, True)
            self.out_regs = (False, False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shldl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xA4]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (False, False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shldl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xA5]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True, True)
            self.out_regs = (False, False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "shldq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xA4]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
            self.in_regs = (True, True, False)
            self.out_regs = (False, False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]) and is_cl(self.operands[2]):
            self._gas_name = "shldq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xA5]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.in_regs = (True, True, True)
            self.out_regs = (False, False, False)
        else:
            raise SyntaxError("Invalid operand types: SHLD " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class ROR(Instruction):
    """Rotate Right"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ROR(r16/m16, cl)
            * ROR(r16/m16, imm8)
            * ROR(r32/m32, cl)
            * ROR(r32/m32, imm8)
            * ROR(r64/m64, cl)
            * ROR(r64/m64, imm8)
            * ROR(r8/m8, cl)
            * ROR(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ROR, self).__init__("ROR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"ROR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORB"
            self._gas_name = "rorb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xC8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORB"
            self._gas_name = "rorb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xC8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORW"
            self._gas_name = "rorw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xC8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORW"
            self._gas_name = "rorw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xC8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORL"
            self._gas_name = "rorl"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xC8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORL"
            self._gas_name = "rorl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xC8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORQ"
            self._gas_name = "rorq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xC8 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xC8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORQ"
            self._gas_name = "rorq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xC8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORB"
            self._gas_name = "rorb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORB"
            self._gas_name = "rorb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORW"
            self._gas_name = "rorw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORW"
            self._gas_name = "rorw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORL"
            self._gas_name = "rorl"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORL"
            self._gas_name = "rorl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RORQ"
            self._gas_name = "rorq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(1, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RORQ"
            self._gas_name = "rorq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: ROR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class ROL(Instruction):
    """Rotate Left"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * ROL(r16/m16, cl)
            * ROL(r16/m16, imm8)
            * ROL(r32/m32, cl)
            * ROL(r32/m32, imm8)
            * ROL(r64/m64, cl)
            * ROL(r64/m64, imm8)
            * ROL(r8/m8, cl)
            * ROL(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(ROL, self).__init__("ROL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"ROL\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLB"
            self._gas_name = "rolb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xC0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLB"
            self._gas_name = "rolb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xC0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLW"
            self._gas_name = "rolw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xC0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLW"
            self._gas_name = "rolw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xC0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLL"
            self._gas_name = "roll"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xC0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLL"
            self._gas_name = "roll"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xC0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLQ"
            self._gas_name = "rolq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xC0 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xC0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLQ"
            self._gas_name = "rolq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xC0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLB"
            self._gas_name = "rolb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLB"
            self._gas_name = "rolb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLW"
            self._gas_name = "rolw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLW"
            self._gas_name = "rolw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLL"
            self._gas_name = "roll"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLL"
            self._gas_name = "roll"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "ROLQ"
            self._gas_name = "rolq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(0, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "ROLQ"
            self._gas_name = "rolq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: ROL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class RORX(Instruction):
    """Rotate Right Logical Without Affecting Flags"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * RORX(r32, r32/m32, imm8)    [BMI2]
            * RORX(r64, r64/m64, imm8)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RORX, self).__init__("RORX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"RORX\" requires 3 operands")
        self.in_regs = (False, True, False)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "rorxl"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE3 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x7B, 0xF0, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "rorxl"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b11, 0x03, op[0].hcode, op[1].address) + bytearray([0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "rorxq"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE3 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xFB, 0xF0, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm8(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm8")
            self._gas_name = "rorxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b11, 0x83, op[0].hcode, op[1].address) + bytearray([0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: RORX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class RCR(Instruction):
    """Rotate Right through Carry Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * RCR(r16/m16, cl)
            * RCR(r16/m16, imm8)
            * RCR(r32/m32, cl)
            * RCR(r32/m32, imm8)
            * RCR(r64/m64, cl)
            * RCR(r64/m64, imm8)
            * RCR(r8/m8, cl)
            * RCR(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RCR, self).__init__("RCR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"RCR\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRB"
            self._gas_name = "rcrb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xD8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRB"
            self._gas_name = "rcrb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xD8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRW"
            self._gas_name = "rcrw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xD8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRW"
            self._gas_name = "rcrw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xD8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRL"
            self._gas_name = "rcrl"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xD8 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRL"
            self._gas_name = "rcrl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xD8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRQ"
            self._gas_name = "rcrq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xD8 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xD8 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRQ"
            self._gas_name = "rcrq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xD8 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRB"
            self._gas_name = "rcrb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRB"
            self._gas_name = "rcrb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRW"
            self._gas_name = "rcrw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRW"
            self._gas_name = "rcrw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRL"
            self._gas_name = "rcrl"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRL"
            self._gas_name = "rcrl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCRQ"
            self._gas_name = "rcrq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(3, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCRQ"
            self._gas_name = "rcrq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: RCR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class RCL(Instruction):
    """Rotate Left through Carry Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * RCL(r16/m16, cl)
            * RCL(r16/m16, imm8)
            * RCL(r32/m32, cl)
            * RCL(r32/m32, imm8)
            * RCL(r64/m64, cl)
            * RCL(r64/m64, imm8)
            * RCL(r8/m8, cl)
            * RCL(r8/m8, imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RCL, self).__init__("RCL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"RCL\" requires 2 operands")
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLB"
            self._gas_name = "rclb"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD0, 0xD0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xC0, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLB"
            self._gas_name = "rclb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xD2, 0xD0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLW"
            self._gas_name = "rclw"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD1, 0xD0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xC1, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLW"
            self._gas_name = "rclw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xD3, 0xD0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLL"
            self._gas_name = "rcll"
            if self.operands[1] == 1:
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD1, 0xD0 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xC1, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLL"
            self._gas_name = "rcll"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xD3, 0xD0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLQ"
            self._gas_name = "rclq"
            if self.operands[1] == 1:
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD1, 0xD0 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xC1, 0xD0 | op[0].lcode, op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLQ"
            self._gas_name = "rclq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xD3, 0xD0 | op[0].lcode])))
            self.in_regs = (True, True)
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLB"
            self._gas_name = "rclb"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD0]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC0]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m8(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLB"
            self._gas_name = "rclb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD2]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLW"
            self._gas_name = "rclw"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLW"
            self._gas_name = "rclw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLL"
            self._gas_name = "rcll"
            if self.operands[1] == 1:
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD1]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xC1]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLL"
            self._gas_name = "rcll"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xD3]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_imm(self.operands[1]):
            if not is_imm8(self.operands[1]):
                raise ValueError("Argument #1 can not be encoded as imm8")
            self.go_name = "RCLQ"
            self._gas_name = "rclq"
            if self.operands[1] == 1:
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD1]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xC1]) + modrm_sib_disp(2, op[0].address, sib, min_disp) + bytearray([op[1] & 0xFF])))
            self.in_regs = (True, False)
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_cl(self.operands[1]):
            self.go_name = "RCLQ"
            self._gas_name = "rclq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xD3]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True, True)
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: RCL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class IMUL(Instruction):
    """Signed Multiply"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * IMUL(r16, r16/m16)
            * IMUL(r16, r16/m16, imm16)
            * IMUL(r16/m16)
            * IMUL(r32, r32/m32)
            * IMUL(r32, r32/m32, imm32)
            * IMUL(r32/m32)
            * IMUL(r64, r64/m64)
            * IMUL(r64, r64/m64, imm32)
            * IMUL(r64/m64)
            * IMUL(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(IMUL, self).__init__("IMUL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) == 1:
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            if is_r8(self.operands[0]):
                self.go_name = "IMULB"
                self._gas_name = "imulb"
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xE8 | op[0].lcode])))
                self._implicit_in_regs = {0: 1}
                self._implicit_out_regs = {0: 3}
            elif is_r16(self.operands[0]):
                self.go_name = "IMULW"
                self._gas_name = "imulw"
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xE8 | op[0].lcode])))
                self._implicit_in_regs = {0: 3}
                self._implicit_out_regs = {0: 3, 2: 3}
            elif is_r32(self.operands[0]):
                self.go_name = "IMULL"
                self._gas_name = "imull"
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xE8 | op[0].lcode])))
                self._implicit_in_regs = {0: 7}
                self._implicit_out_regs = {0: 7, 2: 7}
            elif is_r64(self.operands[0]):
                self.go_name = "IMULQ"
                self._gas_name = "imulq"
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xE8 | op[0].lcode])))
                self._implicit_in_regs = {0: 15}
                self._implicit_out_regs = {0: 15, 2: 15}
            elif is_m8(self.operands[0]):
                self.go_name = "IMULB"
                self._gas_name = "imulb"
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
                self._implicit_in_regs = {0: 1}
                self._implicit_out_regs = {0: 3}
            elif is_m16(self.operands[0]):
                self.go_name = "IMULW"
                self._gas_name = "imulw"
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
                self._implicit_in_regs = {0: 3}
                self._implicit_out_regs = {0: 3, 2: 3}
            elif is_m32(self.operands[0]):
                self.go_name = "IMULL"
                self._gas_name = "imull"
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
                self._implicit_in_regs = {0: 7}
                self._implicit_out_regs = {0: 7, 2: 7}
            elif is_m64(self.operands[0]):
                self.go_name = "IMULQ"
                self._gas_name = "imulq"
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(5, op[0].address, sib, min_disp)))
                self._implicit_in_regs = {0: 15}
                self._implicit_out_regs = {0: 15, 2: 15}
            else:
                raise SyntaxError("Invalid operand types: IMUL " + ", ".join(map(format_operand_type, self.operands)))
        elif len(self.operands) == 2:
            self.in_regs = (True, True)
            self.out_regs = (True, False)
            self.out_operands = (True, False)
            if is_r16(self.operands[0]) and is_r16(self.operands[1]):
                self.go_name = "IMULW"
                self._gas_name = "imulw"
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xAF, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
                self.go_name = "IMULW"
                self._gas_name = "imulw"
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xAF]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
                self.go_name = "IMULL"
                self._gas_name = "imull"
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xAF, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
                self.go_name = "IMULL"
                self._gas_name = "imull"
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xAF]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
                self.go_name = "IMULQ"
                self._gas_name = "imulq"
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xAF, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
                self.go_name = "IMULQ"
                self._gas_name = "imulq"
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xAF]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            else:
                raise SyntaxError("Invalid operand types: IMUL " + ", ".join(map(format_operand_type, self.operands)))
        elif len(self.operands) == 3:
            self.in_regs = (False, True, False)
            self.out_regs = (True, False, False)
            self.out_operands = (True, False, False)
            if is_r16(self.operands[0]) and is_r16(self.operands[1]) and is_imm(self.operands[2]):
                if not is_imm16(self.operands[2]):
                    raise ValueError("Argument #2 can not be encoded as imm16")
                self._gas_name = "imulw"
                if is_imm8(self.operands[2]):
                    self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x6B, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF])))
                self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x69, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF, (op[2] >> 8) & 0xFF])))
            elif is_r16(self.operands[0]) and is_m16(self.operands[1]) and is_imm(self.operands[2]):
                if not is_imm16(self.operands[2]):
                    raise ValueError("Argument #2 can not be encoded as imm16")
                self._gas_name = "imulw"
                if is_imm8(self.operands[2]):
                    self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x6B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x69]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF, (op[2] >> 8) & 0xFF])))
            elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
                if not is_imm32(self.operands[2]):
                    raise ValueError("Argument #2 can not be encoded as imm32")
                self._gas_name = "imull"
                if is_imm8(self.operands[2]):
                    self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x6B, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF])))
                self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x69, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_imm(self.operands[2]):
                if not is_imm32(self.operands[2]):
                    raise ValueError("Argument #2 can not be encoded as imm32")
                self._gas_name = "imull"
                if is_imm8(self.operands[2]):
                    self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x6B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
                self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x69]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
                if not is_imm32(self.operands[2]):
                    raise ValueError("Argument #2 can not be encoded as imm32")
                self.go_name = "IMUL3Q"
                self._gas_name = "imulq"
                if is_imm8(self.operands[2]):
                    self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x6B, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF])))
                self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x69, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_imm(self.operands[2]):
                if not is_imm32(self.operands[2]):
                    raise ValueError("Argument #2 can not be encoded as imm32")
                self.go_name = "IMUL3Q"
                self._gas_name = "imulq"
                if is_imm8(self.operands[2]):
                    self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x6B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF])))
                self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x69]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            else:
                raise SyntaxError("Invalid operand types: IMUL " + ", ".join(map(format_operand_type, self.operands)))
        else:
            raise SyntaxError("Invalid number of operands for instruction \"IMUL\"")
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MUL(Instruction):
    """Unsigned Multiply"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MUL(r16/m16)
            * MUL(r32/m32)
            * MUL(r64/m64)
            * MUL(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MUL, self).__init__("MUL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"MUL\" requires 1 operands")
        self.in_regs = (True,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_r8(self.operands[0]):
            self.go_name = "MULB"
            self._gas_name = "mulb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xE0 | op[0].lcode])))
            self._implicit_in_regs = {0: 1}
            self._implicit_out_regs = {0: 3}
        elif is_r16(self.operands[0]):
            self.go_name = "MULW"
            self._gas_name = "mulw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xE0 | op[0].lcode])))
            self._implicit_in_regs = {0: 3}
            self._implicit_out_regs = {0: 3, 2: 3}
        elif is_r32(self.operands[0]):
            self.go_name = "MULL"
            self._gas_name = "mull"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xE0 | op[0].lcode])))
            self._implicit_in_regs = {0: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
        elif is_r64(self.operands[0]):
            self.go_name = "MULQ"
            self._gas_name = "mulq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xE0 | op[0].lcode])))
            self._implicit_in_regs = {0: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
        elif is_m8(self.operands[0]):
            self.go_name = "MULB"
            self._gas_name = "mulb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 1}
            self._implicit_out_regs = {0: 3}
        elif is_m16(self.operands[0]):
            self.go_name = "MULW"
            self._gas_name = "mulw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 3}
            self._implicit_out_regs = {0: 3, 2: 3}
        elif is_m32(self.operands[0]):
            self.go_name = "MULL"
            self._gas_name = "mull"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
        elif is_m64(self.operands[0]):
            self.go_name = "MULQ"
            self._gas_name = "mulq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
        else:
            raise SyntaxError("Invalid operand types: MUL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MULX(Instruction):
    """Unsigned Multiply Without Affecting Flags"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MULX(r32, r32, r32/m32)    [BMI2]
            * MULX(r64, r64, r64/m64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MULX, self).__init__("MULX", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"MULX\" requires 3 operands")
        self.in_regs = (False, False, True)
        self.out_regs = (True, True, False)
        self.out_operands = (True, True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self._gas_name = "mulxl"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0x7B ^ (op[1].hlcode << 3), 0xF6, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
            self._implicit_in_regs = {2: 7}
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_m32(self.operands[2]):
            self._gas_name = "mulxl"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x03, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF6]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
            self._implicit_in_regs = {2: 7}
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self._gas_name = "mulxq"
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0xFB ^ (op[1].hlcode << 3), 0xF6, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
            self._implicit_in_regs = {2: 15}
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_m64(self.operands[2]):
            self._gas_name = "mulxq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x83, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF6]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
            self._implicit_in_regs = {2: 15}
        else:
            raise SyntaxError("Invalid operand types: MULX " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class IDIV(Instruction):
    """Signed Divide"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * IDIV(r16/m16)
            * IDIV(r32/m32)
            * IDIV(r64/m64)
            * IDIV(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(IDIV, self).__init__("IDIV", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"IDIV\" requires 1 operands")
        self.in_regs = (True,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_r8(self.operands[0]):
            self.go_name = "IDIVB"
            self._gas_name = "idivb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xF8 | op[0].lcode])))
            self._implicit_in_regs = {0: 3}
            self._implicit_out_regs = {0: 3}
        elif is_r16(self.operands[0]):
            self.go_name = "IDIVW"
            self._gas_name = "idivw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xF8 | op[0].lcode])))
            self._implicit_in_regs = {0: 3, 2: 3}
            self._implicit_out_regs = {0: 3, 2: 3}
        elif is_r32(self.operands[0]):
            self.go_name = "IDIVL"
            self._gas_name = "idivl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xF8 | op[0].lcode])))
            self._implicit_in_regs = {0: 7, 2: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
        elif is_r64(self.operands[0]):
            self.go_name = "IDIVQ"
            self._gas_name = "idivq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xF8 | op[0].lcode])))
            self._implicit_in_regs = {0: 15, 2: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
        elif is_m8(self.operands[0]):
            self.go_name = "IDIVB"
            self._gas_name = "idivb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 3}
            self._implicit_out_regs = {0: 3}
        elif is_m16(self.operands[0]):
            self.go_name = "IDIVW"
            self._gas_name = "idivw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 3, 2: 3}
            self._implicit_out_regs = {0: 3, 2: 3}
        elif is_m32(self.operands[0]):
            self.go_name = "IDIVL"
            self._gas_name = "idivl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 7, 2: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
        elif is_m64(self.operands[0]):
            self.go_name = "IDIVQ"
            self._gas_name = "idivq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 15, 2: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
        else:
            raise SyntaxError("Invalid operand types: IDIV " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class DIV(Instruction):
    """Unsigned Divide"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * DIV(r16/m16)
            * DIV(r32/m32)
            * DIV(r64/m64)
            * DIV(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(DIV, self).__init__("DIV", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"DIV\" requires 1 operands")
        self.in_regs = (True,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_r8(self.operands[0]):
            self.go_name = "DIVB"
            self._gas_name = "divb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0xF6, 0xF0 | op[0].lcode])))
            self._implicit_in_regs = {0: 3}
            self._implicit_out_regs = {0: 3}
        elif is_r16(self.operands[0]):
            self.go_name = "DIVW"
            self._gas_name = "divw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xF7, 0xF0 | op[0].lcode])))
            self._implicit_in_regs = {0: 3, 2: 3}
            self._implicit_out_regs = {0: 3, 2: 3}
        elif is_r32(self.operands[0]):
            self.go_name = "DIVL"
            self._gas_name = "divl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xF7, 0xF0 | op[0].lcode])))
            self._implicit_in_regs = {0: 7, 2: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
        elif is_r64(self.operands[0]):
            self.go_name = "DIVQ"
            self._gas_name = "divq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode, 0xF7, 0xF0 | op[0].lcode])))
            self._implicit_in_regs = {0: 15, 2: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
        elif is_m8(self.operands[0]):
            self.go_name = "DIVB"
            self._gas_name = "divb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF6]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 3}
            self._implicit_out_regs = {0: 3}
        elif is_m16(self.operands[0]):
            self.go_name = "DIVW"
            self._gas_name = "divw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 3, 2: 3}
            self._implicit_out_regs = {0: 3, 2: 3}
        elif is_m32(self.operands[0]):
            self.go_name = "DIVL"
            self._gas_name = "divl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xF7]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 7, 2: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
        elif is_m64(self.operands[0]):
            self.go_name = "DIVQ"
            self._gas_name = "divq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0xF7]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 15, 2: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
        else:
            raise SyntaxError("Invalid operand types: DIV " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class LEA(Instruction):
    """Load Effective Address"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * LEA(r16, m)
            * LEA(r32, m)
            * LEA(r64, m)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(LEA, self).__init__("LEA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"LEA\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        if is_r16(self.operands[0]) and is_m(self.operands[1]):
            self.go_name = "LEAW"
            self._gas_name = "leaw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x8D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_m(self.operands[1]):
            self.go_name = "LEAL"
            self._gas_name = "leal"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x8D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_m(self.operands[1]):
            self.go_name = "LEAQ"
            self._gas_name = "leaq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x8D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: LEA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PUSH(Instruction):
    """Push Value Onto the Stack"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PUSH(imm32)
            * PUSH(r16/m16)
            * PUSH(r64/m64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PUSH, self).__init__("PUSH", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PUSH\" requires 1 operands")
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_imm(self.operands[0]):
            if not is_imm32(self.operands[0], ext_size=8):
                raise ValueError("Argument #0 can not be encoded as imm32")
            self.go_name = "PUSHQ"
            self._gas_name = "pushq"
            if is_imm8(self.operands[0], ext_size=8):
                self.encodings.append((0x00, lambda op: bytearray([0x6A, op[0] & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x68, op[0] & 0xFF, (op[0] >> 8) & 0xFF, (op[0] >> 16) & 0xFF, (op[0] >> 24) & 0xFF])))
            self.in_regs = (False,)
        elif is_r16(self.operands[0]):
            self.go_name = "PUSHW"
            self._gas_name = "pushw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x50 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0xFF, 0xF0 | op[0].lcode])))
            self.in_regs = (True,)
        elif is_r64(self.operands[0]):
            self.go_name = "PUSHQ"
            self._gas_name = "pushq"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x50 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xFF, 0xF0 | op[0].lcode])))
            self.in_regs = (True,)
        elif is_m16(self.operands[0]):
            self.go_name = "PUSHW"
            self._gas_name = "pushw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
        elif is_m64(self.operands[0]):
            self.go_name = "PUSHQ"
            self._gas_name = "pushq"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
        else:
            raise SyntaxError("Invalid operand types: PUSH " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class POP(Instruction):
    """Pop a Value from the Stack"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * POP(r16/m16)
            * POP(r64/m64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(POP, self).__init__("POP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"POP\" requires 1 operands")
        self.out_operands = (True,)
        if is_r16(self.operands[0]):
            self.go_name = "POPW"
            self._gas_name = "popw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x58 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x8F, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_r64(self.operands[0]):
            self.go_name = "POPQ"
            self._gas_name = "popq"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x58 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x8F, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m16(self.operands[0]):
            self.go_name = "POPW"
            self._gas_name = "popw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x8F]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        elif is_m64(self.operands[0]):
            self.go_name = "POPQ"
            self._gas_name = "popq"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x8F]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: POP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class POPCNT(Instruction):
    """Count of Number of Bits Set to 1"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * POPCNT(r16, r16/m16)    [POPCNT]
            * POPCNT(r32, r32/m32)    [POPCNT]
            * POPCNT(r64, r64/m64)    [POPCNT]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(POPCNT, self).__init__("POPCNT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"POPCNT\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.popcnt])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "popcntw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xB8, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "popcntw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB8]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "popcntl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xB8, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "popcntl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xB8]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "popcntq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xB8, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "popcntq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xB8]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: POPCNT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class LZCNT(Instruction):
    """Count the Number of Leading Zero Bits"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * LZCNT(r16, r16/m16)    [LZCNT]
            * LZCNT(r32, r32/m32)    [LZCNT]
            * LZCNT(r64, r64/m64)    [LZCNT]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(LZCNT, self).__init__("LZCNT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"LZCNT\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.lzcnt])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "lzcntw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "lzcntw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "lzcntl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "lzcntl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "lzcntq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBD, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "lzcntq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBD]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: LZCNT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class TZCNT(Instruction):
    """Count the Number of Trailing Zero Bits"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * TZCNT(r16, r16/m16)    [BMI]
            * TZCNT(r32, r32/m32)    [BMI]
            * TZCNT(r64, r64/m64)    [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(TZCNT, self).__init__("TZCNT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"TZCNT\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "tzcntw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "tzcntw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "tzcntl"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "tzcntl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF3]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self._gas_name = "tzcntq"
            self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0xBC, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self._gas_name = "tzcntq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF3]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0xBC]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: TZCNT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BEXTR(Instruction):
    """Bit Field Extract"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BEXTR(r32, r32/m32, imm32)    [TBM]
            * BEXTR(r32, r32/m32, r32)      [BMI]
            * BEXTR(r64, r64/m64, imm32)    [TBM]
            * BEXTR(r64, r64/m64, r64)      [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BEXTR, self).__init__("BEXTR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"BEXTR\" requires 3 operands")
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm32(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm32")
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xEA ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x78, 0x10, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            self.in_regs = (False, True, False)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm32(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm32")
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1010, 0x00, op[0].hcode, op[1].address) + bytearray([0x10]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            self.in_regs = (False, True, False)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm32(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm32")
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xEA ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xF8, 0x10, 0xC0 | op[0].lcode << 3 | op[1].lcode, op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            self.in_regs = (False, True, False)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_imm(self.operands[2]):
            if not is_imm32(self.operands[2]):
                raise ValueError("Argument #2 can not be encoded as imm32")
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1010, 0x80, op[0].hcode, op[1].address) + bytearray([0x10]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp) + bytearray([op[2] & 0xFF, (op[2] >> 8) & 0xFF, (op[2] >> 16) & 0xFF, (op[2] >> 24) & 0xFF])))
            self.in_regs = (False, True, False)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x78 ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (False, True, True)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_r32(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x00, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True, True)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xF8 ^ (op[2].hlcode << 3), 0xF7, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.in_regs = (False, True, True)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_r64(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x80, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF7]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.in_regs = (False, True, True)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        else:
            raise SyntaxError("Invalid operand types: BEXTR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PDEP(Instruction):
    """Parallel Bits Deposit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PDEP(r32, r32, r32/m32)    [BMI2]
            * PDEP(r64, r64, r64/m64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PDEP, self).__init__("PDEP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"PDEP\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0x7B ^ (op[1].hlcode << 3), 0xF5, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_m32(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x03, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF5]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0xFB ^ (op[1].hlcode << 3), 0xF5, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_m64(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x83, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF5]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: PDEP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PEXT(Instruction):
    """Parallel Bits Extract"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PEXT(r32, r32, r32/m32)    [BMI2]
            * PEXT(r64, r64, r64/m64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PEXT, self).__init__("PEXT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"PEXT\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0x7A ^ (op[1].hlcode << 3), 0xF5, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_m32(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x02, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF5]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5), 0xFA ^ (op[1].hlcode << 3), 0xF5, 0xC0 | op[0].lcode << 3 | op[2].lcode])))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_m64(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x82, op[0].hcode, op[2].address, op[1].hlcode) + bytearray([0xF5]) + modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: PEXT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BZHI(Instruction):
    """Zero High Bits Starting with Specified Bit Position"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BZHI(r32, r32/m32, r32)    [BMI2]
            * BZHI(r64, r64/m64, r64)    [BMI2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BZHI, self).__init__("BZHI", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 3:
            raise SyntaxError("Instruction \"BZHI\" requires 3 operands")
        self.in_regs = (False, True, True)
        self.out_regs = (True, False, False)
        self.out_operands = (True, False, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi2])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]) and is_r32(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0x78 ^ (op[2].hlcode << 3), 0xF5, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]) and is_r32(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x00, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF5]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]) and is_r64(self.operands[2]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5), 0xF8 ^ (op[2].hlcode << 3), 0xF5, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]) and is_r64(self.operands[2]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x80, op[0].hcode, op[1].address, op[2].hlcode) + bytearray([0xF5]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BZHI " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLCFILL(Instruction):
    """Fill From Lowest Clear Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLCFILL(r32, r32/m32)    [TBM]
            * BLCFILL(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLCFILL, self).__init__("BLCFILL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLCFILL\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xC8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(1, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xC8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(1, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLCFILL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLCI(Instruction):
    """Isolate Lowest Clear Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLCI(r32, r32/m32)    [TBM]
            * BLCI(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLCI, self).__init__("BLCI", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLCI\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x02, 0xF0 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x02]) + modrm_sib_disp(6, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x02, 0xF0 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x02]) + modrm_sib_disp(6, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLCI " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLCIC(Instruction):
    """Isolate Lowest Set Bit and Complement"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLCIC(r32, r32/m32)    [TBM]
            * BLCIC(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLCIC, self).__init__("BLCIC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLCIC\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xE8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(5, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xE8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(5, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLCIC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLCMSK(Instruction):
    """Mask From Lowest Clear Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLCMSK(r32, r32/m32)    [TBM]
            * BLCMSK(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLCMSK, self).__init__("BLCMSK", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLCMSK\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x02, 0xC8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x02]) + modrm_sib_disp(1, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x02, 0xC8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x02]) + modrm_sib_disp(1, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLCMSK " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLCS(Instruction):
    """Set Lowest Clear Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLCS(r32, r32/m32)    [TBM]
            * BLCS(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLCS, self).__init__("BLCS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLCS\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xD8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(3, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xD8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(3, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLCS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLSFILL(Instruction):
    """Fill From Lowest Set Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLSFILL(r32, r32/m32)    [TBM]
            * BLSFILL(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLSFILL, self).__init__("BLSFILL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLSFILL\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xD0 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(2, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xD0 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(2, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLSFILL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLSI(Instruction):
    """Isolate Lowest Set Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLSI(r32, r32/m32)    [BMI]
            * BLSI(r64, r64/m64)    [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLSI, self).__init__("BLSI", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLSI\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0xF3, 0xD8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0xF3]) + modrm_sib_disp(3, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0xF3, 0xD8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0xF3]) + modrm_sib_disp(3, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLSI " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLSIC(Instruction):
    """Isolate Lowest Set Bit and Complement"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLSIC(r32, r32/m32)    [TBM]
            * BLSIC(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLSIC, self).__init__("BLSIC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLSIC\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xF0 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(6, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xF0 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(6, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLSIC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLSMSK(Instruction):
    """Mask From Lowest Set Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLSMSK(r32, r32/m32)    [BMI]
            * BLSMSK(r64, r64/m64)    [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLSMSK, self).__init__("BLSMSK", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLSMSK\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0xF3, 0xD0 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0xF3]) + modrm_sib_disp(2, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0xF3, 0xD0 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0xF3]) + modrm_sib_disp(2, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLSMSK " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class BLSR(Instruction):
    """Reset Lowest Set Bit"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * BLSR(r32, r32/m32)    [BMI]
            * BLSR(r64, r64/m64)    [BMI]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(BLSR, self).__init__("BLSR", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"BLSR\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.bmi])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0xF3, 0xC8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0xF3]) + modrm_sib_disp(1, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0xC4, 0xE2 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0xF3, 0xC8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0xC4, 0b10, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0xF3]) + modrm_sib_disp(1, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: BLSR " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class T1MSKC(Instruction):
    """Inverse Mask From Trailing Ones"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * T1MSKC(r32, r32/m32)    [TBM]
            * T1MSKC(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(T1MSKC, self).__init__("T1MSKC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"T1MSKC\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xF8 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(7, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xF8 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(7, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: T1MSKC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class TZMSK(Instruction):
    """Mask From Trailing Zeros"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * TZMSK(r32, r32/m32)    [TBM]
            * TZMSK(r64, r64/m64)    [TBM]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(TZMSK, self).__init__("TZMSK", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"TZMSK\" requires 2 operands")
        self.in_regs = (False, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.tbm])
        if is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0x78 ^ (op[0].hlcode << 3), 0x01, 0xE0 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x00, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(4, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x8F, 0xE9 ^ (op[1].hcode << 5), 0xF8 ^ (op[0].hlcode << 3), 0x01, 0xE0 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: vex3(0x8F, 0b1001, 0x80, 0, op[1].address, op[0].hlcode) + bytearray([0x01]) + modrm_sib_disp(4, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: TZMSK " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CRC32(Instruction):
    """Accumulate CRC32 Value"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CRC32(r32, r16/m16)    [SSE4.2]
            * CRC32(r32, r32/m32)    [SSE4.2]
            * CRC32(r32, r8/m8)      [SSE4.2]
            * CRC32(r64, r64/m64)    [SSE4.2]
            * CRC32(r64, r8/m8)      [SSE4.2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CRC32, self).__init__("CRC32", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CRC32\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.sse4_2])
        if is_r32(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "CRC32B"
            self._gas_name = "crc32b"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF2]) + optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[1])) + bytearray([0x0F, 0x38, 0xF0, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_r16(self.operands[1]):
            self._gas_name = "crc32w"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66, 0xF2]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x38, 0xF1, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self._gas_name = "crc32l"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0xF2]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x38, 0xF1, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "CRC32B"
            self._gas_name = "crc32b"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF2]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_m16(self.operands[1]):
            self._gas_name = "crc32w"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66, 0xF2]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF1]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self._gas_name = "crc32l"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0xF2]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x38, 0xF1]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "CRC32B"
            self._gas_name = "crc32b"
            self.encodings.append((0x00, lambda op: bytearray([0xF2, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x38, 0xF0, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "CRC32Q"
            self._gas_name = "crc32q"
            self.encodings.append((0x00, lambda op: bytearray([0xF2, 0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x38, 0xF1, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "CRC32B"
            self._gas_name = "crc32b"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF2]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x38, 0xF0]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "CRC32Q"
            self._gas_name = "crc32q"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: bytearray([0xF2]) + rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x38, 0xF1]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CRC32 " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CBW(Instruction):
    """Convert Byte to Word"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CBW()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CBW, self).__init__("CBW", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CBW\" requires 0 operands")
        self._gas_name = "cbtw"
        self.encodings.append((0x00, lambda op: bytearray([0x66, 0x98])))
        self._implicit_in_regs = {0: 1}
        self._implicit_out_regs = {0: 3}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CDQ(Instruction):
    """Convert Doubleword to Quadword"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CDQ()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CDQ, self).__init__("CDQ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CDQ\" requires 0 operands")
        self._gas_name = "cltd"
        self.encodings.append((0x00, lambda op: bytearray([0x99])))
        self._implicit_in_regs = {0: 7}
        self._implicit_out_regs = {2: 7}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CQO(Instruction):
    """Convert Quadword to Octaword"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CQO()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CQO, self).__init__("CQO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CQO\" requires 0 operands")
        self._gas_name = "cqto"
        self.encodings.append((0x00, lambda op: bytearray([0x48, 0x99])))
        self._implicit_in_regs = {0: 15}
        self._implicit_out_regs = {2: 15}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CWD(Instruction):
    """Convert Word to Doubleword"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CWD()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CWD, self).__init__("CWD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CWD\" requires 0 operands")
        self._gas_name = "cwtd"
        self.encodings.append((0x00, lambda op: bytearray([0x66, 0x99])))
        self._implicit_in_regs = {0: 3}
        self._implicit_out_regs = {2: 3}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CWDE(Instruction):
    """Convert Word to Doubleword"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CWDE()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CWDE, self).__init__("CWDE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CWDE\" requires 0 operands")
        self._gas_name = "cwtl"
        self.encodings.append((0x00, lambda op: bytearray([0x98])))
        self._implicit_in_regs = {0: 3}
        self._implicit_out_regs = {0: 7}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CDQE(Instruction):
    """Convert Doubleword to Quadword"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CDQE()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CDQE, self).__init__("CDQE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CDQE\" requires 0 operands")
        self._gas_name = "cltq"
        self.encodings.append((0x00, lambda op: bytearray([0x48, 0x98])))
        self._implicit_in_regs = {0: 7}
        self._implicit_out_regs = {0: 15}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVA(Instruction):
    """Move if above (CF == 0 and ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVA(r16, r16/m16)    [CMOV]
            * CMOVA(r32, r32/m32)    [CMOV]
            * CMOVA(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVA, self).__init__("CMOVA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVA\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x47, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x47]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x47, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x47]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x47, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x47]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNA(Instruction):
    """Move if not above (CF == 1 or ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNA(r16, r16/m16)    [CMOV]
            * CMOVNA(r32, r32/m32)    [CMOV]
            * CMOVNA(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNA, self).__init__("CMOVNA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNA\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x46, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x46]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x46, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x46]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x46, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x46]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVAE(Instruction):
    """Move if above or equal (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVAE(r16, r16/m16)    [CMOV]
            * CMOVAE(r32, r32/m32)    [CMOV]
            * CMOVAE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVAE, self).__init__("CMOVAE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVAE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVAE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNAE(Instruction):
    """Move if not above or equal (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNAE(r16, r16/m16)    [CMOV]
            * CMOVNAE(r32, r32/m32)    [CMOV]
            * CMOVNAE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNAE, self).__init__("CMOVNAE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNAE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNAE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVB(Instruction):
    """Move if below (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVB(r16, r16/m16)    [CMOV]
            * CMOVB(r32, r32/m32)    [CMOV]
            * CMOVB(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVB, self).__init__("CMOVB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVB\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNB(Instruction):
    """Move if not below (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNB(r16, r16/m16)    [CMOV]
            * CMOVNB(r32, r32/m32)    [CMOV]
            * CMOVNB(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNB, self).__init__("CMOVNB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNB\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVBE(Instruction):
    """Move if below or equal (CF == 1 or ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVBE(r16, r16/m16)    [CMOV]
            * CMOVBE(r32, r32/m32)    [CMOV]
            * CMOVBE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVBE, self).__init__("CMOVBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVBE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x46, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x46]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x46, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x46]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x46, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x46]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNBE(Instruction):
    """Move if not below or equal (CF == 0 and ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNBE(r16, r16/m16)    [CMOV]
            * CMOVNBE(r32, r32/m32)    [CMOV]
            * CMOVNBE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNBE, self).__init__("CMOVNBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNBE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x47, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x47]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x47, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x47]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x47, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x47]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVC(Instruction):
    """Move if carry (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVC(r16, r16/m16)    [CMOV]
            * CMOVC(r32, r32/m32)    [CMOV]
            * CMOVC(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVC, self).__init__("CMOVC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVC\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x42, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x42]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNC(Instruction):
    """Move if not carry (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNC(r16, r16/m16)    [CMOV]
            * CMOVNC(r32, r32/m32)    [CMOV]
            * CMOVNC(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNC, self).__init__("CMOVNC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNC\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x43, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x43]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVE(Instruction):
    """Move if equal (ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVE(r16, r16/m16)    [CMOV]
            * CMOVE(r32, r32/m32)    [CMOV]
            * CMOVE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVE, self).__init__("CMOVE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x44, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x44]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x44, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x44]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x44, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x44]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNE(Instruction):
    """Move if not equal (ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNE(r16, r16/m16)    [CMOV]
            * CMOVNE(r32, r32/m32)    [CMOV]
            * CMOVNE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNE, self).__init__("CMOVNE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x45, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x45]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x45, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x45]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x45, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x45]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVG(Instruction):
    """Move if greater (ZF == 0 and SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVG(r16, r16/m16)    [CMOV]
            * CMOVG(r32, r32/m32)    [CMOV]
            * CMOVG(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVG, self).__init__("CMOVG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVG\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4F, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4F]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4F, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4F]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4F, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4F]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNG(Instruction):
    """Move if not greater (ZF == 1 or SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNG(r16, r16/m16)    [CMOV]
            * CMOVNG(r32, r32/m32)    [CMOV]
            * CMOVNG(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNG, self).__init__("CMOVNG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNG\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4E, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4E]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4E, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4E]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4E, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4E]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVGE(Instruction):
    """Move if greater or equal (SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVGE(r16, r16/m16)    [CMOV]
            * CMOVGE(r32, r32/m32)    [CMOV]
            * CMOVGE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVGE, self).__init__("CMOVGE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVGE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4D, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4D, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4D, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVGE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNGE(Instruction):
    """Move if not greater or equal (SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNGE(r16, r16/m16)    [CMOV]
            * CMOVNGE(r32, r32/m32)    [CMOV]
            * CMOVNGE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNGE, self).__init__("CMOVNGE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNGE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4C, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4C]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4C, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4C]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4C, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4C]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNGE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVL(Instruction):
    """Move if less (SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVL(r16, r16/m16)    [CMOV]
            * CMOVL(r32, r32/m32)    [CMOV]
            * CMOVL(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVL, self).__init__("CMOVL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVL\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4C, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4C]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4C, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4C]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4C, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4C]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNL(Instruction):
    """Move if not less (SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNL(r16, r16/m16)    [CMOV]
            * CMOVNL(r32, r32/m32)    [CMOV]
            * CMOVNL(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNL, self).__init__("CMOVNL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNL\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4D, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4D, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4D, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4D]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVLE(Instruction):
    """Move if less or equal (ZF == 1 or SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVLE(r16, r16/m16)    [CMOV]
            * CMOVLE(r32, r32/m32)    [CMOV]
            * CMOVLE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVLE, self).__init__("CMOVLE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVLE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4E, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4E]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4E, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4E]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4E, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4E]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVLE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNLE(Instruction):
    """Move if not less or equal (ZF == 0 and SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNLE(r16, r16/m16)    [CMOV]
            * CMOVNLE(r32, r32/m32)    [CMOV]
            * CMOVNLE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNLE, self).__init__("CMOVNLE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNLE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4F, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4F]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4F, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4F]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4F, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4F]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNLE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVO(Instruction):
    """Move if overflow (OF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVO(r16, r16/m16)    [CMOV]
            * CMOVO(r32, r32/m32)    [CMOV]
            * CMOVO(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVO, self).__init__("CMOVO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVO\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x40, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x40]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x40, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x40]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x40, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x40]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNO(Instruction):
    """Move if not overflow (OF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNO(r16, r16/m16)    [CMOV]
            * CMOVNO(r32, r32/m32)    [CMOV]
            * CMOVNO(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNO, self).__init__("CMOVNO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNO\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x41, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x41]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x41, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x41]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x41, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x41]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVP(Instruction):
    """Move if parity (PF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVP(r16, r16/m16)    [CMOV]
            * CMOVP(r32, r32/m32)    [CMOV]
            * CMOVP(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVP, self).__init__("CMOVP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVP\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNP(Instruction):
    """Move if not parity (PF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNP(r16, r16/m16)    [CMOV]
            * CMOVNP(r32, r32/m32)    [CMOV]
            * CMOVNP(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNP, self).__init__("CMOVNP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNP\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVS(Instruction):
    """Move if sign (SF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVS(r16, r16/m16)    [CMOV]
            * CMOVS(r32, r32/m32)    [CMOV]
            * CMOVS(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVS, self).__init__("CMOVS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVS\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x48, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x48]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x48, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x48]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x48, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x48]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNS(Instruction):
    """Move if not sign (SF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNS(r16, r16/m16)    [CMOV]
            * CMOVNS(r32, r32/m32)    [CMOV]
            * CMOVNS(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNS, self).__init__("CMOVNS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNS\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x49, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x49]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x49, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x49]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x49, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x49]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVZ(Instruction):
    """Move if zero (ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVZ(r16, r16/m16)    [CMOV]
            * CMOVZ(r32, r32/m32)    [CMOV]
            * CMOVZ(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVZ, self).__init__("CMOVZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVZ\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x44, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x44]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x44, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x44]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x44, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x44]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVNZ(Instruction):
    """Move if not zero (ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVNZ(r16, r16/m16)    [CMOV]
            * CMOVNZ(r32, r32/m32)    [CMOV]
            * CMOVNZ(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVNZ, self).__init__("CMOVNZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVNZ\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x45, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x45]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x45, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x45]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x45, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x45]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVNZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVPE(Instruction):
    """Move if parity even (PF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVPE(r16, r16/m16)    [CMOV]
            * CMOVPE(r32, r32/m32)    [CMOV]
            * CMOVPE(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVPE, self).__init__("CMOVPE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVPE\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4A, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4A]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVPE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMOVPO(Instruction):
    """Move if parity odd (PF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMOVPO(r16, r16/m16)    [CMOV]
            * CMOVPO(r32, r32/m32)    [CMOV]
            * CMOVPO(r64, r64/m64)    [CMOV]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMOVPO, self).__init__("CMOVPO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMOVPO\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_regs = (True, False)
        self.out_operands = (True, False)
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cmov])
        if is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x0F, 0x4B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x0F, 0x4B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x0F, 0x4B, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x0F, 0x4B]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
        else:
            raise SyntaxError("Invalid operand types: CMOVPO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETA(Instruction):
    """Set byte if above (CF == 0 and ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETA(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETA, self).__init__("SETA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETA\" requires 1 operands")
        self.go_name = "SETHI"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x97, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x97]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNA(Instruction):
    """Set byte if not above (CF == 1 or ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNA(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNA, self).__init__("SETNA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNA\" requires 1 operands")
        self.go_name = "SETLS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x96, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x96]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETAE(Instruction):
    """Set byte if above or equal (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETAE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETAE, self).__init__("SETAE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETAE\" requires 1 operands")
        self.go_name = "SETCC"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x93, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x93]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETAE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNAE(Instruction):
    """Set byte if not above or equal (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNAE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNAE, self).__init__("SETNAE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNAE\" requires 1 operands")
        self.go_name = "SETCS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x92, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x92]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNAE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETB(Instruction):
    """Set byte if below (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETB(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETB, self).__init__("SETB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETB\" requires 1 operands")
        self.go_name = "SETCS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x92, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x92]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNB(Instruction):
    """Set byte if not below (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNB(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNB, self).__init__("SETNB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNB\" requires 1 operands")
        self.go_name = "SETCC"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x93, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x93]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETBE(Instruction):
    """Set byte if below or equal (CF == 1 or ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETBE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETBE, self).__init__("SETBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETBE\" requires 1 operands")
        self.go_name = "SETLS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x96, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x96]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNBE(Instruction):
    """Set byte if not below or equal (CF == 0 and ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNBE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNBE, self).__init__("SETNBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNBE\" requires 1 operands")
        self.go_name = "SETHI"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x97, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x97]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETC(Instruction):
    """Set byte if carry (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETC(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETC, self).__init__("SETC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETC\" requires 1 operands")
        self.go_name = "SETCS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x92, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x92]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNC(Instruction):
    """Set byte if not carry (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNC(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNC, self).__init__("SETNC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNC\" requires 1 operands")
        self.go_name = "SETCC"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x93, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x93]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETE(Instruction):
    """Set byte if equal (ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETE, self).__init__("SETE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETE\" requires 1 operands")
        self.go_name = "SETEQ"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x94, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x94]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNE(Instruction):
    """Set byte if not equal (ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNE, self).__init__("SETNE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNE\" requires 1 operands")
        self.go_name = "SETNE"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x95, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x95]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETG(Instruction):
    """Set byte if greater (ZF == 0 and SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETG(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETG, self).__init__("SETG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETG\" requires 1 operands")
        self.go_name = "SETGT"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9F, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9F]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNG(Instruction):
    """Set byte if not greater (ZF == 1 or SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNG(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNG, self).__init__("SETNG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNG\" requires 1 operands")
        self.go_name = "SETLE"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9E, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9E]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETGE(Instruction):
    """Set byte if greater or equal (SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETGE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETGE, self).__init__("SETGE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETGE\" requires 1 operands")
        self.go_name = "SETGE"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9D, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9D]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETGE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNGE(Instruction):
    """Set byte if not greater or equal (SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNGE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNGE, self).__init__("SETNGE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNGE\" requires 1 operands")
        self.go_name = "SETLT"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9C, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9C]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNGE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETL(Instruction):
    """Set byte if less (SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETL(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETL, self).__init__("SETL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETL\" requires 1 operands")
        self.go_name = "SETLT"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9C, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9C]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNL(Instruction):
    """Set byte if not less (SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNL(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNL, self).__init__("SETNL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNL\" requires 1 operands")
        self.go_name = "SETGE"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9D, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9D]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETLE(Instruction):
    """Set byte if less or equal (ZF == 1 or SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETLE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETLE, self).__init__("SETLE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETLE\" requires 1 operands")
        self.go_name = "SETLE"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9E, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9E]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETLE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNLE(Instruction):
    """Set byte if not less or equal (ZF == 0 and SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNLE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNLE, self).__init__("SETNLE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNLE\" requires 1 operands")
        self.go_name = "SETGT"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9F, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9F]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNLE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETO(Instruction):
    """Set byte if overflow (OF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETO(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETO, self).__init__("SETO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETO\" requires 1 operands")
        self.go_name = "SETOS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x90, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x90]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNO(Instruction):
    """Set byte if not overflow (OF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNO(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNO, self).__init__("SETNO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNO\" requires 1 operands")
        self.go_name = "SETOC"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x91, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x91]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETP(Instruction):
    """Set byte if parity (PF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETP(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETP, self).__init__("SETP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETP\" requires 1 operands")
        self.go_name = "SETPS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9A, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9A]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNP(Instruction):
    """Set byte if not parity (PF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNP(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNP, self).__init__("SETNP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNP\" requires 1 operands")
        self.go_name = "SETPC"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9B, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9B]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETS(Instruction):
    """Set byte if sign (SF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETS(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETS, self).__init__("SETS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETS\" requires 1 operands")
        self.go_name = "SETMI"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x98, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x98]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNS(Instruction):
    """Set byte if not sign (SF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNS(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNS, self).__init__("SETNS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNS\" requires 1 operands")
        self.go_name = "SETPL"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x99, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x99]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETZ(Instruction):
    """Set byte if zero (ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETZ(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETZ, self).__init__("SETZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETZ\" requires 1 operands")
        self.go_name = "SETEQ"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x94, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x94]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETNZ(Instruction):
    """Set byte if not zero (ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETNZ(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETNZ, self).__init__("SETNZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETNZ\" requires 1 operands")
        self.go_name = "SETNE"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x95, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x95]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETNZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETPE(Instruction):
    """Set byte if parity even (PF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETPE(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETPE, self).__init__("SETPE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETPE\" requires 1 operands")
        self.go_name = "SETPS"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9A, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9A]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETPE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SETPO(Instruction):
    """Set byte if parity odd (PF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SETPO(r8/m8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SETPO, self).__init__("SETPO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"SETPO\" requires 1 operands")
        self.go_name = "SETPC"
        self.out_operands = (True,)
        if is_r8(self.operands[0]):
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex or is_r8rex(op[0])) + bytearray([0x0F, 0x9B, 0xC0 | op[0].lcode])))
            self.in_regs = (False,)
            self.out_regs = (True,)
        elif is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x9B]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
        else:
            raise SyntaxError("Invalid operand types: SETPO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JA(BranchInstruction):
    """Jump if above (CF == 0 and ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JA(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JA, self).__init__("JA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JA\" requires 1 operands")
        self.go_name = "JHI"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x77, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x87, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x87, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x77, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNA(BranchInstruction):
    """Jump if not above (CF == 1 or ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNA(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNA, self).__init__("JNA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNA\" requires 1 operands")
        self.go_name = "JLS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x76, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x86, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x86, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x76, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JAE(BranchInstruction):
    """Jump if above or equal (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JAE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JAE, self).__init__("JAE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JAE\" requires 1 operands")
        self.go_name = "JCC"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x73, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x83, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x83, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x73, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JAE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNAE(BranchInstruction):
    """Jump if not above or equal (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNAE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNAE, self).__init__("JNAE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNAE\" requires 1 operands")
        self.go_name = "JCS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x72, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x82, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x82, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x72, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNAE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JB(BranchInstruction):
    """Jump if below (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JB(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JB, self).__init__("JB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JB\" requires 1 operands")
        self.go_name = "JCS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x72, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x82, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x82, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x72, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNB(BranchInstruction):
    """Jump if not below (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNB(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNB, self).__init__("JNB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNB\" requires 1 operands")
        self.go_name = "JCC"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x73, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x83, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x83, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x73, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JBE(BranchInstruction):
    """Jump if below or equal (CF == 1 or ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JBE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JBE, self).__init__("JBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JBE\" requires 1 operands")
        self.go_name = "JLS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x76, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x86, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x86, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x76, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNBE(BranchInstruction):
    """Jump if not below or equal (CF == 0 and ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNBE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNBE, self).__init__("JNBE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNBE\" requires 1 operands")
        self.go_name = "JHI"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x77, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x87, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x87, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x77, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNBE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JC(BranchInstruction):
    """Jump if carry (CF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JC(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JC, self).__init__("JC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JC\" requires 1 operands")
        self.go_name = "JCS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x72, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x82, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x82, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x72, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNC(BranchInstruction):
    """Jump if not carry (CF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNC(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNC, self).__init__("JNC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNC\" requires 1 operands")
        self.go_name = "JCC"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x73, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x83, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x83, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x73, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNC " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JE(BranchInstruction):
    """Jump if equal (ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JE, self).__init__("JE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JE\" requires 1 operands")
        self.go_name = "JEQ"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x74, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x84, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x84, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x74, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNE(BranchInstruction):
    """Jump if not equal (ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNE, self).__init__("JNE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNE\" requires 1 operands")
        self.go_name = "JNE"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x75, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x85, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x85, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x75, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JG(BranchInstruction):
    """Jump if greater (ZF == 0 and SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JG(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JG, self).__init__("JG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JG\" requires 1 operands")
        self.go_name = "JGT"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7F, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8F, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8F, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7F, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNG(BranchInstruction):
    """Jump if not greater (ZF == 1 or SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNG(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNG, self).__init__("JNG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNG\" requires 1 operands")
        self.go_name = "JLE"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7E, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8E, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8E, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7E, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JGE(BranchInstruction):
    """Jump if greater or equal (SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JGE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JGE, self).__init__("JGE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JGE\" requires 1 operands")
        self.go_name = "JGE"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7D, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8D, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8D, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7D, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JGE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNGE(BranchInstruction):
    """Jump if not greater or equal (SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNGE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNGE, self).__init__("JNGE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNGE\" requires 1 operands")
        self.go_name = "JLT"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7C, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8C, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8C, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7C, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNGE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JL(BranchInstruction):
    """Jump if less (SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JL(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JL, self).__init__("JL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JL\" requires 1 operands")
        self.go_name = "JLT"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7C, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8C, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8C, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7C, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNL(BranchInstruction):
    """Jump if not less (SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNL(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNL, self).__init__("JNL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNL\" requires 1 operands")
        self.go_name = "JGE"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7D, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8D, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8D, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7D, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JLE(BranchInstruction):
    """Jump if less or equal (ZF == 1 or SF != OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JLE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JLE, self).__init__("JLE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JLE\" requires 1 operands")
        self.go_name = "JLE"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7E, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8E, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8E, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7E, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JLE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNLE(BranchInstruction):
    """Jump if not less or equal (ZF == 0 and SF == OF)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNLE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNLE, self).__init__("JNLE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNLE\" requires 1 operands")
        self.go_name = "JGT"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7F, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8F, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8F, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7F, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNLE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JO(BranchInstruction):
    """Jump if overflow (OF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JO(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JO, self).__init__("JO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JO\" requires 1 operands")
        self.go_name = "JOS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x70, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x80, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x80, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x70, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNO(BranchInstruction):
    """Jump if not overflow (OF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNO(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNO, self).__init__("JNO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNO\" requires 1 operands")
        self.go_name = "JOC"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x71, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x81, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x81, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x71, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JP(BranchInstruction):
    """Jump if parity (PF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JP(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JP, self).__init__("JP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JP\" requires 1 operands")
        self.go_name = "JPS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7A, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8A, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8A, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7A, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNP(BranchInstruction):
    """Jump if not parity (PF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNP(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNP, self).__init__("JNP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNP\" requires 1 operands")
        self.go_name = "JPC"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7B, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8B, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8B, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7B, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JS(BranchInstruction):
    """Jump if sign (SF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JS(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JS, self).__init__("JS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JS\" requires 1 operands")
        self.go_name = "JMI"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x78, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x88, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x88, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x78, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNS(BranchInstruction):
    """Jump if not sign (SF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNS(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNS, self).__init__("JNS", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNS\" requires 1 operands")
        self.go_name = "JPL"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x79, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x89, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x89, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x79, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNS " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JZ(BranchInstruction):
    """Jump if zero (ZF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JZ(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JZ, self).__init__("JZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JZ\" requires 1 operands")
        self.go_name = "JEQ"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x74, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x84, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x84, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x74, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JNZ(BranchInstruction):
    """Jump if not zero (ZF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JNZ(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JNZ, self).__init__("JNZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JNZ\" requires 1 operands")
        self.go_name = "JNE"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x75, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x85, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x85, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x75, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JNZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JPE(BranchInstruction):
    """Jump if parity even (PF == 1)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JPE(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JPE, self).__init__("JPE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JPE\" requires 1 operands")
        self.go_name = "JPS"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7A, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8A, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8A, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7A, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JPE " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JPO(BranchInstruction):
    """Jump if parity odd (PF == 0)"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JPO(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JPO, self).__init__("JPO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JPO\" requires 1 operands")
        self.go_name = "JPC"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0x7B, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x8B, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0x0F, 0x8B, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0x7B, off & 0xFF])))
        else:
            raise SyntaxError("Invalid operand types: JPO " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JMP(BranchInstruction):
    """Jump Unconditionally"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JMP(r64/m64)
            * JMP(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JMP, self).__init__("JMP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JMP\" requires 1 operands")
        self.go_name = "JMP"
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            if is_rel8(self.operands[0]):
                self.encodings.append((0x00, lambda op: bytearray([0xEB, op[0].offset & 0xFF])))
            self.encodings.append((0x00, lambda op: bytearray([0xE9, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
            self.in_regs = (False,)
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0xE9, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.encodings.append((0x04, lambda off: bytearray([0xEB, off & 0xFF])))
            self.in_regs = (False,)
        elif is_r64(self.operands[0]):
            self._gas_name = "jmpq"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xFF, 0xE0 | op[0].lcode])))
            self.in_regs = (True,)
        elif is_m64(self.operands[0]):
            self._gas_name = "jmpq"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(4, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
        else:
            raise SyntaxError("Invalid operand types: JMP " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JRCXZ(BranchInstruction):
    """Jump if RCX register is 0"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JRCXZ(rel8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JRCXZ, self).__init__("JRCXZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JRCXZ\" requires 1 operands")
        self.go_name = "JCXZQ"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel8(self.operands[0]):
            self.encodings.append((0x00, lambda op: bytearray([0xE3, op[0].offset & 0xFF])))
            self._implicit_in_regs = {1: 15}
        elif is_label(self.operands[0]):
            self.encodings.append((0x04, lambda off: bytearray([0xE3, off & 0xFF])))
            self._implicit_in_regs = {1: 15}
        else:
            raise SyntaxError("Invalid operand types: JRCXZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class JECXZ(BranchInstruction):
    """Jump if ECX register is 0"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * JECXZ(rel8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(JECXZ, self).__init__("JECXZ", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"JECXZ\" requires 1 operands")
        self.go_name = "JCXZL"
        self.in_regs = (False,)
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel8(self.operands[0]):
            self.encodings.append((0x00, lambda op: bytearray([0xE3, op[0].offset & 0xFF])))
            self._implicit_in_regs = {1: 7}
        elif is_label(self.operands[0]):
            self.encodings.append((0x04, lambda off: bytearray([0xE3, off & 0xFF])))
            self._implicit_in_regs = {1: 7}
        else:
            raise SyntaxError("Invalid operand types: JECXZ " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class RET(Instruction):
    """Return from Procedure"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * RET()
            * RET(imm16)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RET, self).__init__("RET", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) == 0:
            self.go_name = "RET"
            self.encodings.append((0x00, lambda op: bytearray([0xC3])))
        elif len(self.operands) == 1:
            if is_imm(self.operands[0]):
                if not is_imm16(self.operands[0]):
                    raise ValueError("Argument #0 can not be encoded as imm16")
                self.go_name = "RET"
                self.encodings.append((0x00, lambda op: bytearray([0xC2, op[0] & 0xFF, (op[0] >> 8) & 0xFF])))
                self.in_regs = (False,)
                self.out_regs = (False,)
                self.out_operands = (False,)
            else:
                raise SyntaxError("Invalid operand types: RET " + ", ".join(map(format_operand_type, self.operands)))
        else:
            raise SyntaxError("Invalid number of operands for instruction \"RET\"")
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CALL(Instruction):
    """Call Procedure"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CALL(r64/m64)
            * CALL(rel32)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CALL, self).__init__("CALL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"CALL\" requires 1 operands")
        self.out_regs = (False,)
        self.out_operands = (False,)
        if is_rel32(self.operands[0]):
            self.go_name = "CALL"
            self.encodings.append((0x00, lambda op: bytearray([0xE8, op[0].offset & 0xFF, (op[0].offset >> 8) & 0xFF, (op[0].offset >> 16) & 0xFF, (op[0].offset >> 24) & 0xFF])))
            self.in_regs = (False,)
        elif is_label(self.operands[0]):
            self.encodings.append((0x08, lambda off: bytearray([0xE8, off & 0xFF, (off >> 8) & 0xFF, (off >> 16) & 0xFF, (off >> 24) & 0xFF])))
            self.in_regs = (False,)
        elif is_r64(self.operands[0]):
            self._gas_name = "callq"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0xFF, 0xD0 | op[0].lcode])))
            self.in_regs = (True,)
        elif is_m64(self.operands[0]):
            self._gas_name = "callq"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0xFF]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
        else:
            raise SyntaxError("Invalid operand types: CALL " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PAUSE(Instruction):
    """Spin Loop Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PAUSE()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PAUSE, self).__init__("PAUSE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"PAUSE\" requires 0 operands")
        self.go_name = "PAUSE"
        self.encodings.append((0x00, lambda op: bytearray([0xF3, 0x90])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class NOP(Instruction):
    """No Operation"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * NOP()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(NOP, self).__init__("NOP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"NOP\" requires 0 operands")
        self.go_name = "NOP"
        self.encodings.append((0x00, lambda op: bytearray([0x90])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class INT(Instruction):
    """Call to Interrupt Procedure"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * INT(imm8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(INT, self).__init__("INT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"INT\" requires 1 operands")
        if is_imm(self.operands[0]):
            if not is_imm8(self.operands[0]):
                raise ValueError("Argument #0 can not be encoded as imm8")
            self.go_name = "INT"
            if self.operands[0] == 3:
                self.encodings.append((0x00, lambda op: bytearray([0xCC])))
            self.encodings.append((0x00, lambda op: bytearray([0xCD, op[0] & 0xFF])))
            self.in_regs = (False,)
            self.out_regs = (False,)
            self.out_operands = (False,)
        else:
            raise SyntaxError("Invalid operand types: INT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class UD2(Instruction):
    """Undefined Instruction"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * UD2()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(UD2, self).__init__("UD2", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"UD2\" requires 0 operands")
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x0B])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CPUID(Instruction):
    """CPU Identification"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CPUID()    [CPUID]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CPUID, self).__init__("CPUID", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CPUID\" requires 0 operands")
        self.go_name = "CPUID"
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0xA2])))
        self._implicit_in_regs = {0: 7, 1: 7}
        self._implicit_out_regs = {0: 7, 1: 7, 2: 7, 3: 7}
        self.isa_extensions = frozenset([peachpy.x86_64.isa.cpuid])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class RDTSC(Instruction):
    """Read Time-Stamp Counter"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * RDTSC()    [RDTSC]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RDTSC, self).__init__("RDTSC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"RDTSC\" requires 0 operands")
        self.go_name = "RDTSC"
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x31])))
        self._implicit_out_regs = {0: 7, 2: 7}
        self.isa_extensions = frozenset([peachpy.x86_64.isa.rdtsc])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class RDTSCP(Instruction):
    """Read Time-Stamp Counter and Processor ID"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * RDTSCP()    [RDTSCP]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RDTSCP, self).__init__("RDTSCP", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"RDTSCP\" requires 0 operands")
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x01, 0xF9])))
        self._implicit_out_regs = {0: 7, 1: 7, 2: 7}
        self.isa_extensions = frozenset([peachpy.x86_64.isa.rdtscp])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class XGETBV(Instruction):
    """Get Value of Extended Control Register"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * XGETBV()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(XGETBV, self).__init__("XGETBV", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"XGETBV\" requires 0 operands")
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x01, 0xD0])))
        self._implicit_in_regs = {1: 7}
        self._implicit_out_regs = {0: 7, 2: 7}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SYSCALL(Instruction):
    """Fast System Call"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SYSCALL()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SYSCALL, self).__init__("SYSCALL", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"SYSCALL\" requires 0 operands")
        self.go_name = "SYSCALL"
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x05])))
        self._implicit_out_regs = {1: 15, 11: 15}
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class STC(Instruction):
    """Set Carry Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * STC()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(STC, self).__init__("STC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"STC\" requires 0 operands")
        self.go_name = "STC"
        self.encodings.append((0x00, lambda op: bytearray([0xF9])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CLC(Instruction):
    """Clear Carry Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CLC()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CLC, self).__init__("CLC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CLC\" requires 0 operands")
        self.go_name = "CLC"
        self.encodings.append((0x00, lambda op: bytearray([0xF8])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMC(Instruction):
    """Complement Carry Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMC()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMC, self).__init__("CMC", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CMC\" requires 0 operands")
        self.go_name = "CMC"
        self.encodings.append((0x00, lambda op: bytearray([0xF5])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class STD(Instruction):
    """Set Direction Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * STD()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(STD, self).__init__("STD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"STD\" requires 0 operands")
        self.go_name = "STD"
        self.encodings.append((0x00, lambda op: bytearray([0xFD])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CLD(Instruction):
    """Clear Direction Flag"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CLD()
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CLD, self).__init__("CLD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CLD\" requires 0 operands")
        self.go_name = "CLD"
        self.encodings.append((0x00, lambda op: bytearray([0xFC])))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class XADD(Instruction):
    """Exchange and Add"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * XADD(r16/m16, r16)
            * XADD(r32/m32, r32)
            * XADD(r64/m64, r64)
            * XADD(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(XADD, self).__init__("XADD", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"XADD\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_operands = (True, True)
        if is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "XADDB"
            self._gas_name = "xaddb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x0F, 0xC0, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, True)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "XADDW"
            self._gas_name = "xaddw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xC1, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, True)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "XADDL"
            self._gas_name = "xaddl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xC1, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, True)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "XADDQ"
            self._gas_name = "xaddq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xC1, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, True)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "XADDB"
            self._gas_name = "xaddb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x0F, 0xC0]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "XADDW"
            self._gas_name = "xaddw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xC1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "XADDL"
            self._gas_name = "xaddl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xC1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "XADDQ"
            self._gas_name = "xaddq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xC1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        else:
            raise SyntaxError("Invalid operand types: XADD " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class XCHG(Instruction):
    """Exchange Register/Memory with Register"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * XCHG(r16, r16/m16)
            * XCHG(r16/m16, r16)
            * XCHG(r32, r32/m32)
            * XCHG(r32/m32, r32)
            * XCHG(r64, r64/m64)
            * XCHG(r64/m64, r64)
            * XCHG(r8, r8/m8)
            * XCHG(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(XCHG, self).__init__("XCHG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"XCHG\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_operands = (True, True)
        if is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "XCHGB"
            self._gas_name = "xchgb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x86, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x86, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.out_regs = (True, True)
        elif is_r8(self.operands[0]) and is_m8(self.operands[1]):
            self.go_name = "XCHGB"
            self._gas_name = "xchgb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex or is_r8rex(op[0])) + bytearray([0x86]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "XCHGW"
            self._gas_name = "xchgw"
            if is_ax(self.operands[1]):
                self.encodings.append((0x22, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[0], rex) + bytearray([0x90 | op[0].lcode])))
            if is_ax(self.operands[0]):
                self.encodings.append((0x21, lambda op, rex=False: bytearray([0x66]) + optional_rex(0, op[1], rex) + bytearray([0x90 | op[1].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x87, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[0].hcode, op[1], rex) + bytearray([0x87, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.out_regs = (True, True)
        elif is_r16(self.operands[0]) and is_m16(self.operands[1]):
            self.go_name = "XCHGW"
            self._gas_name = "xchgw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x87]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "XCHGL"
            self._gas_name = "xchgl"
            if is_eax(self.operands[1]):
                self.encodings.append((0x22, lambda op, rex=False: optional_rex(0, op[0], rex) + bytearray([0x90 | op[0].lcode])))
            if is_eax(self.operands[0]):
                self.encodings.append((0x21, lambda op, rex=False: optional_rex(0, op[1], rex) + bytearray([0x90 | op[1].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x87, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex) + bytearray([0x87, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.out_regs = (True, True)
        elif is_r32(self.operands[0]) and is_m32(self.operands[1]):
            self.go_name = "XCHGL"
            self._gas_name = "xchgl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[0].hcode, op[1].address, rex) + bytearray([0x87]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "XCHGQ"
            self._gas_name = "xchgq"
            if is_rax(self.operands[1]):
                self.encodings.append((0x02, lambda op: bytearray([0x48 | op[0].hcode, 0x90 | op[0].lcode])))
            if is_rax(self.operands[0]):
                self.encodings.append((0x01, lambda op: bytearray([0x48 | op[1].hcode, 0x90 | op[1].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x87, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[0].hcode << 2 | op[1].hcode, 0x87, 0xC0 | op[0].lcode << 3 | op[1].lcode])))
            self.out_regs = (True, True)
        elif is_r64(self.operands[0]) and is_m64(self.operands[1]):
            self.go_name = "XCHGQ"
            self._gas_name = "xchgq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[0].hcode, op[1].address) + bytearray([0x87]) + modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)))
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "XCHGB"
            self._gas_name = "xchgb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x86]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "XCHGW"
            self._gas_name = "xchgw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x87]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "XCHGL"
            self._gas_name = "xchgl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x87]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "XCHGQ"
            self._gas_name = "xchgq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x87]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, True)
        else:
            raise SyntaxError("Invalid operand types: XCHG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMPXCHG(Instruction):
    """Compare and Exchange"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMPXCHG(r16/m16, r16)
            * CMPXCHG(r32/m32, r32)
            * CMPXCHG(r64/m64, r64)
            * CMPXCHG(r8/m8, r8)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMPXCHG, self).__init__("CMPXCHG", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 2:
            raise SyntaxError("Instruction \"CMPXCHG\" requires 2 operands")
        self.in_regs = (True, True)
        self.out_operands = (True, False)
        if is_r8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "CMPXCHGB"
            self._gas_name = "cmpxchgb"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex or is_r8rex(op[0]) or is_r8rex(op[1])) + bytearray([0x0F, 0xB0, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, False)
        elif is_r16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "CMPXCHGW"
            self._gas_name = "cmpxchgw"
            self.encodings.append((0x20, lambda op, rex=False: bytearray([0x66]) + optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xB1, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, False)
        elif is_r32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "CMPXCHGL"
            self._gas_name = "cmpxchgl"
            self.encodings.append((0x20, lambda op, rex=False: optional_rex(op[1].hcode, op[0], rex) + bytearray([0x0F, 0xB1, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, False)
        elif is_r64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "CMPXCHGQ"
            self._gas_name = "cmpxchgq"
            self.encodings.append((0x00, lambda op: bytearray([0x48 | op[1].hcode << 2 | op[0].hcode, 0x0F, 0xB1, 0xC0 | op[1].lcode << 3 | op[0].lcode])))
            self.out_regs = (True, False)
        elif is_m8(self.operands[0]) and is_r8(self.operands[1]):
            self.go_name = "CMPXCHGB"
            self._gas_name = "cmpxchgb"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex or is_r8rex(op[1])) + bytearray([0x0F, 0xB0]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, False)
        elif is_m16(self.operands[0]) and is_r16(self.operands[1]):
            self.go_name = "CMPXCHGW"
            self._gas_name = "cmpxchgw"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xB1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, False)
        elif is_m32(self.operands[0]) and is_r32(self.operands[1]):
            self.go_name = "CMPXCHGL"
            self._gas_name = "cmpxchgl"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(op[1].hcode, op[0].address, rex) + bytearray([0x0F, 0xB1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, False)
        elif is_m64(self.operands[0]) and is_r64(self.operands[1]):
            self.go_name = "CMPXCHGQ"
            self._gas_name = "cmpxchgq"
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, op[1].hcode, op[0].address) + bytearray([0x0F, 0xB1]) + modrm_sib_disp(op[1].lcode, op[0].address, sib, min_disp)))
            self.out_regs = (False, False)
        else:
            raise SyntaxError("Invalid operand types: CMPXCHG " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMPXCHG8B(Instruction):
    """Compare and Exchange 8 Bytes"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMPXCHG8B(m64)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMPXCHG8B, self).__init__("CMPXCHG8B", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"CMPXCHG8B\" requires 1 operands")
        if is_m64(self.operands[0]):
            self.go_name = "CMPXCHG8B"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xC7]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 7, 1: 7, 2: 7, 3: 7}
            self._implicit_out_regs = {0: 7, 2: 7}
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
        else:
            raise SyntaxError("Invalid operand types: CMPXCHG8B " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CMPXCHG16B(Instruction):
    """Compare and Exchange 16 Bytes"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CMPXCHG16B(m128)
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CMPXCHG16B, self).__init__("CMPXCHG16B", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"CMPXCHG16B\" requires 1 operands")
        if is_m128(self.operands[0]):
            self.encodings.append((0x10, lambda op, sib=False, min_disp=0: rex(1, 0, op[0].address) + bytearray([0x0F, 0xC7]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self._implicit_in_regs = {0: 15, 1: 15, 2: 15, 3: 15}
            self._implicit_out_regs = {0: 15, 2: 15}
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
        else:
            raise SyntaxError("Invalid operand types: CMPXCHG16B " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class SFENCE(Instruction):
    """Store Fence"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * SFENCE()    [MMX+]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(SFENCE, self).__init__("SFENCE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"SFENCE\" requires 0 operands")
        self.go_name = "SFENCE"
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0xAE, 0xF8])))
        self.isa_extensions = frozenset([peachpy.x86_64.isa.mmx_plus])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class MFENCE(Instruction):
    """Memory Fence"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * MFENCE()    [SSE2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(MFENCE, self).__init__("MFENCE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"MFENCE\" requires 0 operands")
        self.go_name = "MFENCE"
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0xAE, 0xF0])))
        self.isa_extensions = frozenset([peachpy.x86_64.isa.sse2])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class LFENCE(Instruction):
    """Load Fence"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * LFENCE()    [SSE2]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(LFENCE, self).__init__("LFENCE", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"LFENCE\" requires 0 operands")
        self.go_name = "LFENCE"
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0xAE, 0xE8])))
        self.isa_extensions = frozenset([peachpy.x86_64.isa.sse2])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCHNTA(Instruction):
    """Prefetch Data Into Caches using NTA Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCHNTA(m8)    [MMX+]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCHNTA, self).__init__("PREFETCHNTA", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCHNTA\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.go_name = "PREFETCHNTA"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x18]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.mmx_plus])
        else:
            raise SyntaxError("Invalid operand types: PREFETCHNTA " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCHT0(Instruction):
    """Prefetch Data Into Caches using T0 Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCHT0(m8)    [MMX+]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCHT0, self).__init__("PREFETCHT0", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCHT0\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.go_name = "PREFETCHT0"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x18]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.mmx_plus])
        else:
            raise SyntaxError("Invalid operand types: PREFETCHT0 " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCHT1(Instruction):
    """Prefetch Data Into Caches using T1 Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCHT1(m8)    [MMX+]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCHT1, self).__init__("PREFETCHT1", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCHT1\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.go_name = "PREFETCHT1"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x18]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.mmx_plus])
        else:
            raise SyntaxError("Invalid operand types: PREFETCHT1 " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCHT2(Instruction):
    """Prefetch Data Into Caches using T2 Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCHT2(m8)    [MMX+]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCHT2, self).__init__("PREFETCHT2", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCHT2\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.go_name = "PREFETCHT2"
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x18]) + modrm_sib_disp(3, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.mmx_plus])
        else:
            raise SyntaxError("Invalid operand types: PREFETCHT2 " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCH(Instruction):
    """Prefetch Data into Caches"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCH(m8)    [PREFETCH]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCH, self).__init__("PREFETCH", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCH\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x0D]) + modrm_sib_disp(0, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.prefetch])
        else:
            raise SyntaxError("Invalid operand types: PREFETCH " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCHW(Instruction):
    """Prefetch Data into Caches in Anticipation of a Write"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCHW(m8)    [PREFETCHW]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCHW, self).__init__("PREFETCHW", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCHW\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x0D]) + modrm_sib_disp(1, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.prefetchw])
        else:
            raise SyntaxError("Invalid operand types: PREFETCHW " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class PREFETCHWT1(Instruction):
    """Prefetch Vector Data Into Caches with Intent to Write and T1 Hint"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * PREFETCHWT1(m8)    [PREFETCHWT1]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(PREFETCHWT1, self).__init__("PREFETCHWT1", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"PREFETCHWT1\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0x0D]) + modrm_sib_disp(2, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.prefetchwt1])
        else:
            raise SyntaxError("Invalid operand types: PREFETCHWT1 " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CLFLUSH(Instruction):
    """Flush Cache Line"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CLFLUSH(m8)    [CLFLUSH]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CLFLUSH, self).__init__("CLFLUSH", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"CLFLUSH\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xAE]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.clflush])
        else:
            raise SyntaxError("Invalid operand types: CLFLUSH " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CLFLUSHOPT(Instruction):
    """Flush Cache Line Optimized"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CLFLUSHOPT(m8)    [CLFLUSHOPT]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CLFLUSHOPT, self).__init__("CLFLUSHOPT", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"CLFLUSHOPT\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xAE]) + modrm_sib_disp(7, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.clflushopt])
        else:
            raise SyntaxError("Invalid operand types: CLFLUSHOPT " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CLWB(Instruction):
    """Cache Line Write Back"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CLWB(m8)    [CLWB]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CLWB, self).__init__("CLWB", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 1:
            raise SyntaxError("Instruction \"CLWB\" requires 1 operands")
        if is_m8(self.operands[0]):
            self.encodings.append((0x30, lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66]) + optional_rex(0, op[0].address, rex) + bytearray([0x0F, 0xAE]) + modrm_sib_disp(6, op[0].address, sib, min_disp)))
            self.in_regs = (True,)
            self.out_regs = (False,)
            self.out_operands = (False,)
            self.isa_extensions = frozenset([peachpy.x86_64.isa.clwb])
        else:
            raise SyntaxError("Invalid operand types: CLWB " + ", ".join(map(format_operand_type, self.operands)))
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


class CLZERO(Instruction):
    """Zero-out 64-bit Cache Line"""

    def __init__(self, *args, **kwargs):
        """Supported forms:

            * CLZERO()    [CLZERO]
        """

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(CLZERO, self).__init__("CLZERO", origin=origin, prototype=prototype)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) != 0:
            raise SyntaxError("Instruction \"CLZERO\" requires 0 operands")
        self.encodings.append((0x00, lambda op: bytearray([0x0F, 0x01, 0xFC])))
        self._implicit_in_regs = {0: 15}
        self.isa_extensions = frozenset([peachpy.x86_64.isa.clzero])
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)


