Beispiel #1
0
def fsqrt_op(config: Configuration) -> None:
    """
    Common logic function for the float SQRT opcodes
    """
    instruction = cast(UnOp, config.current_instruction)

    value = config.pop_f64()

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

    if numpy.isnan(value):
        with allow_invalid():
            config.push_operand(numpy.sqrt(value))
    elif value == 0:
        # TODO: this block and the subsequent _is_negative block are in
        # inverted order in the spec, indicating that the proper response here
        # should potentially be `nan` for the case of `sqrt(-0.0)` but the spec
        # tests assert that is not correct.
        # f32.wasm: line 2419
        config.push_operand(value)
    elif _is_negative(value):
        config.push_operand(instruction.valtype.nan)
    else:
        config.push_operand(numpy.sqrt(value))
Beispiel #2
0
def f32demote_op(config: Configuration) -> None:
    """
    Logic function for the F32_DEMOTE_F64 opcode
    """
    value = config.pop_f64()

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

    config.push_operand(numpy.float32(value))
Beispiel #3
0
def fneg_op(config: Configuration) -> None:
    """
    Common logic function for the float NEG opcodes
    """
    instruction = cast(UnOp, config.current_instruction)

    value = config.pop_f64()

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

    negated_value = _negate_float(value)

    config.push_operand(negated_value)
Beispiel #4
0
def ffloor_op(config: Configuration) -> None:
    """
    Common logic function for the float FLOOR opcodes
    """
    value = config.pop_f64()

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

    if numpy.isnan(value):
        with allow_invalid():
            config.push_operand(numpy.floor(value))
    elif numpy.isinf(value):
        config.push_operand(value)
    elif value == 0:
        config.push_operand(value)
    else:
        config.push_operand(numpy.floor(value))
Beispiel #5
0
def fabs_op(config: Configuration) -> None:
    """
    Common logic function for the float ABS opcodes
    """
    instruction = cast(UnOp, config.current_instruction)

    a = config.pop_f64()

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

    if numpy.isnan(a):
        if _is_negative(a):
            with allow_invalid():
                config.push_operand(_negate_float(a))
        else:
            config.push_operand(a)
    elif numpy.isinf(a):
        config.push_operand(instruction.valtype.inf)
    else:
        config.push_operand(numpy.abs(a))
Beispiel #6
0
def fnearest_op(config: Configuration) -> None:
    """
    Common logic function for the float NEAREST opcodes
    """
    instruction = cast(UnOp, config.current_instruction)

    value = config.pop_f64()

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

    if numpy.isnan(value):
        with allow_invalid():
            config.push_operand(numpy.round(value))
    elif numpy.isinf(value):
        config.push_operand(value)
    elif value == 0:
        config.push_operand(value)
    elif -0.5 <= value < 0.0:
        config.push_operand(instruction.valtype.negzero)
    else:
        config.push_operand(numpy.round(value))
Beispiel #7
0
def ftrunc_op(config: Configuration) -> None:
    """
    Common logic function for the float TRUNC opcodes
    """
    instruction = cast(UnOp, config.current_instruction)

    value = config.pop_f64()

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

    if numpy.isnan(value):
        with allow_invalid():
            config.push_operand(numpy.trunc(value))
    elif numpy.isinf(value):
        config.push_operand(value)
    elif value == 0:
        config.push_operand(value)
    elif -1.0 < value < 0.0:
        # TODO: `numpy.trunc` properly handles this case, can be removed.
        config.push_operand(instruction.valtype.negzero)
    else:
        config.push_operand(numpy.trunc(value))