def IDIV(cpu, src):
        """
        Signed divide.

        Divides (signed) the value in the AL, AX, or EAX register by the source
        operand and stores the result in the AX, DX:AX, or EDX:EAX registers.
        The source operand can be a general-purpose register or a memory
        location. The action of this instruction depends on the operand size.::

        IF SRC  =  0
        THEN #DE; (* divide error *)
        FI;
        IF OpernadSize  =  8 (* word/byte operation *)
        THEN
            temp  =  AX / SRC; (* signed division *)
            IF (temp > 7FH) Operators.OR(temp < 80H)
            (* if a positive result is greater than 7FH or a negative result is
            less than 80H *)
            THEN #DE; (* divide error *) ;
            ELSE
                AL  =  temp;
                AH  =  AX SignedModulus SRC;
            FI;
        ELSE
            IF OpernadSize  =  16 (* doubleword/word operation *)
            THEN
                temp  =  DX:AX / SRC; (* signed division *)
                IF (temp > 7FFFH) Operators.OR(temp < 8000H)
                (* if a positive result is greater than 7FFFH *)
                (* or a negative result is less than 8000H *)
                THEN #DE; (* divide error *) ;
                ELSE
                    AX  =  temp;
                    DX  =  DX:AX SignedModulus SRC;
                FI;
            ELSE (* quadword/doubleword operation *)
                temp  =  EDX:EAX / SRC; (* signed division *)
                IF (temp > 7FFFFFFFH) Operators.OR(temp < 80000000H)
                (* if a positive result is greater than 7FFFFFFFH *)
                (* or a negative result is less than 80000000H *)
                THEN #DE; (* divide error *) ;
                ELSE
                    EAX  =  temp;
                    EDX  =  EDX:EAX SignedModulus SRC;
                FI;
            FI;
        FI;

        :param cpu: current CPU.
        :param src: source operand.
        """

        reg_name_h = {8: 'AH', 16: 'DX', 32: 'EDX', 64: 'RDX'}[src.size]
        reg_name_l = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[src.size]

        dividend = Operators.CONCAT(src.size * 2,
                                    cpu.read_register(reg_name_h),
                                    cpu.read_register(reg_name_l))

        divisor = src.read()
        if isinstance(divisor, int) and divisor == 0:
            raise DivideByZeroError()

        dst_size = src.size * 2

        divisor = Operators.SEXTEND(divisor, src.size, dst_size)
        mask = (1 << dst_size) - 1
        sign_mask = 1 << (dst_size - 1)

        dividend_sign = (dividend & sign_mask) != 0
        divisor_sign = (divisor & sign_mask) != 0

        if isinstance(divisor, int):
            if divisor_sign:
                divisor = ((~divisor) + 1) & mask
                divisor = -divisor

        if isinstance(dividend, int):
            if dividend_sign:
                dividend = ((~dividend) + 1) & mask
                dividend = -dividend

        quotient = Operators.SDIV(dividend, divisor)
        if (isinstance(dividend, int) and
                isinstance(dividend, int)):
            # handle the concrete case
            remainder = dividend - (quotient * divisor)
        else:
            # symbolic case -- optimize via SREM
            remainder = Operators.SREM(dividend, divisor)

        cpu.write_register(reg_name_l, Operators.EXTRACT(quotient, 0, src.size))
        cpu.write_register(reg_name_h, Operators.EXTRACT(remainder, 0, src.size))

def IDIV ( cpu , src ) : reg_name_h = { 8 : 'AH' , 16 : 'DX' , 32 : 'EDX' , 64 : 'RDX' } [ src . size ] reg_name_l = { 8 : 'AL' , 16 : 'AX' , 32 : 'EAX' , 64 : 'RAX' } [ src . size ] dividend = Operators . CONCAT ( src . size * 2 , cpu . read_register ( reg_name_h ) , cpu . read_register ( reg_name_l ) ) divisor = src . read ( ) if isinstance ( divisor , int ) and divisor == 0 : raise DivideByZeroError ( ) dst_size = src . size * 2 divisor = Operators . SEXTEND ( divisor , src . size , dst_size ) mask = ( 1 << dst_size ) - 1 sign_mask = 1 << ( dst_size - 1 ) dividend_sign = ( dividend & sign_mask ) != 0 divisor_sign = ( divisor & sign_mask ) != 0 if isinstance ( divisor , int ) : if divisor_sign : divisor = ( ( ~ divisor ) + 1 ) & mask divisor = - divisor if isinstance ( dividend , int ) : if dividend_sign : dividend = ( ( ~ dividend ) + 1 ) & mask dividend = - dividend quotient = Operators . SDIV ( dividend , divisor ) if ( isinstance ( dividend , int ) and isinstance ( dividend , int ) ) : remainder = dividend - ( quotient * divisor ) else : remainder = Operators . SREM ( dividend , divisor ) cpu . write_register ( reg_name_l , Operators . EXTRACT ( quotient , 0 , src . size ) ) cpu . write_register ( reg_name_h , Operators . EXTRACT ( remainder , 0 , src . size ) )


def IMUL(cpu, *operands):
        """
        Signed multiply.

        Performs a signed multiplication of two operands. This instruction has
        three forms, depending on the number of operands.
            - One-operand form. This form is identical to that used by the MUL
            instruction. Here, the source operand (in a general-purpose
            register or memory location) is multiplied by the value in the AL,
            AX, or EAX register (depending on the operand size) and the product
            is stored in the AX, DX:AX, or EDX:EAX registers, respectively.
            - Two-operand form. With this form the destination operand (the
            first operand) is multiplied by the source operand (second
            operand). The destination operand is a general-purpose register and
            the source operand is an immediate value, a general-purpose
            register, or a memory location. The product is then stored in the
            destination operand location.
            - Three-operand form. This form requires a destination operand (the
            first operand) and two source operands (the second and the third
            operands). Here, the first source operand (which can be a
            general-purpose register or a memory location) is multiplied by the
            second source operand (an immediate value). The product is then
            stored in the destination operand (a general-purpose register).

        When an immediate value is used as an operand, it is sign-extended to
        the length of the destination operand format. The CF and OF flags are
        set when significant bits are carried into the upper half of the
        result. The CF and OF flags are cleared when the result fits exactly in
        the lower half of the result. The three forms of the IMUL instruction
        are similar in that the length of the product is calculated to twice
        the length of the operands. With the one-operand form, the product is
        stored exactly in the destination. With the two- and three- operand
        forms, however, result is truncated to the length of the destination
        before it is stored in the destination register. Because of this
        truncation, the CF or OF flag should be tested to ensure that no
        significant bits are lost. The two- and three-operand forms may also be
        used with unsigned operands because the lower half of the product is
        the same regardless if the operands are signed or unsigned. The CF and
        OF flags, however, cannot be used to determine if the upper half of the
        result is non-zero::

        IF (NumberOfOperands == 1)
        THEN
            IF (OperandSize == 8)
            THEN
                AX = AL * SRC (* Signed multiplication *)
                IF AL == AX
                THEN
                    CF = 0; OF = 0;
                ELSE
                    CF = 1; OF = 1;
                FI;
            ELSE
                IF OperandSize == 16
                THEN
                    DX:AX = AX * SRC (* Signed multiplication *)
                    IF sign_extend_to_32 (AX) == DX:AX
                    THEN
                        CF = 0; OF = 0;
                    ELSE
                        CF = 1; OF = 1;
                    FI;
                ELSE
                    IF OperandSize == 32
                    THEN
                        EDX:EAX = EAX * SRC (* Signed multiplication *)
                        IF EAX == EDX:EAX
                        THEN
                            CF = 0; OF = 0;
                        ELSE
                            CF = 1; OF = 1;
                        FI;
                    ELSE (* OperandSize = 64 *)
                        RDX:RAX = RAX * SRC (* Signed multiplication *)
                        IF RAX == RDX:RAX
                        THEN
                            CF = 0; OF = 0;
                        ELSE
                           CF = 1; OF = 1;
                        FI;
                    FI;
                FI;
        ELSE
            IF (NumberOfOperands = 2)
            THEN
                temp = DEST * SRC (* Signed multiplication; temp is double DEST size *)
                DEST = DEST * SRC (* Signed multiplication *)
                IF temp != DEST
                THEN
                    CF = 1; OF = 1;
                ELSE
                    CF = 0; OF = 0;
                FI;
            ELSE (* NumberOfOperands = 3 *)
                DEST = SRC1 * SRC2 (* Signed multiplication *)
                temp = SRC1 * SRC2 (* Signed multiplication; temp is double SRC1 size *)
                IF temp != DEST
                THEN
                    CF = 1; OF = 1;
                ELSE
                    CF = 0; OF = 0;
                FI;
            FI;
        FI;

        :param cpu: current CPU.
        :param operands: variable list of operands.
        """
        dest = operands[0]
        OperandSize = dest.size
        reg_name_h = {8: 'AH', 16: 'DX', 32: 'EDX', 64: 'RDX'}[OperandSize]
        reg_name_l = {8: 'AL', 16: 'AX', 32: 'EAX', 64: 'RAX'}[OperandSize]

        arg0 = dest.read()
        arg1 = None
        arg2 = None
        res = None
        if len(operands) == 1:
            arg1 = cpu.read_register(reg_name_l)
            temp = (Operators.SEXTEND(arg0, OperandSize, OperandSize * 2) *
                    Operators.SEXTEND(arg1, OperandSize, OperandSize * 2))
            temp = temp & ((1 << (OperandSize * 2)) - 1)
            cpu.write_register(reg_name_l,
                               Operators.EXTRACT(temp, 0, OperandSize))
            cpu.write_register(reg_name_h,
                               Operators.EXTRACT(temp, OperandSize, OperandSize))
            res = Operators.EXTRACT(temp, 0, OperandSize)
        elif len(operands) == 2:
            arg1 = operands[1].read()
            arg1 = Operators.SEXTEND(arg1, OperandSize, OperandSize * 2)
            temp = Operators.SEXTEND(arg0, OperandSize, OperandSize * 2) * arg1
            temp = temp & ((1 << (OperandSize * 2)) - 1)
            res = dest.write(Operators.EXTRACT(temp, 0, OperandSize))
        else:
            arg1 = operands[1].read()
            arg2 = operands[2].read()
            temp = (Operators.SEXTEND(arg1, OperandSize, OperandSize * 2) *
                    Operators.SEXTEND(arg2, operands[2].size, OperandSize * 2))
            temp = temp & ((1 << (OperandSize * 2)) - 1)
            res = dest.write(Operators.EXTRACT(temp, 0, OperandSize))

        cpu.CF = (Operators.SEXTEND(res, OperandSize, OperandSize * 2) != temp)
        cpu.OF = cpu.CF

