tricore: lift remaining floating point instructions (#4514)
* tricore: fix `mfcr` and `mtcr` * tricore: `ftoi` * tricore: fix `round_to_integer` * tricore: tricore_il_fp.inc * tricore: fix `ftoi` `ftoiz` * rzil: Add `rz_il_op_new_float_from_rz_float` * tricore: add `ftoq31` * tricore: add `ftou` * tricore: fix `hptof` and `ftohp` * tricore: set flags and `itof` `q31tof` `utof` * tricore: add.f sub.f mul.f div.f * tricore: qseed.f * tricore: madd.f msub.f * tricore: add rzil asm tests * rzil: validate il op when `aoi` * tricore : add fp emulateme test
This commit is contained in:
parent
d1a7dbad5d
commit
255f6fdd0f
15 changed files with 2941 additions and 1021 deletions
|
|
@ -184,6 +184,11 @@ static const char *TriCoreREGs[] = {
|
|||
"FPU_TRAP_SRC1",
|
||||
"FPU_TRAP_SRC2",
|
||||
"FPU_TRAP_SRC3",
|
||||
"set_FI",
|
||||
"set_FV",
|
||||
"set_FZ",
|
||||
"set_FU",
|
||||
"set_FX",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -403,7 +408,7 @@ static const char *CR_Table(unsigned addr_offset) {
|
|||
case 0xA010: return "FPU_TRAP_SRC1";
|
||||
case 0xA014: return "FPU_TRAP_SRC2";
|
||||
case 0xA018: return "FPU_TRAP_SRC3";
|
||||
default: return NULL;
|
||||
default: break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -807,91 +812,6 @@ static RzILOpPure *sign_32bit(RzILOpPure *val) {
|
|||
return MSB(val);
|
||||
}
|
||||
|
||||
// static const ut32 ADD_NAN __attribute__((unused)) = 0x7fc00001;
|
||||
// static const ut32 DIV_NAN __attribute__((unused)) = 0x7fc00008;
|
||||
// static const ut32 MUL_NAN __attribute__((unused)) = 0x7fc00002;
|
||||
// static const ut32 SQRT_NAN __attribute__((unused)) = 0x7fc00004;
|
||||
//
|
||||
// static const ut32 HP_MAX_VALUE __attribute__((unused)) = 65504;
|
||||
// static const ut32 HP_MIN_NORMAL __attribute__((unused)) = 1024 * 16;
|
||||
|
||||
static const ut32 HP_NEG_INFINITY = 0xfc00;
|
||||
static const ut32 HP_POS_INFINITY = 0x7c00;
|
||||
|
||||
// static const ut32 NEG_INFINITY __attribute__((unused)) = 0xff800000;
|
||||
// static const ut32 POS_INFINITY __attribute__((unused)) = 0x7f800000;
|
||||
|
||||
static inline RzILOpPure *denorm_to_zero(RzILOpFloat *x) {
|
||||
return LET("tmp", x,
|
||||
ITE(AND(FLT(VARLP("tmp"), F32(0.0)), FGT(VARLP("tmp"), F32(powf(-2, -126)))), FNEG(F32(0)),
|
||||
ITE(AND(FGT(VARLP("tmp"), F32(0)), FLT(VARLP("tmp"), F32(powf(2, -126)))), F32(0),
|
||||
VARLP("tmp"))));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert single precision to a half precision
|
||||
*
|
||||
* Convert the contents of data register D[a] from IEEE-754-2008 32-bit single precision floating point to IEEE-754-2008
|
||||
* 16-bit half precision (data interchange) floating point format. The rounded result is put in data register D[c][15:0].
|
||||
* D[c][31:16] is set to zero.
|
||||
*/
|
||||
static RzAnalysisLiftedILOp ftohp(RzAsmTriCoreContext *ctx) {
|
||||
const char *a = R(1);
|
||||
const char *c = R(0);
|
||||
|
||||
// if(sign_32bit(D[a])) then {
|
||||
// D[c][15:0] = HP_NEG_INFINITY;
|
||||
// } else {
|
||||
// D[c][15:0] = HP_POS_INFINITY;
|
||||
// }
|
||||
RzILOpEffect *inf_eff = BRANCH(sign_32bit(VARG(a)),
|
||||
SETG(c, U32(HP_NEG_INFINITY)),
|
||||
SETG(c, U32(HP_POS_INFINITY)));
|
||||
|
||||
// D[c][15] = sign_32bit(D[a]);
|
||||
// D[c][14:10] = 1FH;
|
||||
// D[c][9:8] = D[a][22:21];
|
||||
// D[c][7:0] = D[a][7:0];
|
||||
// Ensure NaN value is preserved
|
||||
// if ((D[c][9:0] == 0)) then {
|
||||
// D[c][8] = 1B;
|
||||
// }
|
||||
RzILOpPure *dc = LOGAND(VARG(a), U32(1U << 31));
|
||||
dc = LOGOR(dc, SHL0(U32(0x1f), 10));
|
||||
dc = LOGOR(dc, SHL0(BITS32(VARG(a), 21, 2), 8));
|
||||
dc = LOGOR(dc, BITS32(VARG(a), 0, 8));
|
||||
RzILOpEffect *nan_eff = SEQ2(SETL("D_c", dc),
|
||||
SETG(c, ITE(EQ(BITS32(VARL("D_c"), 0, 10), U32(0)), BITS32_U(VARL("D_c"), 8, 1, U32(1)), VARL("D_c"))));
|
||||
|
||||
// f = denorm_to_zero(D[a]);
|
||||
// f_rounded = ieee754_round_16bit(f, PSW.RM);
|
||||
// Handle overflow & underflow and convert to 16-bit format
|
||||
// D[a][15:0] = ieee754_16bit_format(f_rounded);
|
||||
RzILOpPure *f = denorm_to_zero(FLOATV32(VARG(a)));
|
||||
// RzILOpPure *f_rounded = FROUND(/*TODO: PSW_RM()*/ 0, f);
|
||||
RzILOpEffect *else_eff = SETG(c,
|
||||
BITS32_U(VARG(a), 0, 16, UNSIGNED(32, F2BV(FCONVERT(RZ_FLOAT_IEEE754_BIN_16, 0, f)))));
|
||||
|
||||
return BRANCH(IS_FINF(FLOATV32(VARG(a))), inf_eff,
|
||||
BRANCH(IS_FNAN(FLOATV32(VARG(a))), nan_eff, else_eff));
|
||||
}
|
||||
|
||||
static RzILOpPure *f_real(RzILOpFloat *x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp ftoiz(RzAsmTriCoreContext *ctx) {
|
||||
RzILOpPure *a = VARG(R(1));
|
||||
const char *cname = R(0);
|
||||
return SETG(cname,
|
||||
ITE(IS_FINF(FLOATV32(a)),
|
||||
U32(0),
|
||||
ITE(SGT(f_real(DUP(a)), U32(0x7FFFFFFF)), U32(0x7FFFFFFF),
|
||||
ITE(SLT(f_real(DUP(a)), U32(0x80000000)),
|
||||
U32(0x80000000),
|
||||
F2SINT(32, RZ_FLOAT_RMODE_RTZ, DUP(a))))));
|
||||
}
|
||||
|
||||
#define Byte_b 8
|
||||
#define HalfWord_b 16
|
||||
#define Word_b 32
|
||||
|
|
@ -940,10 +860,6 @@ static RzILOpPure *reverse16(RzILOpPure *x) {
|
|||
return reflect(x, 16);
|
||||
}
|
||||
|
||||
static RzILOpPure *is_denorm(RzILOpPure *x) {
|
||||
return AND(IS_ZERO(BITS32(x, 23, 8)), NON_ZERO(BITS32(DUP(x), 0, 23)));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp f_cons_(RzILOpEffect *x, RzILOpEffect *y) {
|
||||
if (!(x && x->code == RZ_IL_OP_SEQ)) {
|
||||
goto err;
|
||||
|
|
@ -2717,7 +2633,6 @@ static RzAnalysisLiftedILOp f_madd(
|
|||
RzAnalysisLiftedILOp xs,
|
||||
const char *name1, const char *name2,
|
||||
RzILOpPure *a, RzILOpPure *b, unsigned arg_n, unsigned i1, unsigned i2, unsigned n) {
|
||||
rz_warn_if_fail(arg_n == 1 || arg_n == 0);
|
||||
Mab(madd_a, madd_b);
|
||||
|
||||
f_cons(xs,
|
||||
|
|
@ -2745,7 +2660,6 @@ static RzAnalysisLiftedILOp f_mul(
|
|||
RzAnalysisLiftedILOp xs,
|
||||
const char *name1, const char *name2,
|
||||
RzILOpPure *a, RzILOpPure *b, unsigned arg_n, unsigned i1, unsigned i2, unsigned n) {
|
||||
rz_warn_if_fail(arg_n == 1 || arg_n == 0);
|
||||
Mab(mul_a, mul_b);
|
||||
|
||||
f_cons(xs,
|
||||
|
|
@ -2761,7 +2675,6 @@ static RzAnalysisLiftedILOp f_mulr(
|
|||
RzAnalysisLiftedILOp xs,
|
||||
const char *name1, const char *name2,
|
||||
RzILOpPure *a, RzILOpPure *b, unsigned arg_n, unsigned i1, unsigned i2, unsigned n) {
|
||||
rz_warn_if_fail(arg_n == 1 || arg_n == 0);
|
||||
Mab(mulr_a, mulr_b);
|
||||
|
||||
f_cons(xs,
|
||||
|
|
@ -2778,7 +2691,6 @@ static RzAnalysisLiftedILOp f_maddr(
|
|||
RzAnalysisLiftedILOp xs, RzAsmTriCoreContext *ctx,
|
||||
const char *name1, const char *name2, const char *name3,
|
||||
RzILOpPure *a, RzILOpPure *b, unsigned arg_n, unsigned i1, unsigned i2, unsigned n) {
|
||||
rz_warn_if_fail(arg_n == 1 || arg_n == 0);
|
||||
xs = f_mul(xs, name1, name2, a, b, arg_n, i1, i2, n);
|
||||
return f_cons_(xs,
|
||||
SETL(name3,
|
||||
|
|
@ -3013,6 +2925,8 @@ static RzAnalysisLiftedILOp population_count(
|
|||
return xs;
|
||||
}
|
||||
|
||||
#include "tricore_il_fp.inc"
|
||||
|
||||
RZ_IPI RzAnalysisLiftedILOp tricore_il_op(RzAsmTriCoreContext *ctx, RzAnalysis *a) {
|
||||
ctx->word = rz_read_le32(ctx->insn->bytes);
|
||||
switch (ctx->insn->id) {
|
||||
|
|
@ -3025,35 +2939,23 @@ RZ_IPI RzAnalysisLiftedILOp tricore_il_op(RzAsmTriCoreContext *ctx, RzAnalysis *
|
|||
case TRICORE_INS_FRET: return fret();
|
||||
case TRICORE_INS_FTOHP: return ftohp(ctx);
|
||||
case TRICORE_INS_FTOIZ: return ftoiz(ctx);
|
||||
case TRICORE_INS_FTOI:
|
||||
case TRICORE_INS_FTOQ31Z:
|
||||
case TRICORE_INS_FTOQ31:
|
||||
case TRICORE_INS_FTOUZ:
|
||||
case TRICORE_INS_FTOU:
|
||||
case TRICORE_INS_HPTOF:
|
||||
case TRICORE_INS_ITOF:
|
||||
case TRICORE_INS_Q31TOF:
|
||||
case TRICORE_INS_DIV_F:
|
||||
case TRICORE_INS_ADD_F:
|
||||
case TRICORE_INS_MADD_F:
|
||||
case TRICORE_INS_MSUB_F:
|
||||
case TRICORE_INS_SUB_F:
|
||||
case TRICORE_INS_MUL_F:
|
||||
case TRICORE_INS_QSEED_F:
|
||||
case TRICORE_INS_UTOF: NOT_IMPLEMENTED;
|
||||
case TRICORE_INS_CMP_F: {
|
||||
const char *rc = R(0);
|
||||
const char *ra = R(1);
|
||||
const char *rb = R(2);
|
||||
return SETG(rc,
|
||||
f_op2_chain6(rz_il_op_new_log_or,
|
||||
BOOL_TO_BV32(FLT(FLOATV32(VARG(ra)), FLOATV32(VARG(rb)))),
|
||||
SHL0(BOOL_TO_BV32(FEQ(FLOATV32(VARG(ra)), FLOATV32(VARG(rb)))), 1),
|
||||
SHL0(BOOL_TO_BV32(FGT(FLOATV32(VARG(ra)), FLOATV32(VARG(rb)))), 2),
|
||||
SHL0(BOOL_TO_BV32(OR(IS_FNAN(FLOATV32(VARG(ra))), IS_FNAN(FLOATV32(VARG(rb))))), 3),
|
||||
SHL0(BOOL_TO_BV32(is_denorm(VARG(ra))), 4),
|
||||
SHL0(BOOL_TO_BV32(is_denorm(VARG(rb))), 5)));
|
||||
}
|
||||
case TRICORE_INS_FTOI: return ftoi(ctx);
|
||||
case TRICORE_INS_FTOQ31Z: return ftoq31z(ctx);
|
||||
case TRICORE_INS_FTOQ31: return ftoq31(ctx);
|
||||
case TRICORE_INS_FTOUZ: return ftouz(ctx);
|
||||
case TRICORE_INS_FTOU: return ftou(ctx);
|
||||
case TRICORE_INS_HPTOF: return hptof(ctx);
|
||||
case TRICORE_INS_ITOF: return itof(ctx);
|
||||
case TRICORE_INS_Q31TOF: return q31tof(ctx);
|
||||
case TRICORE_INS_UTOF: return utof(ctx);
|
||||
case TRICORE_INS_ADD_F: return add_f(ctx);
|
||||
case TRICORE_INS_SUB_F: return sub_f(ctx);
|
||||
case TRICORE_INS_MUL_F: return mul_f(ctx);
|
||||
case TRICORE_INS_DIV_F: return div_f(ctx);
|
||||
case TRICORE_INS_MADD_F: return madd_f(ctx);
|
||||
case TRICORE_INS_MSUB_F: return msub_f(ctx);
|
||||
case TRICORE_INS_QSEED_F: return qseed_f(ctx);
|
||||
case TRICORE_INS_CMP_F: return cmp_f(ctx);
|
||||
case TRICORE_INS_UPDFL: {
|
||||
RzILOpPure *m = BITS32(VARG(R(0)), 8, 8);
|
||||
RzILOpPure *v = BITS32(VARG(R(0)), 0, 8);
|
||||
|
|
@ -4066,8 +3968,20 @@ RZ_IPI RzAnalysisLiftedILOp tricore_il_op(RzAsmTriCoreContext *ctx, RzAnalysis *
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TRICORE_INS_MFCR: return SETG(R(0), VARG(CR_Table(I(1))));
|
||||
case TRICORE_INS_MTCR: return SETG(CR_Table(I(0)), VARG(R(1)));
|
||||
case TRICORE_INS_MFCR: {
|
||||
const char *cr = CR_Table(I(1));
|
||||
if (!cr) {
|
||||
return NULL;
|
||||
}
|
||||
return SETG(R(0), VARG(cr));
|
||||
}
|
||||
case TRICORE_INS_MTCR: {
|
||||
const char *cr = CR_Table(I(0));
|
||||
if (!cr) {
|
||||
return NULL;
|
||||
}
|
||||
return SETG(cr, VARG(R(1)));
|
||||
}
|
||||
case TRICORE_INS_BMERGE:
|
||||
return SETG(R(0),
|
||||
APPEND(
|
||||
|
|
|
|||
|
|
@ -68,17 +68,17 @@ static inline RzILOpPure *BITS32_U(RzILOpPure *val, ut32 i, ut32 n, RzILOpPure *
|
|||
}
|
||||
|
||||
// ((value >> start) & (~0ULL >> (0x20 - length)))
|
||||
static ut32 extract32(ut32 x, ut32 start, ut32 len) {
|
||||
static inline ut32 extract32(ut32 x, ut32 start, ut32 len) {
|
||||
return (x >> start) & (~0U >> (0x20 - len));
|
||||
}
|
||||
|
||||
static RzILOpPure *SEXT32(RzILOpPure *value, ut32 length) {
|
||||
static inline RzILOpPure *SEXT32(RzILOpPure *value, ut32 length) {
|
||||
return LET("_sext_val", SIGNED(32, value), rz_il_sextract32(VARLP("_sext_val"), U32(0), U32(length)));
|
||||
}
|
||||
static RzILOpPure *SEXT64(RzILOpPure *value, ut32 length) {
|
||||
static inline RzILOpPure *SEXT64(RzILOpPure *value, ut32 length) {
|
||||
return LET("_sext_val", SIGNED(32, value), rz_il_sextract64(VARLP("_sext_val"), U32(0), U32(length)));
|
||||
}
|
||||
static RzILOpPure *ZEXT32(RzILOpPure *value, ut32 length) {
|
||||
static inline RzILOpPure *ZEXT32(RzILOpPure *value, ut32 length) {
|
||||
return value;
|
||||
}
|
||||
static inline RzILOpPure *SHL0(RzILOpPure *value, ut32 length) {
|
||||
|
|
@ -235,4 +235,7 @@ REG_FIELD(TASK_ASI, ASI, 0, 5);
|
|||
#undef REG_FIELD_VERS
|
||||
#undef REG_FIELD_VER
|
||||
|
||||
RZ_IPI RzAnalysisLiftedILOp tricore_il_op(RzAsmTriCoreContext *ctx, RzAnalysis *a);
|
||||
RZ_IPI RzAnalysisILConfig *tricore_il_config(RZ_NONNULL RzAnalysis *analysis);
|
||||
|
||||
#endif // RIZIN_TRICORE_IL_H
|
||||
|
|
|
|||
602
librz/arch/isa/tricore/tricore_il_fp.inc
Normal file
602
librz/arch/isa/tricore/tricore_il_fp.inc
Normal file
|
|
@ -0,0 +1,602 @@
|
|||
// SPDX-FileCopyrightText: 2024 billow <billow.fun@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
/// The maximum of IEEE-754-2008 16-bit half precision floating point
|
||||
static const ut32 HP_MAX_VALUE = 65504;
|
||||
/// The minimum positive normalized number of IEEE-754-2008 16-bit half precision floating point
|
||||
static const ut32 HP_MIN_NORMAL = 1024 * 16;
|
||||
/// This represents all positive numbers that are too big to be represented accurately as a normalized number.
|
||||
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 denorm_to_zere_(T, x) \
|
||||
LET("tmp", x, \
|
||||
ITE(AND(FLT(VARLP("tmp"), T(0.0)), FGT(VARLP("tmp"), T(powf(-2, -126)))), FNEG(T(0)), \
|
||||
ITE(AND(FGT(VARLP("tmp"), T(0)), FLT(VARLP("tmp"), T(powf(2, -126)))), T(0), \
|
||||
VARLP("tmp"))))
|
||||
|
||||
#define denorm_to_zere64(x) denorm_to_zere_(F64, x)
|
||||
|
||||
#define F6432(x) FCONVERT(RZ_FLOAT_IEEE754_BIN_32, 0, x)
|
||||
#define F3264(x) FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, x)
|
||||
#define _32F64(x) F3264(FLOATV32(x))
|
||||
#define i32F32(x) SINT2F(RZ_FLOAT_IEEE754_BIN_32, 0, x)
|
||||
#define i32F64(x) F3264(i32F32(x))
|
||||
|
||||
static inline RzILOpPure *is_denorm(RzILOpPure *x) {
|
||||
return AND(IS_ZERO(BITS32(x, 23, 8)), NON_ZERO(BITS32(DUP(x), 0, 23)));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the Q31 format value ‘x’ as an infinitely accurate real value.
|
||||
*/
|
||||
static inline RzILOpFloat *q_real(ut32 x) {
|
||||
float y = x & 0x80000000 ? -1.f : 0.f;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
ut32 m = 1u << (30 - i);
|
||||
float b = 1.f / (float)(2u << i);
|
||||
if (x & m) {
|
||||
y += b;
|
||||
}
|
||||
}
|
||||
RzFloat *value = rz_float_new_from_f32(y);
|
||||
if (!value) {
|
||||
return NULL;
|
||||
}
|
||||
return rz_il_op_new_float_from_rz_float(value);
|
||||
}
|
||||
|
||||
static inline RzILOpEffect *q_real_set_v(const char *k, RzILOpPure *x) {
|
||||
return SEQ4(
|
||||
SETL("_x", x),
|
||||
SETL("_i", U32(0)),
|
||||
SETL(k, ITE(MSB(VARL("_x")), F32(-1.), F32(0.f))),
|
||||
REPEAT(
|
||||
ULT(VARL("_i"), U32(31)),
|
||||
SEQ4(
|
||||
SETL("_i", ADD(VARL("_i"), U32(1))),
|
||||
SETL("_m", SHIFTL0(U32(1), SUB(U32(30), VARL("_i")))),
|
||||
SETL("_b", FDIV(RZ_FLOAT_RMODE_RNE, F32(1.f), FLOATV32(SHIFTL0(U32(2), VARL("_i"))))),
|
||||
BRANCH(
|
||||
NON_ZERO(LOGAND(VARL("_x"), VARL("_m"))),
|
||||
SETL(k, FADD(0, VARL(k), VARL("_b"))),
|
||||
NOP()))));
|
||||
}
|
||||
|
||||
#define FCAST_(f, _1, x, mode, _default) \
|
||||
LET("_mode", UNSIGNED(8, mode), \
|
||||
LET("_x", x, \
|
||||
ITE(EQ(VARLP("_mode"), U8(0)), \
|
||||
f(_1, RZ_FLOAT_RMODE_RNE, VARLP("_x")), \
|
||||
ITE(EQ(VARLP("_mode"), U8(1)), \
|
||||
f(_1, RZ_FLOAT_RMODE_RNA, VARLP("_x")), \
|
||||
ITE(EQ(VARLP("_mode"), U8(2)), \
|
||||
f(_1, RZ_FLOAT_RMODE_RTN, VARLP("_x")), \
|
||||
ITE(EQ(VARLP("_mode"), U8(3)), \
|
||||
f(_1, RZ_FLOAT_RMODE_RTP, VARLP("_x")), \
|
||||
ITE(EQ(VARLP("_mode"), U8(4)), \
|
||||
f(_1, RZ_FLOAT_RMODE_RTZ, VARLP("_x")), \
|
||||
_default)))))))
|
||||
|
||||
#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))
|
||||
|
||||
static RzILOpPure *minmax(const char *k, st64 min, st64 max, RzILOpPure *x) {
|
||||
return ITE(IS_FNAN(VARL(k)),
|
||||
U32(0),
|
||||
ITE(FGT(VARL(k), F64(max)),
|
||||
U32(max),
|
||||
ITE(FLT(VARL(k), F64(min)),
|
||||
U32(min),
|
||||
x)));
|
||||
}
|
||||
|
||||
// The maximum of the Q31 format value
|
||||
#define Q31_MAX q_real(0x7FFFFFFF)
|
||||
// The minimum of the Q31 format value
|
||||
#define Q31_MIN F32(-1.f)
|
||||
|
||||
static RzILOpPure *minmax_q31(const char *k, RzILOpPure *x) {
|
||||
return ITE(FGT(VARL(k), q_real(0x7FFFFFFF)),
|
||||
U32(0x7FFFFFFF),
|
||||
ITE(FLT(VARL(k), F32(-1.0)),
|
||||
U32(0x80000000),
|
||||
x));
|
||||
}
|
||||
|
||||
#define not_in(x, min, max) OR(FGT(x, max), FLT(DUP(x), min))
|
||||
|
||||
#define not_in_q31(x) not_in(x, Q31_MIN, Q31_MAX)
|
||||
#define not_in_u32(x) not_in(x, F64(0.f), F64(UT32_MAX))
|
||||
#define not_in_i32(x) not_in(x, F64(ST32_MIN), F64(ST32_MAX))
|
||||
|
||||
#define set_FPU_s(k, x) SETG("set_" #k, x)
|
||||
|
||||
#define set_FPU(k, x) SEQ2( \
|
||||
SETG("set_" #k, x), \
|
||||
BRANCH(VARG("set_" #k), set_PSW_##k(U32(1)), NOP()))
|
||||
|
||||
static RzILOpPure *ieee754_16bit_underflow(RzILOpPure *x) {
|
||||
return AND(FLT(x, FLOATV32(U32(HP_MIN_NORMAL))), FGT(DUP(x), F32(0)));
|
||||
}
|
||||
|
||||
static RzILOpPure *ieee754_16bit_overflow(RzILOpFloat *x) {
|
||||
return FGT(x, FLOATV32(U32(HP_MAX_VALUE)));
|
||||
}
|
||||
|
||||
#define set_PSW_FSb(x) set_PSW_FS(BOOL_TO_BV32(x))
|
||||
#define set_FS_or_FI_FV_FU_FX set_PSW_FSb(f_op2_chain4(rz_il_op_new_bool_or, VARG("set_FI"), VARG("set_FV"), VARG("set_FU"), VARG("set_FX")))
|
||||
|
||||
/**
|
||||
* \brief Convert single precision to a half precision
|
||||
*
|
||||
* Convert the contents of data register D[a] from IEEE-754-2008 32-bit single precision floating point to IEEE-754-2008
|
||||
* 16-bit half precision (data interchange) floating point format. The rounded result is put in data register D[c][15:0].
|
||||
* D[c][31:16] is set to zero.
|
||||
*/
|
||||
static RzAnalysisLiftedILOp ftohp(RzAsmTriCoreContext *ctx) {
|
||||
const char *a = R(1);
|
||||
const char *c = R(0);
|
||||
|
||||
// if(sign_32bit(D[a])) then {
|
||||
// D[c][15:0] = HP_NEG_INFINITY;
|
||||
// } else {
|
||||
// D[c][15:0] = HP_POS_INFINITY;
|
||||
// }
|
||||
RzILOpEffect *inf_eff = BRANCH(sign_32bit(VARG(a)),
|
||||
SETG(c, U32(HP_NEG_INFINITY)),
|
||||
SETG(c, U32(HP_POS_INFINITY)));
|
||||
|
||||
// D[c][15] = sign_32bit(D[a]);
|
||||
// D[c][14:10] = 1FH;
|
||||
// D[c][9:8] = D[a][22:21];
|
||||
// D[c][7:0] = D[a][7:0];
|
||||
// Ensure NaN value is preserved
|
||||
// if ((D[c][9:0] == 0)) then {
|
||||
// D[c][8] = 1B;
|
||||
// }
|
||||
RzILOpPure *dc = LOGAND(VARG(a), U32(1U << 31));
|
||||
dc = LOGOR(dc, SHL0(U32(0x1f), 10));
|
||||
dc = LOGOR(dc, SHL0(BITS32(VARG(a), 21, 2), 8));
|
||||
dc = LOGOR(dc, BITS32(VARG(a), 0, 8));
|
||||
RzILOpEffect *nan_eff = SEQ2(SETL("D_c", dc),
|
||||
SETG(c, ITE(EQ(BITS32(VARL("D_c"), 0, 10), U32(0)), BITS32_U(VARL("D_c"), 8, 1, U32(1)), VARL("D_c"))));
|
||||
|
||||
// f = denorm_to_zero(D[a]);
|
||||
// f_rounded = ieee754_round_16bit(f, PSW.RM);
|
||||
// Handle overflow & underflow and convert to 16-bit format
|
||||
// D[a][15:0] = ieee754_16bit_format(f_rounded);
|
||||
RzILOpEffect *else_eff =
|
||||
SEQ3(SETL("_fa", denorm_to_zere64(FLOATV32(VARG(a)))),
|
||||
SETL("_f_rounded", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_16, VARL("_fa"), PSW_RM())),
|
||||
SETG(c, BITS32_U(VARG(c), 0, 16, UNSIGNED(32, VARL("_f_rounded")))));
|
||||
|
||||
RzILOpEffect *set_status = SEQ5(
|
||||
set_FPU(FX, FNE(VARL("_fa"), FLOATV32(UNSIGNED(16, VARG(R(1)))))),
|
||||
set_FPU(FU, AND(ieee754_16bit_underflow(VARL("_fa")), VARG("set_FX"))),
|
||||
set_FPU(FV, ieee754_16bit_overflow(VARL("_fa"))),
|
||||
set_FPU(FI, IS_FNAN(VARG(R(1)))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQ4(
|
||||
SETL("_fa", F32(0)),
|
||||
SETL("_f_rounded", F32(0)),
|
||||
BRANCH(IS_FINF(FLOATV32(VARG(a))), inf_eff,
|
||||
BRANCH(IS_FNAN(FLOATV32(VARG(a))), nan_eff, else_eff)),
|
||||
set_status);
|
||||
}
|
||||
|
||||
/**
|
||||
* HPTOF D[c], D[a] (RR)
|
||||
* hp = D[a][15:0];
|
||||
* if (is_inf_16bit(hp)) then {
|
||||
* // Signed Infinity
|
||||
* if(sign_16bit(hp)) then {
|
||||
* D[c][31:0] = NEG_INFINITY;
|
||||
* } else {
|
||||
* D[c][31:0] = POS_INFINITY;
|
||||
* }
|
||||
* } else if (is_nan_16bit(hp)) then {
|
||||
* // Signed NaN
|
||||
* D[c][31] = sign_16bit(hp);
|
||||
* D[c][30:23] = FFH;
|
||||
* D[c][22:21] = D[a][9:8];
|
||||
* D[c][20:8] = 0;
|
||||
* D[c][7:0] = D[a][7:0];
|
||||
* } else {
|
||||
* f = f_real_16bit(hp);
|
||||
* D[c] = ieee754_32bit_format(f);
|
||||
* }
|
||||
*/
|
||||
static RzAnalysisLiftedILOp hptof(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ4(
|
||||
SETL("_hp", UNSIGNED(16, VARG(R(1)))),
|
||||
SETL("_result", FCONVERT(RZ_FLOAT_IEEE754_BIN_32, RZ_FLOAT_RMODE_RNA, FLOATV16(VARL("_hp")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
SEQ2(set_FPU(FI, IS_FNAN(VARL("_hp"))),
|
||||
set_PSW_FSb((VARG("set_FI")))));
|
||||
}
|
||||
|
||||
/**
|
||||
* D[c], D[a] (RR)
|
||||
* if(is_nan(D[a])) then result = 0;
|
||||
* else if(f_real(D[a]) > 2^31-1) then result = 7FFFFFFFH;
|
||||
* else if(f_real(D[a]) < -2^31) then result = 80000000H;
|
||||
* else result = round_to_integer(D[a], PSW.RM);
|
||||
* D[c] = result[31:0];
|
||||
*/
|
||||
static RzAnalysisLiftedILOp ftoi(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ4(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_result_i", minmax("_fa", ST32_MAX, ST32_MIN, round_to_integer(VARL("_fa"), PSW_RM()))),
|
||||
SETG(R(0), VARL("_result_i")),
|
||||
SEQ3(set_FPU(FI, OR(not_in_i32(VARL("_fa")), IS_FNAN(VARL("_fa")))),
|
||||
set_FPU(FX, FNE(VARL("_fa"), i32F64(VARL("_result_i")))),
|
||||
set_PSW_FSb(OR(VARG("set_FX"), VARG("set_FI")))));
|
||||
}
|
||||
|
||||
/**
|
||||
* FTOIZ D[c], D[a] (RR)
|
||||
* if(is_nan(D[a])) then result = 0;
|
||||
* else if(f_real(D[a]) > 2^31-1) then result = 7FFFFFFFH;
|
||||
* else if(f_real(D[a]) < -2^31) then result = 80000000H;
|
||||
* else result = round_to_integer(D[a], 11B);
|
||||
* D[c] = result[31:0];
|
||||
*/
|
||||
static RzAnalysisLiftedILOp ftoiz(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ4(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_result_i", minmax("_fa", ST32_MAX, ST32_MIN, F2SINT32(VARL("_fa"), RZ_FLOAT_RMODE_RTZ))),
|
||||
SETG(R(0), VARL("_result_i")),
|
||||
SEQ3(set_FPU(FI, OR(not_in_u32(VARL("_fa")), IS_FNAN(VARL("_fa")))),
|
||||
set_FPU(FX, FNE(VARL("_fa"), i32F64(VARL("_result_i")))),
|
||||
set_PSW_FSb((OR(VARG("set_FX"), VARG("set_FI"))))));
|
||||
}
|
||||
|
||||
/**
|
||||
* D[c], D[a] (RR)
|
||||
*
|
||||
* rounded_result = ieee754_round(i_real(D[a]), PSW.RM);
|
||||
* result = ieee754_32bit_format(rounded_result);
|
||||
* D[c] = result[31:0];
|
||||
*/
|
||||
static RzAnalysisLiftedILOp itof(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ6(
|
||||
SETL("_a", VARG(R(1))),
|
||||
SETL("_result64", FCAST64(SINT2F, RZ_FLOAT_IEEE754_BIN_64, VARL("_a"), PSW_RM())),
|
||||
SETL("_result32", FCAST32(SINT2F, RZ_FLOAT_IEEE754_BIN_32, VARL("_a"), PSW_RM())),
|
||||
SETL("_result32_64", FCAST64(FCONVERT, RZ_FLOAT_IEEE754_BIN_64, VARL("_result32"), PSW_RM())),
|
||||
SETG(R(0), F2BV(VARL("_result32"))),
|
||||
SEQ2(set_FPU(FX, FNE(VARL("_result32_64"), VARL("_result64"))),
|
||||
set_PSW_FSb((VARG("set_FX")))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp ftou(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ4(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_result_i", minmax("_fa", UT32_MAX, UT32_MIN, round_to_integer(VARL("_fa"), PSW_RM()))),
|
||||
SETG(R(0), VARL("_result_i")),
|
||||
SEQ3(set_FPU(FI, OR(not_in_u32(VARL("_fa")), IS_FNAN(VARL("_fa")))),
|
||||
set_FPU(FX, FNE(VARL("_fa"), i32F64(VARL("_result_i")))),
|
||||
set_PSW_FSb(OR(VARG("set_FX"), VARG("set_FI")))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp ftouz(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ4(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_result_i", minmax("_fa", UT32_MAX, UT32_MIN, F2SINT32(VARL("_fa"), RZ_FLOAT_RMODE_RTZ))),
|
||||
SETG(R(0), VARL("_result_i")),
|
||||
SEQ3(set_FPU(FI, OR(not_in_u32(VARL("_fa")), IS_FNAN(VARL("_fa")))),
|
||||
set_FPU(FX, FNE(VARL("_fa"), i32F64(VARL("_result_i")))),
|
||||
set_PSW_FSb(OR(VARG("set_FX"), VARG("set_FI")))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp utof(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ4(
|
||||
SETL("_a", VARG(R(1))),
|
||||
SETL("_result", FCAST32(INT2F, RZ_FLOAT_IEEE754_BIN_32, VARL("_a"), PSW_RM())),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
SEQ2(set_FPU(FX, FNE(i32F32(VARL("_a")), VARL("_result"))),
|
||||
set_PSW_FSb(VARG("set_FX"))));
|
||||
}
|
||||
|
||||
/**
|
||||
* FTOQ31 D[c], D[a], D[b] (RR)
|
||||
* arg_a = denorm_to_zere64(f_real(D[a]);
|
||||
* if(is_nan(D[a])) then result = 0;
|
||||
* else precise_result = mul(arg_a, 2^-D[b][8:0]);
|
||||
* if(precise_result > q_real(7FFFFFFFH)) then result = 7FFFFFFFH;
|
||||
* else if(precise_result < -1.0) then result = 80000000H;
|
||||
* else result = round_to_q31(precise_result);
|
||||
* D[c] = result[31:0];
|
||||
*/
|
||||
static RzAnalysisLiftedILOp ftoq31(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ8(
|
||||
SETL("_a", VARG(R(1))),
|
||||
SETL("_arg_a", F32(0)),
|
||||
q_real_set_v("_arg_a", VARL("_a")),
|
||||
SETL("_arg_a", denorm_to_zere_(F32, VARL("_arg_a"))),
|
||||
SETL("_precise_result", FDIV(0, VARL("_arg_a"), FPOW(0, F32(2), FLOATV32(LOGAND(VARG(R(2)), U32(0x1ff)))))),
|
||||
SETL("_result_i",
|
||||
ITE(IS_FNAN(FLOATV32(VARL("_a"))),
|
||||
U32(0),
|
||||
minmax_q31("_precise_result", round_to_integer(VARL("_precise_result"), PSW_RM())))),
|
||||
SETG(R(0), VARL("_result_i")),
|
||||
SEQ5(SETL("_res_q_real", F32(0)),
|
||||
q_real_set_v("_res_q_real", VARL("_result_i")),
|
||||
set_FPU(FI, OR(not_in_q31(VARL("_precise_result")), IS_FNAN(FLOATV32(VARL("_a"))))),
|
||||
set_FPU(FX, FNE(FLOATV32(VARL("_a")), VARL("_res_q_real"))),
|
||||
set_PSW_FSb(OR(VARG("set_FX"), VARG("set_FI")))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp ftoq31z(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ9(
|
||||
SETL("_a", VARG(R(1))),
|
||||
SETL("_fa", FLOATV32(VARL("_a"))),
|
||||
SETL("_arg_a", F32(0)),
|
||||
q_real_set_v("_arg_a", VARL("_a")),
|
||||
SETL("_arg_a", denorm_to_zere_(F32, VARL("_arg_a"))),
|
||||
SETL("_precise_result", FDIV(0, VARL("_arg_a"), FPOW(0, F32(2), FLOATV32(LOGAND(VARG(R(2)), U32(0x1ff)))))),
|
||||
SETL("_result_i",
|
||||
ITE(IS_FNAN(VARL("_fa")),
|
||||
U32(0),
|
||||
minmax_q31("_precise_result", F2SINT32(VARL("_precise_result"), RZ_FLOAT_RMODE_RTZ)))),
|
||||
SETG(R(0), VARL("_result_i")),
|
||||
SEQ5(SETL("_res_q_real", F32(0)),
|
||||
q_real_set_v("_res_q_real", VARL("_result_i")),
|
||||
set_FPU(FI, OR(not_in_q31(VARL("_precise_result")), IS_FNAN(FLOATV32(VARL("_a"))))),
|
||||
set_FPU(FX, FNE(VARL("_fa"), VARL("_res_q_real"))),
|
||||
set_PSW_FSb(OR(VARG("set_FX"), VARG("set_FI")))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Q31TOF D[c], D[a], D[b] (RR)
|
||||
*
|
||||
* precise_result = mul(q_real(D[a]),2^D[b][8:0]);
|
||||
* rounded_result = ieee754_round(precise_result, PSW.RM);
|
||||
* result = ieee754_32bit_format(rounded_result);
|
||||
* D[c] = result[31:0];
|
||||
*/
|
||||
static RzAnalysisLiftedILOp q31tof(RzAsmTriCoreContext *ctx) {
|
||||
return SEQ7(
|
||||
SETL("_a", VARG(R(1))),
|
||||
SETL("_qa", F32(0)),
|
||||
q_real_set_v("_qa", VARL("_a")),
|
||||
SETL("_precise_result", FMUL(RZ_FLOAT_RMODE_RNE, VARL("_qa"), FPOW(0, F32(2.), FLOATV32(LOGAND(VARG(R(2)), U32(0x1ff)))))),
|
||||
SETL("_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_precise_result"), PSW_RM())),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
SEQ3(set_FPU(FX, FNE(VARL("_precise_result"), VARL("_result"))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F32(1. / 0x2p126))),
|
||||
set_PSW_FSb(VARG("set_FX"))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp cmp_f(RzAsmTriCoreContext *ctx) {
|
||||
const char *rc = R(0);
|
||||
const char *ra = R(1);
|
||||
const char *rb = R(2);
|
||||
return SETG(rc,
|
||||
f_op2_chain6(rz_il_op_new_log_or,
|
||||
BOOL_TO_BV32(FLT(FLOATV32(VARG(ra)), FLOATV32(VARG(rb)))),
|
||||
SHL0(BOOL_TO_BV32(FEQ(FLOATV32(VARG(ra)), FLOATV32(VARG(rb)))), 1),
|
||||
SHL0(BOOL_TO_BV32(FGT(FLOATV32(VARG(ra)), FLOATV32(VARG(rb)))), 2),
|
||||
SHL0(BOOL_TO_BV32(OR(IS_FNAN(FLOATV32(VARG(ra))), IS_FNAN(FLOATV32(VARG(rb))))), 3),
|
||||
SHL0(BOOL_TO_BV32(is_denorm(VARG(ra))), 4),
|
||||
SHL0(BOOL_TO_BV32(is_denorm(VARG(rb))), 5)));
|
||||
}
|
||||
|
||||
#define SEQ10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) SEQN(10, e0, e1, e2, e3, e4, e5, e6, e7, e8, e9)
|
||||
|
||||
/**
|
||||
* ADD.F D[c], D[d], D[a] (RRR)
|
||||
* arg_a = denorm_to_zere64(f_real(D[a]);
|
||||
* arg_b = denorm_to_zere64(f_real(D[d]);
|
||||
* if(is_nan(D[a]) OR is_nan(D[d])) then result = QUIET_NAN;
|
||||
* else if(is_pos_inf(D[a]) AND is_neg_inf(D[d])) then result = ADD_NAN;
|
||||
* else if(is_neg_inf(D[a]) AND is_pos_inf(D[d])) then result = ADD_NAN;
|
||||
* else {
|
||||
* precise_result = add(arg_a,arg_b);
|
||||
* normal_result = denorm_to_zere64(precise_result);
|
||||
* rounded_result = ieee754_round(normal_result, PSW.RM);
|
||||
* result = ieee754_32bit_format(rounded_result);
|
||||
* }
|
||||
* D[c] = result[31:0];
|
||||
*/
|
||||
static RzAnalysisLiftedILOp add_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ6(
|
||||
set_FPU(FI, OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb")))),
|
||||
set_FPU(FV, FGE(VARL("_rounded_result"), F32(0x2p128))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F64(0x2p-126))),
|
||||
set_FPU_s(FX, FNE(VARL("_precise_result"), FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, VARL("_result")))),
|
||||
set_PSW_FX(BOOL_TO_BV32(AND(VARG("set_FX"), INV(VARG("set_FI"))))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQ10(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_fb", _32F64(VARG(R(2)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_arg_b", denorm_to_zere64(VARL("_fb"))),
|
||||
SETL("_precise_result", FADD(0, VARL("_arg_a"), VARL("_arg_b"))),
|
||||
SETL("_normal_result", denorm_to_zere64(VARL("_precise_result"))),
|
||||
SETL("_rounded_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_normal_result"), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))),
|
||||
IL_FQNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
ITE(AND(IS_FINF(VARL("_fa")), IS_FINF(VARL("_fb"))),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_rounded_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp sub_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ6(
|
||||
set_FPU(FI, OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb")))),
|
||||
set_FPU(FV, FGE(VARL("_rounded_result"), F32(0x2p128))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F64(0x2p-126))),
|
||||
set_FPU_s(FX, FNE(VARL("_precise_result"), FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, VARL("_result")))),
|
||||
set_PSW_FX(BOOL_TO_BV32(AND(VARG("set_FX"), INV(VARG("set_FI"))))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQ10(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_fb", _32F64(VARG(R(2)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_arg_b", denorm_to_zere64(VARL("_fb"))),
|
||||
SETL("_precise_result", FADD(0, FNEG(VARL("_arg_a")), VARL("_arg_b"))),
|
||||
SETL("_normal_result", denorm_to_zere64(VARL("_precise_result"))),
|
||||
SETL("_rounded_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_normal_result"), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))),
|
||||
IL_FQNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
ITE(AND(IS_FINF(VARL("_fa")), IS_FINF(VARL("_fb"))),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_rounded_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp mul_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ6(
|
||||
set_FPU(FI, OR(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))), IS_FNAN(VARL("_result")))),
|
||||
set_FPU(FV, FGE(VARL("_rounded_result"), F32(0x2p128))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F64(0x2p-126))),
|
||||
set_FPU_s(FX, FNE(VARL("_precise_result"), FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, VARL("_result")))),
|
||||
set_PSW_FX(BOOL_TO_BV32(AND(VARG("set_FX"), INV(VARG("set_FI"))))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQ10(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_fb", _32F64(VARG(R(2)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_arg_b", denorm_to_zere64(VARL("_fb"))),
|
||||
SETL("_precise_result", FMUL(0, VARL("_arg_a"), VARL("_arg_b"))),
|
||||
SETL("_normal_result", denorm_to_zere64(VARL("_precise_result"))),
|
||||
SETL("_rounded_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_normal_result"), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))),
|
||||
IL_FQNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
ITE(OR(AND(IS_FINF(VARL("_fa")), IS_FZERO(VARL("_fb"))),
|
||||
AND(IS_FZERO(VARL("_fa")), IS_FINF(VARL("_fb")))),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_rounded_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp div_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ7(
|
||||
set_FPU(FI, OR(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))), IS_FNAN(VARL("_result")))),
|
||||
set_FPU(FV, FGE(VARL("_rounded_result"), F32(0x2p128))),
|
||||
set_FPU(FZ, AND(IS_FZERO(VARL("_fb")), INV(IS_FINF(VARL("_fa"))))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F64(0x2p-126))),
|
||||
set_FPU_s(FX, FNE(VARL("_precise_result"), FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, VARL("_result")))),
|
||||
set_PSW_FX(BOOL_TO_BV32(AND(VARG("set_FX"), INV(VARG("set_FI"))))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQ10(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_fb", _32F64(VARG(R(2)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_arg_b", denorm_to_zere64(VARL("_fb"))),
|
||||
SETL("_precise_result", FDIV(0, VARL("_arg_a"), VARL("_arg_b"))),
|
||||
SETL("_normal_result", denorm_to_zere64(VARL("_precise_result"))),
|
||||
SETL("_rounded_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_normal_result"), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))),
|
||||
IL_FQNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
ITE(OR(AND(IS_FINF(VARL("_fa")), IS_FINF(VARL("_fb"))),
|
||||
AND(IS_FZERO(VARL("_fa")), IS_FZERO(VARL("_fb")))),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_rounded_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp qseed_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ2(
|
||||
set_FPU(FI, OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_result")))),
|
||||
set_PSW_FSb(VARG("set_FI")));
|
||||
|
||||
return SEQ6(
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_normal_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, FRSQRT(0, VARL("_arg_a")), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(IS_FZERO(VARL("_arg_a")),
|
||||
F32(0),
|
||||
ITE(FLT(VARL("_fa"), F64(0)),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_normal_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp madd_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ6(
|
||||
set_FPU(FI, OR(OR(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))), IS_FNAN(VARL("_fc"))), IS_FNAN(VARL("_result")))),
|
||||
set_FPU(FV, FGE(VARL("_rounded_result"), F32(0x2p128))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F64(0x2p-126))),
|
||||
set_FPU_s(FX, FNE(VARL("_precise_result"), FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, VARL("_result")))),
|
||||
set_PSW_FX(BOOL_TO_BV32(AND(VARG("set_FX"), INV(VARG("set_FI"))))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQN(12,
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_fb", _32F64(VARG(R(2)))),
|
||||
SETL("_fc", _32F64(VARG(R(3)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_arg_b", denorm_to_zere64(VARL("_fb"))),
|
||||
SETL("_arg_c", denorm_to_zere64(VARL("_fc"))),
|
||||
SETL("_precise_mul_result", FMUL(0, VARL("_arg_a"), VARL("_arg_b"))),
|
||||
SETL("_precise_result", FADD(0, VARL("_precise_mul_result"), VARL("_arg_c"))),
|
||||
SETL("_normal_result", denorm_to_zere64(VARL("_precise_result"))),
|
||||
SETL("_rounded_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_normal_result"), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(OR(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))), IS_FNAN(VARL("_fc"))),
|
||||
IL_FQNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
ITE(OR(OR(AND(IS_FINF(VARL("_fa")), IS_FZERO(VARL("_fb"))),
|
||||
AND(IS_FZERO(VARL("_fa")), IS_FINF(VARL("_fb")))),
|
||||
AND(AND(IS_FINF(VARL("_fa")), IS_FINF(VARL("_fa"))),
|
||||
IS_FINF(VARL("_fc")))),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_rounded_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp msub_f(RzAsmTriCoreContext *ctx) {
|
||||
RzAnalysisLiftedILOp set_status = SEQ6(
|
||||
set_FPU(FI, OR(OR(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))), IS_FNAN(VARL("_fc"))), IS_FNAN(VARL("_result")))),
|
||||
set_FPU(FV, FGE(VARL("_rounded_result"), F32(0x2p128))),
|
||||
set_FPU(FU, FLT(FABS(VARL("_precise_result")), F64(0x2p-126))),
|
||||
set_FPU_s(FX, FNE(VARL("_precise_result"), FCONVERT(RZ_FLOAT_IEEE754_BIN_64, 0, VARL("_result")))),
|
||||
set_PSW_FX(BOOL_TO_BV32(AND(VARG("set_FX"), INV(VARG("set_FI"))))),
|
||||
set_FS_or_FI_FV_FU_FX);
|
||||
|
||||
return SEQN(12,
|
||||
SETL("_fa", _32F64(VARG(R(1)))),
|
||||
SETL("_fb", _32F64(VARG(R(2)))),
|
||||
SETL("_fc", _32F64(VARG(R(3)))),
|
||||
SETL("_arg_a", denorm_to_zere64(VARL("_fa"))),
|
||||
SETL("_arg_b", denorm_to_zere64(VARL("_fb"))),
|
||||
SETL("_arg_c", denorm_to_zere64(VARL("_fc"))),
|
||||
SETL("_precise_mul_result", FMUL(0, VARL("_arg_a"), VARL("_arg_b"))),
|
||||
SETL("_precise_result", FADD(0, FNEG(VARL("_precise_mul_result")), VARL("_arg_c"))),
|
||||
SETL("_normal_result", denorm_to_zere64(VARL("_precise_result"))),
|
||||
SETL("_rounded_result", FCAST32(FCONVERT, RZ_FLOAT_IEEE754_BIN_32, VARL("_normal_result"), PSW_RM())),
|
||||
SETL("_result",
|
||||
ITE(OR(OR(IS_FNAN(VARL("_fa")), IS_FNAN(VARL("_fb"))), IS_FNAN(VARL("_fc"))),
|
||||
IL_FQNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
ITE(OR(OR(AND(IS_FINF(VARL("_fa")), IS_FZERO(VARL("_fb"))),
|
||||
AND(IS_FZERO(VARL("_fa")), IS_FINF(VARL("_fb")))),
|
||||
AND(AND(IS_FINF(VARL("_fa")), IS_FINF(VARL("_fa"))),
|
||||
IS_FINF(VARL("_fc")))),
|
||||
IL_FSNAN(RZ_FLOAT_IEEE754_BIN_32),
|
||||
VARL("_rounded_result")))),
|
||||
SETG(R(0), F2BV(VARL("_result"))),
|
||||
set_status);
|
||||
}
|
||||
|
|
@ -8,9 +8,7 @@
|
|||
#include <capstone/capstone.h>
|
||||
|
||||
#include <tricore/tricore.inc>
|
||||
|
||||
RZ_IPI RzAnalysisLiftedILOp tricore_il_op(RzAsmTriCoreContext *ctx, RzAnalysis *a);
|
||||
RZ_IPI RzAnalysisILConfig *tricore_il_config(RZ_NONNULL RzAnalysis *analysis);
|
||||
#include "tricore/tricore_il.h"
|
||||
|
||||
#define TRICORE_REG_SP TRICORE_REG_A10
|
||||
|
||||
|
|
@ -241,7 +239,12 @@ static char *tricore_reg_profile(RzAnalysis *_) {
|
|||
"drx FPU_TRAP_OPC .32 812 0\n"
|
||||
"drx FPU_TRAP_SRC1 .32 816 0\n"
|
||||
"drx FPU_TRAP_SRC2 .32 820 0\n"
|
||||
"drx FPU_TRAP_SRC3 .32 824 0\n";
|
||||
"drx FPU_TRAP_SRC3 .32 824 0\n"
|
||||
"drx set_FI .1 900 0\n"
|
||||
"drx set_FV .1 901 0\n"
|
||||
"drx set_FZ .1 902 0\n"
|
||||
"drx set_FU .1 903 0\n"
|
||||
"drx set_FX .1 904 0\n";
|
||||
return strdup(p);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -859,6 +859,10 @@ RZ_IPI void rz_core_il_cons_print(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_BORROW
|
|||
const char delim = pretty ? '\n' : ' ';
|
||||
RzStrBuf sb;
|
||||
|
||||
RzAnalysisILVM *vm = rz_analysis_il_vm_new(core->analysis, NULL);
|
||||
RzILValidateGlobalContext *ctx = vm ? rz_il_validate_global_context_new_from_vm(vm->vm)
|
||||
: NULL;
|
||||
|
||||
RzAnalysisOp *op = NULL;
|
||||
rz_iterator_foreach(iter, op) {
|
||||
if (!op->il_op) {
|
||||
|
|
@ -868,14 +872,27 @@ RZ_IPI void rz_core_il_cons_print(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_BORROW
|
|||
|
||||
rz_strbuf_init(&sb);
|
||||
rz_il_op_effect_stringify(op->il_op, &sb, pretty);
|
||||
|
||||
il_stmt = rz_strbuf_get(&sb);
|
||||
if (colorize) {
|
||||
core_colorify_il_statement(core->cons->context, il_stmt, delim, op->addr);
|
||||
} else {
|
||||
rz_cons_printf("0x%" PFMT64x "%c%s\n", op->addr, delim, il_stmt);
|
||||
}
|
||||
|
||||
if (ctx) {
|
||||
RzILTypeEffect t;
|
||||
char *report;
|
||||
rz_il_validate_effect(op->il_op, ctx, NULL, &t, &report);
|
||||
if (report) {
|
||||
rz_cons_println(report);
|
||||
free(report);
|
||||
}
|
||||
}
|
||||
rz_strbuf_fini(&sb);
|
||||
}
|
||||
rz_analysis_il_vm_free(vm);
|
||||
rz_il_validate_global_context_free(ctx);
|
||||
}
|
||||
|
||||
// used to speedup strcmp with rz_config_get in loops
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ RZ_API RZ_OWN RzFloat *rz_il_float_new(RZ_NONNULL RzFloatFormat format, RZ_NONNU
|
|||
|
||||
ut32 len = rz_float_get_format_info(format, RZ_FLOAT_INFO_TOTAL_LEN);
|
||||
if (len != bv->len) {
|
||||
RZ_LOG_ERROR("The size of the float :%d does not match the size of the bitvector :%d.\n", len, bv->len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1025,6 +1025,9 @@ RZ_API void rz_il_op_effect_stringify(RZ_NONNULL RzILOpEffect *op, RZ_NONNULL Rz
|
|||
*/
|
||||
RZ_API char *rz_il_value_stringify(RZ_NONNULL const RzILVal *val) {
|
||||
rz_return_val_if_fail(val, NULL);
|
||||
if (val->type == RZ_IL_TYPE_PURE_FLOAT) {
|
||||
return rz_float_as_string(val->data.f);
|
||||
}
|
||||
RzBitVector *bv = rz_il_value_to_bv(val);
|
||||
if (!bv) {
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -760,22 +760,27 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float(RzFloatFormat format, RZ_NONNULL R
|
|||
return ret;
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_rz_float(RZ_NONNULL RZ_OWN RzFloat *fl) {
|
||||
rz_return_val_if_fail(fl, NULL);
|
||||
RzILOpFloat *ret = NULL;
|
||||
RzFloatFormat r = fl->r;
|
||||
RzILOpBitVector *bv = rz_il_op_new_bitv(fl->s);
|
||||
if (!bv) {
|
||||
goto err;
|
||||
}
|
||||
fl->s = NULL;
|
||||
rz_il_op_new_2(Float, RZ_IL_OP_FLOAT, RzILOpArgsFloat, float_, r, bv);
|
||||
err:
|
||||
rz_float_free(fl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f32(float f) {
|
||||
RzFloat *value = rz_float_new_from_f32(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;
|
||||
return rz_il_op_new_float_from_rz_float(value);
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f64(double f) {
|
||||
|
|
@ -783,17 +788,7 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f64(double 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;
|
||||
return rz_il_op_new_float_from_rz_float(value);
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f80(long double f) {
|
||||
|
|
@ -801,17 +796,7 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_f80(long double 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;
|
||||
return rz_il_op_new_float_from_rz_float(value);
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_fbits(RZ_NONNULL RzILOpFloat *f) {
|
||||
|
|
|
|||
|
|
@ -359,15 +359,10 @@ VALIDATOR_PURE(ite) {
|
|||
VALIDATOR_DESCEND(args->x, &sx);
|
||||
RzILSortPure sy;
|
||||
VALIDATOR_DESCEND(args->y, &sy);
|
||||
if (!rz_il_sort_pure_eq(sx, sy)) {
|
||||
char *sxs = rz_il_sort_pure_stringify(sx);
|
||||
char *sys = rz_il_sort_pure_stringify(sy);
|
||||
rz_strbuf_appendf(report_builder, "Types of ite branches do not agree: %s vs. %s.\n",
|
||||
rz_str_get_null(sxs), rz_str_get_null(sys));
|
||||
free(sxs);
|
||||
free(sys);
|
||||
return false;
|
||||
}
|
||||
VALIDATOR_ASSERT(rz_il_sort_pure_eq(sx, sy), "Types of ite branches do not agree: %s vs. %s.\n",
|
||||
rz_il_sort_pure_stringify(sx),
|
||||
rz_il_sort_pure_stringify(sy));
|
||||
|
||||
*sort_out = sx;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -611,16 +606,10 @@ VALIDATOR_PURE(forder) {
|
|||
VALIDATOR_ASSERT(sy.type == RZ_IL_TYPE_PURE_FLOAT, "Right operand of %s op is not a float.\n", rz_il_op_pure_code_stringify(op->code));
|
||||
|
||||
// flatten validator assert
|
||||
if (!(sx.props.f.format == sy.props.f.format)) {
|
||||
char *ssx = rz_il_sort_pure_stringify(sx);
|
||||
char *ssy = rz_il_sort_pure_stringify(sy);
|
||||
|
||||
rz_strbuf_appendf(report_builder, "Op %s formats of left operand (%s) and right operand (%s) do not agree.\n",
|
||||
rz_il_op_pure_code_stringify(op->code), ssx, ssy);
|
||||
free(ssx);
|
||||
free(ssy);
|
||||
return false;
|
||||
}
|
||||
VALIDATOR_ASSERT(sx.props.f.format == sy.props.f.format, "Op %s formats of left operand (%s) and right operand (%s) do not agree.\n",
|
||||
rz_il_op_pure_code_stringify(op->code),
|
||||
rz_il_sort_pure_stringify(sx),
|
||||
rz_il_sort_pure_stringify(sy));
|
||||
|
||||
*sort_out = rz_il_sort_pure_bool();
|
||||
return true;
|
||||
|
|
@ -652,17 +641,10 @@ VALIDATOR_PURE(float_binop_with_round) {
|
|||
VALIDATOR_ASSERT(sy.type == RZ_IL_TYPE_PURE_FLOAT, "Right operand of %s op is not a float.\n", rz_il_op_pure_code_stringify(op->code));
|
||||
|
||||
// flatten validator assert
|
||||
if (!(sx.props.f.format == sy.props.f.format)) {
|
||||
char *ssx = rz_il_sort_pure_stringify(sx);
|
||||
char *ssy = rz_il_sort_pure_stringify(sy);
|
||||
|
||||
rz_strbuf_appendf(report_builder, "Op %s formats of left operand (%s) and right operand (%s) do not agree.\n",
|
||||
rz_il_op_pure_code_stringify(op->code), ssx, ssy);
|
||||
|
||||
free(ssx);
|
||||
free(ssy);
|
||||
return false;
|
||||
}
|
||||
VALIDATOR_ASSERT(sx.props.f.format == sy.props.f.format, "Op %s formats of left operand (%s) and right operand (%s) do not agree.\n",
|
||||
rz_il_op_pure_code_stringify(op->code),
|
||||
rz_il_sort_pure_stringify(sx),
|
||||
rz_il_sort_pure_stringify(sy));
|
||||
|
||||
*sort_out = sx;
|
||||
return true;
|
||||
|
|
@ -681,22 +663,12 @@ VALIDATOR_PURE(float_terop_with_round) {
|
|||
VALIDATOR_DESCEND(args->z, &sz);
|
||||
VALIDATOR_ASSERT(sz.type == RZ_IL_TYPE_PURE_FLOAT, "3rd operand of %s op is not a float.\n", rz_il_op_pure_code_stringify(op->code));
|
||||
|
||||
if (!((sx.props.f.format == sy.props.f.format) &&
|
||||
(sx.props.f.format == sz.props.f.format))) {
|
||||
char *ssx = rz_il_sort_pure_stringify(sx);
|
||||
char *ssy = rz_il_sort_pure_stringify(sy);
|
||||
char *ssz = rz_il_sort_pure_stringify(sz);
|
||||
|
||||
rz_strbuf_appendf(report_builder,
|
||||
"types of operand in op %s do not agree: operand1 (%s) operand2 (%s) operand3 (%s)",
|
||||
rz_il_op_pure_code_stringify(op->code),
|
||||
ssx, ssy, ssz);
|
||||
|
||||
free(ssx);
|
||||
free(ssy);
|
||||
free(ssz);
|
||||
return false;
|
||||
}
|
||||
VALIDATOR_ASSERT((sx.props.f.format == sy.props.f.format) && (sx.props.f.format == sz.props.f.format),
|
||||
"types of operand in op %s do not agree: operand1 (%s) operand2 (%s) operand3 (%s)",
|
||||
rz_il_op_pure_code_stringify(op->code),
|
||||
rz_il_sort_pure_stringify(sx),
|
||||
rz_il_sort_pure_stringify(sy),
|
||||
rz_il_sort_pure_stringify(sz));
|
||||
|
||||
*sort_out = sx;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@
|
|||
#define FORDER(flx, fly) rz_il_op_new_forder(flx, fly)
|
||||
#define FROUND(rmode, fl) rz_il_op_new_fround(rmode, fl)
|
||||
#define FSQRT(rmode, fl) rz_il_op_new_fsqrt(rmode, fl)
|
||||
#define FRSQRT(rmode, fl) rz_il_op_new_frsqrt(rmode, fl)
|
||||
#define FADD(rmode, flx, fly) rz_il_op_new_fadd(rmode, flx, fly)
|
||||
#define FSUB(rmode, flx, fly) rz_il_op_new_fsub(rmode, flx, fly)
|
||||
#define FMUL(rmode, flx, fly) rz_il_op_new_fmul(rmode, flx, fly)
|
||||
|
|
@ -89,6 +90,9 @@
|
|||
#define FPOW(rmode, flx, fly) rz_il_op_new_fpow(rmode, flx, fly)
|
||||
#define FMAD(rmode, flx, fly, flz) rz_il_op_new_fmad(rmode, flx, fly, flz)
|
||||
|
||||
#define IL_FQNAN(f) rz_il_op_new_float_from_rz_float(rz_float_new_qnan(f))
|
||||
#define IL_FSNAN(f) rz_il_op_new_float_from_rz_float(rz_float_new_snan(f))
|
||||
|
||||
// TODO: add `feq` as prime operator in fbasic
|
||||
// https://smtlib.cs.uiowa.edu/theories-FloatingPoint.shtml
|
||||
|
||||
|
|
@ -99,12 +103,12 @@
|
|||
#define AND(x, y) rz_il_op_new_bool_and(x, y)
|
||||
#define OR(x, y) rz_il_op_new_bool_or(x, y)
|
||||
|
||||
#define FNEQ(flx, fly) rz_il_op_new_fneq(flx, fly)
|
||||
#define FEQ(flx, fly) rz_il_op_new_feq(flx, fly)
|
||||
#define FLT(flx, fly) rz_il_op_new_flt(flx, fly)
|
||||
#define FLE(flx, fly) rz_il_op_new_fle(flx, fly)
|
||||
#define FGT(flx, fly) rz_il_op_new_fgt(flx, fly)
|
||||
#define FGE(flx, fly) rz_il_op_new_fge(flx, fly)
|
||||
#define FNE(flx, fly) rz_il_op_new_fneq(flx, fly)
|
||||
#define FEQ(flx, fly) rz_il_op_new_feq(flx, fly)
|
||||
#define FLT(flx, fly) rz_il_op_new_flt(flx, fly)
|
||||
#define FLE(flx, fly) rz_il_op_new_fle(flx, fly)
|
||||
#define FGT(flx, fly) rz_il_op_new_fgt(flx, fly)
|
||||
#define FGE(flx, fly) rz_il_op_new_fge(flx, fly)
|
||||
|
||||
#define UNSIGNED(n, x) rz_il_op_new_unsigned(n, x)
|
||||
#define SIGNED(n, x) rz_il_op_new_signed(n, x)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
#undef FMOD
|
||||
#undef FPOW
|
||||
#undef FMAD
|
||||
#undef FNEQ
|
||||
#undef FNE
|
||||
#undef FEQ
|
||||
#undef FLT
|
||||
#undef FLE
|
||||
|
|
|
|||
|
|
@ -733,6 +733,7 @@ RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_append(RZ_NONNULL RzILOpBitVector *h
|
|||
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_load(RzILMemIndex mem, RZ_NONNULL RzILOpBitVector *key);
|
||||
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_loadw(RzILMemIndex mem, RZ_NONNULL RzILOpBitVector *key, ut32 n_bits);
|
||||
|
||||
RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_float_from_rz_float(RZ_NONNULL RZ_OWN RzFloat *fl);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -276,6 +276,11 @@ drx FPU_TRAP_OPC .32 812 0
|
|||
drx FPU_TRAP_SRC1 .32 816 0
|
||||
drx FPU_TRAP_SRC2 .32 820 0
|
||||
drx FPU_TRAP_SRC3 .32 824 0
|
||||
drx set_FI .1 900 0
|
||||
drx set_FV .1 901 0
|
||||
drx set_FZ .1 902 0
|
||||
drx set_FU .1 903 0
|
||||
drx set_FX .1 904 0
|
||||
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
2984
test/db/asm/tricore
2984
test/db/asm/tricore
File diff suppressed because one or more lines are too long
|
|
@ -15,3 +15,33 @@ FCX = 0x1
|
|||
Hello from RzIL!
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=Testing the decryption in emulateme
|
||||
FILE=bins/tricore/emulateme-fp.tricore.elf
|
||||
TIMEOUT=30
|
||||
CMDS=<<EOF
|
||||
e io.cache=1
|
||||
aezi
|
||||
aezsu 0x80000450 # add.f
|
||||
ar d2
|
||||
aezsu 0x80000460 # sub.f
|
||||
ar d2
|
||||
aezsu 0x80000470 # mul.f
|
||||
ar d2
|
||||
aezsu 0x80000480 # div.f
|
||||
ar d2
|
||||
aezsu 0x80000498 # madd.f
|
||||
ar d2
|
||||
aezsu 0x800004b0 # msub.f
|
||||
ar d2
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
d2 = 0x47157f3b
|
||||
d2 = 0x47157f3b
|
||||
d2 = 0x47157f3b
|
||||
d2 = 0x47157f3b
|
||||
d2 = 0x47e03ed8
|
||||
d2 = 0x489d1884
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue