@instruction<EOL><INDENT>def RCR(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>count = src.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND((count & countMask) % (src.size + <NUM_LIT:1>), OperandSize)<EOL>value = dest.read()<EOL>if isinstance(tempCount, int) and tempCount == <NUM_LIT:0>:<EOL><INDENT>new_val = value<EOL>dest.write(new_val)<EOL><DEDENT>else:<EOL><INDENT>carry = Operators.ITEBV(OperandSize, cpu.CF, <NUM_LIT:1>, <NUM_LIT:0>)<EOL>left = value >> (tempCount - <NUM_LIT:1>)<EOL>right = value << (OperandSize - tempCount)<EOL>new_val = (left >> <NUM_LIT:1>) | (carry << (OperandSize - tempCount)) | (right << <NUM_LIT:1>)<EOL>dest.write(new_val)<EOL>cpu.CF = Operators.ITE(tempCount != <NUM_LIT:0>, (left & <NUM_LIT:1>) == <NUM_LIT:1>, cpu.CF)<EOL>s_MSB = ((new_val >> (OperandSize - <NUM_LIT:1>)) & <NUM_LIT>) == <NUM_LIT:1><EOL>s_MSB2 = ((new_val >> (OperandSize - <NUM_LIT:2>)) & <NUM_LIT>) == <NUM_LIT:1><EOL>cpu.OF = Operators.ITE(tempCount == <NUM_LIT:1>,<EOL>s_MSB ^ s_MSB2, cpu.OF)<EOL><DEDENT>

Rotates through carry right (RCR).

Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the
second operand (count operand) and stores the result in the destination operand. The destination operand can be
a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in
the CL register. In legacy and compatibility mode, the processor restricts the count to a number between 0 and 31
by masking all the bits in the count operand except the 5 least-significant bits.

Rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except
for the least-significant bit, which is rotated to the most-significant bit location. The RCR instruction shifts the
CF flag into the most-significant bit and shifts the least-significant bit into the CF flag.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


@instruction<EOL><INDENT>def ROL(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>count = src.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND((count & countMask) % (OperandSize), OperandSize)<EOL>value = dest.read()<EOL>newValue = (value << tempCount) | (value >> (OperandSize - tempCount))<EOL>dest.write(newValue)<EOL>cpu.CF = Operators.ITE(tempCount != <NUM_LIT:0>, (newValue & <NUM_LIT:1>) == <NUM_LIT:1>, cpu.CF)<EOL>s_MSB = ((newValue >> (OperandSize - <NUM_LIT:1>)) & <NUM_LIT>) == <NUM_LIT:1><EOL>cpu.OF = Operators.ITE(tempCount == <NUM_LIT:1>, s_MSB ^ cpu.CF, cpu.OF)<EOL>

Rotates left (ROL).

Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the
second operand (count operand) and stores the result in the destination operand. The destination operand can be
a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in
the CL register. In legacy and compatibility mode, the processor restricts the count to a number between 0 and 31
by masking all the bits in the count operand except the 5 least-significant bits.

The rotate left shift all the bits toward more-significant bit positions, except for the most-significant bit, which
is rotated to the least-significant bit location.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


@instruction<EOL><INDENT>def ROR(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>count = src.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND((count & countMask) % (OperandSize), OperandSize)<EOL>value = dest.read()<EOL>newValue = (value >> tempCount) | (value << (OperandSize - tempCount))<EOL>dest.write(newValue)<EOL>cpu.CF = Operators.ITE(tempCount != <NUM_LIT:0>, ((newValue >> (OperandSize - <NUM_LIT:1>)) & <NUM_LIT>) == <NUM_LIT:1>, cpu.CF)<EOL>s_MSB = ((newValue >> (OperandSize - <NUM_LIT:1>)) & <NUM_LIT>) == <NUM_LIT:1><EOL>s_MSB2 = ((newValue >> (OperandSize - <NUM_LIT:2>)) & <NUM_LIT>) == <NUM_LIT:1><EOL>cpu.OF = Operators.ITE(tempCount == <NUM_LIT:1>, s_MSB ^ s_MSB2, cpu.OF)<EOL>

Rotates right (ROR).

Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the
second operand (count operand) and stores the result in the destination operand. The destination operand can be
a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in
the CL register. In legacy and compatibility mode, the processor restricts the count to a number between 0 and 31
by masking all the bits in the count operand except the 5 least-significant bits.

The rotate right (ROR) instruction shift all the bits toward less significant bit positions, except
for the least-significant bit, which is rotated to the most-significant bit location.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


@instruction<EOL><INDENT>def SAL(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>count = src.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND(count & countMask, dest.size)<EOL>tempDest = value = dest.read()<EOL>res = dest.write(Operators.ITEBV(dest.size, tempCount == <NUM_LIT:0>, tempDest, value << tempCount))<EOL>MASK = (<NUM_LIT:1> << OperandSize) - <NUM_LIT:1><EOL>SIGN_MASK = <NUM_LIT:1> << (OperandSize - <NUM_LIT:1>)<EOL>cpu.CF = Operators.OR(Operators.AND(tempCount == <NUM_LIT:0>, cpu.CF), Operators.AND(tempCount != <NUM_LIT:0>, (tempDest & (<NUM_LIT:1> << (OperandSize - tempCount)) != <NUM_LIT:0>)))<EOL>cpu.OF = Operators.ITE(tempCount != <NUM_LIT:0>, (cpu.CF) ^ (((res >> (OperandSize - <NUM_LIT:1>)) & <NUM_LIT>) == <NUM_LIT:1>), cpu.OF)<EOL>cpu.SF = Operators.OR(Operators.AND(tempCount == <NUM_LIT:0>, cpu.SF), Operators.AND(tempCount != <NUM_LIT:0>, (res & SIGN_MASK) != <NUM_LIT:0>))<EOL>cpu.ZF = Operators.OR(Operators.AND(tempCount == <NUM_LIT:0>, cpu.ZF), Operators.AND(tempCount != <NUM_LIT:0>, res == <NUM_LIT:0>))<EOL>cpu.PF = Operators.OR(Operators.AND(tempCount == <NUM_LIT:0>, cpu.PF), Operators.AND(tempCount != <NUM_LIT:0>, cpu._calculate_parity_flag(res)))<EOL>

The shift arithmetic left.

Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the
second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF
flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination
operand.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


return cpu.SAL(dest, src)<EOL>

The shift logical left.

The shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation.

:param cpu: current cpu.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def SAR(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>count = src.read() & countMask<EOL>value = dest.read()<EOL>res = Operators.SAR(OperandSize, value, Operators.ZEXTEND(count, OperandSize))<EOL>dest.write(res)<EOL>SIGN_MASK = (<NUM_LIT:1> << (OperandSize - <NUM_LIT:1>))<EOL>if issymbolic(count):<EOL><INDENT>cpu.CF = Operators.ITE(Operators.AND(count != <NUM_LIT:0>, count <= OperandSize), ((value >> Operators.ZEXTEND(count - <NUM_LIT:1>, OperandSize)) & <NUM_LIT:1>) != <NUM_LIT:0>, cpu.CF)<EOL><DEDENT>else:<EOL><INDENT>if count != <NUM_LIT:0>:<EOL><INDENT>if count > OperandSize:<EOL><INDENT>count = OperandSize<EOL><DEDENT>cpu.CF = Operators.EXTRACT(value, count - <NUM_LIT:1>, <NUM_LIT:1>) != <NUM_LIT:0><EOL><DEDENT><DEDENT>cpu.ZF = Operators.ITE(count != <NUM_LIT:0>, res == <NUM_LIT:0>, cpu.ZF)<EOL>cpu.SF = Operators.ITE(count != <NUM_LIT:0>, (res & SIGN_MASK) != <NUM_LIT:0>, cpu.SF)<EOL>cpu.OF = Operators.ITE(count == <NUM_LIT:1>, False, cpu.OF)<EOL>cpu.PF = Operators.ITE(count != <NUM_LIT:0>, cpu._calculate_parity_flag(res), cpu.PF)<EOL>

Shift arithmetic right.

The shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to
the right (toward less significant bit locations). For each shift count, the least significant bit of the destination
operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction
type. The SHR instruction clears the most significant bit. the SAR instruction sets or clears the most significant bit
to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR
instruction fills the empty bit position's shifted value with the sign of the unshifted value

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def SHR(cpu, dest, src):<DEDENT>

OperandSize = dest.size<EOL>count = Operators.ZEXTEND(src.read() & (OperandSize - <NUM_LIT:1>), OperandSize)<EOL>value = dest.read()<EOL>res = dest.write(value >> count)  <EOL>MASK = (<NUM_LIT:1> << OperandSize) - <NUM_LIT:1><EOL>SIGN_MASK = <NUM_LIT:1> << (OperandSize - <NUM_LIT:1>)<EOL>if issymbolic(count):<EOL><INDENT>cpu.CF = Operators.ITE(count != <NUM_LIT:0>,<EOL>((value >> Operators.ZEXTEND(count - <NUM_LIT:1>, OperandSize)) & <NUM_LIT:1>) != <NUM_LIT:0>,<EOL>cpu.CF)<EOL><DEDENT>else:<EOL><INDENT>if count != <NUM_LIT:0>:<EOL><INDENT>cpu.CF = Operators.EXTRACT(value, count - <NUM_LIT:1>, <NUM_LIT:1>) != <NUM_LIT:0><EOL><DEDENT><DEDENT>cpu.ZF = Operators.ITE(count != <NUM_LIT:0>, res == <NUM_LIT:0>, cpu.ZF)<EOL>cpu.SF = Operators.ITE(count != <NUM_LIT:0>, (res & SIGN_MASK) != <NUM_LIT:0>, cpu.SF)<EOL>cpu.OF = Operators.ITE(count != <NUM_LIT:0>, ((value >> (OperandSize - <NUM_LIT:1>)) & <NUM_LIT>) == <NUM_LIT:1>, cpu.OF)<EOL>cpu.PF = Operators.ITE(count != <NUM_LIT:0>, cpu._calculate_parity_flag(res), cpu.PF)<EOL>

Shift logical right.

The shift arithmetic right (SAR) and shift logical right (SHR)
instructions shift the bits of the destination operand to the right
(toward less significant bit locations). For each shift count, the
least significant bit of the destination operand is shifted into the CF
flag, and the most significant bit is either set or cleared depending
on the instruction type. The SHR instruction clears the most
significant bit.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


@instruction<EOL><INDENT>def SHRD(cpu, dest, src, count):<DEDENT>

OperandSize = dest.size<EOL>MASK = ((<NUM_LIT:1> << OperandSize) - <NUM_LIT:1>)<EOL>tempCount = Operators.ZEXTEND(count.read(), OperandSize) & (OperandSize - <NUM_LIT:1>)<EOL>if isinstance(tempCount, int) and tempCount == <NUM_LIT:0>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>arg0 = dest.read()<EOL>arg1 = src.read()<EOL>res = Operators.ITEBV(OperandSize, tempCount == <NUM_LIT:0>, arg0, (arg0 >> tempCount) | (arg1 << (dest.size - tempCount)))<EOL>res = res & MASK<EOL>dest.write(res)<EOL>lastbit = <NUM_LIT:0> != (arg0 >> (tempCount - <NUM_LIT:1>)) & <NUM_LIT:1><EOL>cpu._set_shiftd_flags(OperandSize, arg0, res, lastbit, tempCount)<EOL><DEDENT>

Double precision shift right.

Shifts the first operand (destination operand) to the right the number of bits specified by the third operand
(count operand). The second operand (source operand) provides bits to shift in from the left (starting with
the most significant bit of the destination operand).

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.
:param count: count operand


@instruction<EOL><INDENT>def SHLD(cpu, dest, src, count):<DEDENT>

OperandSize = dest.size<EOL>tempCount = Operators.ZEXTEND(count.read(), OperandSize) & (OperandSize - <NUM_LIT:1>)<EOL>arg0 = dest.read()<EOL>arg1 = src.read()<EOL>MASK = ((<NUM_LIT:1> << OperandSize) - <NUM_LIT:1>)<EOL>t0 = (arg0 << tempCount)<EOL>t1 = arg1 >> (OperandSize - tempCount)<EOL>res = Operators.ITEBV(OperandSize, tempCount == <NUM_LIT:0>, arg0, t0 | t1)<EOL>res = res & MASK<EOL>dest.write(res)<EOL>if isinstance(tempCount, int) and tempCount == <NUM_LIT:0>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>SIGN_MASK = <NUM_LIT:1> << (OperandSize - <NUM_LIT:1>)<EOL>lastbit = <NUM_LIT:0> != ((arg0 << (tempCount - <NUM_LIT:1>)) & SIGN_MASK)<EOL>cpu._set_shiftd_flags(OperandSize, arg0, res, lastbit, tempCount)<EOL><DEDENT>

Double precision shift right.

Shifts the first operand (destination operand) to the left the number of bits specified by the third operand
(count operand). The second operand (source operand) provides bits to shift in from the right (starting with
the least significant bit of the destination operand).

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.
:param count: count operand


def _getMemoryBit(cpu, bitbase, bitoffset):

assert bitbase.type == '<STR_LIT>'<EOL>assert bitbase.size >= bitoffset.size<EOL>addr = bitbase.address()<EOL>offt = Operators.SEXTEND(bitoffset.read(), bitoffset.size, bitbase.size)<EOL>offt_is_neg = offt >= (<NUM_LIT:1> << (bitbase.size - <NUM_LIT:1>))<EOL>offt_in_bytes = offt // <NUM_LIT:8><EOL>bitpos = offt % <NUM_LIT:8><EOL>new_addr = addr + Operators.ITEBV(bitbase.size, offt_is_neg, -offt_in_bytes, offt_in_bytes)<EOL>return (new_addr, bitpos)<EOL>

Calculate address and bit offset given a base address and a bit offset
            relative to that address (in the form of asm operands)


@instruction<EOL><INDENT>def BSF(cpu, dest, src):<DEDENT>

value = src.read()<EOL>flag = Operators.EXTRACT(value, <NUM_LIT:0>, <NUM_LIT:1>) == <NUM_LIT:1><EOL>res = <NUM_LIT:0><EOL>for pos in range(<NUM_LIT:1>, src.size):<EOL><INDENT>res = Operators.ITEBV(dest.size, flag, res, pos)<EOL>flag = Operators.OR(flag, Operators.EXTRACT(value, pos, <NUM_LIT:1>) == <NUM_LIT:1>)<EOL><DEDENT>cpu.ZF = value == <NUM_LIT:0><EOL>dest.write(Operators.ITEBV(dest.size, cpu.ZF, dest.read(), res))<EOL>

Bit scan forward.

Searches the source operand (second operand) for the least significant
set bit (1 bit). If a least significant 1 bit is found, its bit index
is stored in the destination operand (first operand). The source operand
can be a register or a memory location; the destination operand is a register.
The bit index is an unsigned offset from bit 0 of the source operand.
If the contents source operand are 0, the contents of the destination
operand is undefined::

            IF SRC  =  0
            THEN
                ZF  =  1;
                DEST is undefined;
            ELSE
                ZF  =  0;
                temp  =  0;
                WHILE Bit(SRC, temp)  =  0
                DO
                    temp  =  temp + 1;
                    DEST  =  temp;
                OD;
            FI;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def BSR(cpu, dest, src):<DEDENT>

value = src.read()<EOL>flag = Operators.EXTRACT(value, src.size - <NUM_LIT:1>, <NUM_LIT:1>) == <NUM_LIT:1><EOL>res = <NUM_LIT:0><EOL>for pos in reversed(range(<NUM_LIT:0>, src.size)):<EOL><INDENT>res = Operators.ITEBV(dest.size, flag, res, pos)<EOL>flag = Operators.OR(flag, (Operators.EXTRACT(value, pos, <NUM_LIT:1>) == <NUM_LIT:1>))<EOL><DEDENT>cpu.PF = cpu._calculate_parity_flag(res)<EOL>cpu.ZF = value == <NUM_LIT:0><EOL>dest.write(Operators.ITEBV(dest.size, cpu.ZF, dest.read(), res))<EOL>

Bit scan reverse.

Searches the source operand (second operand) for the most significant
set bit (1 bit). If a most significant 1 bit is found, its bit index is
stored in the destination operand (first operand). The source operand
can be a register or a memory location; the destination operand is a register.
The bit index is an unsigned offset from bit 0 of the source operand.
If the contents source operand are 0, the contents of the destination
operand is undefined::

        IF SRC  =  0
        THEN
            ZF  =  1;
            DEST is undefined;
        ELSE
            ZF  =  0;
            temp  =  OperandSize - 1;
            WHILE Bit(SRC, temp)  =  0
            DO
                temp  =  temp - 1;
                DEST  =  temp;
            OD;
        FI;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def BT(cpu, dest, src):<DEDENT>

if dest.type == '<STR_LIT>':<EOL><INDENT>cpu.CF = ((dest.read() >> (src.read() % dest.size)) & <NUM_LIT:1>) != <NUM_LIT:0><EOL><DEDENT>elif dest.type == '<STR_LIT>':<EOL><INDENT>addr, pos = cpu._getMemoryBit(dest, src)<EOL>base, size, ty = cpu.get_descriptor(cpu.DS)<EOL>value = cpu.read_int(addr + base, <NUM_LIT:8>)<EOL>cpu.CF = Operators.EXTRACT(value, pos, <NUM_LIT:1>) == <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError(f"<STR_LIT>")<EOL><DEDENT>

Bit Test.

Selects the bit in a bit string (specified with the first operand, called the bit base) at the
bit-position designated by the bit offset (specified by the second operand) and stores the value
of the bit in the CF flag. The bit base operand can be a register or a memory location; the bit
offset operand can be a register or an immediate value:
    - If the bit base operand specifies a register, the instruction takes the modulo 16, 32, or 64
      of the bit offset operand (modulo size depends on the mode and register size; 64-bit operands
      are available only in 64-bit mode).
    - If the bit base operand specifies a memory location, the operand represents the address of the
      byte in memory that contains the bit base (bit 0 of the specified byte) of the bit string. The
      range of the bit position that can be referenced by the offset operand depends on the operand size.

:param cpu: current CPU.
:param dest: bit base.
:param src: bit offset.


@instruction<EOL><INDENT>def BTC(cpu, dest, src):<DEDENT>

if dest.type == '<STR_LIT>':<EOL><INDENT>value = dest.read()<EOL>pos = src.read() % dest.size<EOL>cpu.CF = value & (<NUM_LIT:1> << pos) == <NUM_LIT:1> << pos<EOL>dest.write(value ^ (<NUM_LIT:1> << pos))<EOL><DEDENT>elif dest.type == '<STR_LIT>':<EOL><INDENT>addr, pos = cpu._getMemoryBit(dest, src)<EOL>base, size, ty = cpu.get_descriptor(cpu.DS)<EOL>addr += base<EOL>value = cpu.read_int(addr, <NUM_LIT:8>)<EOL>cpu.CF = value & (<NUM_LIT:1> << pos) == <NUM_LIT:1> << pos<EOL>value = value ^ (<NUM_LIT:1> << pos)<EOL>cpu.write_int(addr, value, <NUM_LIT:8>)<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError(f"<STR_LIT>")<EOL><DEDENT>

Bit test and complement.

Selects the bit in a bit string (specified with the first operand, called
the bit base) at the bit-position designated by the bit offset operand
(second operand), stores the value of the bit in the CF flag, and complements
the selected bit in the bit string.

:param cpu: current CPU.
:param dest: bit base operand.
:param src: bit offset operand.


@instruction<EOL><INDENT>def BTR(cpu, dest, src):<DEDENT>

if dest.type == '<STR_LIT>':<EOL><INDENT>value = dest.read()<EOL>pos = src.read() % dest.size<EOL>cpu.CF = value & (<NUM_LIT:1> << pos) == <NUM_LIT:1> << pos<EOL>dest.write(value & ~(<NUM_LIT:1> << pos))<EOL><DEDENT>elif dest.type == '<STR_LIT>':<EOL><INDENT>addr, pos = cpu._getMemoryBit(dest, src)<EOL>base, size, ty = cpu.get_descriptor(cpu.DS)<EOL>addr += base<EOL>value = cpu.read_int(addr, <NUM_LIT:8>)<EOL>cpu.CF = value & (<NUM_LIT:1> << pos) == <NUM_LIT:1> << pos<EOL>value = value & ~(<NUM_LIT:1> << pos)<EOL>cpu.write_int(addr, value, <NUM_LIT:8>)<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError(f"<STR_LIT>")<EOL><DEDENT>

Bit test and reset.

Selects the bit in a bit string (specified with the first operand, called
the bit base) at the bit-position designated by the bit offset operand
(second operand), stores the value of the bit in the CF flag, and clears
the selected bit in the bit string to 0.

:param cpu: current CPU.
:param dest: bit base operand.
:param src: bit offset operand.


@instruction<EOL><INDENT>def BTS(cpu, dest, src):<DEDENT>

if dest.type == '<STR_LIT>':<EOL><INDENT>value = dest.read()<EOL>pos = src.read() % dest.size<EOL>cpu.CF = value & (<NUM_LIT:1> << pos) == <NUM_LIT:1> << pos<EOL>dest.write(value | (<NUM_LIT:1> << pos))<EOL><DEDENT>elif dest.type == '<STR_LIT>':<EOL><INDENT>addr, pos = cpu._getMemoryBit(dest, src)<EOL>base, size, ty = cpu.get_descriptor(cpu.DS)<EOL>addr += base<EOL>value = cpu.read_int(addr, <NUM_LIT:8>)<EOL>cpu.CF = value & (<NUM_LIT:1> << pos) == <NUM_LIT:1> << pos<EOL>value = value | (<NUM_LIT:1> << pos)<EOL>cpu.write_int(addr, value, <NUM_LIT:8>)<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError(f"<STR_LIT>")<EOL><DEDENT>

Bit test and set.

Selects the bit in a bit string (specified with the first operand, called
the bit base) at the bit-position designated by the bit offset operand
(second operand), stores the value of the bit in the CF flag, and sets
the selected bit in the bit string to 1.

:param cpu: current CPU.
:param dest: bit base operand.
:param src: bit offset operand.


@instruction<EOL><INDENT>def POPCNT(cpu, dest, src):<DEDENT>

count = <NUM_LIT:0><EOL>source = src.read()<EOL>for i in range(src.size):<EOL><INDENT>count += Operators.ITEBV(dest.size, (source >> i) & <NUM_LIT:1> == <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>)<EOL><DEDENT>dest.write(count)<EOL>cpu.OF = False<EOL>cpu.SF = False<EOL>cpu.AF = False<EOL>cpu.CF = False<EOL>cpu.PF = False<EOL>cpu.ZF = source == <NUM_LIT:0><EOL>

This instruction calculates of number of bits set to 1 in the second
operand (source) and returns the count in the first operand (a destination
register).
Count = 0;
For (i=0; i < OperandSize; i++) {
    IF (SRC[ i] = 1) // i'th bit
        THEN Count++;
    FI;
}
DEST = Count;
Flags Affected
OF, SF, ZF, AF, CF, PF are all cleared.
ZF is set if SRC = 0, otherwise ZF is cleared


cpu.DF = False<EOL>

Clears direction flag.
Clears the DF flag in the EFLAGS register. When the DF flag is set to 0, string operations
increment the index registers (ESI and/or EDI)::

    DF  =  0;

:param cpu: current CPU.


cpu.DF = True<EOL>

Sets direction flag.

Sets the DF flag in the EFLAGS register. When the DF flag is set to 1, string operations decrement
the index registers (ESI and/or EDI)::

    DF  =  1;

:param cpu: current CPU.


cpu.CF = False<EOL>


cpu.CF = True<EOL>


@repe<EOL><INDENT>def CMPS(cpu, dest, src):<DEDENT>

src_reg = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[cpu.address_bit_size]<EOL>dest_reg = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[cpu.address_bit_size]<EOL>base, _, ty = cpu.get_descriptor(cpu.DS)<EOL>src_addr = cpu.read_register(src_reg) + base<EOL>dest_addr = cpu.read_register(dest_reg) + base<EOL>size = dest.size<EOL>arg1 = cpu.read_int(dest_addr, size)<EOL>arg0 = cpu.read_int(src_addr, size)<EOL>res = (arg0 - arg1) & ((<NUM_LIT:1> << size) - <NUM_LIT:1>)<EOL>cpu._calculate_CMP_flags(size, res, arg0, arg1)<EOL>increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // <NUM_LIT:8>, size // <NUM_LIT:8>)<EOL>cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)<EOL>cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)<EOL>

Compares string operands.

Compares the byte, word, double word or quad specified with the first source
operand with the byte, word, double or quad word specified with the second
source operand and sets the status flags in the EFLAGS register according
to the results. Both the source operands are located in memory::

        temp  = SRC1 - SRC2;
        SetStatusFlags(temp);
        IF (byte comparison)
        THEN IF DF  =  0
            THEN
                (E)SI  =  (E)SI + 1;
                (E)DI  =  (E)DI + 1;
            ELSE
                (E)SI  =  (E)SI - 1;
                (E)DI  =  (E)DI - 1;
            FI;
        ELSE IF (word comparison)
            THEN IF DF  =  0
                (E)SI  =  (E)SI + 2;
                (E)DI  =  (E)DI + 2;
            ELSE
                (E)SI  =  (E)SI - 2;
                (E)DI  =  (E)DI - 2;
            FI;
        ELSE (* doubleword comparison*)
            THEN IF DF  =  0
                (E)SI  =  (E)SI + 4;
                (E)DI  =  (E)DI + 4;
            ELSE
                (E)SI  =  (E)SI - 4;
                (E)DI  =  (E)DI - 4;
            FI;
        FI;

:param cpu: current CPU.
:param dest: first source operand.
:param src: second source operand.


@rep<EOL><INDENT>def LODS(cpu, dest, src):<DEDENT>

src_reg = {<NUM_LIT:8>: '<STR_LIT>', <NUM_LIT:32>: '<STR_LIT>', <NUM_LIT:64>: '<STR_LIT>'}[cpu.address_bit_size]<EOL>base, _, ty = cpu.get_descriptor(cpu.DS)<EOL>src_addr = cpu.read_register(src_reg) + base<EOL>size = dest.size<EOL>arg0 = cpu.read_int(src_addr, size)<EOL>dest.write(arg0)<EOL>increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // <NUM_LIT:8>, size // <NUM_LIT:8>)<EOL>cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)<EOL>

Loads string.

Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register, respectively. The
source operand is a memory location, the address of which is read from the DS:ESI or the DS:SI registers
(depending on the address-size attribute of the instruction, 32 or 16, respectively). The DS segment may be over-
ridden with a segment override prefix.
After the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the
(E)SI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS
register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decremented.)
The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for
doubleword operations.

:param cpu: current CPU.
:param dest: source operand.


@rep<EOL><INDENT>def MOVS(cpu, dest, src):<DEDENT>

base, size, ty = cpu.get_descriptor(cpu.DS)<EOL>src_addr = src.address() + base<EOL>dest_addr = dest.address() + base<EOL>src_reg = src.mem.base<EOL>dest_reg = dest.mem.base<EOL>size = dest.size<EOL>dest.write(src.read())<EOL>increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // <NUM_LIT:8>, size // <NUM_LIT:8>)<EOL>cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)<EOL>cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)<EOL>

Moves data from string to string.

Moves the byte, word, or doubleword specified with the second operand (source operand) to the location specified
with the first operand (destination operand). Both the source and destination operands are located in memory. The
address of the source operand is read from the DS:ESI or the DS:SI registers (depending on the address-size
attribute of the instruction, 32 or 16, respectively). The address of the destination operand is read from the ES:EDI
or the ES:DI registers (again depending on the address-size attribute of the instruction). The DS segment may be
overridden with a segment override prefix, but the ES segment cannot be overridden.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@repe<EOL><INDENT>def SCAS(cpu, dest, src):<DEDENT>

dest_reg = dest.reg<EOL>mem_reg = src.mem.base  <EOL>size = dest.size<EOL>arg0 = dest.read()<EOL>arg1 = src.read()<EOL>res = arg0 - arg1<EOL>cpu._calculate_CMP_flags(size, res, arg0, arg1)<EOL>increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // <NUM_LIT:8>, size // <NUM_LIT:8>)<EOL>cpu.write_register(mem_reg, cpu.read_register(mem_reg) + increment)<EOL>

Scans String.

Compares the byte, word, or double word specified with the memory operand
with the value in the AL, AX, EAX, or RAX register, and sets the status flags
according to the results. The memory operand address is read from either
the ES:RDI, ES:EDI or the ES:DI registers (depending on the address-size
attribute of the instruction, 32 or 16, respectively)::

        IF (byte comparison)
        THEN
            temp  =  AL - SRC;
            SetStatusFlags(temp);
            THEN IF DF  =  0
                THEN (E)DI  =  (E)DI + 1;
                ELSE (E)DI  =  (E)DI - 1;
                FI;
            ELSE IF (word comparison)
                THEN
                    temp  =  AX - SRC;
                    SetStatusFlags(temp)
                    THEN IF DF  =  0
                        THEN (E)DI  =  (E)DI + 2;
                        ELSE (E)DI  =  (E)DI - 2;
                        FI;
             ELSE (* doubleword comparison *)
                   temp  =  EAX - SRC;
                   SetStatusFlags(temp)
                   THEN IF DF  =  0
                        THEN
                            (E)DI  =  (E)DI + 4;
                        ELSE
                            (E)DI  =  (E)DI - 4;
                        FI;
                   FI;
             FI;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@rep<EOL><INDENT>def STOS(cpu, dest, src):<DEDENT>

size = src.size<EOL>dest.write(src.read())<EOL>dest_reg = dest.mem.base<EOL>increment = Operators.ITEBV({'<STR_LIT>': <NUM_LIT:64>, '<STR_LIT>': <NUM_LIT:32>, '<STR_LIT>': <NUM_LIT:16>}[dest_reg], cpu.DF, -size // <NUM_LIT:8>, size // <NUM_LIT:8>)<EOL>cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)<EOL>

Stores String.

Stores a byte, word, or doubleword from the AL, AX, or EAX register,
respectively, into the destination operand. The destination operand is
a memory location, the address of which is read from either the ES:EDI
or the ES:DI registers (depending on the address-size attribute of the
instruction, 32 or 16, respectively). The ES segment cannot be overridden
with a segment override prefix.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


cpu.FPTAG = <NUM_LIT><EOL>

Empty MMX Technology State

Sets the values of all the tags in the x87 FPU tag word to empty (all
1s). This operation marks the x87 FPU data registers (which are aliased
to the MMX technology registers) as available for use by x87 FPU
floating-point instructions.

    x87FPUTagWord <- FFFFH;


Store MXCSR Register State
        Stores the contents of the MXCSR control and status register to the destination operand.
        The destination operand is a 32-bit memory location. The reserved bits in the MXCSR register
        are stored as 0s.


@instruction<EOL><INDENT>def ANDN(cpu, dest, src1, src2):<DEDENT>

value = ~src1.read() & src2.read()<EOL>dest.write(value)<EOL>cpu.ZF = value == <NUM_LIT:0><EOL>cpu.SF = (value & (<NUM_LIT:1> << dest.size)) != <NUM_LIT:0><EOL>cpu.OF = False<EOL>cpu.CF = False<EOL>

Performs a bitwise logical AND of inverted second operand (the first source operand)
           with the third operand (the second source operand). The result is stored in the first
           operand (destination operand).

                DEST <- (NOT SRC1) bitwiseAND SRC2;
                SF <- DEST[OperandSize -1];
                ZF <- (DEST = 0);
           Flags Affected
                SF and ZF are updated based on result. OF and CF flags are cleared. AF and PF flags are undefined.


@instruction<EOL><INDENT>def SHLX(cpu, dest, src, count):<DEDENT>

OperandSize = dest.size<EOL>count = count.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND(count & countMask, dest.size)<EOL>tempDest = value = src.read()<EOL>res = dest.write(Operators.ITEBV(dest.size, tempCount == <NUM_LIT:0>, tempDest, value << tempCount))<EOL>

The shift arithmetic left.

Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the
second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF
flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination
operand.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


@instruction<EOL><INDENT>def SHRX(cpu, dest, src, count):<DEDENT>

OperandSize = dest.size<EOL>count = count.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = Operators.ZEXTEND(count & countMask, dest.size)<EOL>tempDest = value = src.read()<EOL>res = dest.write(Operators.ITEBV(dest.size, tempCount == <NUM_LIT:0>, tempDest, value >> tempCount))<EOL>

The shift arithmetic right.

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


@instruction<EOL><INDENT>def SARX(cpu, dest, src, count):<DEDENT>

OperandSize = dest.size<EOL>count = count.read()<EOL>countMask = {<NUM_LIT:8>: <NUM_LIT>,<EOL><NUM_LIT:16>: <NUM_LIT>,<EOL><NUM_LIT:32>: <NUM_LIT>,<EOL><NUM_LIT:64>: <NUM_LIT>}[OperandSize]<EOL>tempCount = count & countMask<EOL>tempDest = value = src.read()<EOL>sign = value & (<NUM_LIT:1> << (OperandSize - <NUM_LIT:1>))<EOL>while tempCount != <NUM_LIT:0>:<EOL><INDENT>cpu.CF = (value & <NUM_LIT>) != <NUM_LIT:0>  <EOL>value = (value >> <NUM_LIT:1>) | sign<EOL>tempCount = tempCount - <NUM_LIT:1><EOL><DEDENT>res = dest.write(value)<EOL>


@instruction<EOL><INDENT>def PMINUB(cpu, dest, src):<DEDENT>

dest_value = dest.read()<EOL>src_value = src.read()<EOL>result = <NUM_LIT:0><EOL>for pos in range(<NUM_LIT:0>, dest.size, <NUM_LIT:8>):<EOL><INDENT>itema = (dest_value >> pos) & <NUM_LIT><EOL>itemb = (src_value >> pos) & <NUM_LIT><EOL>result |= Operators.ITEBV(dest.size, itema < itemb, itema, itemb) << pos<EOL><DEDENT>dest.write(result)<EOL>

PMINUB: returns minimum of packed unsigned byte integers in the dest operand
see PMAXUB


@instruction<EOL><INDENT>def PMAXUB(cpu, dest, src):<DEDENT>

dest_value = dest.read()<EOL>src_value = src.read()<EOL>result = <NUM_LIT:0><EOL>for pos in range(<NUM_LIT:0>, dest.size, <NUM_LIT:8>):<EOL><INDENT>itema = (dest_value >> pos) & <NUM_LIT><EOL>itemb = (src_value >> pos) & <NUM_LIT><EOL>result |= Operators.ITEBV(dest.size, itema > itemb, itema, itemb) << pos<EOL><DEDENT>dest.write(result)<EOL>

PMAXUB: returns maximum of packed unsigned byte integers in the dest operand

Performs a SIMD compare of the packed unsigned byte in the second source operand
and the first source operand and returns the maximum value for each pair of
integers to the destination operand.

Example :
$xmm1.v16_int8 = {..., 0xf2, 0xd1}
$xmm2.v16_int8 = {..., 0xd2, 0xf1}
# after pmaxub xmm1, xmm2, we get
$xmm1.v16_int8 = {..., 0xf2, 0xf1}


@instruction<EOL><INDENT>def PXOR(cpu, dest, src):<DEDENT>

res = dest.write(dest.read() ^ src.read())<EOL>

Logical exclusive OR.

Performs a bitwise logical exclusive-OR (XOR) operation on the quadword
source (second) and destination (first) operands and stores the result
in the destination operand location. The source operand can be an MMX(TM)
technology register or a quadword memory location; the destination operand
must be an MMX register. Each bit of the result is 1 if the corresponding
bits of the two operands are different; each bit is 0 if the corresponding
bits of the operands are the same::

    DEST  =  DEST XOR SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: quadword source operand.


def _PUNPCKL(cpu, dest, src, item_size):

assert dest.size == src.size<EOL>size = dest.size<EOL>dest_value = dest.read()<EOL>src_value = src.read()<EOL>mask = (<NUM_LIT:1> << item_size) - <NUM_LIT:1><EOL>res = <NUM_LIT:0><EOL>count = <NUM_LIT:0><EOL>for pos in range(<NUM_LIT:0>, size // item_size):<EOL><INDENT>if count >= size:<EOL><INDENT>break<EOL><DEDENT>item0 = Operators.ZEXTEND((dest_value >> (pos * item_size)) & mask, size)<EOL>item1 = Operators.ZEXTEND((src_value >> (pos * item_size)) & mask, size)<EOL>res |= item0 << count<EOL>count += item_size<EOL>res |= item1 << count<EOL>count += item_size<EOL><DEDENT>dest.write(res)<EOL>


def _PUNPCKH(cpu, dest, src, item_size):

assert dest.size == src.size<EOL>size = dest.size<EOL>dest_value = dest.read()<EOL>src_value = src.read()<EOL>mask = (<NUM_LIT:1> << item_size) - <NUM_LIT:1><EOL>res = <NUM_LIT:0><EOL>count = <NUM_LIT:0><EOL>for pos in reversed(range(<NUM_LIT:0>, size // item_size)):<EOL><INDENT>if count >= size:<EOL><INDENT>break<EOL><DEDENT>item0 = Operators.ZEXTEND((dest_value >> (pos * item_size)) & mask, size)<EOL>item1 = Operators.ZEXTEND((src_value >> (pos * item_size)) & mask, size)<EOL>res = res << item_size<EOL>res |= item1<EOL>res = res << item_size<EOL>res |= item0<EOL>count += item_size * <NUM_LIT:2><EOL><DEDENT>dest.write(res)<EOL>


@instruction<EOL><INDENT>def PUNPCKLBW(cpu, dest, src):<DEDENT>

cpu._PUNPCKL(dest, src, <NUM_LIT:8>)<EOL>

Interleaves the low-order bytes of the source and destination operands.

Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords)
of the destination operand (first operand) and source operand (second operand) into the
destination operand.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def PUNPCKLWD(cpu, dest, src):<DEDENT>

cpu._PUNPCKL(dest, src, <NUM_LIT:16>)<EOL>


@instruction<EOL><INDENT>def PUNPCKLQDQ(cpu, dest, src):<DEDENT>

cpu._PUNPCKL(dest, src, <NUM_LIT:64>)<EOL>

Interleaves the low-order quad-words of the source and destination operands.

Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords)
of the destination operand (first operand) and source operand (second operand) into the
destination operand.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def PUNPCKLDQ(cpu, dest, src):<DEDENT>

cpu._PUNPCKL(dest, src, <NUM_LIT:32>)<EOL>

Interleaves the low-order double-words of the source and destination operands.

Unpacks and interleaves the low-order data elements (bytes, words, doublewords, and quadwords)
of the destination operand (first operand) and source operand (second operand) into the
destination operand.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def PSHUFW(cpu, op0, op1, op3):<DEDENT>

size = op0.size<EOL>arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>arg3 = Operators.ZEXTEND(op3.read(), size)<EOL>assert size == <NUM_LIT:64><EOL>arg0 |= ((arg1 >> ((arg3 >> <NUM_LIT:0>) & <NUM_LIT:3> * <NUM_LIT:16>)) & <NUM_LIT>)<EOL>arg0 |= ((arg1 >> ((arg3 >> <NUM_LIT:2>) & <NUM_LIT:3> * <NUM_LIT:16>)) & <NUM_LIT>) << <NUM_LIT:16><EOL>arg0 |= ((arg1 >> ((arg3 >> <NUM_LIT:4>) & <NUM_LIT:3> * <NUM_LIT:16>)) & <NUM_LIT>) << <NUM_LIT:32><EOL>arg0 |= ((arg1 >> ((arg3 >> <NUM_LIT:6>) & <NUM_LIT:3> * <NUM_LIT:16>)) & <NUM_LIT>) << <NUM_LIT><EOL>op0.write(arg0)<EOL>

Packed shuffle words.

Copies doublewords from source operand (second operand) and inserts them in the destination operand
(first operand) at locations selected with the order operand (third operand).

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.
:param op3: order operand.


@instruction<EOL><INDENT>def PSHUFLW(cpu, op0, op1, op3):<DEDENT>

size = op0.size<EOL>arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>arg3 = Operators.ZEXTEND(op3.read(), size)<EOL>arg0 = arg1 & <NUM_LIT><EOL>arg0 |= ((arg1 >> (((arg3 >> <NUM_LIT:0>) & <NUM_LIT:3>) * <NUM_LIT:16>)) & <NUM_LIT>)<EOL>arg0 |= ((arg1 >> (((arg3 >> <NUM_LIT:2>) & <NUM_LIT:3>) * <NUM_LIT:16>)) & <NUM_LIT>) << <NUM_LIT:16><EOL>arg0 |= ((arg1 >> (((arg3 >> <NUM_LIT:4>) & <NUM_LIT:3>) * <NUM_LIT:16>)) & <NUM_LIT>) << <NUM_LIT:32><EOL>arg0 |= ((arg1 >> (((arg3 >> <NUM_LIT:6>) & <NUM_LIT:3>) * <NUM_LIT:16>)) & <NUM_LIT>) << <NUM_LIT><EOL>op0.write(arg0)<EOL>

Shuffle Packed Low Words

Copies words from the low quadword of the source operand (second operand)
and inserts them in the low quadword of the destination operand (first operand)
at word locations selected with the order operand (third operand).

This operation is similar to the operation used by the PSHUFD instruction.

    Operation
    Destination[0..15] = (Source >> (Order[0..1] * 16))[0..15];
    Destination[16..31] = (Source >> (Order[2..3] * 16))[0..15];
    Destination[32..47] = (Source >> (Order[4..5] * 16))[0..15];
    Destination[48..63] = (Source >> (Order[6..7] * 16))[0..15];
    Destination[64..127] = Source[64..127];


@instruction<EOL><INDENT>def PSHUFD(cpu, op0, op1, op3):<DEDENT>

size = op0.size<EOL>arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>order = Operators.ZEXTEND(op3.read(), size)<EOL>arg0 = arg0 & <NUM_LIT><EOL>arg0 |= ((arg1 >> (((order >> <NUM_LIT:0>) & <NUM_LIT:3>) * <NUM_LIT:32>)) & <NUM_LIT>)<EOL>arg0 |= ((arg1 >> (((order >> <NUM_LIT:2>) & <NUM_LIT:3>) * <NUM_LIT:32>)) & <NUM_LIT>) << <NUM_LIT:32><EOL>arg0 |= ((arg1 >> (((order >> <NUM_LIT:4>) & <NUM_LIT:3>) * <NUM_LIT:32>)) & <NUM_LIT>) << <NUM_LIT:64><EOL>arg0 |= ((arg1 >> (((order >> <NUM_LIT:6>) & <NUM_LIT:3>) * <NUM_LIT:32>)) & <NUM_LIT>) << <NUM_LIT><EOL>op0.write(arg0)<EOL>

Packed shuffle doublewords.

Copies doublewords from source operand (second operand) and inserts them in the destination operand
(first operand) at locations selected with the order operand (third operand).

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.
:param op3: order operand.


@instruction<EOL><INDENT>def MOVDQU(cpu, op0, op1):<DEDENT>

Moves unaligned double quadword.

Moves a double quadword from the source operand (second operand) to the destination operand
(first operand)::

    OP0  =  OP1;

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.


@instruction<EOL><INDENT>def MOVDQA(cpu, op0, op1):<DEDENT>

Moves aligned double quadword.

Moves a double quadword from the source operand (second operand) to the destination operand
(first operand)::
    OP0  =  OP1;

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.
@todo: check alignment.


@instruction<EOL><INDENT>def PCMPEQB(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:8>):<EOL><INDENT>res = Operators.ITEBV(op0.size, Operators.EXTRACT(arg0, i, <NUM_LIT:8>) == Operators.EXTRACT(arg1, i, <NUM_LIT:8>), res | (<NUM_LIT> << i), res)<EOL><DEDENT>op0.write(res)<EOL>

Packed compare for equal.

Performs a SIMD compare for equality of the packed bytes, words, or doublewords in the
destination operand (first operand) and the source operand (second operand). If a pair of
data elements are equal, the corresponding data element in the destination operand is set
to all 1s; otherwise, it is set to all 0s. The source operand can be an MMX(TM) technology
register or a 64-bit memory location, or it can be an XMM register or a 128-bit memory location.
The destination operand can be an MMX or an XMM register.
The PCMPEQB instruction compares the bytes in the destination operand to the corresponding bytes
in the source operand.

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.


@instruction<EOL><INDENT>def PCMPEQD(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:32>):<EOL><INDENT>res = Operators.ITEBV(op0.size, Operators.EXTRACT(arg0, i, <NUM_LIT:32>) == Operators.EXTRACT(arg1, i, <NUM_LIT:32>), res | (<NUM_LIT> << i), res)<EOL><DEDENT>op0.write(res)<EOL>

PCMPEQD: Packed compare for equal with double words
see PCMPEQB


@instruction<EOL><INDENT>def PCMPGTD(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:32>):<EOL><INDENT>res = Operators.ITEBV(op0.size, Operators.EXTRACT(arg0, i, <NUM_LIT:32>) > Operators.EXTRACT(arg1, i, <NUM_LIT:32>), res | (<NUM_LIT> << i), res)<EOL><DEDENT>op0.write(res)<EOL>

PCMPGTD: Packed compare for greater than with double words
see PCMPEQB


@instruction<EOL><INDENT>def PADDD(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:32>):<EOL><INDENT>res |= ((Operators.EXTRACT(arg0, i, <NUM_LIT:32>) + Operators.EXTRACT(arg1, i, <NUM_LIT:32>)) & <NUM_LIT>) << i<EOL><DEDENT>op0.write(res)<EOL>

PADDD: Packed add with double words

Performs a SIMD add of the packed integers from the source operand (second operand)
and the destination operand (first operand), and stores the packed integer results
in the destination operand

Example :
$xmm1.v16_int8 = {..., 0x00000003, 0x00000001}
$xmm2.v16_int8 = {..., 0x00000004, 0x00000002}
# after paddd xmm1, xmm2, we get
$xmm1.v16_int8 = {..., 0x00000007, 0x00000003}


@instruction<EOL><INDENT>def PADDQ(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:64>):<EOL><INDENT>res |= ((Operators.EXTRACT(arg0, i, <NUM_LIT:64>) + Operators.EXTRACT(arg1, i, <NUM_LIT:64>)) & <NUM_LIT>) << i<EOL><DEDENT>op0.write(res)<EOL>

PADDQ: Packed add with quadruple words
see PADDD


@instruction<EOL><INDENT>def PSLLD(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:32>):<EOL><INDENT>res |= ((Operators.EXTRACT(arg0, i, <NUM_LIT:32>) << arg1) & <NUM_LIT>) << i<EOL><DEDENT>op0.write(res)<EOL>

PSLLD: Packed shift left logical with double words

Shifts the destination operand (first operand) to the left by the number of bytes specified
in the count operand (second operand). The empty low-order bytes are cleared (set to all 0s).
If the value specified by the count operand is greater than 15, the destination operand is
set to all 0s. The count operand is an 8-bit immediate.

Example :
$xmm1.v16_int8 = {..., 0x00000003, 0x00000001}
# after pslld xmm1, 2, we get
$xmm1.v16_int8 = {..., 0x0000000c, 0x00000004}


@instruction<EOL><INDENT>def PSLLQ(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, op0.size, <NUM_LIT:64>):<EOL><INDENT>res |= ((Operators.EXTRACT(arg0, i, <NUM_LIT:64>) << arg1) & <NUM_LIT>) << i<EOL><DEDENT>op0.write(res)<EOL>

PSLLQ: Packed shift left logical with quadruple words
see PSLLD


@instruction<EOL><INDENT>def PMOVMSKB(cpu, op0, op1):<DEDENT>

arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>res = <NUM_LIT:0><EOL>for i in reversed(range(<NUM_LIT:7>, op1.size, <NUM_LIT:8>)):<EOL><INDENT>res = (res << <NUM_LIT:1>) | ((arg1 >> i) & <NUM_LIT:1>)<EOL><DEDENT>op0.write(Operators.EXTRACT(res, <NUM_LIT:0>, op0.size))<EOL>

Moves byte mask to general-purpose register.

Creates an 8-bit mask made up of the most significant bit of each byte of the source operand
(second operand) and stores the result in the low byte or word of the destination operand
(first operand). The source operand is an MMX(TM) technology or an XXM register; the destination
operand is a general-purpose register.

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.


@instruction<EOL><INDENT>def PSRLDQ(cpu, dest, src):<DEDENT>

<EOL>temp = Operators.EXTRACT(src.read(), <NUM_LIT:0>, <NUM_LIT:8>)<EOL>temp = Operators.ITEBV(src.size, temp > <NUM_LIT:15>, <NUM_LIT:16>, temp)<EOL>dest.write(dest.read() >> (temp * <NUM_LIT:8>))<EOL>

Packed shift right logical double quadword.

Shifts the destination operand (first operand) to the right by the number
of bytes specified in the count operand (second operand). The empty high-order
bytes are cleared (set to all 0s). If the value specified by the count
operand is greater than 15, the destination operand is set to all 0s.
The destination operand is an XMM register. The count operand is an 8-bit
immediate::

    TEMP  =  SRC;
    if (TEMP > 15) TEMP  =  16;
    DEST  =  DEST >> (temp * 8);

:param cpu: current CPU.
:param dest: destination operand.
:param src: count operand.


No Operation.

Performs no operation. This instruction is a one-byte instruction that  takes up space in the
instruction stream but does not affect the machine.
The NOP instruction is an alias mnemonic for the XCHG (E)AX, (E)AX instruction.

:param cpu: current CPU.
:param arg0: this argument is ignored.


@instruction<EOL><INDENT>def MOVZX(cpu, op0, op1):<DEDENT>

op0.write(Operators.ZEXTEND(op1.read(), op0.size))<EOL>

Moves with zero-extend.

Copies the contents of the source operand (register or memory location) to the destination
operand (register) and zero extends the value to 16 or 32 bits. The size of the converted value
depends on the operand-size attribute::

        OP0  =  ZeroExtend(OP1);

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.


@instruction<EOL><INDENT>def MOVSX(cpu, op0, op1):<DEDENT>

op0.write(Operators.SEXTEND(op1.read(), op1.size, op0.size))<EOL>

Moves with sign-extension.

Copies the contents of the source operand (register or memory location) to the destination
operand (register) and sign extends the value to 16::

        OP0  =  SignExtend(OP1);

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.


@instruction<EOL><INDENT>def MOVSXD(cpu, op0, op1):<DEDENT>

Move DWORD with sign extension to QWORD.


res = Operators.SEXTEND(cpu.RAX, <NUM_LIT:64>, <NUM_LIT>)<EOL>cpu.RAX = Operators.EXTRACT(res, <NUM_LIT:0>, <NUM_LIT:64>)<EOL>cpu.RDX = Operators.EXTRACT(res, <NUM_LIT:64>, <NUM_LIT:64>)<EOL>


cpu.RAX = Operators.SEXTEND(cpu.EAX, <NUM_LIT:32>, <NUM_LIT:64>)<EOL>


cpu.EDX = Operators.EXTRACT(Operators.SEXTEND(cpu.EAX, <NUM_LIT:32>, <NUM_LIT:64>), <NUM_LIT:32>, <NUM_LIT:32>)<EOL>


bit = Operators.EXTRACT(cpu.AX, <NUM_LIT:15>, <NUM_LIT:1>)<EOL>cpu.EAX = Operators.SEXTEND(cpu.AX, <NUM_LIT:16>, <NUM_LIT:32>)<EOL>cpu.EDX = Operators.SEXTEND(bit, <NUM_LIT:1>, <NUM_LIT:32>)<EOL>

Converts word to doubleword.

::
    DX = sign-extend of AX.

:param cpu: current CPU.


cpu.AX = Operators.SEXTEND(cpu.AL, <NUM_LIT:8>, <NUM_LIT:16>)<EOL>

Converts byte to word.

Double the size of the source operand by means of sign extension::

        AX = sign-extend of AL.

:param cpu: current CPU.


val = cpu.icount<EOL>cpu.RAX = val & <NUM_LIT><EOL>cpu.RDX = (val >> <NUM_LIT:32>) & <NUM_LIT><EOL>

Reads time-stamp counter.

Loads the current value of the processor's time-stamp counter into the
EDX:EAX registers.  The time-stamp counter is contained in a 64-bit
MSR. The high-order 32 bits of the MSR are loaded into the EDX
register, and the low-order 32 bits are loaded into the EAX register.
The processor increments the time-stamp counter MSR every clock cycle
and resets it to 0 whenever the processor is reset.

:param cpu: current CPU.


cpu.write_int(dest.address(), cpu.FPCW, <NUM_LIT:16>)<EOL>

Stores x87 FPU Control Word.

Stores the current value of the FPU control word at the specified destination in memory.
The FSTCW instruction checks for and handles pending unmasked floating-point exceptions
before storing the control word; the FNSTCW instruction does not::

    DEST  =  FPUControlWord;

:param cpu: current CPU.
:param dest: destination operand.


cpu.RCX = cpu.RIP<EOL>cpu.R11 = cpu.RFLAGS<EOL>raise Syscall()<EOL>

Calls to interrupt procedure.

The INT n instruction generates a call to the interrupt or exception handler specified
with the destination operand. The INT n instruction is the general mnemonic for executing
a software-generated call to an interrupt handler. The INTO instruction is a special
mnemonic for calling overflow exception (#OF), interrupt vector number 4. The overflow
interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler
if the OF flag is set to 1.

:param cpu: current CPU.


@instruction<EOL><INDENT>def MOVLPD(cpu, dest, src):<DEDENT>

value = src.read()<EOL>if src.size == <NUM_LIT:64> and dest.size == <NUM_LIT>:<EOL><INDENT>value = (dest.read() & <NUM_LIT>) | Operators.ZEXTEND(value, <NUM_LIT>)<EOL><DEDENT>dest.write(value)<EOL>

Moves low packed double-precision floating-point value.

Moves a double-precision floating-point value from the source operand (second operand) and the
destination operand (first operand). The source and destination operands can be an XMM register
or a 64-bit memory location. This instruction allows double-precision floating-point values to be moved
to and from the low quadword of an XMM register and memory. It cannot be used for register to register
or memory to memory moves. When the destination operand is an XMM register, the high quadword of the
register remains unchanged.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def MOVHPD(cpu, dest, src):<DEDENT>

if src.size == <NUM_LIT>:<EOL><INDENT>assert dest.size == <NUM_LIT:64><EOL>dest.write(Operators.EXTRACT(src.read(), <NUM_LIT:64>, <NUM_LIT:64>))<EOL><DEDENT>else:<EOL><INDENT>assert src.size == <NUM_LIT:64> and dest.size == <NUM_LIT><EOL>value = Operators.EXTRACT(dest.read(), <NUM_LIT:0>, <NUM_LIT:64>)  <EOL>dest.write(Operators.CONCAT(<NUM_LIT>, src.read(), value))<EOL><DEDENT>

Moves high packed double-precision floating-point value.

Moves a double-precision floating-point value from the source operand (second operand) and the
destination operand (first operand). The source and destination operands can be an XMM register
or a 64-bit memory location. This instruction allows double-precision floating-point values to be moved
to and from the high quadword of an XMM register and memory. It cannot be used for register to
register or memory to memory moves. When the destination operand is an XMM register, the low quadword
of the register remains unchanged.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def PSUBB(cpu, dest, src):<DEDENT>

result = []<EOL>value_a = dest.read()<EOL>value_b = src.read()<EOL>for i in reversed(range(<NUM_LIT:0>, dest.size, <NUM_LIT:8>)):<EOL><INDENT>a = Operators.EXTRACT(value_a, i, <NUM_LIT:8>)<EOL>b = Operators.EXTRACT(value_b, i, <NUM_LIT:8>)<EOL>result.append((a - b) & <NUM_LIT>)<EOL><DEDENT>dest.write(Operators.CONCAT(<NUM_LIT:8> * len(result), *result))<EOL>

Packed subtract.

Performs a SIMD subtract of the packed integers of the source operand (second operand) from the packed
integers of the destination operand (first operand), and stores the packed integer results in the
destination operand. The source operand can be an MMX(TM) technology register or a 64-bit memory location,
or it can be an XMM register or a 128-bit memory location. The destination operand can be an MMX or an XMM
register.
The PSUBB instruction subtracts packed byte integers. When an individual result is too large or too small
to be represented in a byte, the result is wrapped around and the low 8 bits are written to the
destination element.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def POR(cpu, dest, src):<DEDENT>

res = dest.write(dest.read() | src.read())<EOL>

Performs a bitwise logical OR operation on the source operand (second operand) and the destination operand
(first operand) and stores the result in the destination operand. The source operand can be an MMX technology
register or a 64-bit memory location or it can be an XMM register or a 128-bit memory location. The destination
operand can be an MMX technology register or an XMM register. Each bit of the result is set to 1 if either
or both of the corresponding bits of the first and second operands are 1; otherwise, it is set to 0.


@instruction<EOL><INDENT>def XORPS(cpu, dest, src):<DEDENT>

res = dest.write(dest.read() ^ src.read())<EOL>


@instruction<EOL><INDENT>def VORPD(cpu, dest, src, src2):<DEDENT>

res = dest.write(src.read() | src2.read())<EOL>

Performs a bitwise logical OR operation on the source operand (second operand) and second source operand (third operand)
 and stores the result in the destination operand (first operand).


@instruction<EOL><INDENT>def VORPS(cpu, dest, src, src2):<DEDENT>


@instruction<EOL><INDENT>def MOVAPS(cpu, dest, src):<DEDENT>

dest.write(src.read())<EOL>

Moves aligned packed single-precision floating-point values.

Moves a double quadword containing four packed single-precision floating-point numbers from the
source operand (second operand) to the destination operand (first operand). This instruction can be
used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register
into a 128-bit memory location, or move data between two XMM registers.
When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte
boundary or a general-protection exception (#GP) will be generated::

        DEST  =  SRC;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def MOVQ(cpu, dest, src):<DEDENT>

<EOL>if dest.size == src.size and dest.size == <NUM_LIT:64>:<EOL><INDENT>dest.write(src.read())<EOL><DEDENT>elif dest.size == src.size and dest.size == <NUM_LIT>:<EOL><INDENT>src_lo = Operators.EXTRACT(src.read(), <NUM_LIT:0>, <NUM_LIT:64>)<EOL>dest.write(Operators.ZEXTEND(src_lo, <NUM_LIT>))<EOL><DEDENT>elif dest.size == <NUM_LIT> and src.size == <NUM_LIT:64>:<EOL><INDENT>dest.write(Operators.ZEXTEND(src.read(), dest.size))<EOL><DEDENT>elif dest.size == <NUM_LIT:64> and src.size == <NUM_LIT>:<EOL><INDENT>dest.write(Operators.EXTRACT(src.read(), <NUM_LIT:0>, dest.size))<EOL><DEDENT>else:<EOL><INDENT>msg = '<STR_LIT>'<EOL>logger.error(msg)<EOL>raise Exception(msg)<EOL><DEDENT>

Move quadword.

Copies a quadword from the source operand (second operand) to the destination operand (first operand).
The source and destination operands can be MMX(TM) technology registers, XMM registers, or 64-bit memory
locations. This instruction can be used to move a between two MMX registers or between an MMX register
and a 64-bit memory location, or to move data between two XMM registers or between an XMM register and
a 64-bit memory location. The instruction cannot be used to transfer data between memory locations.
When the source operand is an XMM register, the low quadword is moved; when the destination operand is
an XMM register, the quadword is stored to the low quadword of the register, and the high quadword is
cleared to all 0s::

    MOVQ instruction when operating on MMX registers and memory locations:

    DEST  =  SRC;

    MOVQ instruction when source and destination operands are XMM registers:

    DEST[63-0]  =  SRC[63-0];

    MOVQ instruction when source operand is XMM register and destination operand is memory location:

    DEST  =  SRC[63-0];

    MOVQ instruction when source operand is memory location and destination operand is XMM register:

    DEST[63-0]  =  SRC;
    DEST[127-64]  =  0000000000000000H;

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def MOVSD(cpu, dest, src):<DEDENT>

assert dest.type != '<STR_LIT>' or src.type != '<STR_LIT>'<EOL>value = Operators.EXTRACT(src.read(), <NUM_LIT:0>, <NUM_LIT:64>)<EOL>if dest.size > src.size:<EOL><INDENT>value = Operators.ZEXTEND(value, dest.size)<EOL><DEDENT>dest.write(value)<EOL>

Move Scalar Double-Precision Floating-Point Value

Moves a scalar double-precision floating-point value from the source
operand (second operand) to the destination operand (first operand).
The source and destination operands can be XMM registers or 64-bit memory
locations. This instruction can be used to move a double-precision
floating-point value to and from the low quadword of an XMM register and
a 64-bit memory location, or to move a double-precision floating-point
value between the low quadwords of two XMM registers. The instruction
cannot be used to transfer data between memory locations.
When the source and destination operands are XMM registers, the high
quadword of the destination operand remains unchanged. When the source
operand is a memory location and destination operand is an XMM registers,
the high quadword of the destination operand is cleared to all 0s.

:param cpu: current CPU.
:param dest: destination operand.
:param src: source operand.


@instruction<EOL><INDENT>def MOVSS(cpu, dest, src):<DEDENT>

if dest.type == '<STR_LIT>' and src.type == '<STR_LIT>':<EOL><INDENT>assert dest.size == <NUM_LIT> and src.size == <NUM_LIT><EOL>dest.write(dest.read() & ~<NUM_LIT> | src.read() & <NUM_LIT>)<EOL><DEDENT>elif dest.type == '<STR_LIT>':<EOL><INDENT>assert src.type == '<STR_LIT>'<EOL>dest.write(Operators.EXTRACT(src.read(), <NUM_LIT:0>, dest.size))<EOL><DEDENT>else:<EOL><INDENT>assert src.type == '<STR_LIT>' and dest.type == '<STR_LIT>'<EOL>assert src.size == <NUM_LIT:32> and dest.size == <NUM_LIT><EOL>dest.write(Operators.ZEXTEND(src.read(), <NUM_LIT>))<EOL><DEDENT>

Moves a scalar single-precision floating-point value

Moves a scalar single-precision floating-point value from the source operand (second operand)
to the destination operand (first operand). The source and destination operands can be XMM
registers or 32-bit memory locations. This instruction can be used to move a single-precision
floating-point value to and from the low doubleword of an XMM register and a 32-bit memory
location, or to move a single-precision floating-point value between the low doublewords of
two XMM registers. The instruction cannot be used to transfer data between memory locations.
When the source and destination operands are XMM registers, the three high-order doublewords of the
destination operand remain unchanged. When the source operand is a memory location and destination
operand is an XMM registers, the three high-order doublewords of the destination operand are cleared to all 0s.

//MOVSS instruction when source and destination operands are XMM registers:
if(IsXMM(Source) && IsXMM(Destination))
    Destination[0..31] = Source[0..31];
    //Destination[32..127] remains unchanged
    //MOVSS instruction when source operand is XMM register and destination operand is memory location:
else if(IsXMM(Source) && IsMemory(Destination))
    Destination = Source[0..31];
//MOVSS instruction when source operand is memory location and destination operand is XMM register:
else {
        Destination[0..31] = Source;
        Destination[32..127] = 0;
}


@instruction<EOL><INDENT>def VMOVDQA(cpu, dest, src):<DEDENT>

<EOL>dest.write(src.read())<EOL>

Move Aligned Double Quadword

Moves 128 bits of packed integer values from the source operand (second
operand) to the destination operand (first operand). This instruction
can be used to load an XMM register from a 128-bit memory location, to
store the contents of an XMM register into a 128-bit memory location, or
to move data between two XMM registers.

When the source or destination operand is a memory operand, the operand
must be aligned on a 16-byte boundary or a general-protection exception
(#GP) will be generated. To move integer data to and from unaligned
memory locations, use the VMOVDQU instruction.


@instruction<EOL><INDENT>def VMOVDQU(cpu, dest, src):<DEDENT>

<EOL>dest.write(src.read())<EOL>

Move Unaligned Double Quadword

Moves 128 bits of packed integer values from the source operand (second operand)
to the destination operand (first operand). This instruction can be used to load
an XMM register from a 128-bit memory location, to store the contents of an XMM
register into a 128-bit memory location, or to move data between two XMM registers.
When the source or destination operand is a memory operand, the operand may be
unaligned on a 16-byte boundary without causing a general-protection exception
(#GP) to be generated.

    VMOVDQU (VEX.128 encoded version)
    DEST[127:0] <- SRC[127:0]
    DEST[VLMAX-1:128] <- 0
    VMOVDQU (VEX.256 encoded version)
    DEST[255:0] <- SRC[255:0]


@instruction<EOL><INDENT>def VEXTRACTF128(cpu, dest, src, offset):<DEDENT>

offset = offset.read()<EOL>dest.write(Operators.EXTRACT(src.read(), offset * <NUM_LIT>, (offset + <NUM_LIT:1>) * <NUM_LIT>))<EOL>

Extract Packed Floating-Point Values

        Extracts 128-bits of packed floating-point values from the source
        operand (second operand) at an 128-bit offset from imm8[0] into the
        destination operand (first operand). The destination may be either an
        XMM register or an 128-bit memory location.


Not implemented.

Performs no operation.


@instruction<EOL><INDENT>def PALIGNR(cpu, dest, src, offset):<DEDENT>

dest.write(<EOL>Operators.EXTRACT(<EOL>Operators.CONCAT(dest.size * <NUM_LIT:2>, dest.read(), src.read()),<EOL>offset.read() * <NUM_LIT:8>,<EOL>dest.size))<EOL>

ALIGNR concatenates the destination operand (the first operand) and the source
            operand (the second operand) into an intermediate composite, shifts the composite
            at byte granularity to the right by a constant immediate, and extracts the right-
            aligned result into the destination.


@instruction<EOL><INDENT>def PSLLDQ(cpu, dest, src):<DEDENT>

count = Operators.ZEXTEND(src.read(), dest.size * <NUM_LIT:2>)<EOL>byte_count = Operators.ITEBV(src.size * <NUM_LIT:2>, count > <NUM_LIT:15>, <NUM_LIT:16>, count)<EOL>bit_count = byte_count * <NUM_LIT:8><EOL>val = Operators.ZEXTEND(dest.read(), dest.size * <NUM_LIT:2>)<EOL>val = val << (Operators.ZEXTEND(bit_count, dest.size * <NUM_LIT:2>))<EOL>dest.write(Operators.EXTRACT(val, <NUM_LIT:0>, dest.size))<EOL>

Packed Shift Left Logical Double Quadword
        Shifts the destination operand (first operand) to the left by the number
         of bytes specified in the count operand (second operand). The empty low-order
         bytes are cleared (set to all 0s). If the value specified by the count
         operand is greater than 15, the destination operand is set to all 0s.
         The destination operand is an XMM register. The count operand is an 8-bit
         immediate.

            TEMP  =  COUNT;
            if (TEMP > 15) TEMP  =  16;
            DEST  =  DEST << (TEMP * 8);


@instruction<EOL><INDENT>def PSRLQ(cpu, dest, src):<DEDENT>

count = src.read()<EOL>count = Operators.ITEBV(src.size, Operators.UGT(count, <NUM_LIT>), <NUM_LIT:64>, count)<EOL>count = Operators.EXTRACT(count, <NUM_LIT:0>, <NUM_LIT:64>)<EOL>if dest.size == <NUM_LIT:64>:<EOL><INDENT>dest.write(dest.read() >> count)<EOL><DEDENT>else:<EOL><INDENT>hi = Operators.EXTRACT(dest.read(), <NUM_LIT:64>, <NUM_LIT:64>) >> count<EOL>low = Operators.EXTRACT(dest.read(), <NUM_LIT:0>, <NUM_LIT:64>) >> count<EOL>dest.write(Operators.CONCAT(<NUM_LIT>, hi, low))<EOL><DEDENT>

Shift Packed Data Right Logical

        Shifts the bits in the individual quadword in the destination operand to the right by
        the number of bits specified in the count operand . As the bits in the data elements
        are shifted right, the empty high-order bits are cleared (set to 0). If the value
        specified by the count operand is greater than  63, then the destination operand is set
        to all 0s.

        if(OperandSize == 64) {
                        //PSRLQ instruction with 64-bit operand:
                        if(Count > 63) Destination[64..0] = 0;
                        else Destination = ZeroExtend(Destination >> Count);
                }
                else {
                        //PSRLQ instruction with 128-bit operand:
                        if(Count > 15) Destination[128..0] = 0;
                        else {
                                Destination[0..63] = ZeroExtend(Destination[0..63] >> Count);
                                Destination[64..127] = ZeroExtend(Destination[64..127] >> Count);
                        }
                }


raise Syscall()<EOL>

Calls to system

Executes a fast call to a level 0 system procedure or routine

:param cpu: current CPU.


@instruction<EOL><INDENT>def TZCNT(cpu, dest, src):<DEDENT>

value = src.read()<EOL>flag = Operators.EXTRACT(value, <NUM_LIT:0>, <NUM_LIT:1>) == <NUM_LIT:1><EOL>res = <NUM_LIT:0><EOL>for pos in range(<NUM_LIT:1>, src.size):<EOL><INDENT>res = Operators.ITEBV(dest.size, flag, res, pos)<EOL>flag = Operators.OR(flag, Operators.EXTRACT(value, pos, <NUM_LIT:1>) == <NUM_LIT:1>)<EOL><DEDENT>cpu.CF = res == src.size<EOL>cpu.ZF = res == <NUM_LIT:0><EOL>dest.write(res)<EOL>

Count the number of trailing least significant zero bits in source
operand (second operand) and returns the result in destination
operand (first operand). TZCNT is an extension of the BSF instruction.

The key difference between TZCNT and BSF instruction is that TZCNT
provides operand size as output when source operand is zero while in
the case of BSF instruction, if source operand is zero, the content of
destination operand are undefined. On processors that do not support
TZCNT, the instruction byte encoding is executed as BSF


@instruction<EOL><INDENT>def VPSHUFB(cpu, op0, op1, op3):<DEDENT>

size = op0.size<EOL>arg0 = op0.read()<EOL>arg1 = op1.read()<EOL>arg3 = Operators.ZEXTEND(op3.read(), size)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT:7>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, (arg1 >> ((arg3 >> <NUM_LIT:0>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT:15>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT:8>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT:8>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT:16>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT:16>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT:32>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT:32>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT:64>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT:64>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>arg0 |= Operators.ITEBV(size, Operators.EXTRACT(arg3, <NUM_LIT>, <NUM_LIT:1>) == <NUM_LIT:1>, <NUM_LIT:0>, ((arg1 >> ((arg3 >> <NUM_LIT>) & <NUM_LIT:7> * <NUM_LIT:8>)) & <NUM_LIT>) << <NUM_LIT>)<EOL>op0.write(arg0)<EOL>

Packed shuffle bytes.

Copies bytes from source operand (second operand) and inserts them in the destination operand
(first operand) at locations selected with the order operand (third operand).

:param cpu: current CPU.
:param op0: destination operand.
:param op1: source operand.
:param op3: order operand.


def __init__(self, memory, *args, **kwargs):

super().__init__(AMD64RegFile(aliases={'<STR_LIT>': '<STR_LIT>', '<STR_LIT>': '<STR_LIT>', '<STR_LIT>': '<STR_LIT>'}, ),<EOL>memory,<EOL>*args,<EOL>**kwargs)<EOL>

Builds a CPU model.
:param memory: memory object for this CPU.


CHEADER = '<STR_LIT>'<EOL>CBLUE = '<STR_LIT>'<EOL>CGREEN = '<STR_LIT>'<EOL>CWARNING = '<STR_LIT>'<EOL>CFAIL = '<STR_LIT>'<EOL>CEND = '<STR_LIT>'<EOL>pos = <NUM_LIT:0><EOL>result = "<STR_LIT>"<EOL>try:<EOL><INDENT>instruction = self.instruction<EOL>result += f"<STR_LIT>"<EOL><DEDENT>except BaseException:<EOL><INDENT>result += "<STR_LIT>"<EOL><DEDENT>regs = ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL>for reg_name in regs:<EOL><INDENT>value = self.read_register(reg_name)<EOL>if issymbolic(value):<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>result += f"<STR_LIT>"<EOL><DEDENT>pos = <NUM_LIT:0><EOL><DEDENT>pos = <NUM_LIT:0><EOL>for reg_name in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>value = self.read_register(reg_name)<EOL>if issymbolic(value):<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>pos = <NUM_LIT:0><EOL><DEDENT>for reg_name in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>base, size, ty = self.get_descriptor(self.read_register(reg_name))<EOL>result += f'<STR_LIT>'<EOL><DEDENT>for reg_name in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>value = getattr(self, reg_name)<EOL>result += f'<STR_LIT>'<EOL>pos = <NUM_LIT:0><EOL><DEDENT>return result<EOL>

Returns a string representation of cpu state

:rtype: str
:return: a string containing the name and current value for all the registers.


cpu.AL = cpu.read_int(cpu.RBX + Operators.ZEXTEND(cpu.AL, <NUM_LIT:64>), <NUM_LIT:8>)<EOL>

Table look-up translation.

Locates a byte entry in a table in memory, using the contents of the
AL register as a table index, then copies the contents of the table entry
back into the AL register. The index in the AL register is treated as
an unsigned integer. The XLAT and XLATB instructions get the base address
of the table in memory from either the DS:EBX or the DS:BX registers.
In 64-bit mode, operation is similar to that in legacy or compatibility mode.
AL is used to specify the table index (the operand size is fixed at 8 bits).
RBX, however, is used to specify the table's base address::

        IF address_bit_size = 16
        THEN
            AL = (DS:BX + ZeroExtend(AL));
        ELSE IF (address_bit_size = 32)
            AL = (DS:EBX + ZeroExtend(AL)); FI;
        ELSE (address_bit_size = 64)
            AL = (RBX + ZeroExtend(AL));
        FI;

:param cpu: current CPU.
:param dest: destination operand.


super().__init__(AMD64RegFile({'<STR_LIT>': '<STR_LIT>', '<STR_LIT>': '<STR_LIT>', '<STR_LIT>': '<STR_LIT>'}),<EOL>memory,<EOL>*args,<EOL>**kwargs)<EOL>


CHEADER = '<STR_LIT>'<EOL>CBLUE = '<STR_LIT>'<EOL>CGREEN = '<STR_LIT>'<EOL>CWARNING = '<STR_LIT>'<EOL>CFAIL = '<STR_LIT>'<EOL>CEND = '<STR_LIT>'<EOL>pos = <NUM_LIT:0><EOL>result = "<STR_LIT>"<EOL>try:<EOL><INDENT>instruction = self.instruction<EOL>result += f"<STR_LIT>"<EOL><DEDENT>except BaseException:<EOL><INDENT>result += "<STR_LIT>"<EOL><DEDENT>regs = ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL>for reg_name in regs:<EOL><INDENT>value = self.read_register(reg_name)<EOL>if issymbolic(value):<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>pos = <NUM_LIT:0><EOL><DEDENT>pos = <NUM_LIT:0><EOL>for reg_name in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>value = self.read_register(reg_name)<EOL>if issymbolic(value):<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>result += f'<STR_LIT>'<EOL><DEDENT>pos = <NUM_LIT:0><EOL><DEDENT>for reg_name in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>base, size, ty = self.get_descriptor(self.read_register(reg_name))<EOL>result += f'<STR_LIT>'<EOL><DEDENT>for reg_name in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>value = getattr(self, reg_name)<EOL>result += f'<STR_LIT>'<EOL>pos = <NUM_LIT:0><EOL><DEDENT>return result<EOL>


cpu.AL = cpu.read_int(cpu.EBX + Operators.ZEXTEND(cpu.AL, <NUM_LIT:32>), <NUM_LIT:8>)<EOL>


return (<NUM_LIT:1> << width) - <NUM_LIT:1><EOL>

Return a mask with the low `width` bits set.

:param int width: How many bits to set to 1
:return: int or long


return Operators.EXTRACT(value, idx, <NUM_LIT:1>)<EOL>

Extract `idx` bit from `value`.

:param value: Source value from which to extract.
:type value: int or long or BitVec
:param idx: Bit index
:return: int or long or BitVex


<EOL>if isinstance(value, int):<EOL><INDENT>return Operators.EXTRACT(value, <NUM_LIT:0>, nbits)<EOL><DEDENT>elif isinstance(value, BitVec):<EOL><INDENT>if value.size < nbits:<EOL><INDENT>return Operators.ZEXTEND(value, nbits)<EOL><DEDENT>else:<EOL><INDENT>return Operators.EXTRACT(value, <NUM_LIT:0>, nbits)<EOL><DEDENT><DEDENT>

Get the first `nbits` from `value`.

:param value: Source value from which to extract
:type value: int or long or BitVec
:param int nbits: How many bits to extract
:return: Low `nbits` bits of `value`.
:rtype int or long or BitVec


return Operators.ITEBV(width, Bit(value, width - <NUM_LIT:1>) == <NUM_LIT:1>,<EOL>GetNBits(value, width) - <NUM_LIT:2>**width,<EOL>GetNBits(value, width))<EOL>

Convert a bitstring `value` of `width` bits to a signed integer
representation.

:param value: The value to convert.
:type value: int or long or BitVec
:param int width: The width of the bitstring to consider
:return: The converted value
:rtype int or long or BitVec


return GetNBits(value, width)<EOL>

Return integer value of `value` as a bitstring of `width` width.

:param value: The value to convert.
:type value: int or long or BitVec
:param int width: The width of the bitstring to consider
:return: The integer value
:rtype int or long or BitVec


assert amount > <NUM_LIT:0><EOL>value = Operators.ZEXTEND(value, width * <NUM_LIT:2>)<EOL>shifted = value << amount<EOL>result = GetNBits(shifted, width)<EOL>carry = Bit(shifted, width)<EOL>return (result, carry)<EOL>

The ARM LSL_C (logical left shift with carry) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to shift it.
:param int width: Width of the value
:return: Resultant value and the carry result
:rtype tuple


if amount == <NUM_LIT:0>:<EOL><INDENT>return value<EOL><DEDENT>result, _ = LSL_C(value, amount, width)<EOL>return result<EOL>

The ARM LSL (logical left shift) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to shift it.
:param int width: Width of the value
:return: Resultant value
:rtype int or BitVec


assert amount > <NUM_LIT:0><EOL>result = GetNBits(value >> amount, width)<EOL>carry = Bit(value >> (amount - <NUM_LIT:1>), <NUM_LIT:0>)<EOL>return (result, carry)<EOL>

The ARM LSR_C (logical shift right with carry) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to shift it.
:param int width: Width of the value
:return: Resultant value and carry result
:rtype tuple


if amount == <NUM_LIT:0>:<EOL><INDENT>return value<EOL><DEDENT>result, _ = LSR_C(value, amount, width)<EOL>return result<EOL>

The ARM LSR (logical shift right) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to shift it.
:param int width: Width of the value
:return: Resultant value
:rtype int or BitVec


assert amount <= width<EOL>assert amount > <NUM_LIT:0><EOL>assert amount + width <= width * <NUM_LIT:2><EOL>value = Operators.SEXTEND(value, width, width * <NUM_LIT:2>)<EOL>result = GetNBits(value >> amount, width)<EOL>carry = Bit(value, amount - <NUM_LIT:1>)<EOL>return (result, carry)<EOL>

The ARM ASR_C (arithmetic shift right with carry) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to shift it.
:param int width: Width of the value
:return: Resultant value and carry result
:rtype tuple


if amount == <NUM_LIT:0>:<EOL><INDENT>return value<EOL><DEDENT>result, _ = ASR_C(value, amount, width)<EOL>return result<EOL>

The ARM ASR (arithmetic shift right) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to shift it.
:param int width: Width of the value
:return: Resultant value
:rtype int or BitVec


assert amount <= width<EOL>assert amount > <NUM_LIT:0><EOL>m = amount % width<EOL>right, _ = LSR_C(value, m, width)<EOL>left, _ = LSL_C(value, width - m, width)<EOL>result = left | right<EOL>carry = Bit(result, width - <NUM_LIT:1>)<EOL>return (result, carry)<EOL>

The ARM ROR_C (rotate right with carry) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to rotate it.
:param int width: Width of the value
:return: Resultant value and carry result
:rtype tuple


if amount == <NUM_LIT:0>:<EOL><INDENT>return value<EOL><DEDENT>result, _ = ROR_C(value, amount, width)<EOL>return result<EOL>

The ARM ROR (rotate right) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to rotate it.
:param int width: Width of the value
:return: Resultant value
:rtype int or BitVec


carry_out = Bit(value, <NUM_LIT:0>)<EOL>result = (value >> <NUM_LIT:1>) | (carry << (width - <NUM_LIT:1>))<EOL>return (result, carry_out)<EOL>

The ARM RRX (rotate right with extend and with carry) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to rotate it.
:param int width: Width of the value
:return: Resultant value and carry result
:rtype tuple


result, _ = RRX_C(value, carry, width)<EOL>return result<EOL>

The ARM RRX (rotate right with extend) operation.

:param value: Value to shift
:type value: int or long or BitVec
:param int amount: How many bits to rotate it.
:param int width: Width of the value
:return: Resultant value
:rtype int or BitVec


return self.__type<EOL>

Corresponds to capstone's `operand.type` (cs.arm.ARM_OP_*).


return self.op.shift.type != cs.arm.ARM_SFT_INVALID<EOL>

In ARM some of the operands may have an additional metadata which means they can be shifted
with either a register or immediate value.

See:
* https://github.com/aquynh/capstone/blob/fdebc371ba0568acde007e08dad2cc3c9333e3fa/include/arm.h#L22-L34

* 11.5 Syntax of Operand2 as a register with optional shift
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0473m/dom1361289852638.html

:return: True if operand is shifted, otherwise False.


insn = struct.unpack('<STR_LIT>', self.cpu.instruction.bytes)[<NUM_LIT:0>]<EOL>unrotated = insn & Mask(<NUM_LIT:8>)<EOL>shift = Operators.EXTRACT(insn, <NUM_LIT:8>, <NUM_LIT:4>)<EOL>_, carry = self.cpu._shift(unrotated, cs.arm.ARM_SFT_ROR, <NUM_LIT:2> * shift, carryIn)<EOL>return carry<EOL>

Manually compute the carry bit produced by expanding an immediate operand (see ARMExpandImm_C)


super().__init__({'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'})<EOL>self._regs = {}<EOL>for reg_name in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>self._regs[reg_name] = Register(<NUM_LIT:32>)<EOL><DEDENT>for reg_name in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>self._regs[reg_name] = Register(<NUM_LIT:64>)<EOL><DEDENT>self._regs['<STR_LIT>'] = Register(<NUM_LIT:1>)<EOL>self._regs['<STR_LIT>'] = Register(<NUM_LIT:1>)<EOL>self._regs['<STR_LIT>'] = Register(<NUM_LIT:1>)<EOL>self._regs['<STR_LIT>'] = Register(<NUM_LIT:1>)<EOL>self._regs['<STR_LIT>'] = Register(<NUM_LIT:4>)<EOL>self._regs['<STR_LIT>'] = Register(<NUM_LIT:32>)<EOL>

ARM Register file abstraction. GPRs use ints for read/write. APSR
flags allow writes of bool/{1, 0} but always read bools.


V = Operators.EXTRACT(apsr, <NUM_LIT>, <NUM_LIT:1>)<EOL>C = Operators.EXTRACT(apsr, <NUM_LIT>, <NUM_LIT:1>)<EOL>Z = Operators.EXTRACT(apsr, <NUM_LIT:30>, <NUM_LIT:1>)<EOL>N = Operators.EXTRACT(apsr, <NUM_LIT>, <NUM_LIT:1>)<EOL>self.write('<STR_LIT>', V)<EOL>self.write('<STR_LIT>', C)<EOL>self.write('<STR_LIT>', Z)<EOL>self.write('<STR_LIT>', N)<EOL>

Auxiliary function - Writes flags from a full APSR (only 4 msb used)


assert self.mode in (cs.CS_MODE_ARM, cs.CS_MODE_THUMB)<EOL>if self.mode == cs.CS_MODE_ARM:<EOL><INDENT>self.mode = cs.CS_MODE_THUMB<EOL><DEDENT>else:<EOL><INDENT>self.mode = cs.CS_MODE_ARM<EOL><DEDENT>


unupdated_flags = self._last_flags.keys() - flags.keys()<EOL>for flag in unupdated_flags:<EOL><INDENT>flag_name = f'<STR_LIT>'<EOL>self._last_flags[flag] = self.regfile.read(flag_name)<EOL><DEDENT>self._last_flags.update(flags)<EOL>

Note: For any unmodified flags, update _last_flags with the most recent
committed value. Otherwise, for example, this could happen:

    overflow=0
    instr1 computes overflow=1, updates _last_flags, doesn't commit
    instr2 updates all flags in _last_flags except overflow (overflow remains 1 in _last_flags)
    instr2 commits all in _last_flags
    now overflow=1 even though it should still be 0


def _shift(cpu, value, _type, amount, carry):

assert(cs.arm.ARM_SFT_INVALID < _type <= cs.arm.ARM_SFT_RRX_REG)<EOL>if _type in (cs.arm.ARM_SFT_RRX, cs.arm.ARM_SFT_RRX_REG) and amount != <NUM_LIT:1>:<EOL><INDENT>amount = <NUM_LIT:1><EOL><DEDENT>elif _type in range(cs.arm.ARM_SFT_ASR_REG, cs.arm.ARM_SFT_RRX_REG + <NUM_LIT:1>):<EOL><INDENT>if cpu.mode == cs.CS_MODE_THUMB:<EOL><INDENT>src = amount.read()<EOL><DEDENT>else:<EOL><INDENT>src_reg = cpu.instruction.reg_name(amount).upper()<EOL>src = cpu.regfile.read(src_reg)<EOL><DEDENT>amount = Operators.EXTRACT(src, <NUM_LIT:0>, <NUM_LIT:8>)<EOL><DEDENT>if amount == <NUM_LIT:0>:<EOL><INDENT>return value, carry<EOL><DEDENT>width = cpu.address_bit_size<EOL>if _type in (cs.arm.ARM_SFT_ASR, cs.arm.ARM_SFT_ASR_REG):<EOL><INDENT>return ASR_C(value, amount, width)<EOL><DEDENT>elif _type in (cs.arm.ARM_SFT_LSL, cs.arm.ARM_SFT_LSL_REG):<EOL><INDENT>return LSL_C(value, amount, width)<EOL><DEDENT>elif _type in (cs.arm.ARM_SFT_LSR, cs.arm.ARM_SFT_LSR_REG):<EOL><INDENT>return LSR_C(value, amount, width)<EOL><DEDENT>elif _type in (cs.arm.ARM_SFT_ROR, cs.arm.ARM_SFT_ROR_REG):<EOL><INDENT>return ROR_C(value, amount, width)<EOL><DEDENT>elif _type in (cs.arm.ARM_SFT_RRX, cs.arm.ARM_SFT_RRX_REG):<EOL><INDENT>return RRX_C(value, carry, width)<EOL><DEDENT>raise NotImplementedError("<STR_LIT>")<EOL>

See Shift() and Shift_C() in the ARM manual


@instruction<EOL><INDENT>def MOV(cpu, dest, src):<DEDENT>

if cpu.mode == cs.CS_MODE_ARM:<EOL><INDENT>result, carry_out = src.read(with_carry=True)<EOL>dest.write(result)<EOL>cpu.set_flags(C=carry_out, N=HighBit(result), Z=(result == <NUM_LIT:0>))<EOL><DEDENT>else:<EOL><INDENT>result = src.read()<EOL>dest.write(result)<EOL>cpu.set_flags(N=HighBit(result), Z=(result == <NUM_LIT:0>))<EOL><DEDENT>

Implement the MOV{S} instruction.

Note: If src operand is PC, temporarily release our logical PC
view and conform to the spec, which dictates PC = curr instr + 8

:param Armv7Operand dest: The destination operand; register.
:param Armv7Operand src: The source operand; register or immediate.


@instruction<EOL><INDENT>def MOVT(cpu, dest, src):<DEDENT>

assert src.type == '<STR_LIT>'<EOL>imm = src.read()<EOL>low_halfword = dest.read() & Mask(<NUM_LIT:16>)<EOL>dest.write((imm << <NUM_LIT:16>) | low_halfword)<EOL>

MOVT writes imm16 to Rd[31:16]. The write does not affect Rd[15:0].

:param Armv7Operand dest: The destination operand; register
:param Armv7Operand src: The source operand; 16-bit immediate


@instruction<EOL><INDENT>def MRC(cpu, coprocessor, opcode1, dest, coprocessor_reg_n, coprocessor_reg_m, opcode2):<DEDENT>

assert coprocessor.type == '<STR_LIT>'<EOL>assert opcode1.type == '<STR_LIT>'<EOL>assert opcode2.type == '<STR_LIT>'<EOL>assert dest.type == '<STR_LIT>'<EOL>imm_coprocessor = coprocessor.read()<EOL>imm_opcode1 = opcode1.read()<EOL>imm_opcode2 = opcode2.read()<EOL>coprocessor_n_name = coprocessor_reg_n.read()<EOL>coprocessor_m_name = coprocessor_reg_m.read()<EOL>if <NUM_LIT:15> == imm_coprocessor:  <EOL><INDENT>if <NUM_LIT:0> == imm_opcode1:<EOL><INDENT>if <NUM_LIT> == coprocessor_n_name:<EOL><INDENT>if <NUM_LIT:3> == imm_opcode2:<EOL><INDENT>dest.write(cpu.regfile.read('<STR_LIT>'))<EOL>return<EOL><DEDENT><DEDENT><DEDENT><DEDENT>raise NotImplementedError("<STR_LIT>")<EOL>

MRC moves to ARM register from coprocessor.

:param Armv7Operand coprocessor: The name of the coprocessor; immediate
:param Armv7Operand opcode1: coprocessor specific opcode; 3-bit immediate
:param Armv7Operand dest: the destination operand: register
:param Armv7Operand coprocessor_reg_n: the coprocessor register; immediate
:param Armv7Operand coprocessor_reg_m: the coprocessor register; immediate
:param Armv7Operand opcode2: coprocessor specific opcode; 3-bit immediate


@instruction<EOL><INDENT>def LDRD(cpu, dest1, dest2, src, offset=None):<DEDENT>

assert dest1.type == '<STR_LIT>'<EOL>assert dest2.type == '<STR_LIT>'<EOL>assert src.type == '<STR_LIT>'<EOL>mem1 = cpu.read_int(src.address(), <NUM_LIT:32>)<EOL>mem2 = cpu.read_int(src.address() + <NUM_LIT:4>, <NUM_LIT:32>)<EOL>writeback = cpu._compute_writeback(src, offset)<EOL>dest1.write(mem1)<EOL>dest2.write(mem2)<EOL>cpu._cs_hack_ldr_str_writeback(src, offset, writeback)<EOL>


@instruction<EOL><INDENT>def STRD(cpu, src1, src2, dest, offset=None):<DEDENT>

assert src1.type == '<STR_LIT>'<EOL>assert src2.type == '<STR_LIT>'<EOL>assert dest.type == '<STR_LIT>'<EOL>val1 = src1.read()<EOL>val2 = src2.read()<EOL>writeback = cpu._compute_writeback(dest, offset)<EOL>cpu.write_int(dest.address(), val1, <NUM_LIT:32>)<EOL>cpu.write_int(dest.address() + <NUM_LIT:4>, val2, <NUM_LIT:32>)<EOL>cpu._cs_hack_ldr_str_writeback(dest, offset, writeback)<EOL>

Writes the contents of two registers to memory.


@instruction<EOL><INDENT>def LDREX(cpu, dest, src, offset=None):<DEDENT>

<EOL>cpu._LDR(dest, src, <NUM_LIT:32>, False, offset)<EOL>

LDREX loads data from memory.
* If the physical address has the shared TLB attribute, LDREX
  tags the physical address as exclusive access for the current
  processor, and clears any exclusive access tag for this
  processor for any other physical address.
* Otherwise, it tags the fact that the executing processor has
  an outstanding tagged physical address.

:param Armv7Operand dest: the destination register; register
:param Armv7Operand src: the source operand: register


@instruction<EOL><INDENT>def STREX(cpu, status, *args):<DEDENT>

<EOL>status.write(<NUM_LIT:0>)<EOL>return cpu._STR(cpu.address_bit_size, *args)<EOL>

STREX performs a conditional store to memory.
:param Armv7Operand status: the destination register for the returned status; register


val = GetNBits(src.read(), src_width)<EOL>word = Operators.ZEXTEND(val, cpu.address_bit_size)<EOL>dest.write(word)<EOL>

Helper for UXT* family of instructions.

:param ARMv7Operand dest: the destination register; register
:param ARMv7Operand dest: the source register; register
:param int src_width: bits to consider of the src operand


@instruction<EOL><INDENT>def UXTB(cpu, dest, src):<DEDENT>

cpu._UXT(dest, src, <NUM_LIT:8>)<EOL>

UXTB extracts an 8-bit value from a register, zero-extends
it to the size of the register, and writes the result to the destination register.

:param ARMv7Operand dest: the destination register; register
:param ARMv7Operand dest: the source register; register


@instruction<EOL><INDENT>def UXTH(cpu, dest, src):<DEDENT>

cpu._UXT(dest, src, <NUM_LIT:16>)<EOL>

UXTH extracts an 16-bit value from a register, zero-extends
it to the size of the register, and writes the result to the destination register.

:param ARMv7Operand dest: the destination register; register
:param ARMv7Operand dest: the source register; register


@instruction<EOL><INDENT>def PLD(cpu, addr, offset=None):<DEDENT>

PLD instructs the cpu that the address at addr might be loaded soon.


@instruction<EOL><INDENT>def ADR(cpu, dest, src):<DEDENT>

aligned_pc = (cpu.instruction.address + <NUM_LIT:4>) & <NUM_LIT><EOL>dest.write(aligned_pc + src.read())<EOL>

Address to Register adds an immediate value to the PC value, and writes the result to the destination register.

:param ARMv7Operand dest: Specifies the destination register.
:param ARMv7Operand src:
    Specifies the label of an instruction or literal data item whose address is to be loaded into
    <Rd>. The assembler calculates the required value of the offset from the Align(PC,4)
    value of the ADR instruction to this label.


@instruction<EOL><INDENT>def ADDW(cpu, dest, src, add):<DEDENT>

aligned_pc = (cpu.instruction.address + <NUM_LIT:4>) & <NUM_LIT><EOL>if src.type == '<STR_LIT>' and src.reg in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>src = aligned_pc<EOL><DEDENT>else:<EOL><INDENT>src = src.read()<EOL><DEDENT>dest.write(src + add.read())<EOL>

This instruction adds an immediate value to a register value, and writes the result to the destination register.
It doesn't update the condition flags.

:param ARMv7Operand dest: Specifies the destination register. If omitted, this register is the same as src.
:param ARMv7Operand src:
    Specifies the register that contains the first operand. If the SP is specified for dest, see ADD (SP plus
    immediate). If the PC is specified for dest, see ADR.
:param ARMv7Operand add:
    Specifies the immediate value to be added to the value obtained from src. The range of allowed values is
    0-4095.


@instruction<EOL><INDENT>def SUBW(cpu, dest, src, add):<DEDENT>

aligned_pc = (cpu.instruction.address + <NUM_LIT:4>) & <NUM_LIT><EOL>if src.type == '<STR_LIT>' and src.reg in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>src = aligned_pc<EOL><DEDENT>else:<EOL><INDENT>src = src.read()<EOL><DEDENT>dest.write(src - add.read())<EOL>

This instruction subtracts an immediate value from a register value, and writes the result to the destination
register. It can optionally update the condition flags based on the result.

:param ARMv7Operand dest: Specifies the destination register. If omitted, this register is the same as src.
:param ARMv7Operand src:
    Specifies the register that contains the first operand. If the SP is specified for dest, see ADD (SP plus
    immediate). If the PC is specified for dest, see ADR.
:param ARMv7Operand add:
    Specifies the immediate value to be added to the value obtained from src. The range of allowed values is
    0-4095.


@instruction<EOL><INDENT>def CBZ(cpu, op, dest):<DEDENT>

cpu.PC = Operators.ITEBV(cpu.address_bit_size,<EOL>op.read(), cpu.PC, dest.read())<EOL>

Compare and Branch on Zero compares the value in a register with zero, and conditionally branches forward
a constant value. It does not affect the condition flags.

:param ARMv7Operand op: Specifies the register that contains the first operand.
:param ARMv7Operand dest:
    Specifies the label of the instruction that is to be branched to. The assembler calculates the
    required value of the offset from the PC value of the CBZ instruction to this label, then
    selects an encoding that will set imm32 to that offset. Allowed offsets are even numbers in
    the range 0 to 126.


@instruction<EOL><INDENT>def CBNZ(cpu, op, dest):<DEDENT>

cpu.PC = Operators.ITEBV(cpu.address_bit_size,<EOL>op.read(), dest.read(), cpu.PC)<EOL>

Compare and Branch on Non-Zero compares the value in a register with zero, and conditionally branches
forward a constant value. It does not affect the condition flags.

:param ARMv7Operand op: Specifies the register that contains the first operand.
:param ARMv7Operand dest:
    Specifies the label of the instruction that is to be branched to. The assembler calculates the
    required value of the offset from the PC value of the CBNZ instruction to this label, then
    selects an encoding that will set imm32 to that offset. Allowed offsets are even numbers in
    the range 0 to 126.


<EOL>base_addr = dest.get_mem_base_addr()<EOL>if dest.mem.base in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>base_addr = cpu.PC<EOL><DEDENT>offset = cpu.read_int(base_addr + dest.get_mem_offset(), <NUM_LIT:8>)<EOL>offset = Operators.ZEXTEND(offset, cpu.address_bit_size)<EOL>cpu.PC += (offset << <NUM_LIT:1>)<EOL>

Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. A base register
provides a pointer to the table, and a second register supplies an index into the table. The branch length is
twice the value of the byte returned from the table.

:param ARMv7Operand dest: see below; register