def IMUL ( cpu , * operands ) : dest = operands [ 0 ] OperandSize = dest . size reg_name_h = { 8 : 'AH' , 16 : 'DX' , 32 : 'EDX' , 64 : 'RDX' } [ OperandSize ] reg_name_l = { 8 : 'AL' , 16 : 'AX' , 32 : 'EAX' , 64 : 'RAX' } [ OperandSize ] arg0 = dest . read ( ) arg1 = None arg2 = None res = None if len ( operands ) == 1 : arg1 = cpu . read_register ( reg_name_l ) temp = ( Operators . SEXTEND ( arg0 , OperandSize , OperandSize * 2 ) * Operators . SEXTEND ( arg1 , OperandSize , OperandSize * 2 ) ) temp = temp & ( ( 1 << ( OperandSize * 2 ) ) - 1 ) cpu . write_register ( reg_name_l , Operators . EXTRACT ( temp , 0 , OperandSize ) ) cpu . write_register ( reg_name_h , Operators . EXTRACT ( temp , OperandSize , OperandSize ) ) res = Operators . EXTRACT ( temp , 0 , OperandSize ) elif len ( operands ) == 2 : arg1 = operands [ 1 ] . read ( ) arg1 = Operators . SEXTEND ( arg1 , OperandSize , OperandSize * 2 ) temp = Operators . SEXTEND ( arg0 , OperandSize , OperandSize * 2 ) * arg1 temp = temp & ( ( 1 << ( OperandSize * 2 ) ) - 1 ) res = dest . write ( Operators . EXTRACT ( temp , 0 , OperandSize ) ) else : arg1 = operands [ 1 ] . read ( ) arg2 = operands [ 2 ] . read ( ) temp = ( Operators . SEXTEND ( arg1 , OperandSize , OperandSize * 2 ) * Operators . SEXTEND ( arg2 , operands [ 2 ] . size , OperandSize * 2 ) ) temp = temp & ( ( 1 << ( OperandSize * 2 ) ) - 1 ) res = dest . write ( Operators . EXTRACT ( temp , 0 , OperandSize ) ) cpu . CF = ( Operators . SEXTEND ( res , OperandSize , OperandSize * 2 ) != temp ) cpu . OF = cpu . CF


def INC(cpu, dest):
        """
        Increments by 1.

        Adds 1 to the destination operand, while preserving the state of the
        CF flag. The destination operand can be a register or a memory location.
        This instruction allows a loop counter to be updated without disturbing
        the CF flag. (Use a ADD instruction with an immediate operand of 1 to
        perform an increment operation that does updates the CF flag.)::

                DEST  =  DEST +1;

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        arg0 = dest.read()
        res = dest.write(arg0 + 1)
        res &= (1 << dest.size) - 1
        SIGN_MASK = 1 << (dest.size - 1)
        cpu.AF = ((arg0 ^ 1) ^ res) & 0x10 != 0
        cpu.ZF = res == 0
        cpu.SF = (res & SIGN_MASK) != 0
        cpu.OF = res == SIGN_MASK
        cpu.PF = cpu._calculate_parity_flag(res)

def INC ( cpu , dest ) : arg0 = dest . read ( ) res = dest . write ( arg0 + 1 ) res &= ( 1 << dest . size ) - 1 SIGN_MASK = 1 << ( dest . size - 1 ) cpu . AF = ( ( arg0 ^ 1 ) ^ res ) & 0x10 != 0 cpu . ZF = res == 0 cpu . SF = ( res & SIGN_MASK ) != 0 cpu . OF = res == SIGN_MASK cpu . PF = cpu . _calculate_parity_flag ( res )


def MUL(cpu, src):
        """
        Unsigned multiply.

        Performs an unsigned multiplication of the first operand (destination
        operand) and the second operand (source operand) and stores the result
        in the destination operand. The destination operand is an implied operand
        located in register AL, AX or EAX (depending on the size of the operand);
        the source operand is located in a general-purpose register or a memory location.

        The result is stored in register AX, register pair DX:AX, or register
        pair EDX:EAX (depending on the operand size), with the high-order bits
        of the product contained in register AH, DX, or EDX, respectively. If
        the high-order bits of the product are 0, the CF and OF flags are cleared;
        otherwise, the flags are set::

                IF byte operation
                THEN
                    AX  =  AL * SRC
                ELSE (* word or doubleword operation *)
                    IF OperandSize  =  16
                    THEN
                        DX:AX  =  AX * SRC
                    ELSE (* OperandSize  =  32 *)
                        EDX:EAX  =  EAX * SRC
                    FI;
                FI;

        :param cpu: current CPU.
        :param src: source operand.
        """
        size = src.size
        reg_name_low, reg_name_high = {8: ('AL', 'AH'),
                                       16: ('AX', 'DX'),
                                       32: ('EAX', 'EDX'),
                                       64: ('RAX', 'RDX')}[size]
        res = (Operators.ZEXTEND(cpu.read_register(reg_name_low), 256) *
               Operators.ZEXTEND(src.read(), 256))
        cpu.write_register(reg_name_low, Operators.EXTRACT(res, 0, size))
        cpu.write_register(reg_name_high, Operators.EXTRACT(res, size, size))
        cpu.OF = Operators.EXTRACT(res, size, size) != 0
        cpu.CF = cpu.OF

def MUL ( cpu , src ) : size = src . size reg_name_low , reg_name_high = { 8 : ( 'AL' , 'AH' ) , 16 : ( 'AX' , 'DX' ) , 32 : ( 'EAX' , 'EDX' ) , 64 : ( 'RAX' , 'RDX' ) } [ size ] res = ( Operators . ZEXTEND ( cpu . read_register ( reg_name_low ) , 256 ) * Operators . ZEXTEND ( src . read ( ) , 256 ) ) cpu . write_register ( reg_name_low , Operators . EXTRACT ( res , 0 , size ) ) cpu . write_register ( reg_name_high , Operators . EXTRACT ( res , size , size ) ) cpu . OF = Operators . EXTRACT ( res , size , size ) != 0 cpu . CF = cpu . OF


def NEG(cpu, dest):
        """
        Two's complement negation.

        Replaces the value of operand (the destination operand) with its two's complement.
        (This operation is equivalent to subtracting the operand from 0.) The destination operand is
        located in a general-purpose register or a memory location::

                IF DEST  =  0
                THEN CF  =  0
                ELSE CF  =  1;
                FI;
                DEST  =  - (DEST)

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        source = dest.read()
        res = dest.write(-source)
        cpu._calculate_logic_flags(dest.size, res)
        cpu.CF = source != 0
        cpu.AF = (res & 0x0f) != 0x00

