def _translate_imul(self, tb, instruction):
        # Flags Affected
        # For the one operand form of the instruction, the CF and OF flags are
        # set when significant bits are carried into the upper half of the
        # result and cleared when the result fits exactly in the lower half of
        # the result. For the two- and three-operand forms of the instruction,
        # the CF and OF flags are set when the result must be truncated to fit
        # in the destination operand size and cleared when the result fits
        # exactly in the destination operand size. The SF, ZF, AF, and PF flags
        # are undefined.

        # TODO: Implement CF and OF flags.
        # FIXME: Make this a signed multiply.

        # 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;
        # 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;


        if len(instruction.operands) == 1:

            oprnd0 = tb.read(instruction.operands[0])

            if oprnd0.size == 8:
                oprnd1 = ReilRegisterOperand("al", 8)

                tmp0 = tb.temporal(16)
                result_low = ReilRegisterOperand("al", 8)
                result_high = ReilRegisterOperand("ah", 8)
            elif oprnd0.size == 16:
                oprnd1 = ReilRegisterOperand("ax", 16)

                tmp0 = tb.temporal(32)
                result_low = ReilRegisterOperand("dx", 16)
                result_high = ReilRegisterOperand("ax", 16)
            elif oprnd0.size == 32:
                oprnd1 = ReilRegisterOperand("eax", 32)

                tmp0 = tb.temporal(64)
                result_low = ReilRegisterOperand("edx", 32)
                result_high = ReilRegisterOperand("eax", 32)
            elif oprnd0.size == 64:
                oprnd1 = ReilRegisterOperand("rax", 64)

                tmp0 = tb.temporal(64)
                result_low = ReilRegisterOperand("rdx", 64)
                result_high = ReilRegisterOperand("rax", 64)

        elif len(instruction.operands) == 2:

            oprnd0 = tb.read(instruction.operands[0])
            oprnd1 = tb.read(instruction.operands[1])

        elif len(instruction.operands) == 3:

            oprnd0 = tb.read(instruction.operands[1])
            oprnd1 = tb.read(instruction.operands[2])

        imm0 = tb.immediate(-oprnd0.size, 2*oprnd0.size)

        tmp0 = tb.temporal(2*oprnd0.size)

        # Do multiplication.
        tb.add(self._builder.gen_mul(oprnd0, oprnd1, tmp0))

        # Save result.
        if len(instruction.operands) == 1:

            tb.add(self._builder.gen_bsh(tmp0, imm0, result_high))
            tb.add(self._builder.gen_str(tmp0, result_low))

        elif len(instruction.operands) == 2:

            tb.write(instruction.operands[0], tmp0)

        elif len(instruction.operands) == 3:

            tb.write(instruction.operands[0], tmp0)

        if self._translation_mode == FULL_TRANSLATION:
            # Flags : OF, CF
            # TODO: Implement.
            self._undefine_flag(tb, self._flags["sf"])
            self._undefine_flag(tb, self._flags["zf"])
            self._undefine_flag(tb, self._flags["af"])
            self._undefine_flag(tb, self._flags["pf"])
dataset/ETHPy150Open programa-stic/barf-project/barf/barf/arch/x86/x86translator.py/X86Translator._translate_imul/original