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