diff --git a/librz/analysis/arch/x86/common.c b/librz/analysis/arch/x86/common.c index 2dd06ca9b3b..3c574c831e3 100644 --- a/librz/analysis/arch/x86/common.c +++ b/librz/analysis/arch/x86/common.c @@ -1083,11 +1083,11 @@ RzILOpPure *x86_il_fpu_get_rmode() { * \brief Get the float stored in FPU stack \p reg * * \param reg - * \return RzILOpFloat* IEEE754 64 bit float + * \return RzILOpFloat* IEEE754 80 bit float */ RzILOpFloat *x86_il_get_st_reg(X86Reg reg) { rz_return_val_if_fail(x86_il_is_st_reg(reg), NULL); - return BV2F(RZ_FLOAT_IEEE754_BIN_64, VARG(x86_registers[reg])); + return BV2F(RZ_FLOAT_IEEE754_BIN_80, VARG(x86_registers[reg])); } #define FLOAT_FORMAT_SWITCH_CASE(n) \ @@ -1107,7 +1107,7 @@ RzILOpFloat *x86_il_get_st_reg(X86Reg reg) { * \return RzILOpFloat* */ RzILOpFloat *x86_il_resize_floating(RzILOpFloat *val, ut32 width) { - RzFloatFormat format = RZ_FLOAT_IEEE754_BIN_64; + RzFloatFormat format; switch (width) { FLOAT_FORMAT_SWITCH_CASE(16); @@ -1172,11 +1172,11 @@ RzILOpBitVector *x86_il_int_from_floating(RzILOpFloat *float_val, ut32 width) { RzILOpEffect *x86_il_set_st_reg(X86Reg reg, RzILOpFloat *val, ut64 val_size) { rz_return_val_if_fail(x86_il_is_st_reg(reg), NULL); - if (val_size == 64) { + if (val_size == 80) { return SETG(x86_registers[reg], F2BV(val)); } else { RzILOpEffect *rmode = INIT_RMODE(); - RzILOpFloat *converted_val = x86_il_resize_floating(val, 64); + RzILOpFloat *converted_val = x86_il_resize_floating(val, val_size); return SEQ2(rmode, SETG(x86_registers[reg], F2BV(converted_val))); } @@ -1211,7 +1211,7 @@ RzILOpEffect *x86_il_set_fpu_stack_top(RzILOpPure *top) { return x86_il_set_reg_bits(X86_REG_FPSW, new_fpsw, 0); } -#define ST_MOVE_RIGHT(l, r) x86_il_set_st_reg(X86_REG_ST##r, x86_il_get_st_reg(X86_REG_ST##l), 64) +#define ST_MOVE_RIGHT(l, r) x86_il_set_st_reg(X86_REG_ST##r, x86_il_get_st_reg(X86_REG_ST##l), 80) RzILOpEffect *x86_il_st_push(RzILOpFloat *val, int val_size) { /* No need for a modulo here since the bitvector width will truncate any top @@ -1234,7 +1234,7 @@ RzILOpEffect *x86_il_st_push(RzILOpFloat *val, int val_size) { return SEQ3(set_top, st_shift, set_overflow); } -#define ST_MOVE_LEFT(l, r) x86_il_set_st_reg(X86_REG_ST##l, x86_il_get_st_reg(X86_REG_ST##r), 64) +#define ST_MOVE_LEFT(l, r) x86_il_set_st_reg(X86_REG_ST##l, x86_il_get_st_reg(X86_REG_ST##r), 80) RzILOpEffect *x86_il_st_pop() { RzILOpEffect *set_top = x86_il_set_fpu_stack_top(ADD(x86_il_get_fpu_stack_top(), UN(3, 1))); @@ -1333,8 +1333,6 @@ RzILOpEffect *x86_il_set_floating_operand_bits(X86Op op, RzILOpFloat *val, ut64 switch (op.type) { case X86_OP_REG: - /* We assume that the only registers we will be writing to would be the - * FPU stack registers, hence the 64 resize width. */ ret = x86_il_set_st_reg(op.reg, val, val_size); break; case X86_OP_MEM: { diff --git a/librz/analysis/arch/x86/il_fp_ops.inc b/librz/analysis/arch/x86/il_fp_ops.inc index 3c72d30bbbf..8cbff72b29f 100644 --- a/librz/analysis/arch/x86/il_fp_ops.inc +++ b/librz/analysis/arch/x86/il_fp_ops.inc @@ -75,7 +75,7 @@ IL_LIFTER(fnclex) { */ IL_LIFTER(fabs) { RzILOpFloat *abs_value = FABS(x86_il_get_st_reg(X86_REG_ST0)); - return SEQ2(x86_il_set_st_reg(X86_REG_ST0, abs_value, 64), x86_il_set_fpu_flag(X86_FPU_C1, IL_FALSE)); + return SEQ2(x86_il_set_st_reg(X86_REG_ST0, abs_value, 80), x86_il_set_fpu_flag(X86_FPU_C1, IL_FALSE)); } /** @@ -92,7 +92,7 @@ IL_LIFTER(fld) { * Stores the floating point value stored at the top of the FPU stack in ST(0) */ IL_LIFTER(fst) { - return x86_il_set_floating_op(0, x86_il_get_st_reg(X86_REG_ST0), 64); + return x86_il_set_floating_op(0, x86_il_get_st_reg(X86_REG_ST0), 80); } /** @@ -105,7 +105,7 @@ IL_LIFTER(fstp) { RzILOpPure *pop_val; X86_IL_ST_POP(pop_val, pop_eff); - return SEQ2(x86_il_set_floating_op(0, pop_val, 64), pop_eff); + return SEQ2(x86_il_set_floating_op(0, pop_val, 80), pop_eff); } /** @@ -113,7 +113,7 @@ IL_LIFTER(fstp) { * Load +1.0 */ IL_LIFTER(fld1) { - return x86_il_st_push(F64(1.0), 64); + return x86_il_st_push(F80(1.0), 80); } /** @@ -121,7 +121,7 @@ IL_LIFTER(fld1) { * Load +0.0 */ IL_LIFTER(fldz) { - return x86_il_st_push(F64(0.0), 64); + return x86_il_st_push(F80(0.0), 80); } /* @@ -147,13 +147,13 @@ IL_LIFTER(fldz) { #define FPU_LN2 0x3ffeb17217f7d1cfULL, 0x79abc9e3b39828efULL RzILOpFloat *math_const_to_float(uint64_t upper, uint64_t lower) { - RzILOpPure *upper_unshifted = UN(128, upper); - RzILOpPure *upper_shifted = SHIFTL0(upper_unshifted, UN(8, 64)); + RzILOpPure *upper_unshifted = UN(80, upper); + RzILOpPure *upper_shifted = SHIFTL0(upper_unshifted, UN(8, 16)); uint64_t stripped_lower = lower & ~(0x3fffffffffffULL); - RzILOpPure *final_bits = LOGOR(upper_shifted, UN(128, stripped_lower)); + RzILOpPure *final_bits = LOGOR(upper_shifted, UN(80, (stripped_lower >> (64 - 16)))); - return x86_il_resize_floating(BV2F(RZ_FLOAT_IEEE754_BIN_128, final_bits), 64); + return x86_il_resize_floating(BV2F(RZ_FLOAT_IEEE754_BIN_80, final_bits), 80); } /** @@ -161,7 +161,7 @@ RzILOpFloat *math_const_to_float(uint64_t upper, uint64_t lower) { * Load log2(10) */ IL_LIFTER(fldl2t) { - return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_L2T), 64)); + return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_L2T), 80)); } /** @@ -169,7 +169,7 @@ IL_LIFTER(fldl2t) { * Load log2(e) */ IL_LIFTER(fldl2e) { - return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_L2E), 64)); + return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_L2E), 80)); } /** @@ -177,7 +177,7 @@ IL_LIFTER(fldl2e) { * Load pi */ IL_LIFTER(fldpi) { - return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_PI), 64)); + return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_PI), 80)); } /** @@ -185,7 +185,7 @@ IL_LIFTER(fldpi) { * Load log10(2) */ IL_LIFTER(fldlg2) { - return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_LG2), 64)); + return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_LG2), 80)); } /** @@ -193,7 +193,7 @@ IL_LIFTER(fldlg2) { * Load ln(2) */ IL_LIFTER(fldln2) { - return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_LN2), 64)); + return SEQ2(INIT_RMODE(), x86_il_st_push(math_const_to_float(FPU_LN2), 80)); } /** @@ -215,8 +215,8 @@ IL_LIFTER(fxch) { but it doesn't matter for now so I'm not bothering with it. */ return SEQ4( SETL("tmp", x86_il_get_st_reg(X86_REG_ST0)), - x86_il_set_st_reg(X86_REG_ST0, x86_il_get_st_reg(reg), 64), - x86_il_set_st_reg(reg, VARL("tmp"), 64), + x86_il_set_st_reg(X86_REG_ST0, x86_il_get_st_reg(reg), 80), + x86_il_set_st_reg(reg, VARL("tmp"), 80), x86_il_set_fpu_flag(X86_FPU_C1, IL_FALSE)); } @@ -226,9 +226,9 @@ IL_LIFTER(fxch) { */ IL_LIFTER(fild) { RzILOpPure *int_val = x86_il_get_op(0); - RzILOpFloat *float_val = x86_il_floating_from_int(int_val, RZ_FLOAT_IEEE754_BIN_64); + RzILOpFloat *float_val = x86_il_floating_from_int(int_val, RZ_FLOAT_IEEE754_BIN_80); - return SEQ2(INIT_RMODE(), x86_il_st_push(float_val, 64)); + return SEQ2(INIT_RMODE(), x86_il_st_push(float_val, 80)); } /** diff --git a/librz/il/il_opcodes.c b/librz/il/il_opcodes.c index 21f5aeda3de..3a627bcf36a 100644 --- a/librz/il/il_opcodes.c +++ b/librz/il/il_opcodes.c @@ -796,6 +796,24 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f64(double f) { return ret; } +RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f80(long double f) { + RzFloat *value = rz_float_new_from_f80(f); + if (!value) { + return NULL; + } + RzILOpFloat *ret = RZ_NEW0(RzILOpFloat); + if (!ret) { + rz_float_free(value); + return NULL; + } + + ret->code = RZ_IL_OP_FLOAT; + ret->op.float_.bv = rz_il_op_new_bitv(value->s); + ret->op.float_.r = value->r; + free(value); + return ret; +} + RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fbits(RZ_NONNULL RzILOpFloat *f) { rz_return_val_if_fail(f, NULL); RzILOpBitVector *ret; diff --git a/librz/include/rz_il/rz_il_opbuilder_begin.h b/librz/include/rz_il/rz_il_opbuilder_begin.h index b8fde9c1865..2d0944f984c 100644 --- a/librz/include/rz_il/rz_il_opbuilder_begin.h +++ b/librz/include/rz_il/rz_il_opbuilder_begin.h @@ -57,6 +57,7 @@ #define BV2F(fmt, bv) rz_il_op_new_float(fmt, bv) #define F32(f32) rz_il_op_new_float_from_f32(f32) #define F64(f64) rz_il_op_new_float_from_f64(f64) +#define F80(f80) rz_il_op_new_float_from_f80(f80) #define F2BV(fl) rz_il_op_new_fbits(fl) #define IS_FINITE(fl) rz_il_op_new_is_finite(fl) #define IS_FNAN(fl) rz_il_op_new_is_nan(fl) diff --git a/librz/include/rz_il/rz_il_opbuilder_end.h b/librz/include/rz_il/rz_il_opbuilder_end.h index 08da2d66591..c6fe9f62547 100644 --- a/librz/include/rz_il/rz_il_opbuilder_end.h +++ b/librz/include/rz_il/rz_il_opbuilder_end.h @@ -24,6 +24,7 @@ #undef BV2F #undef F32 #undef F64 +#undef F80 #undef F2BV #undef IS_FINITE #undef IS_FNAN diff --git a/librz/include/rz_il/rz_il_opcodes.h b/librz/include/rz_il/rz_il_opcodes.h index e52f1d49cfb..e5ec47995d4 100644 --- a/librz/include/rz_il/rz_il_opcodes.h +++ b/librz/include/rz_il/rz_il_opcodes.h @@ -736,6 +736,7 @@ RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_loadw(RzILMemIndex mem, RZ_NONNULL R RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float(RzFloatFormat format, RZ_NONNULL RzILOpBitVector *bv); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f32(float f); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f64(double f); +RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f80(long double f); RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fbits(RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_finite(RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_nan(RZ_NONNULL RzILOpFloat *f);