def NEG ( cpu , dest ) : source = dest . read ( ) res = dest . write ( - source ) cpu . _calculate_logic_flags ( dest . size , res ) cpu . CF = source != 0 cpu . AF = ( res & 0x0f ) != 0x00


def SBB(cpu, dest, src):
        """
        Integer subtraction with borrow.

        Adds the source operand (second operand) and the carry (CF) flag, and
        subtracts the result from the destination operand (first operand). The
        result of the subtraction is stored in the destination operand. The
        destination operand can be a register or a memory location; the source
        operand can be an immediate, a register, or a memory location.
        (However, two memory operands cannot be used in one instruction.) The
        state of the CF flag represents a borrow from a previous subtraction.
        When an immediate value is used as an operand, it is sign-extended to
        the length of the destination operand format.
        The SBB instruction does not distinguish between signed or unsigned
        operands. Instead, the processor evaluates the result for both data
        types and sets the OF and CF flags to indicate a borrow in the signed
        or unsigned result, respectively. The SF flag indicates the sign of the
        signed result.  The SBB instruction is usually executed as part of a
        multibyte or multiword subtraction in which a SUB instruction is
        followed by a SBB instruction::

                DEST  =  DEST - (SRC + CF);

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        cpu._SUB(dest, src, carry=True)

def SBB ( cpu , dest , src ) : cpu . _SUB ( dest , src , carry = True )


def XADD(cpu, dest, src):
        """
        Exchanges and adds.

        Exchanges the first operand (destination operand) with the second operand
        (source operand), then loads the sum of the two values into the destination
        operand. The destination operand can be a register or a memory location;
        the source operand is a register.
        This instruction can be used with a LOCK prefix::

                TEMP  =  SRC + DEST
                SRC  =  DEST
                DEST  =  TEMP

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        MASK = (1 << dest.size) - 1
        SIGN_MASK = 1 << (dest.size - 1)

        arg0 = dest.read()
        arg1 = src.read()
        temp = (arg1 + arg0) & MASK
        src.write(arg0)
        dest.write(temp)

        # Affected flags: oszapc
        tempCF = Operators.OR(Operators.ULT(temp, arg0), Operators.ULT(temp, arg1))
        cpu.CF = tempCF
        cpu.AF = ((arg0 ^ arg1) ^ temp) & 0x10 != 0
        cpu.ZF = temp == 0
        cpu.SF = (temp & SIGN_MASK) != 0
        cpu.OF = (((arg0 ^ arg1 ^ SIGN_MASK) & (temp ^ arg1)) & SIGN_MASK) != 0
        cpu.PF = cpu._calculate_parity_flag(temp)

def XADD ( cpu , dest , src ) : MASK = ( 1 << dest . size ) - 1 SIGN_MASK = 1 << ( dest . size - 1 ) arg0 = dest . read ( ) arg1 = src . read ( ) temp = ( arg1 + arg0 ) & MASK src . write ( arg0 ) dest . write ( temp ) tempCF = Operators . OR ( Operators . ULT ( temp , arg0 ) , Operators . ULT ( temp , arg1 ) ) cpu . CF = tempCF cpu . AF = ( ( arg0 ^ arg1 ) ^ temp ) & 0x10 != 0 cpu . ZF = temp == 0 cpu . SF = ( temp & SIGN_MASK ) != 0 cpu . OF = ( ( ( arg0 ^ arg1 ^ SIGN_MASK ) & ( temp ^ arg1 ) ) & SIGN_MASK ) != 0 cpu . PF = cpu . _calculate_parity_flag ( temp )


def BSWAP(cpu, dest):
        """
        Byte swap.

        Reverses the byte order of a 32-bit (destination) register: bits 0 through
        7 are swapped with bits 24 through 31, and bits 8 through 15 are swapped
        with bits 16 through 23. This instruction is provided for converting little-endian
        values to big-endian format and vice versa.
        To swap bytes in a word value (16-bit register), use the XCHG instruction.
        When the BSWAP instruction references a 16-bit register, the result is
        undefined::

            TEMP  =  DEST
            DEST[7..0]  =  TEMP[31..24]
            DEST[15..8]  =  TEMP[23..16]
            DEST[23..16]  =  TEMP[15..8]
            DEST[31..24]  =  TEMP[7..0]

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        parts = []
        arg0 = dest.read()
        for i in range(0, dest.size, 8):
            parts.append(Operators.EXTRACT(arg0, i, 8))

        dest.write(Operators.CONCAT(8 * len(parts), *parts))

def BSWAP ( cpu , dest ) : parts = [ ] arg0 = dest . read ( ) for i in range ( 0 , dest . size , 8 ) : parts . append ( Operators . EXTRACT ( arg0 , i , 8 ) ) dest . write ( Operators . CONCAT ( 8 * len ( parts ) , * parts ) )


def CMOVG(cpu, dest, src):
        """
        Conditional move - Greater.

        Tests the status flags in the EFLAGS register and moves the source operand
        (second operand) to the destination operand (first operand) if the given
        test condition is true.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.ZF == 0, cpu.SF == cpu.OF), src.read(), dest.read()))

def CMOVG ( cpu , dest , src ) : dest . write ( Operators . ITEBV ( dest . size , Operators . AND ( cpu . ZF == 0 , cpu . SF == cpu . OF ) , src . read ( ) , dest . read ( ) ) )


def CMOVO(cpu, dest, src):
        """
        Conditional move - Overflow.

        Tests the status flags in the EFLAGS register and moves the source operand
        (second operand) to the destination operand (first operand) if the given
        test condition is true.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF, src.read(), dest.read()))

def CMOVO ( cpu , dest , src ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF , src . read ( ) , dest . read ( ) ) )


def CMOVNO(cpu, dest, src):
        """
        Conditional move - Not overflow.

        Tests the status flags in the EFLAGS register and moves the source operand
        (second operand) to the destination operand (first operand) if the given
        test condition is true.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF == False, src.read(), dest.read()))

def CMOVNO ( cpu , dest , src ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF == False , src . read ( ) , dest . read ( ) ) )


def LAHF(cpu):
        """
        Loads status flags into AH register.

        Moves the low byte of the EFLAGS register (which includes status flags
        SF, ZF, AF, PF, and CF) to the AH register. Reserved bits 1, 3, and 5
        of the EFLAGS register are set in the AH register::

                AH  =  EFLAGS(SF:ZF:0:AF:0:PF:1:CF);

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        used_regs = (cpu.SF, cpu.ZF, cpu.AF, cpu.PF, cpu.CF)
        is_expression = any(issymbolic(x) for x in used_regs)

        def make_flag(val, offset):
            if is_expression:
                return Operators.ITEBV(8, val,
                                       BitVecConstant(8, 1 << offset),
                                       BitVecConstant(8, 0))
            else:
                return val << offset

        cpu.AH = (make_flag(cpu.SF, 7) |
                  make_flag(cpu.ZF, 6) |
                  make_flag(0, 5) |
                  make_flag(cpu.AF, 4) |
                  make_flag(0, 3) |
                  make_flag(cpu.PF, 2) |
                  make_flag(1, 1) |
                  make_flag(cpu.CF, 0))

def LAHF ( cpu ) : used_regs = ( cpu . SF , cpu . ZF , cpu . AF , cpu . PF , cpu . CF ) is_expression = any ( issymbolic ( x ) for x in used_regs ) def make_flag ( val , offset ) : if is_expression : return Operators . ITEBV ( 8 , val , BitVecConstant ( 8 , 1 << offset ) , BitVecConstant ( 8 , 0 ) ) else : return val << offset cpu . AH = ( make_flag ( cpu . SF , 7 ) | make_flag ( cpu . ZF , 6 ) | make_flag ( 0 , 5 ) | make_flag ( cpu . AF , 4 ) | make_flag ( 0 , 3 ) | make_flag ( cpu . PF , 2 ) | make_flag ( 1 , 1 ) | make_flag ( cpu . CF , 0 ) )


def LEA(cpu, dest, src):
        """
        Loads effective address.

        Computes the effective address of the second operand (the source operand) and stores it in the first operand
        (destination operand). The source operand is a memory address (offset part) specified with one of the processors
        addressing modes; the destination operand is a general-purpose register. The address-size and operand-size
        attributes affect the action performed by this instruction. The operand-size
        attribute of the instruction is determined by the chosen register; the address-size attribute is determined by the
        attribute of the code segment.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        dest.write(Operators.EXTRACT(src.address(), 0, dest.size))

def LEA ( cpu , dest , src ) : dest . write ( Operators . EXTRACT ( src . address ( ) , 0 , dest . size ) )


