From 97d336738cea7d5919aa3b069a90de7b0244d739 Mon Sep 17 00:00:00 2001 From: Dhruv Maroo Date: Wed, 3 Jan 2024 18:52:58 +0530 Subject: [PATCH] Add a new helper to convert a `long double` to an 80-bit RzIL float (#4062) * Add a new helper to convert a `long double` to an 80-bit RzIL float * New function: `rz_il_op_new_float_from_f80` * New opbuilder: `F80` * Add test for `rz_il_op_new_float_from_f80` * Also add a float format check in `rz_il_sort_pure_eq` * Add a few `includes` so that some types are visible --- librz/il/il_opcodes.c | 18 ++++++++++++++++++ librz/include/rz_il/definitions/sort.h | 4 ++++ librz/include/rz_il/rz_il_opbuilder_begin.h | 1 + librz/include/rz_il/rz_il_opbuilder_end.h | 1 + librz/include/rz_il/rz_il_opcodes.h | 1 + librz/include/rz_util/rz_float.h | 1 + test/unit/test_il_validate.c | 16 ++++++++++++++++ 7 files changed, 42 insertions(+) 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/definitions/sort.h b/librz/include/rz_il/definitions/sort.h index 186d0df9a1d..61ba23e393c 100644 --- a/librz/include/rz_il/definitions/sort.h +++ b/librz/include/rz_il/definitions/sort.h @@ -5,6 +5,7 @@ #define RZ_IL_SORT_H #include +#include #ifdef __cplusplus extern "C" { @@ -45,6 +46,9 @@ static inline bool rz_il_sort_pure_eq(RzILSortPure a, RzILSortPure b) { if (a.type == RZ_IL_TYPE_PURE_BITVECTOR && a.props.bv.length != b.props.bv.length) { return false; } + if (a.type == RZ_IL_TYPE_PURE_FLOAT && a.props.f.format != b.props.f.format) { + return false; + } return true; } 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); diff --git a/librz/include/rz_util/rz_float.h b/librz/include/rz_util/rz_float.h index 0f9e9932840..e3ae1dcf916 100644 --- a/librz/include/rz_util/rz_float.h +++ b/librz/include/rz_util/rz_float.h @@ -9,6 +9,7 @@ #ifndef RZ_FLOAT_H #define RZ_FLOAT_H #include +#include /** * diff --git a/test/unit/test_il_validate.c b/test/unit/test_il_validate.c index 02ac6f44d4d..d0b455952f3 100644 --- a/test/unit/test_il_validate.c +++ b/test/unit/test_il_validate.c @@ -1344,6 +1344,21 @@ static bool test_il_validate_pure_float() { mu_end; } +static bool test_il_validate_pure_float80() { + RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24); + RzILOpPure *op = rz_il_op_new_float_from_f80(4.2L); + RzILSortPure sort; + RzILValidateReport report; + bool val = rz_il_validate_pure(op, ctx, &sort, &report); + mu_assert_true(val, "valid"); + mu_assert_true(rz_il_sort_pure_eq(sort, rz_il_sort_pure_float(RZ_FLOAT_IEEE754_BIN_80)), "sort"); + mu_assert_null(report, "no report"); + rz_il_op_pure_free(op); + + rz_il_validate_global_context_free(ctx); + mu_end; +} + static bool test_il_validate_pure_fbits() { RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24); @@ -1745,6 +1760,7 @@ bool all_tests() { mu_run_test(test_il_validate_effect_repeat); mu_run_test(test_il_validate_effect_branch); mu_run_test(test_il_validate_pure_float); + mu_run_test(test_il_validate_pure_float80); mu_run_test(test_il_validate_pure_fbits); mu_run_test(test_il_validate_pure_float_bool_uop); mu_run_test(test_il_validate_pure_float_uop);