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))
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))
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)
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))
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))
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))
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))