def MOVBE(cpu, dest, src):
        """
        Moves data after swapping bytes.

        Performs a byte swap operation on the data copied from the second operand (source operand) and store the result
        in the first operand (destination operand). The source operand can be a general-purpose register, or memory location; the destination register can be a general-purpose register, or a memory location; however, both operands can
        not be registers, and only one operand can be a memory location. Both operands must be the same size, which can
        be a word, a doubleword or quadword.
        The MOVBE instruction is provided for swapping the bytes on a read from memory or on a write to memory; thus
        providing support for converting little-endian values to big-endian format and vice versa.
        In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits::

                TEMP = SRC
                IF ( OperandSize = 16)
                THEN
                    DEST[7:0] = TEMP[15:8];
                    DEST[15:8] = TEMP[7:0];
                ELSE IF ( OperandSize = 32)
                    DEST[7:0] = TEMP[31:24];
                    DEST[15:8] = TEMP[23:16];
                    DEST[23:16] = TEMP[15:8];
                    DEST[31:23] = TEMP[7:0];
                ELSE IF ( OperandSize = 64)
                    DEST[7:0] = TEMP[63:56];
                    DEST[15:8] = TEMP[55:48];
                    DEST[23:16] = TEMP[47:40];
                    DEST[31:24] = TEMP[39:32];
                    DEST[39:32] = TEMP[31:24];
                    DEST[47:40] = TEMP[23:16];
                    DEST[55:48] = TEMP[15:8];
                    DEST[63:56] = TEMP[7:0];
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: source operand.
        """
        size = dest.size
        arg0 = dest.read()
        temp = 0
        for pos in range(0, size, 8):
            temp = (temp << 8) | (arg0 & 0xff)
            arg0 = arg0 >> 8
        dest.write(arg0)

def MOVBE ( cpu , dest , src ) : size = dest . size arg0 = dest . read ( ) temp = 0 for pos in range ( 0 , size , 8 ) : temp = ( temp << 8 ) | ( arg0 & 0xff ) arg0 = arg0 >> 8 dest . write ( arg0 )


def SAHF(cpu):
        """
        Stores AH into flags.

        Loads the SF, ZF, AF, PF, and CF flags of the EFLAGS register with values
        from the corresponding bits in the AH register (bits 7, 6, 4, 2, and 0,
        respectively). Bits 1, 3, and 5 of register AH are ignored; the corresponding
        reserved bits (1, 3, and 5) in the EFLAGS register remain as shown below::

                EFLAGS(SF:ZF:0:AF:0:PF:1:CF)  =  AH;

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

        eflags_size = 32
        val = cpu.AH & 0xD5 | 0x02

        cpu.EFLAGS = Operators.ZEXTEND(val, eflags_size)

def SAHF ( cpu ) : eflags_size = 32 val = cpu . AH & 0xD5 | 0x02 cpu . EFLAGS = Operators . ZEXTEND ( val , eflags_size )


def SETA(cpu, dest):
        """
        Sets byte if above.

        Sets the destination operand to 0 or 1 depending on the settings of the status flags (CF, SF, OF, ZF, and PF, 1, 0) in the
        EFLAGS register. The destination operand points to a byte register or a byte in memory. The condition code suffix
        (cc, 1, 0) indicates the condition being tested for::
                IF condition
                THEN
                    DEST = 1;
                ELSE
                    DEST = 0;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
         """
        dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF) == False, 1, 0))

def SETA ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . OR ( cpu . CF , cpu . ZF ) == False , 1 , 0 ) )


def SETB(cpu, dest):
        """
        Sets byte if below.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF, 1, 0))

def SETB ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF , 1 , 0 ) )


def SETBE(cpu, dest):
        """
        Sets byte if below or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.CF, cpu.ZF), 1, 0))

def SETBE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . OR ( cpu . CF , cpu . ZF ) , 1 , 0 ) )


def SETC(cpu, dest):
        """
        Sets if carry.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF, 1, 0))

def SETC ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF , 1 , 0 ) )


def SETE(cpu, dest):
        """
        Sets byte if equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, 1, 0))

def SETE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , 1 , 0 ) )


def SETGE(cpu, dest):
        """
        Sets byte if greater or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.SF == cpu.OF, 1, 0))

def SETGE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . SF == cpu . OF , 1 , 0 ) )


def SETNAE(cpu, dest):
        """
        Sets byte if not above or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF, 1, 0))

def SETNAE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF , 1 , 0 ) )


def SETNB(cpu, dest):
        """
        Sets byte if not below.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.CF == False, 1, 0))

def SETNB ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . CF == False , 1 , 0 ) )


def SETNBE(cpu, dest):
        """
        Sets byte if not below or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.CF == False, cpu.ZF == False), 1, 0))

def SETNBE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . AND ( cpu . CF == False , cpu . ZF == False ) , 1 , 0 ) )


def SETNG(cpu, dest):
        """
        Sets byte if not greater.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.OR(cpu.ZF, cpu.SF != cpu.OF), 1, 0))

def SETNG ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . OR ( cpu . ZF , cpu . SF != cpu . OF ) , 1 , 0 ) )


def SETNLE(cpu, dest):
        """
        Sets byte if not less or equal.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, Operators.AND(cpu.ZF == False, cpu.SF == cpu.OF), 1, 0))

def SETNLE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , Operators . AND ( cpu . ZF == False , cpu . SF == cpu . OF ) , 1 , 0 ) )


def SETNO(cpu, dest):
        """
        Sets byte if not overflow.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF == False, 1, 0))

def SETNO ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF == False , 1 , 0 ) )


def SETNS(cpu, dest):
        """
        Sets byte if not sign.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.SF == False, 1, 0))

def SETNS ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . SF == False , 1 , 0 ) )


def SETNZ(cpu, dest):
        """
        Sets byte if not zero.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.ZF == False, 1, 0))

def SETNZ ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . ZF == False , 1 , 0 ) )


def SETO(cpu, dest):
        """
        Sets byte if overflow.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.OF, 1, 0))

def SETO ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . OF , 1 , 0 ) )


def SETP(cpu, dest):
        """
        Sets byte if parity.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.PF, 1, 0))

def SETP ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . PF , 1 , 0 ) )


def SETPE(cpu, dest):
        """
        Sets byte if parity even.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.PF, 1, 0))

def SETPE ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . PF , 1 , 0 ) )


def SETPO(cpu, dest):
        """
        Sets byte if parity odd.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.PF == False, 1, 0))

def SETPO ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . PF == False , 1 , 0 ) )


def SETS(cpu, dest):
        """
        Sets byte if sign.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.SF, 1, 0))

def SETS ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . SF , 1 , 0 ) )


def SETZ(cpu, dest):
        """
        Sets byte if zero.

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, 1, 0))

def SETZ ( cpu , dest ) : dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , 1 , 0 ) )


def LEAVE(cpu):
        """
        High level procedure exit.

        Releases the stack frame set up by an earlier ENTER instruction. The
        LEAVE instruction copies the frame pointer (in the EBP register) into
        the stack pointer register (ESP), which releases the stack space allocated
        to the stack frame. The old frame pointer (the frame pointer for the calling
        procedure that was saved by the ENTER instruction) is then popped from
        the stack into the EBP register, restoring the calling procedure's stack
        frame.
        A RET instruction is commonly executed following a LEAVE instruction
        to return program control to the calling procedure::

                IF Stackaddress_bit_size  =  32
                THEN
                    ESP  =  EBP;
                ELSE (* Stackaddress_bit_size  =  16*)
                    SP  =  BP;
                FI;
                IF OperandSize  =  32
                THEN
                    EBP  =  Pop();
                ELSE (* OperandSize  =  16*)
                    BP  =  Pop();
                FI;

        :param cpu: current CPU.
        """
        cpu.STACK = cpu.FRAME
        cpu.FRAME = cpu.pop(cpu.address_bit_size)

def LEAVE ( cpu ) : cpu . STACK = cpu . FRAME cpu . FRAME = cpu . pop ( cpu . address_bit_size )


def PUSH(cpu, src):
        """
        Pushes a value onto the stack.

        Decrements the stack pointer and then stores the source operand on the top of the stack.

        :param cpu: current CPU.
        :param src: source operand.
        """
        # http://stackoverflow.com/questions/11291151/how-push-imm-encodes
        size = src.size
        v = src.read()
        if size != 64 and size != cpu.address_bit_size // 2:
            v = Operators.SEXTEND(v, size, cpu.address_bit_size)
            size = cpu.address_bit_size
        cpu.push(v, size)

def PUSH ( cpu , src ) : size = src . size v = src . read ( ) if size != 64 and size != cpu . address_bit_size // 2 : v = Operators . SEXTEND ( v , size , cpu . address_bit_size ) size = cpu . address_bit_size cpu . push ( v , size )


