diff --git a/librz/arch/isa/arm/arm_il32.c b/librz/arch/isa/arm/arm_il32.c index 6eb077c2927..84edbdffe35 100644 --- a/librz/arch/isa/arm/arm_il32.c +++ b/librz/arch/isa/arm/arm_il32.c @@ -3682,9 +3682,9 @@ static RzILOpEffect *try_as_int_cvt(cs_insn *insn, bool is_thumb, bool *success) // VCVT.F32.S32/U32 , RzILOpBitVector *from_val; if (is_f2i) { - from_val = is_signed ? F2SINT(bv_sz, RZ_FLOAT_RMODE_RTZ, + from_val = is_signed ? F2SINT(bv_sz, RZ_FLOAT_RMODE_RTZ, RZ_FLOAT_CAST_OOB_SATURATE, BV2F(from_fmt, REG(1))) - : F2INT(bv_sz, RZ_FLOAT_RMODE_RTZ, + : F2INT(bv_sz, RZ_FLOAT_RMODE_RTZ, RZ_FLOAT_CAST_OOB_SATURATE, BV2F(from_fmt, REG(1))); } else { from_val = is_signed ? F2BV(SINT2F(to_fmt, RZ_FLOAT_RMODE_RNE, @@ -3700,10 +3700,10 @@ static RzILOpEffect *try_as_int_cvt(cs_insn *insn, bool is_thumb, bool *success) for (int i = 0; i < REG_WIDTH(0) / bv_sz; ++i) { RzILOpBitVector *from_val; if (is_f2i) { - from_val = is_signed ? F2SINT(bv_sz, RZ_FLOAT_RMODE_RTZ, + from_val = is_signed ? F2SINT(bv_sz, RZ_FLOAT_RMODE_RTZ, RZ_FLOAT_CAST_OOB_SATURATE, BV2F(from_fmt, read_reg_lane(REGID(1), i, fl_sz))) - : F2INT(bv_sz, RZ_FLOAT_RMODE_RTZ, + : F2INT(bv_sz, RZ_FLOAT_RMODE_RTZ, RZ_FLOAT_CAST_OOB_SATURATE, BV2F(from_fmt, read_reg_lane(REGID(1), i, fl_sz))); } else { diff --git a/librz/arch/isa/hexagon/hexagon_il.h b/librz/arch/isa/hexagon/hexagon_il.h index 2345b74caa5..99f662780c9 100644 --- a/librz/arch/isa/hexagon/hexagon_il.h +++ b/librz/arch/isa/hexagon/hexagon_il.h @@ -32,10 +32,10 @@ #define HEX_FCIRC_ADD(bundle, RxV, offset, mu, CS) hex_fcircadd(bundle, RxV, offset, mu, CS) #define HEX_GET_CORRESPONDING_CS(pkt, Mu) hex_get_corresponding_cs(pkt, Mu) #define HEX_GET_INSN_RMODE(insn) (insn->fround_mode) -#define HEX_D_TO_SINT(mode, fval) F2SINT(64, mode, fval) -#define HEX_F_TO_SINT(mode, fval) F2SINT(32, mode, fval) -#define HEX_D_TO_INT(mode, fval) F2INT(64, mode, fval) -#define HEX_F_TO_INT(mode, fval) F2INT(32, mode, fval) +#define HEX_D_TO_SINT(mode, fval) F2SINT(64, mode, RZ_FLOAT_CAST_OOB_TRUNCATE, fval) +#define HEX_F_TO_SINT(mode, fval) F2SINT(32, mode, RZ_FLOAT_CAST_OOB_TRUNCATE, fval) +#define HEX_D_TO_INT(mode, fval) F2INT(64, mode, RZ_FLOAT_CAST_OOB_TRUNCATE, fval) +#define HEX_F_TO_INT(mode, fval) F2INT(32, mode, RZ_FLOAT_CAST_OOB_TRUNCATE, fval) #define HEX_SINT_TO_D(mode, fval) SINT2F(64, mode, fval) #define HEX_SINT_TO_F(mode, fval) SINT2F(32, mode, fval) #define HEX_INT_TO_D(mode, fval) INT2F(64, mode, fval) diff --git a/librz/arch/isa/sparc/sparc_il_ops.c b/librz/arch/isa/sparc/sparc_il_ops.c index 0ff602bdafb..fe691a746f2 100644 --- a/librz/arch/isa/sparc/sparc_il_ops.c +++ b/librz/arch/isa/sparc/sparc_il_ops.c @@ -673,7 +673,7 @@ static RzILOpEffect *convert_float_op(const csh handle, const cs_insn *insn, con case SPARC_INS_FDTOX: case SPARC_INS_FQTOX: case SPARC_INS_FSTOX: - return rz_sparc_bv_to_consec_regs(handle, mode, dst, F2INT(dst_width, SPARC_RMODE(), src0), dst_width); + return rz_sparc_bv_to_consec_regs(handle, mode, dst, F2INT(dst_width, SPARC_RMODE(), RZ_FLOAT_CAST_OOB_TRUNCATE, src0), dst_width); // BitVector to Float case SPARC_INS_FITOS: case SPARC_INS_FXTOS: diff --git a/librz/arch/isa/tricore/tricore_il_fp.inc b/librz/arch/isa/tricore/tricore_il_fp.inc index c23228b83d8..75407ff031b 100644 --- a/librz/arch/isa/tricore/tricore_il_fp.inc +++ b/librz/arch/isa/tricore/tricore_il_fp.inc @@ -10,7 +10,7 @@ static const ut32 HP_NEG_INFINITY = 0xfc00; /// This represents all negative numbers with an absolute value that is too big to be represented accurately as a normalized number. static const ut32 HP_POS_INFINITY = 0x7c00; -#define F2SINT32(x, m) F2SINT(32, m, x) +#define F2SINT32(x, m) F2SINT(32, m, RZ_FLOAT_CAST_OOB_TRUNCATE, x) #define denorm_to_zere_(T, x) \ LET("tmp", x, \ @@ -83,7 +83,8 @@ static inline RzILOpEffect *q_real_set_v(const char *k, RzILOpPure *x) { #define FCAST32(f, _1, x, mode) FCAST_(f, _1, x, mode, F32(0)) #define FCAST64(f, _1, x, mode) FCAST_(f, _1, x, mode, F64(0)) -#define round_to_integer(x, m) FCAST_(F2SINT, 32, x, m, U32(UT32_MAX)) +#define F2SINT_TRUNC(_1, rmode, x) F2SINT(_1, rmode, RZ_FLOAT_CAST_OOB_TRUNCATE, x) +#define round_to_integer(x, m) FCAST_(F2SINT_TRUNC, 32, x, m, U32(UT32_MAX)) static RzILOpPure *minmax(const char *k, st64 min, st64 max, RzILOpPure *x) { return ITE(IS_FNAN(VARL(k)), diff --git a/librz/arch/isa/v810/v810_il.c b/librz/arch/isa/v810/v810_il.c index d324ccc47b4..c1f7b26bb17 100644 --- a/librz/arch/isa/v810/v810_il.c +++ b/librz/arch/isa/v810/v810_il.c @@ -177,11 +177,11 @@ static RzILOpPure *bv2f32(RzILOpPure *x) { } static RzILOpPure *f32_2int(RzILOpPure *x) { - return F2SINT(32, 0, x); + return F2SINT(32, 0, RZ_FLOAT_CAST_OOB_TRUNCATE, x); } static RzILOpPure *f32_trunc2int(RzILOpPure *x) { - return F2SINT(32, 0, FROUND(0, x)); + return F2SINT(32, 0, RZ_FLOAT_CAST_OOB_TRUNCATE, FROUND(0, x)); } typedef struct { diff --git a/librz/arch/isa/x86/common.c b/librz/arch/isa/x86/common.c index 0c7b19c44bf..7ad09a4d46c 100644 --- a/librz/arch/isa/x86/common.c +++ b/librz/arch/isa/x86/common.c @@ -1165,7 +1165,7 @@ RZ_IPI ILPureEffectPair x86_il_floating_from_int_ctx(RZ_OWN RZ_NONNULL RzILOpBit } RzILOpFloat *f2sint_floating_helper(RzFloatRMode rmode, ut32 width, RzILOpFloat *val) { - return F2SINT(width, rmode, val); + return F2SINT(width, rmode, RZ_FLOAT_CAST_OOB_INDEFINITE, val); } /** diff --git a/librz/arch/isa/x86/il_sse_ops.inc b/librz/arch/isa/x86/il_sse_ops.inc index b1c72345e2b..37444722c2b 100644 --- a/librz/arch/isa/x86/il_sse_ops.inc +++ b/librz/arch/isa/x86/il_sse_ops.inc @@ -166,7 +166,7 @@ IL_LIFTER(cvtsi2ss) { do { \ RzILOpFloat *f = x86_il_get_scalar_floating_op(ins->operands[1], (fmt), analysis->bits, pc); \ ut32 width = ins->operands[0].size * BITS_PER_BYTE; \ - return x86_il_set_op(0, F2SINT(width, rmode, f)); \ + return x86_il_set_op(0, F2SINT(width, rmode, RZ_FLOAT_CAST_OOB_INDEFINITE, f)); \ } while (0) /** diff --git a/librz/arch/isa/xtensa/xtensa_il.c b/librz/arch/isa/xtensa/xtensa_il.c index 804954be1d0..20a125f097f 100644 --- a/librz/arch/isa/xtensa/xtensa_il.c +++ b/librz/arch/isa/xtensa/xtensa_il.c @@ -687,7 +687,7 @@ static RzAnalysisLiftedILOp op_callx12(XtensaContext *ctx) { static RzAnalysisLiftedILOp op_ceil_s(XtensaContext *ctx) { return SEQ3( SETL("fres", FMUL(RZ_FLOAT_RMODE_RNA, FLOATV32(IREG(1)), F32(powf(2, IMM(2))))), - SETG(REGN(0), F2INT(32, RZ_FLOAT_RMODE_RNA, VARL("fres"))), + SETG(REGN(0), F2INT(32, RZ_FLOAT_RMODE_RNA, RZ_FLOAT_CAST_OOB_TRUNCATE, VARL("fres"))), FSR_set(FSR_V | FSR_I, VARL("fres"))); } @@ -798,7 +798,7 @@ static RzAnalysisLiftedILOp op_float_s(XtensaContext *ctx) { static RzAnalysisLiftedILOp op_floor_s(XtensaContext *ctx) { return SEQ3( SETL("fres", FMUL(RZ_FLOAT_RMODE_RNA, FLOATV32(IREG(1)), F32(pow(2, IMM(2))))), - SETG(REGN(0), F2SINT(32, RZ_FLOAT_RMODE_RNA, VARL("fres"))), + SETG(REGN(0), F2SINT(32, RZ_FLOAT_RMODE_RNA, RZ_FLOAT_CAST_OOB_TRUNCATE, VARL("fres"))), FSR_set(FSR_V | FSR_I, VARL("fres"))); } @@ -1638,7 +1638,7 @@ static RzAnalysisLiftedILOp op_syscall(XtensaContext *ctx) { // statusflags: VI static RzAnalysisLiftedILOp op_trunc_s(XtensaContext *ctx) { return SEQ3(SETL("fres", FMUL(RZ_FLOAT_RMODE_RNA, FLOATV32(IREG(1)), F32(pow(2, IMM(2))))), - SETG(REGN(0), F2SINT(32, RZ_FLOAT_RMODE_RNA, VARL("fres"))), + SETG(REGN(0), F2SINT(32, RZ_FLOAT_RMODE_RNA, RZ_FLOAT_CAST_OOB_TRUNCATE, VARL("fres"))), FSR_set(FSR_V | FSR_I, VARL("fres"))); } @@ -1682,7 +1682,7 @@ static RzAnalysisLiftedILOp op_un_s(XtensaContext *ctx) { // statusflags: VI static RzAnalysisLiftedILOp op_utrunc_s(XtensaContext *ctx) { return SEQ3(SETL("fres", FMUL(RZ_FLOAT_RMODE_RNA, FLOATV32(IREG(1)), F32(pow(2, IMM(2))))), - SETG(REGN(0), F2INT(32, RZ_FLOAT_RMODE_RNA, VARL("fres"))), + SETG(REGN(0), F2INT(32, RZ_FLOAT_RMODE_RNA, RZ_FLOAT_CAST_OOB_TRUNCATE, VARL("fres"))), FSR_set(FSR_V | FSR_I, VARL("fres"))); } diff --git a/librz/il/il_export_json.c b/librz/il/il_export_json.c index 7fe0f9ee545..5fcd5d111b4 100644 --- a/librz/il/il_export_json.c +++ b/librz/il/il_export_json.c @@ -354,6 +354,7 @@ static void il_opdmp_fcast_int(RzILOpPure *op, PJ *pj) { pj_o(pj); pj_ks(pj, "opcode", "fcast_int"); pj_kn(pj, "length", opx->length); + pj_kn(pj, "oob_behavior", opx->oob_behavior); pj_k(pj, "rmode"); il_op_float_rmode_json_resolve(&opx->rmode, pj); pj_k(pj, "value"); @@ -366,6 +367,7 @@ static void il_opdmp_fcast_sint(RzILOpPure *op, PJ *pj) { pj_o(pj); pj_ks(pj, "opcode", "fcast_sint"); pj_kn(pj, "length", opx->length); + pj_kn(pj, "oob_behavior", opx->oob_behavior); pj_k(pj, "rmode"); il_op_float_rmode_json_resolve(&opx->rmode, pj); pj_k(pj, "value"); diff --git a/librz/il/il_export_string.c b/librz/il/il_export_string.c index db4edaf0d9e..b22541faf8b 100644 --- a/librz/il/il_export_string.c +++ b/librz/il/il_export_string.c @@ -436,19 +436,19 @@ static void il_opdmp_fabs(RzILOpPure *op, RzStrBuf *sb, int pad) { static void il_opdmp_fcast_int(RzILOpPure *op, RzStrBuf *sb, int pad) { RzILOpArgsFCastint *opx = &op->op.fcast_int; if (pad < 0) { - rz_strbuf_appendf(sb, "(fcast_int %u ", opx->length); + rz_strbuf_appendf(sb, "(fcast_int %u %d ", opx->length, opx->oob_behavior); il_op_float_rmode_string_resolve(&opx->rmode, sb, pad); rz_strbuf_append(sb, " "); il_op_pure_string_resolve(opx->f, sb, pad); rz_strbuf_append(sb, ")"); } else if (opx->rmode.kind == RZ_IL_OP_ARG_FLOAT_RMODE_STATIC) { - rz_strbuf_appendf(sb, "%*.s(fcast_int %u ", pad, "", opx->length); + rz_strbuf_appendf(sb, "%*.s(fcast_int %u %d ", pad, "", opx->length, opx->oob_behavior); il_op_float_rmode_string_resolve(&opx->rmode, sb, pad); rz_strbuf_append(sb, "\n"); il_op_pure_string_resolve(opx->f, sb, pad + PRETTY_PAD); rz_strbuf_append(sb, ")"); } else { - rz_strbuf_appendf(sb, "%*.s(fcast_int %u\n", pad, "", opx->length); + rz_strbuf_appendf(sb, "%*.s(fcast_int %u %d\n", pad, "", opx->length, opx->oob_behavior); il_op_float_rmode_string_resolve(&opx->rmode, sb, pad + PRETTY_PAD); rz_strbuf_append(sb, "\n"); il_op_pure_string_resolve(opx->f, sb, pad + PRETTY_PAD); @@ -459,19 +459,19 @@ static void il_opdmp_fcast_int(RzILOpPure *op, RzStrBuf *sb, int pad) { static void il_opdmp_fcast_sint(RzILOpPure *op, RzStrBuf *sb, int pad) { RzILOpArgsFCastsint *opx = &op->op.fcast_sint; if (pad < 0) { - rz_strbuf_appendf(sb, "(fcast_sint %u ", opx->length); + rz_strbuf_appendf(sb, "(fcast_sint %u %d ", opx->length, opx->oob_behavior); il_op_float_rmode_string_resolve(&opx->rmode, sb, pad); rz_strbuf_append(sb, " "); il_op_pure_string_resolve(opx->f, sb, pad); rz_strbuf_append(sb, ")"); } else if (opx->rmode.kind == RZ_IL_OP_ARG_FLOAT_RMODE_STATIC) { - rz_strbuf_appendf(sb, "%*.s(fcast_sint %u ", pad, "", opx->length); + rz_strbuf_appendf(sb, "%*.s(fcast_sint %u %d ", pad, "", opx->length, opx->oob_behavior); il_op_float_rmode_string_resolve(&opx->rmode, sb, pad); rz_strbuf_append(sb, "\n"); il_op_pure_string_resolve(opx->f, sb, pad + PRETTY_PAD); rz_strbuf_append(sb, ")"); } else { - rz_strbuf_appendf(sb, "%*.s(fcast_sint %u\n", pad, "", opx->length); + rz_strbuf_appendf(sb, "%*.s(fcast_sint %u %d\n", pad, "", opx->length, opx->oob_behavior); il_op_float_rmode_string_resolve(&opx->rmode, sb, pad + PRETTY_PAD); rz_strbuf_append(sb, "\n"); il_op_pure_string_resolve(opx->f, sb, pad + PRETTY_PAD); diff --git a/librz/il/il_graph.c b/librz/il/il_graph.c index e143d034571..8ba9cb1ecc7 100644 --- a/librz/il/il_graph.c +++ b/librz/il/il_graph.c @@ -308,7 +308,7 @@ static void il_op_graph_fabs(RzILOpPure *op, RzGraph /**/ *g, RzGraphNode *from) { RzILOpArgsFCastint *opx = &op->op.fcast_int; - char *value = rz_str_newf("fcast_int: %u", opx->length); + char *value = rz_str_newf("fcast_int: %u %d", opx->length, opx->oob_behavior); if (!value) { return; } @@ -321,7 +321,7 @@ static void il_op_graph_fcast_int(RzILOpPure *op, RzGraph /**/ *g, RzGraphNode *from) { RzILOpArgsFCastsint *opx = &op->op.fcast_sint; - char *value = rz_str_newf("fcast_sint: %u", opx->length); + char *value = rz_str_newf("fcast_sint: %u %d", opx->length, opx->oob_behavior); if (!value) { return; } diff --git a/librz/il/il_opcodes.c b/librz/il/il_opcodes.c index f5cf15f0876..a23cf1d7d15 100644 --- a/librz/il/il_opcodes.c +++ b/librz/il/il_opcodes.c @@ -45,6 +45,19 @@ ret->op.s.v2 = v2; \ } while (0) +#define rz_il_op_new_4(sort, id, t, s, v0, v1, v2, v3) \ + do { \ + ret = RZ_NEW0(RzILOp##sort); \ + if (!ret) { \ + return NULL; \ + } \ + ret->code = id; \ + ret->op.s.v0 = v0; \ + ret->op.s.v1 = v1; \ + ret->op.s.v2 = v2; \ + ret->op.s.v3 = v3; \ + } while (0) + static RzILOpArgFloatRMode float_rmode_static(RzFloatRMode mode) { return (RzILOpArgFloatRMode){ .kind = RZ_IL_OP_ARG_FLOAT_RMODE_STATIC, @@ -879,19 +892,19 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fabs(RZ_NONNULL RzILOpFloat *f) { return ret; } -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int(ut32 length, RzFloatRMode mode, RZ_NONNULL RzILOpFloat *f) { +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int(ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f) { rz_return_val_if_fail(f, NULL); RzILOpArgFloatRMode rmode = float_rmode_static(mode); RzILOpBitVector *ret; - rz_il_op_new_3(BitVector, RZ_IL_OP_FCAST_INT, RzILOpArgsFCastint, fcast_int, length, rmode, f); + rz_il_op_new_4(BitVector, RZ_IL_OP_FCAST_INT, RzILOpArgsFCastint, fcast_int, length, rmode, oob_behavior, f); return ret; } -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint(ut32 length, RzFloatRMode mode, RZ_NONNULL RzILOpFloat *f) { +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint(ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f) { rz_return_val_if_fail(f, NULL); RzILOpArgFloatRMode rmode = float_rmode_static(mode); RzILOpBitVector *ret; - rz_il_op_new_3(BitVector, RZ_IL_OP_FCAST_SINT, RzILOpArgsFCastsint, fcast_sint, length, rmode, f); + rz_il_op_new_4(BitVector, RZ_IL_OP_FCAST_SINT, RzILOpArgsFCastsint, fcast_sint, length, rmode, oob_behavior, f); return ret; } @@ -911,19 +924,19 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcast_sfloat(RzFloatFormat format, RzFlo return ret; } -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *mode, RZ_NONNULL RzILOpFloat *f) { +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *mode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f) { rz_return_val_if_fail(mode && f, NULL); RzILOpArgFloatRMode rmode = float_rmode_dynamic(mode); RzILOpBitVector *ret; - rz_il_op_new_3(BitVector, RZ_IL_OP_FCAST_INT, RzILOpArgsFCastint, fcast_int, length, rmode, f); + rz_il_op_new_4(BitVector, RZ_IL_OP_FCAST_INT, RzILOpArgsFCastint, fcast_int, length, rmode, oob_behavior, f); return ret; } -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *mode, RZ_NONNULL RzILOpFloat *f) { +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *mode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f) { rz_return_val_if_fail(mode && f, NULL); RzILOpArgFloatRMode rmode = float_rmode_dynamic(mode); RzILOpBitVector *ret; - rz_il_op_new_3(BitVector, RZ_IL_OP_FCAST_SINT, RzILOpArgsFCastsint, fcast_sint, length, rmode, f); + rz_il_op_new_4(BitVector, RZ_IL_OP_FCAST_SINT, RzILOpArgsFCastsint, fcast_sint, length, rmode, oob_behavior, f); return ret; } diff --git a/librz/il/theory_fbasic.c b/librz/il/theory_fbasic.c index 85c085c6063..8ab1f8c8e89 100644 --- a/librz/il/theory_fbasic.c +++ b/librz/il/theory_fbasic.c @@ -176,7 +176,7 @@ void *rz_il_handler_fcast_int(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) { return NULL; } ut32 length = cast_int.length; - RzBitVector *ret = rz_float_cast_int(f, length, mode); + RzBitVector *ret = rz_float_cast_int(f, length, mode, cast_int.oob_behavior); rz_float_free(f); @@ -197,7 +197,7 @@ void *rz_il_handler_fcast_sint(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) { return NULL; } ut32 length = cast_sint.length; - RzBitVector *ret = rz_float_cast_sint(f, length, mode); + RzBitVector *ret = rz_float_cast_sint(f, length, mode, cast_sint.oob_behavior); rz_float_free(f); diff --git a/librz/include/rz_il/rz_il_opbuilder_begin.h b/librz/include/rz_il/rz_il_opbuilder_begin.h index b58640f6264..e38bf9fe500 100644 --- a/librz/include/rz_il/rz_il_opbuilder_begin.h +++ b/librz/include/rz_il/rz_il_opbuilder_begin.h @@ -67,12 +67,12 @@ #define IS_FPOS(fl) rz_il_op_new_is_fpos(fl) #define FNEG(fl) rz_il_op_new_fneg(fl) #define FABS(fl) rz_il_op_new_fabs(fl) -#define F2INT(l, rmode, fl) rz_il_op_new_fcast_int(l, rmode, fl) -#define F2SINT(l, rmode, fl) rz_il_op_new_fcast_sint(l, rmode, fl) +#define F2INT(l, rmode, oob, fl) rz_il_op_new_fcast_int(l, rmode, oob, fl) +#define F2SINT(l, rmode, oob, fl) rz_il_op_new_fcast_sint(l, rmode, oob, fl) #define INT2F(fmt, rmode, bv) rz_il_op_new_fcast_float(fmt, rmode, bv) #define SINT2F(fmt, rmode, bv) rz_il_op_new_fcast_sfloat(fmt, rmode, bv) -#define F2INT_DYN_RMODE(l, rmode, fl) rz_il_op_new_fcast_int_dyn_rmode(l, rmode, fl) -#define F2SINT_DYN_RMODE(l, rmode, fl) rz_il_op_new_fcast_sint_dyn_rmode(l, rmode, fl) +#define F2INT_DYN_RMODE(l, rmode, oob, fl) rz_il_op_new_fcast_int_dyn_rmode(l, rmode, oob, fl) +#define F2SINT_DYN_RMODE(l, rmode, oob, fl) rz_il_op_new_fcast_sint_dyn_rmode(l, rmode, oob, fl) #define INT2F_DYN_RMODE(fmt, rmode, bv) rz_il_op_new_fcast_float_dyn_rmode(fmt, rmode, bv) #define SINT2F_DYN_RMODE(fmt, rmode, bv) rz_il_op_new_fcast_sfloat_dyn_rmode(fmt, rmode, bv) #define FCONVERT(fmt, rmode, fl) rz_il_op_new_fconvert(fmt, rmode, fl) diff --git a/librz/include/rz_il/rz_il_opcodes.h b/librz/include/rz_il/rz_il_opcodes.h index 6848c835e4a..7213e59e569 100644 --- a/librz/include/rz_il/rz_il_opcodes.h +++ b/librz/include/rz_il/rz_il_opcodes.h @@ -399,6 +399,7 @@ typedef struct rz_il_op_arg_float_rmode_t { typedef struct rz_il_op_args_float_cast_int_t { ut32 length; RzILOpArgFloatRMode rmode; + RzFloatCastOobBehavior oob_behavior; RzILOpFloat *f; } RzILOpArgsFCastInt; @@ -818,12 +819,12 @@ RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_fneg(RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_fpos(RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fneg(RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fabs(RZ_NONNULL RzILOpFloat *f); -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int(ut32 length, RzFloatRMode mode, RZ_NONNULL RzILOpFloat *f); -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint(ut32 length, RzFloatRMode mode, RZ_NONNULL RzILOpFloat *f); +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int(ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f); +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint(ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcast_float(RzFloatFormat format, RzFloatRMode mode, RZ_NONNULL RzILOpBitVector *bv); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcast_sfloat(RzFloatFormat format, RzFloatRMode mode, RZ_NONNULL RzILOpBitVector *bv); -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *rmode, RZ_NONNULL RzILOpFloat *f); -RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *rmode, RZ_NONNULL RzILOpFloat *f); +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_int_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *rmode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f); +RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fcast_sint_dyn_rmode(ut32 length, RZ_NONNULL RzILOpBitVector *rmode, RzFloatCastOobBehavior oob_behavior, RZ_NONNULL RzILOpFloat *f); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcast_float_dyn_rmode(RzFloatFormat format, RZ_NONNULL RzILOpBitVector *rmode, RZ_NONNULL RzILOpBitVector *bv); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcast_sfloat_dyn_rmode(RzFloatFormat format, RZ_NONNULL RzILOpBitVector *rmode, RZ_NONNULL RzILOpBitVector *bv); RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fconvert(RzFloatFormat format, RzFloatRMode mode, RZ_NONNULL RzILOpFloat *f); diff --git a/librz/include/rz_util/rz_float.h b/librz/include/rz_util/rz_float.h index b8027e8cf20..cfc4aa80510 100644 --- a/librz/include/rz_util/rz_float.h +++ b/librz/include/rz_util/rz_float.h @@ -72,6 +72,12 @@ typedef enum rz_float_round_enum { RZ_FLOAT_RMODE_UNK ///< end } RzFloatRMode; ///< Rounding Mode +typedef enum rz_float_cast_oob_behavior_enum { + RZ_FLOAT_CAST_OOB_TRUNCATE, ///< Truncate out of bounds value + RZ_FLOAT_CAST_OOB_SATURATE, ///< Saturate to integer min/max + RZ_FLOAT_CAST_OOB_INDEFINITE, ///< Return the indefinite value (e.g., 0x80..00) +} RzFloatCastOobBehavior; + /** Precision used by SoftFloat binary80 arithmetic. */ typedef enum rz_float_rprecision_enum { RZ_FLOAT_RPREC_32 = 32, ///< 24-bit significand precision @@ -210,8 +216,8 @@ RZ_API RZ_OWN RzFloat *rz_float_new_snan(RzFloatFormat format); RZ_API RZ_OWN RzFloat *rz_float_cast_float(RZ_NONNULL RzBitVector *bv, RzFloatFormat format, RzFloatRMode mode); RZ_API RZ_OWN RzFloat *rz_float_cast_sfloat(RZ_NONNULL RzBitVector *bv, RzFloatFormat format, RzFloatRMode mode); -RZ_API RZ_OWN RzBitVector *rz_float_cast_int(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode); -RZ_API RZ_OWN RzBitVector *rz_float_cast_sint(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode); +RZ_API RZ_OWN RzBitVector *rz_float_cast_int(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior); +RZ_API RZ_OWN RzBitVector *rz_float_cast_sint(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior); RZ_API RZ_OWN RzFloat *rz_float_convert(RZ_NONNULL RzFloat *f, RzFloatFormat format, RzFloatRMode mode); RZ_API RzFloatRPrecision rz_float_ext80_get_rounding_precision(void); RZ_API bool rz_float_ext80_set_rounding_precision(RzFloatRPrecision precision); diff --git a/librz/util/float/float.c b/librz/util/float/float.c index dc54d7d53ee..d9a02bbd5c8 100644 --- a/librz/util/float/float.c +++ b/librz/util/float/float.c @@ -1779,9 +1779,9 @@ RZ_API RZ_OWN RzFloat *rz_float_cast_sfloat(RZ_NONNULL RzBitVector *bv, RzFloatF * \param mode rounding mode * \return unsigned bitvector converted from f */ -RZ_API RZ_OWN RzBitVector *rz_float_cast_int(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode) { +RZ_API RZ_OWN RzBitVector *rz_float_cast_int(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior) { rz_return_val_if_fail(f, NULL); - return rz_float_cast_sint(f, length, mode); + return rz_float_cast_sint(f, length, mode, oob_behavior); } /** @@ -1792,11 +1792,11 @@ RZ_API RZ_OWN RzBitVector *rz_float_cast_int(RZ_NONNULL RzFloat *f, ut32 length, * \param mode rounding mode * \return signed bitvector in 2's complement */ -RZ_API RZ_OWN RzBitVector *rz_float_cast_sint(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode) { +RZ_API RZ_OWN RzBitVector *rz_float_cast_sint(RZ_NONNULL RzFloat *f, ut32 length, RzFloatRMode mode, RzFloatCastOobBehavior oob_behavior) { rz_return_val_if_fail(f, NULL); RzBitVector *ret = rz_bv_new(length); - RzBitVector *tmp, *rounded; + RzBitVector *tmp = NULL, *rounded = NULL; ut32 exp = float_exponent(f); RzFloatFormat format = f->r; bool sign = get_sign(f->s, format); @@ -1806,14 +1806,31 @@ RZ_API RZ_OWN RzBitVector *rz_float_cast_sint(RZ_NONNULL RzFloat *f, ut32 length ut32 total_len = rz_float_get_format_info(format, RZ_FLOAT_INFO_TOTAL_LEN); ut32 man_len = rz_float_get_format_info(format, RZ_FLOAT_INFO_MAN_LEN); + bool is_nan = rz_float_is_nan(f); + bool is_inf = rz_float_is_inf(f); + + bool is_oob = false; + bool should_inc = false; + bool inexact = false; + RzBitVector *sig = NULL; + bool is_zero = false; + + if (is_nan || is_inf) { + is_oob = true; + } else if (exp_no_bias > (st32)(length - 1)) { + is_oob = true; + } + + if (is_oob && oob_behavior != RZ_FLOAT_CAST_OOB_TRUNCATE) { + goto handle_oob; + } + // rounding float to get an integer means // we should try to reserve `exponent` bits of mantissa // drop extra bits or append zeros // 1.MM..M * 2^exp = 1MM..M * 2^0 (integer) - bool should_inc = false; - bool inexact = false; - RzBitVector *sig = rz_float_get_mantissa(f); - bool is_zero = rz_bv_is_zero_vector(sig) && exp == 0; + sig = rz_float_get_mantissa(f); + is_zero = rz_bv_is_zero_vector(sig) && exp == 0; // binary80 stores the integer bit explicitly in the mantissa; all other // normal formats use a hidden bit that must be injected here @@ -1860,6 +1877,46 @@ RZ_API RZ_OWN RzBitVector *rz_float_cast_sint(RZ_NONNULL RzFloat *f, ut32 length rz_bv_free(tmp); tmp = NULL; + if (!is_oob && rz_bv_len(rounded) >= length) { + ut32 r_len = rz_bv_len(rounded); + for (ut32 i = length; i < r_len; i++) { + if (rz_bv_get(rounded, i)) { + is_oob = true; + break; + } + } + if (!is_oob && rz_bv_get(rounded, length - 1)) { + bool lower_zeros = true; + for (ut32 i = 0; i < length - 1; i++) { + if (rz_bv_get(rounded, i)) { + lower_zeros = false; + break; + } + } + if (!sign || !lower_zeros) { + is_oob = true; + } + } + } + +handle_oob: + if (is_oob && oob_behavior != RZ_FLOAT_CAST_OOB_TRUNCATE) { + rz_bv_set_all(ret, false); + if (oob_behavior == RZ_FLOAT_CAST_OOB_INDEFINITE) { + rz_bv_set(ret, length - 1, true); + } else if (oob_behavior == RZ_FLOAT_CAST_OOB_SATURATE) { + if (is_nan) { + // NaN saturates to 0 for most architectures (like ARM) + } else if (sign) { + rz_bv_set(ret, length - 1, true); // min int + } else { + rz_bv_set_range(ret, 0, length - 2, true); // max int + } + } + if (rounded) { rz_bv_free(rounded); } + return ret; + } + // assume we r handling absolute value // now for negative, convert it to 2's complement if (sign && !is_zero) { diff --git a/test/unit/test_float.c b/test/unit/test_float.c index 5e95c695194..fea77bed254 100644 --- a/test/unit/test_float.c +++ b/test/unit/test_float.c @@ -1634,7 +1634,7 @@ bool f32_ieee_cast_test(void) { // test cast_sint only, since cast_int is a wrapper of cast_sint fval = rz_float_new_from_f32(1.0f); expect_bv = rz_bv_new_one(32); - cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint 1.0f)"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1643,7 +1643,7 @@ bool f32_ieee_cast_test(void) { // 2-2. normal fval = rz_float_new_from_f32(12345678.0f); expect_bv = rz_bv_new_from_ut64(32, 12345678); - cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint 12345678.0f)"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1651,7 +1651,7 @@ bool f32_ieee_cast_test(void) { fval = rz_float_new_from_f32(1.125f); expect_bv = rz_bv_new_from_ut64(32, 2); - cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RTP); + cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RTP, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "sticky bit rounds 1.125f toward positive infinity"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1660,7 +1660,7 @@ bool f32_ieee_cast_test(void) { // 2-3. huge fval = rz_float_new_from_f32(1.2345679E8f); expect_bv = rz_bv_new_from_ut64(32, 123456792); - cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint 1.2345679E8)"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1669,7 +1669,7 @@ bool f32_ieee_cast_test(void) { // 2-4. negative fval = rz_float_new_from_f32(-1.0f); expect_bv = rz_bv_new_from_ut64(32, 0xFFFFFFFF); - cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint -1.0f)"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1678,7 +1678,7 @@ bool f32_ieee_cast_test(void) { // 2-5 normal negative fval = rz_float_new_from_f32(-1234.0f); expect_bv = rz_bv_new_from_ut64(64, 0xFFFFFFFFFFFFFB2E); - cast_bv = rz_float_cast_sint(fval, 64, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 64, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint -1234.0f)"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1687,7 +1687,7 @@ bool f32_ieee_cast_test(void) { // 2-6 pure small number fval = rz_float_new_from_f32(0.119823f); expect_bv = rz_bv_new_zero(16); - cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint 0.119823f), rne"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1695,7 +1695,7 @@ bool f32_ieee_cast_test(void) { fval = rz_float_new_from_f32(0.119823f); expect_bv = rz_bv_new_one(16); - cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RTP); + cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RTP, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint 0.119823f), rtp"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1705,7 +1705,7 @@ bool f32_ieee_cast_test(void) { fval = rz_float_new_from_f32(-0.119823f); expect_bv = rz_bv_new_zero(16); rz_bv_toggle_all(expect_bv); - cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RTN); + cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RTN, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint -0.119823f)"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1714,7 +1714,7 @@ bool f32_ieee_cast_test(void) { // Cast (negative) zero fval = rz_float_new_zero(RZ_FLOAT_IEEE754_BIN_32, true); expect_bv = rz_bv_new_zero(16); - cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint -0.0f), rne"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1723,7 +1723,7 @@ bool f32_ieee_cast_test(void) { // Cast zero fval = rz_float_new_zero(RZ_FLOAT_IEEE754_BIN_32, false); expect_bv = rz_bv_new_zero(16); - cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(fval, 16, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expect_bv, cast_bv), "test (cast-sint -0.0f), rne"); rz_float_free(fval); rz_bv_free(cast_bv); @@ -1982,7 +1982,7 @@ bool f80_ieee_cast_sint_test(void) { // explicitly, unlike other IEEE-754 formats where it is implicit for normals RzFloat *f80_val = new_f80_from_bytes("\x40\x00\xc0\x00\x00\x00\x00\x00\x00\x00"); RzBitVector *expected_bv = rz_bv_new_from_ut64(32, 3); - RzBitVector *cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE); + RzBitVector *cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expected_bv, cast_bv), "cast-sint preserves 3.0 in ieee754-bin80"); @@ -1996,7 +1996,7 @@ bool f80_ieee_cast_sint_test(void) { bool f80_ieee_cast_sint_large_test(void) { RzFloat *f80_val = new_f80_from_bytes("\x40\x1b\x80\x00\x00\x00\x00\x00\x00\x00"); RzBitVector *expected_bv = rz_bv_new_from_ut64(32, 1ULL << 28); - RzBitVector *cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE); + RzBitVector *cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expected_bv, cast_bv), "cast-sint preserves 2^28 in ieee754-bin80"); rz_float_free(f80_val); rz_bv_free(expected_bv); @@ -2004,7 +2004,7 @@ bool f80_ieee_cast_sint_large_test(void) { f80_val = new_f80_from_bytes("\x40\x1c\x80\x00\x00\x00\x00\x00\x00\x00"); expected_bv = rz_bv_new_from_ut64(32, 1ULL << 29); - cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expected_bv, cast_bv), "cast-sint preserves 2^29 in ieee754-bin80"); rz_float_free(f80_val); rz_bv_free(expected_bv); @@ -2012,7 +2012,7 @@ bool f80_ieee_cast_sint_large_test(void) { f80_val = new_f80_from_bytes("\x40\x1d\x80\x00\x00\x00\x00\x00\x00\x00"); expected_bv = rz_bv_new_from_ut64(32, 1ULL << 30); - cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expected_bv, cast_bv), "cast-sint preserves 2^30 in ieee754-bin80"); rz_float_free(f80_val); rz_bv_free(expected_bv); @@ -2020,7 +2020,7 @@ bool f80_ieee_cast_sint_large_test(void) { f80_val = new_f80_from_bytes("\x40\x1e\x80\x00\x00\x00\x00\x00\x00\x00"); expected_bv = rz_bv_new_from_ut64(32, 1ULL << 31); - cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE); + cast_bv = rz_float_cast_sint(f80_val, 32, RZ_FLOAT_RMODE_RNE, RZ_FLOAT_CAST_OOB_TRUNCATE); mu_assert_true(rz_bv_eq(expected_bv, cast_bv), "cast-sint preserves 2^31 in ieee754-bin80"); rz_float_free(f80_val); rz_bv_free(expected_bv); diff --git a/test/unit/test_il_validate.c b/test/unit/test_il_validate.c index fcb476ec608..ed5ac0ffdee 100644 --- a/test/unit/test_il_validate.c +++ b/test/unit/test_il_validate.c @@ -1645,6 +1645,7 @@ static bool test_il_validate_pure_fcast_to_int() { RzILOpPure *op = rz_il_op_new_fcast_int( 64, RZ_FLOAT_RMODE_RNE, + RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f64(12.345)); RzILSortPure sort; RzILValidateReport report = NULL; @@ -1657,6 +1658,7 @@ static bool test_il_validate_pure_fcast_to_int() { op = rz_il_op_new_fcast_int( 64, RZ_FLOAT_RMODE_RNE, + RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_bitv_from_ut64(64, 11)); val = rz_il_validate_pure(op, ctx, &sort, &report); mu_assert_false(val, "invalid"); @@ -1666,6 +1668,7 @@ static bool test_il_validate_pure_fcast_to_int() { op = rz_il_op_new_fcast_int( 0, RZ_FLOAT_RMODE_RNE, + RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f64(11.11)); val = rz_il_validate_pure(op, ctx, &sort, &report); mu_assert_false(val, "invalid"); @@ -1782,7 +1785,7 @@ static bool test_il_validate_float_rmode_argument() { } while (0) CHECK_INVALID_STATIC_RMODE( - rz_il_op_new_fcast_int(32, RZ_FLOAT_RMODE_UNK, rz_il_op_new_float_from_f32(1.0f)), + rz_il_op_new_fcast_int(32, RZ_FLOAT_RMODE_UNK, RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f32(1.0f)), "fcast_int"); CHECK_INVALID_STATIC_RMODE( rz_il_op_new_fcast_float(RZ_FLOAT_IEEE754_BIN_32, RZ_FLOAT_RMODE_UNK, rz_il_op_new_bitv_from_ut64(32, 1)), diff --git a/test/unit/test_il_vm.c b/test/unit/test_il_vm.c index c0bcc981b89..2f13d01243d 100644 --- a/test/unit/test_il_vm.c +++ b/test/unit/test_il_vm.c @@ -1036,6 +1036,7 @@ static bool test_rzil_vm_op_fcast() { RzILOpBitVector *op2 = rz_il_op_new_fcast_int( 64, RZ_FLOAT_RMODE_RNE, + RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_fcast_float( RZ_FLOAT_IEEE754_BIN_64, RZ_FLOAT_RMODE_RNE, @@ -1348,10 +1349,10 @@ static bool test_rzil_vm_all_float_rmode_payloads() { } while (0) CHECK_DYNAMIC_RMODE_OP( - rz_il_op_new_fcast_int_dyn_rmode(32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RNE), rz_il_op_new_float_from_f32(1.0f)), + rz_il_op_new_fcast_int_dyn_rmode(32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RNE), RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f32(1.0f)), RZ_IL_OP_FCAST_INT, fcast_int); CHECK_DYNAMIC_RMODE_OP( - rz_il_op_new_fcast_sint_dyn_rmode(32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RNE), rz_il_op_new_float_from_f32(-1.0f)), + rz_il_op_new_fcast_sint_dyn_rmode(32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RNE), RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f32(-1.0f)), RZ_IL_OP_FCAST_SINT, fcast_sint); CHECK_DYNAMIC_RMODE_OP( rz_il_op_new_fcast_float_dyn_rmode(RZ_FLOAT_IEEE754_BIN_32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RNE), rz_il_op_new_bitv_from_ut64(32, 1)), @@ -1481,6 +1482,7 @@ static bool test_rzil_vm_runtime_rmode_helpers() { RzILOpBitVector *cast_int_op = rz_il_op_new_fcast_int_dyn_rmode( 32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RTP), + RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f32(1.125f)); RzBitVector *cast_int = rz_il_evaluate_bitv(vm, cast_int_op); mu_assert_notnull(cast_int, "runtime unsigned float-to-integer cast"); @@ -1491,6 +1493,7 @@ static bool test_rzil_vm_runtime_rmode_helpers() { RzILOpBitVector *cast_sint_op = rz_il_op_new_fcast_sint_dyn_rmode( 32, rz_il_op_new_bitv_from_ut64(32, RZ_FLOAT_RMODE_RTN), + RZ_FLOAT_CAST_OOB_TRUNCATE, rz_il_op_new_float_from_f32(-0.125f)); RzBitVector *cast_sint = rz_il_evaluate_bitv(vm, cast_sint_op); mu_assert_notnull(cast_sint, "runtime signed float-to-integer cast");