Beispiel #1
0
def fge_op(config: Configuration) -> None:
    """
    Common logic function for the float GT opcodes
    """
    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", config.current_instruction.opcode.text, a,
                     b)

    if numpy.isnan(a) or numpy.isnan(b):
        config.push_operand(constants.U32_ZERO)
    elif a.tobytes() == b.tobytes():
        config.push_operand(constants.U32_ONE)
    elif numpy.isposinf(a):
        config.push_operand(constants.U32_ONE)
    elif numpy.isneginf(a):
        config.push_operand(constants.U32_ZERO)
    elif numpy.isposinf(b):
        config.push_operand(constants.U32_ZERO)
    elif numpy.isneginf(b):
        config.push_operand(constants.U32_ONE)
    elif a == 0 and b == 0:
        config.push_operand(constants.U32_ONE)
    elif a >= b:
        config.push_operand(constants.U32_ONE)
    else:
        config.push_operand(constants.U32_ZERO)
Beispiel #2
0
def fadd_op(config: Configuration) -> None:
    """
    Common logic function for the float ADD opcodes
    """
    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", config.current_instruction.opcode.text, a,
                     b)

    with allow_multiple(over=True, invalid=True):
        config.push_operand(a + b)
Beispiel #3
0
def fcopysign_op(config: Configuration) -> None:
    """
    Common logic function for the float COPYSIGN opcodes
    """
    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", config.current_instruction.opcode.text, a,
                     b)

    a_is_negative = _is_negative(a)
    b_is_negative = _is_negative(b)

    if a_is_negative is b_is_negative:
        config.push_operand(a)
    else:
        config.push_operand(_negate_float(a))
Beispiel #4
0
def fdiv_op(config: Configuration) -> None:
    """
    Common logic function for the float DIV opcodes
    """
    instruction = cast(BinOp, config.current_instruction)

    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", instruction.opcode.text, a, b)

    with allow_multiple(over=True, under=True, invalid=True):
        if numpy.isnan(a) or numpy.isnan(b):
            config.push_operand(a / b)
        elif numpy.isinf(a) and numpy.isinf(b):
            config.push_operand(a / b)
        elif a == 0 and b == 0:
            with allow_zerodiv():
                config.push_operand(a / b)
        elif numpy.isinf(a):
            if _same_signed(a, b):
                config.push_operand(instruction.valtype.inf)
            else:
                config.push_operand(instruction.valtype.neginf)
        elif numpy.isinf(b):
            if _same_signed(a, b):
                config.push_operand(instruction.valtype.zero)
            else:
                config.push_operand(instruction.valtype.negzero)
        elif a == 0:
            if _same_signed(a, b):
                config.push_operand(instruction.valtype.zero)
            else:
                config.push_operand(instruction.valtype.negzero)
        elif b == 0:
            if _same_signed(a, b):
                config.push_operand(instruction.valtype.inf)
            else:
                config.push_operand(instruction.valtype.neginf)
        else:
            config.push_operand(a / b)
Beispiel #5
0
def fsub_op(config: Configuration) -> None:
    """
    Common logic function for the float SUB opcodes
    """
    instruction = cast(BinOp, config.current_instruction)

    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", instruction.opcode.text, a, b)

    with allow_multiple(over=True, invalid=True):
        if numpy.isnan(a) or numpy.isnan(b):
            config.push_operand(a - b)
        elif _same_signed_inf(a, b):
            config.push_operand(a - b)
        elif numpy.isinf(a):
            config.push_operand(a)
        elif numpy.isinf(b):
            config.push_operand(instruction.valtype.value(-1) * b)
        else:
            config.push_operand(a - b)
Beispiel #6
0
def fmax_op(config: Configuration) -> None:
    """
    Common logic function for the float MAX opcodes
    """
    instruction = cast(BinOp, config.current_instruction)

    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", instruction.opcode.text, a, b)

    if numpy.isnan(a) or numpy.isnan(b):
        with allow_invalid():
            config.push_operand(a + b)
    elif numpy.isposinf(a) or numpy.isposinf(b):
        config.push_operand(instruction.valtype.inf)
    elif a == 0 and b == 0:
        if _same_signed(a, b):
            config.push_operand(a)
        else:
            config.push_operand(instruction.valtype.zero)
    else:
        config.push_operand(max(a, b))
Beispiel #7
0
def fmul_op(config: Configuration) -> None:
    """
    Common logic function for the float MUL opcodes
    """
    instruction = cast(BinOp, config.current_instruction)

    b, a = config.pop2_f64()

    if config.enable_logic_fn_logging:
        logger.debug("%s(%s, %s)", instruction.opcode.text, a, b)

    with allow_multiple(over=True, under=True, invalid=True):
        if numpy.isnan(a) or numpy.isnan(b):
            config.push_operand(a * b)
        elif _same_signed_inf(a, b):
            config.push_operand(instruction.valtype.inf)
        elif _different_signed_inf(a, b):
            config.push_operand(instruction.valtype.neginf)
        elif instruction.valtype is ValType.f64:
            config.push_operand(a * b)
        elif instruction.valtype is ValType.f32:
            config.push_operand(a * b)
        else:
            raise Exception("Unreachable")