def CALL(cpu, op0):
        """
        Procedure call.

        Saves procedure linking information on the stack and branches to the called procedure specified using the target
        operand. The target operand specifies the address of the first instruction in the called procedure. The operand can
        be an immediate value, a general-purpose register, or a memory location.

        :param cpu: current CPU.
        :param op0: target operand.
        """
        # TODO FIX 64Bit FIX segment
        proc = op0.read()
        cpu.push(cpu.PC, cpu.address_bit_size)
        cpu.PC = proc

def CALL ( cpu , op0 ) : proc = op0 . read ( ) cpu . push ( cpu . PC , cpu . address_bit_size ) cpu . PC = proc


def RET(cpu, *operands):
        """
        Returns from procedure.

        Transfers program control to a return address located on the top of
        the stack. The address is usually placed on the stack by a CALL instruction,
        and the return is made to the instruction that follows the CALL instruction.
        The optional source operand specifies the number of stack bytes to be
        released after the return address is popped; the default is none.

        :param cpu: current CPU.
        :param operands: variable operands list.
        """
        # TODO FIX 64Bit FIX segment
        N = 0
        if len(operands) > 0:
            N = operands[0].read()
        cpu.PC = cpu.pop(cpu.address_bit_size)
        cpu.STACK += N

def RET ( cpu , * operands ) : N = 0 if len ( operands ) > 0 : N = operands [ 0 ] . read ( ) cpu . PC = cpu . pop ( cpu . address_bit_size ) cpu . STACK += N


def JA(cpu, target):
        """
        Jumps short if above.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(cpu.CF == False, cpu.ZF == False), target.read(), cpu.PC)

def JA ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . AND ( cpu . CF == False , cpu . ZF == False ) , target . read ( ) , cpu . PC )


def JB(cpu, target):
        """
        Jumps short if below.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF == True, target.read(), cpu.PC)

def JB ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CF == True , target . read ( ) , cpu . PC )


def JBE(cpu, target):
        """
        Jumps short if below or equal.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.OR(cpu.CF, cpu.ZF), target.read(), cpu.PC)

def JBE ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . OR ( cpu . CF , cpu . ZF ) , target . read ( ) , cpu . PC )


def JC(cpu, target):
        """
        Jumps short if carry.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF, target.read(), cpu.PC)

def JC ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CF , target . read ( ) , cpu . PC )


def JCXZ(cpu, target):
        """
        Jumps short if CX register is 0.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CX == 0, target.read(), cpu.PC)

def JCXZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CX == 0 , target . read ( ) , cpu . PC )


def JECXZ(cpu, target):
        """
        Jumps short if ECX register is 0.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.ECX == 0, target.read(), cpu.PC)

def JECXZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . ECX == 0 , target . read ( ) , cpu . PC )


def JRCXZ(cpu, target):
        """
        Jumps short if RCX register is 0.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.RCX == 0, target.read(), cpu.PC)

def JRCXZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . RCX == 0 , target . read ( ) , cpu . PC )


def JG(cpu, target):
        """
        Jumps short if greater.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.AND(cpu.ZF == False, cpu.SF == cpu.OF), target.read(), cpu.PC)

def JG ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . AND ( cpu . ZF == False , cpu . SF == cpu . OF ) , target . read ( ) , cpu . PC )


def JGE(cpu, target):
        """
        Jumps short if greater or equal.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, (cpu.SF == cpu.OF), target.read(), cpu.PC)

def JGE ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , ( cpu . SF == cpu . OF ) , target . read ( ) , cpu . PC )


def JNB(cpu, target):
        """
        Jumps short if not below.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.CF == False, target.read(), cpu.PC)

def JNB ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . CF == False , target . read ( ) , cpu . PC )


def JNE(cpu, target):
        """
        Jumps short if not equal.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.ZF, target.read(), cpu.PC)

def JNE ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . ZF , target . read ( ) , cpu . PC )


def JNG(cpu, target):
        """
        Jumps short if not greater.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, Operators.OR(cpu.ZF, cpu.SF != cpu.OF), target.read(), cpu.PC)

def JNG ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , Operators . OR ( cpu . ZF , cpu . SF != cpu . OF ) , target . read ( ) , cpu . PC )


def JNO(cpu, target):
        """
        Jumps short if not overflow.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.OF, target.read(), cpu.PC)

def JNO ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . OF , target . read ( ) , cpu . PC )


def JNP(cpu, target):
        """
        Jumps short if not parity.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.PF, target.read(), cpu.PC)

def JNP ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . PF , target . read ( ) , cpu . PC )


def JNS(cpu, target):
        """
        Jumps short if not sign.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, False == cpu.SF, target.read(), cpu.PC)

def JNS ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , False == cpu . SF , target . read ( ) , cpu . PC )


def JO(cpu, target):
        """
        Jumps short if overflow.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.OF, target.read(), cpu.PC)

def JO ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . OF , target . read ( ) , cpu . PC )


def JP(cpu, target):
        """
        Jumps short if parity.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.PF, target.read(), cpu.PC)

def JP ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . PF , target . read ( ) , cpu . PC )


def JS(cpu, target):
        """
        Jumps short if sign.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.SF, target.read(), cpu.PC)

def JS ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . SF , target . read ( ) , cpu . PC )


def JZ(cpu, target):
        """
        Jumps short if zero.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, cpu.ZF, target.read(), cpu.PC)

def JZ ( cpu , target ) : cpu . PC = Operators . ITEBV ( cpu . address_bit_size , cpu . ZF , target . read ( ) , cpu . PC )


def LJMP(cpu, cs_selector, target):
        """
        We are just going to ignore the CS selector for now.
        """
        logger.info("LJMP: Jumping to: %r:%r", cs_selector.read(), target.read())
        cpu.CS = cs_selector.read()
        cpu.PC = target.read()

def
LJMP
(
cpu
,
cs_selector
,
target
)
:
logger
.
info
(
"LJMP: Jumping to: %r:%r"
,
cs_selector
.
read
(
)
,
target
.
read
(
)
)
cpu
.
CS
=
cs_selector
.
read
(
)
cpu
.
PC
=
target
.
read
(
)

We are just going to ignore the CS selector for now .


def LOOP(cpu, dest):
        """
        Loops according to ECX counter.

        Performs a loop operation using the ECX or CX register as a counter.
        Each time the LOOP instruction is executed, the count register is decremented,
        then checked for 0. If the count is 0, the loop is terminated and program
        execution continues with the instruction following the LOOP instruction.
        If the count is not zero, a near jump is performed to the destination
        (target) operand, which is presumably the instruction at the beginning
        of the loop. If the address-size attribute is 32 bits, the ECX register
        is used as the count register; otherwise the CX register is used::

                IF address_bit_size  =  32
                THEN
                    Count is ECX;
                ELSE (* address_bit_size  =  16 *)
                    Count is CX;
                FI;
                Count  =  Count - 1;

                IF (Count  0)  =  1
                THEN
                    EIP  =  EIP + SignExtend(DEST);
                    IF OperandSize  =  16
                    THEN
                        EIP  =  EIP AND 0000FFFFH;
                    FI;
                ELSE
                    Terminate loop and continue program execution at EIP;
                FI;

        :param cpu: current CPU.
        :param dest: destination operand.
        """
        counter_name = {16: 'CX', 32: 'ECX', 64: 'RCX'}[cpu.address_bit_size]
        counter = cpu.write_register(counter_name, cpu.read_register(counter_name) - 1)
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, counter == 0, (cpu.PC + dest.read()) & ((1 << dest.size) - 1), cpu.PC + cpu.instruction.size)

def LOOP ( cpu , dest ) : counter_name = { 16 : 'CX' , 32 : 'ECX' , 64 : 'RCX' } [ cpu . address_bit_size ] counter = cpu . write_register ( counter_name , cpu . read_register ( counter_name ) - 1 ) cpu . PC = Operators . ITEBV ( cpu . address_bit_size , counter == 0 , ( cpu . PC + dest . read ( ) ) & ( ( 1 << dest . size ) - 1 ) , cpu . PC + cpu . instruction . size )


def LOOPNZ(cpu, target):
        """
        Loops if ECX counter is nonzero.

        :param cpu: current CPU.
        :param target: destination operand.
        """
        counter_name = {16: 'CX', 32: 'ECX', 64: 'RCX'}[cpu.address_bit_size]
        counter = cpu.write_register(counter_name, cpu.read_register(counter_name) - 1)
        cpu.PC = Operators.ITEBV(cpu.address_bit_size, counter != 0, (cpu.PC + target.read()) & ((1 << target.size) - 1), cpu.PC + cpu.instruction.size)

def LOOPNZ ( cpu , target ) : counter_name = { 16 : 'CX' , 32 : 'ECX' , 64 : 'RCX' } [ cpu . address_bit_size ] counter = cpu . write_register ( counter_name , cpu . read_register ( counter_name ) - 1 ) cpu . PC = Operators . ITEBV ( cpu . address_bit_size , counter != 0 , ( cpu . PC + target . read ( ) ) & ( ( 1 << target . size ) - 1 ) , cpu . PC + cpu . instruction . size )


def RCL(cpu, dest, src):
        """
        Rotates through carry left.

        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 RCL instruction shifts the CF flag into the least-significant bit and shifts the most-significant bit into the CF flag.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: count operand.
        """
        OperandSize = dest.size
        count = src.read()
        countMask = {8: 0x1f,
                     16: 0x1f,
                     32: 0x1f,
                     64: 0x3f}[OperandSize]
        tempCount = Operators.ZEXTEND((count & countMask) % (src.size + 1), OperandSize)

        value = dest.read()

        if isinstance(tempCount, int) and tempCount == 0:
            # this is a no-op
            new_val = value
            dest.write(new_val)
        else:
            carry = Operators.ITEBV(OperandSize, cpu.CF, 1, 0)
            right = value >> (OperandSize - tempCount)
            new_val = (value << tempCount) | (carry << (tempCount - 1)) | (right >> 1)
            dest.write(new_val)

            def sf(v, size):
                return (v & (1 << (size - 1))) != 0
            cpu.CF = sf(value << (tempCount - 1), OperandSize)
            cpu.OF = Operators.ITE(tempCount == 1,
                                   sf(new_val, OperandSize) != cpu.CF,
                                   cpu.OF)

def RCL ( cpu , dest , src ) : OperandSize = dest . size count = src . read ( ) countMask = { 8 : 0x1f , 16 : 0x1f , 32 : 0x1f , 64 : 0x3f } [ OperandSize ] tempCount = Operators . ZEXTEND ( ( count & countMask ) % ( src . size + 1 ) , OperandSize ) value = dest . read ( ) if isinstance ( tempCount , int ) and tempCount == 0 : new_val = value dest . write ( new_val ) else : carry = Operators . ITEBV ( OperandSize , cpu . CF , 1 , 0 ) right = value >> ( OperandSize - tempCount ) new_val = ( value << tempCount ) | ( carry << ( tempCount - 1 ) ) | ( right >> 1 ) dest . write ( new_val ) def sf ( v , size ) : return ( v & ( 1 << ( size - 1 ) ) ) != 0 cpu . CF = sf ( value << ( tempCount - 1 ) , OperandSize ) cpu . OF = Operators . ITE ( tempCount == 1 , sf ( new_val , OperandSize ) != cpu . CF , cpu . OF )


def SAR(cpu, dest, src):
        """
        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.
        """
        OperandSize = dest.size
        countMask = {8: 0x1f,
                     16: 0x1f,
                     32: 0x1f,
                     64: 0x3f}[OperandSize]

        count = src.read() & countMask
        value = dest.read()

        res = Operators.SAR(OperandSize, value, Operators.ZEXTEND(count, OperandSize))
        dest.write(res)

        SIGN_MASK = (1 << (OperandSize - 1))

        # We can't use this one as the 'true' expression gets eagerly calculated even on count == 0		 +        cpu.CF = Operators.ITE(count!=0, ((value >> Operators.ZEXTEND(count-1, OperandSize)) & 1) !=0, cpu.CF)
        # cpu.CF = Operators.ITE(count!=0, ((value >> Operators.ZEXTEND(count-1, OperandSize)) & 1) !=0, cpu.CF)

        if issymbolic(count):
            # We can't use this one as the EXTRACT op needs the offset arguments to be concrete
            #    cpu.CF = Operators.ITE(count!=0, Operands.EXTRACT(value,count-1,1) !=0, cpu.CF)
            cpu.CF = Operators.ITE(Operators.AND(count != 0, count <= OperandSize), ((value >> Operators.ZEXTEND(count - 1, OperandSize)) & 1) != 0, cpu.CF)
        else:
            if count != 0:
                if count > OperandSize:
                    count = OperandSize
                cpu.CF = Operators.EXTRACT(value, count - 1, 1) != 0

        # on count == 0 AF is unaffected, for count > 0, AF is undefined.
        # in either case, do not touch AF
        cpu.ZF = Operators.ITE(count != 0, res == 0, cpu.ZF)
        cpu.SF = Operators.ITE(count != 0, (res & SIGN_MASK) != 0, cpu.SF)
        cpu.OF = Operators.ITE(count == 1, False, cpu.OF)
        cpu.PF = Operators.ITE(count != 0, cpu._calculate_parity_flag(res), cpu.PF)

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


def SHR(cpu, dest, src):
        """
        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.
        """
        OperandSize = dest.size
        count = Operators.ZEXTEND(src.read() & (OperandSize - 1), OperandSize)
        value = dest.read()

        res = dest.write(value >> count)  # UNSIGNED Operators.UDIV2 !! TODO Check

        MASK = (1 << OperandSize) - 1
        SIGN_MASK = 1 << (OperandSize - 1)

        if issymbolic(count):
            cpu.CF = Operators.ITE(count != 0,
                                   ((value >> Operators.ZEXTEND(count - 1, OperandSize)) & 1) != 0,
                                   cpu.CF)
        else:
            if count != 0:
                cpu.CF = Operators.EXTRACT(value, count - 1, 1) != 0

        cpu.ZF = Operators.ITE(count != 0, res == 0, cpu.ZF)
        cpu.SF = Operators.ITE(count != 0, (res & SIGN_MASK) != 0, cpu.SF)
        # OF is only defined for count == 1, but in practice (unit tests from real cpu) it's calculated for count != 0
        cpu.OF = Operators.ITE(count != 0, ((value >> (OperandSize - 1)) & 0x1) == 1, cpu.OF)
        cpu.PF = Operators.ITE(count != 0, cpu._calculate_parity_flag(res), cpu.PF)

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


def SHLD(cpu, dest, src, count):
        """
        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
        """
        OperandSize = dest.size
        tempCount = Operators.ZEXTEND(count.read(), OperandSize) & (OperandSize - 1)
        arg0 = dest.read()
        arg1 = src.read()

        MASK = ((1 << OperandSize) - 1)
        t0 = (arg0 << tempCount)
        t1 = arg1 >> (OperandSize - tempCount)
        res = Operators.ITEBV(OperandSize, tempCount == 0, arg0, t0 | t1)
        res = res & MASK
        dest.write(res)
        if isinstance(tempCount, int) and tempCount == 0:
            pass
        else:
            SIGN_MASK = 1 << (OperandSize - 1)
            lastbit = 0 != ((arg0 << (tempCount - 1)) & SIGN_MASK)

            cpu._set_shiftd_flags(OperandSize, arg0, res, lastbit, tempCount)

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


def BSF(cpu, dest, src):
        """
        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.
        """
        value = src.read()
        flag = Operators.EXTRACT(value, 0, 1) == 1
        res = 0
        for pos in range(1, src.size):
            res = Operators.ITEBV(dest.size, flag, res, pos)
            flag = Operators.OR(flag, Operators.EXTRACT(value, pos, 1) == 1)

        cpu.ZF = value == 0
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, dest.read(), res))

def BSF ( cpu , dest , src ) : value = src . read ( ) flag = Operators . EXTRACT ( value , 0 , 1 ) == 1 res = 0 for pos in range ( 1 , src . size ) : res = Operators . ITEBV ( dest . size , flag , res , pos ) flag = Operators . OR ( flag , Operators . EXTRACT ( value , pos , 1 ) == 1 ) cpu . ZF = value == 0 dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , dest . read ( ) , res ) )


def BSR(cpu, dest, src):
        """
        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.
        """
        value = src.read()
        flag = Operators.EXTRACT(value, src.size - 1, 1) == 1
        res = 0

        for pos in reversed(range(0, src.size)):
            res = Operators.ITEBV(dest.size, flag, res, pos)
            flag = Operators.OR(flag, (Operators.EXTRACT(value, pos, 1) == 1))

        cpu.PF = cpu._calculate_parity_flag(res)
        cpu.ZF = value == 0
        dest.write(Operators.ITEBV(dest.size, cpu.ZF, dest.read(), res))

def BSR ( cpu , dest , src ) : value = src . read ( ) flag = Operators . EXTRACT ( value , src . size - 1 , 1 ) == 1 res = 0 for pos in reversed ( range ( 0 , src . size ) ) : res = Operators . ITEBV ( dest . size , flag , res , pos ) flag = Operators . OR ( flag , ( Operators . EXTRACT ( value , pos , 1 ) == 1 ) ) cpu . PF = cpu . _calculate_parity_flag ( res ) cpu . ZF = value == 0 dest . write ( Operators . ITEBV ( dest . size , cpu . ZF , dest . read ( ) , res ) )


def BT(cpu, dest, src):
        """
        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.
        """
        if dest.type == 'register':
            cpu.CF = ((dest.read() >> (src.read() % dest.size)) & 1) != 0
        elif dest.type == 'memory':
            addr, pos = cpu._getMemoryBit(dest, src)
            base, size, ty = cpu.get_descriptor(cpu.DS)
            value = cpu.read_int(addr + base, 8)
            cpu.CF = Operators.EXTRACT(value, pos, 1) == 1
        else:
            raise NotImplementedError(f"Unknown operand for BT: {dest.type}")

def
BT
(
cpu
,
dest
,
src
)
:
if
dest
.
type
==
'register'
:
cpu
.
CF
=
(
(
dest
.
read
(
)
>>
(
src
.
read
(
)
%
dest
.
size
)
)
&
1
)
!=
0
elif
dest
.
type
==
'memory'
:
addr
,
pos
=
cpu
.
_getMemoryBit
(
dest
,
src
)
base
,
size
,
ty
=
cpu
.
get_descriptor
(
cpu
.
DS
)
value
=
cpu
.
read_int
(
addr
+
base
,
8
)
cpu
.
CF
=
Operators
.
EXTRACT
(
value
,
pos
,
1
)
==
1
else
:
raise
NotImplementedError
(
f"Unknown operand for BT: {dest.type}"
)


def BTC(cpu, dest, src):
        """
        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.
        """
        if dest.type == 'register':
            value = dest.read()
            pos = src.read() % dest.size
            cpu.CF = value & (1 << pos) == 1 << pos
            dest.write(value ^ (1 << pos))
        elif dest.type == 'memory':
            addr, pos = cpu._getMemoryBit(dest, src)
            base, size, ty = cpu.get_descriptor(cpu.DS)
            addr += base
            value = cpu.read_int(addr, 8)
            cpu.CF = value & (1 << pos) == 1 << pos
            value = value ^ (1 << pos)
            cpu.write_int(addr, value, 8)
        else:
            raise NotImplementedError(f"Unknown operand for BTC: {dest.type}")

def
BTC
(
cpu
,
dest
,
src
)
:
if
dest
.
type
==
'register'
:
value
=
dest
.
read
(
)
pos
=
src
.
read
(
)
%
dest
.
size
cpu
.
CF
=
value
&
(
1
<<
pos
)
==
1
<<
pos
dest
.
write
(
value
^
(
1
<<
pos
)
)
elif
dest
.
type
==
'memory'
:
addr
,
pos
=
cpu
.
_getMemoryBit
(
dest
,
src
)
base
,
size
,
ty
=
cpu
.
get_descriptor
(
cpu
.
DS
)
addr
+=
base
value
=
cpu
.
read_int
(
addr
,
8
)
cpu
.
CF
=
value
&
(
1
<<
pos
)
==
1
<<
pos
value
=
value
^
(
1
<<
pos
)
cpu
.
write_int
(
addr
,
value
,
8
)
else
:
raise
NotImplementedError
(
f"Unknown operand for BTC: {dest.type}"
)


def CMPS(cpu, dest, src):
        """
        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.
        """
        src_reg = {8: 'SI', 32: 'ESI', 64: 'RSI'}[cpu.address_bit_size]
        dest_reg = {8: 'DI', 32: 'EDI', 64: 'RDI'}[cpu.address_bit_size]

        base, _, ty = cpu.get_descriptor(cpu.DS)

        src_addr = cpu.read_register(src_reg) + base
        dest_addr = cpu.read_register(dest_reg) + base
        size = dest.size

        # Compare
        arg1 = cpu.read_int(dest_addr, size)
        arg0 = cpu.read_int(src_addr, size)
        res = (arg0 - arg1) & ((1 << size) - 1)

        cpu._calculate_CMP_flags(size, res, arg0, arg1)

        #Advance EDI/ESI pointers
        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)
        cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)

def CMPS ( cpu , dest , src ) : src_reg = { 8 : 'SI' , 32 : 'ESI' , 64 : 'RSI' } [ cpu . address_bit_size ] dest_reg = { 8 : 'DI' , 32 : 'EDI' , 64 : 'RDI' } [ cpu . address_bit_size ] base , _ , ty = cpu . get_descriptor ( cpu . DS ) src_addr = cpu . read_register ( src_reg ) + base dest_addr = cpu . read_register ( dest_reg ) + base size = dest . size arg1 = cpu . read_int ( dest_addr , size ) arg0 = cpu . read_int ( src_addr , size ) res = ( arg0 - arg1 ) & ( ( 1 << size ) - 1 ) cpu . _calculate_CMP_flags ( size , res , arg0 , arg1 ) increment = Operators . ITEBV ( cpu . address_bit_size , cpu . DF , - size // 8 , size // 8 ) cpu . write_register ( src_reg , cpu . read_register ( src_reg ) + increment ) cpu . write_register ( dest_reg , cpu . read_register ( dest_reg ) + increment )


def LODS(cpu, dest, src):
        """
        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.
        """
        src_reg = {8: 'SI', 32: 'ESI', 64: 'RSI'}[cpu.address_bit_size]
        base, _, ty = cpu.get_descriptor(cpu.DS)

        src_addr = cpu.read_register(src_reg) + base
        size = dest.size

        arg0 = cpu.read_int(src_addr, size)
        dest.write(arg0)

        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)

def LODS ( cpu , dest , src ) : src_reg = { 8 : 'SI' , 32 : 'ESI' , 64 : 'RSI' } [ cpu . address_bit_size ] base , _ , ty = cpu . get_descriptor ( cpu . DS ) src_addr = cpu . read_register ( src_reg ) + base size = dest . size arg0 = cpu . read_int ( src_addr , size ) dest . write ( arg0 ) increment = Operators . ITEBV ( cpu . address_bit_size , cpu . DF , - size // 8 , size // 8 ) cpu . write_register ( src_reg , cpu . read_register ( src_reg ) + increment )


def MOVS(cpu, dest, src):
        """
        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.
        """
        base, size, ty = cpu.get_descriptor(cpu.DS)
        src_addr = src.address() + base
        dest_addr = dest.address() + base

        src_reg = src.mem.base
        dest_reg = dest.mem.base
        size = dest.size

        # Copy the data
        dest.write(src.read())

        #Advance EDI/ESI pointers
        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(src_reg, cpu.read_register(src_reg) + increment)
        cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)

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


def SCAS(cpu, dest, src):
        """
        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.
        """
        dest_reg = dest.reg
        mem_reg = src.mem.base  # , src.type, src.read()
        size = dest.size
        arg0 = dest.read()
        arg1 = src.read()
        res = arg0 - arg1
        cpu._calculate_CMP_flags(size, res, arg0, arg1)

        increment = Operators.ITEBV(cpu.address_bit_size, cpu.DF, -size // 8, size // 8)
        cpu.write_register(mem_reg, cpu.read_register(mem_reg) + increment)

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


def STOS(cpu, dest, src):
        """
        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.
        """
        size = src.size
        dest.write(src.read())
        dest_reg = dest.mem.base
        increment = Operators.ITEBV({'RDI': 64, 'EDI': 32, 'DI': 16}[dest_reg], cpu.DF, -size // 8, size // 8)
        cpu.write_register(dest_reg, cpu.read_register(dest_reg) + increment)

def STOS ( cpu , dest , src ) : size = src . size dest . write ( src . read ( ) ) dest_reg = dest . mem . base increment = Operators . ITEBV ( { 'RDI' : 64 , 'EDI' : 32 , 'DI' : 16 } [ dest_reg ] , cpu . DF , - size // 8 , size // 8 ) cpu . write_register ( dest_reg , cpu . read_register ( dest_reg ) + increment )


def SARX(cpu, dest, src, count):
        """
        The shift arithmetic right.

        :param cpu: current CPU.
        :param dest: destination operand.
        :param src: count operand.
        """
        OperandSize = dest.size
        count = count.read()
        countMask = {8: 0x1f,
                     16: 0x1f,
                     32: 0x1f,
                     64: 0x3f}[OperandSize]
        tempCount = count & countMask
        tempDest = value = src.read()

        sign = value & (1 << (OperandSize - 1))
        while tempCount != 0:
            cpu.CF = (value & 0x1) != 0  # LSB
            value = (value >> 1) | sign
            tempCount = tempCount - 1
        res = dest.write(value)

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


def PSHUFW(cpu, op0, op1, op3):
        """
        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.
         """
        size = op0.size
        arg0 = op0.read()
        arg1 = op1.read()
        arg3 = Operators.ZEXTEND(op3.read(), size)
        assert size == 64
        arg0 |= ((arg1 >> ((arg3 >> 0) & 3 * 16)) & 0xffff)
        arg0 |= ((arg1 >> ((arg3 >> 2) & 3 * 16)) & 0xffff) << 16
        arg0 |= ((arg1 >> ((arg3 >> 4) & 3 * 16)) & 0xffff) << 32
        arg0 |= ((arg1 >> ((arg3 >> 6) & 3 * 16)) & 0xffff) << 48
        op0.write(arg0)


def PSHUFD(cpu, op0, op1, op3):
        """
        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.
         """
        size = op0.size
        arg0 = op0.read()
        arg1 = op1.read()
        order = Operators.ZEXTEND(op3.read(), size)

        arg0 = arg0 & 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000
        arg0 |= ((arg1 >> (((order >> 0) & 3) * 32)) & 0xffffffff)
        arg0 |= ((arg1 >> (((order >> 2) & 3) * 32)) & 0xffffffff) << 32
        arg0 |= ((arg1 >> (((order >> 4) & 3) * 32)) & 0xffffffff) << 64
        arg0 |= ((arg1 >> (((order >> 6) & 3) * 32)) & 0xffffffff) << 96

        op0.write(arg0)


def PMOVMSKB(cpu, op0, op1):
        """
        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.
        """
        arg0 = op0.read()
        arg1 = op1.read()

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

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

Moves byte mask to general - purpose register .


def PSRLDQ(cpu, dest, src):
        """
        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.
        """
        # TODO(yan): Verify the correctness of truncating SRC like this ( tests
        # use '-1' as the value
        temp = Operators.EXTRACT(src.read(), 0, 8)
        temp = Operators.ITEBV(src.size, temp > 15, 16, temp)
        dest.write(dest.read() >> (temp * 8))

def PSRLDQ ( cpu , dest , src ) : temp = Operators . EXTRACT ( src . read ( ) , 0 , 8 ) temp = Operators . ITEBV ( src . size , temp > 15 , 16 , temp ) dest . write ( dest . read ( ) >> ( temp * 8 ) )

Packed shift right logical double quadword .


def MOVZX(cpu, op0, op1):
        """
        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.
        """
        op0.write(Operators.ZEXTEND(op1.read(), op0.size))

def MOVZX ( cpu , op0 , op1 ) : op0 . write ( Operators . ZEXTEND ( op1 . read ( ) , op0 . size ) )


def MOVSX(cpu, op0, op1):
        """
        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.
        """
        op0.write(Operators.SEXTEND(op1.read(), op1.size, op0.size))

def MOVSX ( cpu , op0 , op1 ) : op0 . write ( Operators . SEXTEND ( op1 . read ( ) , op1 . size , op0 . size ) )


def CWDE(cpu):
        """
        Converts word to doubleword.

        ::
            DX = sign-extend of AX.

        :param cpu: current CPU.
        """
        bit = Operators.EXTRACT(cpu.AX, 15, 1)
        cpu.EAX = Operators.SEXTEND(cpu.AX, 16, 32)
        cpu.EDX = Operators.SEXTEND(bit, 1, 32)

def CWDE ( cpu ) : bit = Operators . EXTRACT ( cpu . AX , 15 , 1 ) cpu . EAX = Operators . SEXTEND ( cpu . AX , 16 , 32 ) cpu . EDX = Operators . SEXTEND ( bit , 1 , 32 )


def RDTSC(cpu):
        """
        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.
        """
        val = cpu.icount
        cpu.RAX = val & 0xffffffff
        cpu.RDX = (val >> 32) & 0xffffffff

def RDTSC ( cpu ) : val = cpu . icount cpu . RAX = val & 0xffffffff cpu . RDX = ( val >> 32 ) & 0xffffffff


def MOVLPD(cpu, dest, src):
        """
        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.
        """
        value = src.read()
        if src.size == 64 and dest.size == 128:
            value = (dest.read() & 0xffffffffffffffff0000000000000000) | Operators.ZEXTEND(value, 128)
        dest.write(value)

def MOVLPD ( cpu , dest , src ) : value = src . read ( ) if src . size == 64 and dest . size == 128 : value = ( dest . read ( ) & 0xffffffffffffffff0000000000000000 ) | Operators . ZEXTEND ( value , 128 ) dest . write ( value )

Moves low packed double - precision floating - point value .


def MOVHPD(cpu, dest, src):
        """
        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.
        """
        if src.size == 128:
            assert dest.size == 64
            dest.write(Operators.EXTRACT(src.read(), 64, 64))
        else:
            assert src.size == 64 and dest.size == 128
            value = Operators.EXTRACT(dest.read(), 0, 64)  # low part
            dest.write(Operators.CONCAT(128, src.read(), value))

def MOVHPD ( cpu , dest , src ) : if src . size == 128 : assert dest . size == 64 dest . write ( Operators . EXTRACT ( src . read ( ) , 64 , 64 ) ) else : assert src . size == 64 and dest . size == 128 value = Operators . EXTRACT ( dest . read ( ) , 0 , 64 ) dest . write ( Operators . CONCAT ( 128 , src . read ( ) , value ) )

Moves high packed double - precision floating - point value .


def PSUBB(cpu, dest, src):
        """
        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.
        """
        result = []
        value_a = dest.read()
        value_b = src.read()
        for i in reversed(range(0, dest.size, 8)):
            a = Operators.EXTRACT(value_a, i, 8)
            b = Operators.EXTRACT(value_b, i, 8)
            result.append((a - b) & 0xff)
        dest.write(Operators.CONCAT(8 * len(result), *result))

def PSUBB ( cpu , dest , src ) : result = [ ] value_a = dest . read ( ) value_b = src . read ( ) for i in reversed ( range ( 0 , dest . size , 8 ) ) : a = Operators . EXTRACT ( value_a , i , 8 ) b = Operators . EXTRACT ( value_b , i , 8 ) result . append ( ( a - b ) & 0xff ) dest . write ( Operators . CONCAT ( 8 * len ( result ) , * result ) )


def MOVQ(cpu, dest, src):
        """
        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.
        """
        # mmx to mmx or mmx to mem
        if dest.size == src.size and dest.size == 64:
            dest.write(src.read())
        # two xmm regs
        elif dest.size == src.size and dest.size == 128:
            src_lo = Operators.EXTRACT(src.read(), 0, 64)
            dest.write(Operators.ZEXTEND(src_lo, 128))
        # mem to xmm
        elif dest.size == 128 and src.size == 64:
            dest.write(Operators.ZEXTEND(src.read(), dest.size))
        # xmm to mem
        elif dest.size == 64 and src.size == 128:
            dest.write(Operators.EXTRACT(src.read(), 0, dest.size))
        else:
            msg = 'Invalid size in MOVQ'
            logger.error(msg)
            raise Exception(msg)

def
MOVQ
(
cpu
,
dest
,
src
)
:
if
dest
.
size
==
src
.
size
and
dest
.
size
==
64
:
dest
.
write
(
src
.
read
(
)
)
elif
dest
.
size
==
src
.
size
and
dest
.
size
==
128
:
src_lo
=
Operators
.
EXTRACT
(
src
.
read
(
)
,
0
,
64
)
dest
.
write
(
Operators
.
ZEXTEND
(
src_lo
,
128
)
)
elif
dest
.
size
==
128
and
src
.
size
==
64
:
dest
.
write
(
Operators
.
ZEXTEND
(
src
.
read
(
)
,
dest
.
size
)
)
elif
dest
.
size
==
64
and
src
.
size
==
128
:
dest
.
write
(
Operators
.
EXTRACT
(
src
.
read
(
)
,
0
,
dest
.
size
)
)
else
:
msg
=
'Invalid size in MOVQ'
logger
.
error
(
msg
)
raise
Exception
(
msg
)


def MOVSD(cpu, dest, src):
        """
        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.
        """
        assert dest.type != 'memory' or src.type != 'memory'
        value = Operators.EXTRACT(src.read(), 0, 64)
        if dest.size > src.size:
            value = Operators.ZEXTEND(value, dest.size)
        dest.write(value)

def MOVSD ( cpu , dest , src ) : assert dest . type != 'memory' or src . type != 'memory' value = Operators . EXTRACT ( src . read ( ) , 0 , 64 ) if dest . size > src . size : value = Operators . ZEXTEND ( value , dest . size ) dest . write ( value )

Move Scalar Double - Precision Floating - Point Value