rizin/librz/il/theory_fbasic.c
Heersin 2b748567fa
Add fbasic theory to rzil using rz_util/float (#3184)
* Fbasic dev build test

* Add fbasic structure and enums

* Add fbasic op new

* Add fbasic op dup

* Add fbasic op free

* Add partial theory of float

* Add fbasic handlers to pure table default

* Add fbasic stringfy

* Add temporary float functions

* Add rz-float value and evaluation

* Add float json dump functions, todo add mode info in il_opdmp_* functions and compelete il_resolve_pure

* Complete fbasic il in il_export

* Fix detected error in compilation

* Add doxygen for il/definition/float

* Pack float_round function

* Add new version of rounding

* Add cast and convert, todo add 'float_get_sign' and 'float_get_no_bias_exp'

* Add comments and fix new version rounding

* Add util float functions

* Implement theory fbasic : cast, convert and round

* Remove bv_one warning

* Move basic functions into rz_util from definition/float

* Add two basic test cmp and extra format test

* Add test to fsucc, fpred and fneg

* Add round significant test case 1 and fix bug to pass it

* Test round significant and bug fixes

* Add 6 types test cases to round_and_pack function

* Finish round significant and round_pack test with bug fixes and signature changes

* Leave fround as unimplement now

* Pass all test to cast and convert

* Add SPDX header

* Add SPDX header

* Add round to integral float with test and bug fixes

* Add more tests to cast_sint and bug fixes

* Fix mem leak in cast_sfloat

* Replace the deprecated rounding method, fix bugs and pass tests

* Resolve some reviewed issues

* Fix most memleak and bug found

* Remove deprecated round_bv

* Remove unused functions to eliminate warnings

* Fix typo in comments

* Uncommented implmented operations

* Add test cases and bug fixes for fbasic theory in rzil

* Fix ret type of new_bitv_from_* from Bool to BitVector

* Add new float op from f32 and f64
2023-02-15 18:18:40 +08:00

415 lines
11 KiB
C

// SPDX-FileCopyrightText: 2023 heersin <teablearcher@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_il/rz_il_opcodes.h>
#include <rz_il/rz_il_vm.h>
void *rz_il_handler_float(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFloat op_f = op->op.float_;
RzBitVector *bv = rz_il_evaluate_bitv(vm, op_f.bv);
RzFloat *ret = rz_il_float_new(op_f.r, bv);
rz_bv_free(bv);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fbits(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFbits op_fbits = op->op.fbits;
RzFloat *f = rz_il_evaluate_float(vm, op_fbits.f);
RzBitVector *ret = rz_bv_dup(f->s);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BITVECTOR;
return ret;
}
void *rz_il_handler_is_finite(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsIsFinite is_finite = op->op.is_finite;
RzFloat *f = rz_il_evaluate_float(vm, is_finite.f);
RzILBool *ret = rz_il_bool_new(!rz_float_is_inf(f));
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_is_nan(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsIsNan is_nan = op->op.is_nan;
RzFloat *f = rz_il_evaluate_float(vm, is_nan.f);
RzILBool *ret = rz_il_bool_new(rz_float_is_nan(f));
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_is_inf(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsIsInf is_inf = op->op.is_inf;
RzFloat *f = rz_il_evaluate_float(vm, is_inf.f);
RzILBool *ret = rz_il_bool_new(rz_float_is_inf(f));
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_is_fzero(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsIsFzero is_fzero = op->op.is_fzero;
RzFloat *f = rz_il_evaluate_float(vm, is_fzero.f);
RzILBool *ret = rz_il_bool_new(rz_float_is_zero(f));
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_is_fneg(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsIsFneg is_fneg = op->op.is_fneg;
RzFloat *f = rz_il_evaluate_float(vm, is_fneg.f);
RzILBool *ret = rz_il_bool_new(rz_float_is_negative(f));
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_is_fpos(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsIsFpos is_fpos = op->op.is_fpos;
RzFloat *f = rz_il_evaluate_float(vm, is_fpos.f);
RzILBool *ret = rz_il_bool_new(!rz_float_is_negative(f));
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_fneg(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFneg fneg = op->op.fneg;
RzFloat *f = rz_il_evaluate_float(vm, fneg.f);
RzFloat *ret = rz_float_neg(f);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fabs(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFabs fabs = op->op.fabs;
RzFloat *f = rz_il_evaluate_float(vm, fabs.f);
RzFloat *ret = rz_float_abs(f);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fcast_int(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFCastint cast_int = op->op.fcast_int;
RzFloat *f = rz_il_evaluate_float(vm, cast_int.f);
ut32 length = cast_int.length;
RzFloatRMode mode = cast_int.mode;
RzBitVector *ret = rz_float_cast_int(f, length, mode);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BITVECTOR;
return ret;
}
void *rz_il_handler_fcast_sint(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFCastint cast_sint = op->op.fcast_sint;
RzFloat *f = rz_il_evaluate_float(vm, cast_sint.f);
ut32 length = cast_sint.length;
RzFloatRMode mode = cast_sint.mode;
RzBitVector *ret = rz_float_cast_sint(f, length, mode);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_BITVECTOR;
return ret;
}
void *rz_il_handler_fcast_float(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFCastfloat cast = op->op.fcast_float;
RzBitVector *bv = rz_il_evaluate_bitv(vm, cast.bv);
RzFloatFormat format = cast.format;
RzFloatRMode mode = cast.mode;
RzFloat *ret = rz_float_cast_float(bv, format, mode);
rz_bv_free(bv);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fcast_sfloat(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFCastsfloat cast = op->op.fcast_sfloat;
RzBitVector *bv = rz_il_evaluate_bitv(vm, cast.bv);
RzFloatFormat format = cast.format;
RzFloatRMode mode = cast.mode;
RzFloat *ret = rz_float_cast_sfloat(bv, format, mode);
rz_bv_free(bv);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fconvert(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFconvert convert = op->op.fconvert;
RzFloat *f = rz_il_evaluate_float(vm, convert.f);
RzFloatFormat format = convert.format;
RzFloatRMode mode = convert.mode;
RzFloat *ret = rz_float_convert(f, format, mode);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_frequal(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFrequal frequal = op->op.frequal;
RzILBool *ret = rz_il_bool_new(frequal.x == frequal.y);
*type = RZ_IL_TYPE_PURE_BOOL;
return ret;
}
void *rz_il_handler_fsucc(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFsucc fsucc = op->op.fsucc;
RzFloat *f = rz_il_evaluate_float(vm, fsucc.f);
RzFloat *ret = rz_float_succ(f);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fpred(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFpred fpred = op->op.fpred;
RzFloat *f = rz_il_evaluate_float(vm, fpred.f);
RzFloat *ret = rz_float_pred(f);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_forder(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsForder forder = op->op.forder;
RzFloat *x = rz_il_evaluate_float(vm, forder.x);
RzFloat *y = rz_il_evaluate_float(vm, forder.y);
RzILBool *order = rz_il_bool_new(rz_float_cmp(x, y) == -1);
rz_float_free(x);
rz_float_free(y);
*type = RZ_IL_TYPE_PURE_BOOL;
return order;
}
void *rz_il_handler_fround(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFround fround = op->op.fround;
RzFloat *f = rz_il_evaluate_float(vm, fround.f);
RzFloatRMode mode = fround.rmode;
RzFloat *ret = rz_float_round_to_integral(f, mode);
rz_float_free(f);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fsqrt(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFsqrt sqrt = op->op.fsqrt;
RzFloat *n = rz_il_evaluate_float(vm, sqrt.f);
RzFloatRMode mode = sqrt.rmode;
RzFloat *ret = rz_float_sqrt(n, mode);
rz_float_free(n);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_frsqrt(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
// TODO : float todo unimplemented
rz_return_val_if_fail(vm && op && type, NULL);
return NULL;
}
void *rz_il_handler_fadd(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFadd fadd = op->op.fadd;
RzFloat *x = rz_il_evaluate_float(vm, fadd.x);
RzFloat *y = rz_il_evaluate_float(vm, fadd.y);
RzFloatRMode mode = fadd.rmode;
RzFloat *ret = rz_float_add(x, y, mode);
rz_float_free(x);
rz_float_free(y);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fsub(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFsub fsub = op->op.fsub;
RzFloat *x = rz_il_evaluate_float(vm, fsub.x);
RzFloat *y = rz_il_evaluate_float(vm, fsub.y);
RzFloatRMode mode = fsub.rmode;
RzFloat *ret = rz_float_sub(x, y, mode);
rz_float_free(x);
rz_float_free(y);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fdiv(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFdiv fdiv = op->op.fdiv;
RzFloat *x = rz_il_evaluate_float(vm, fdiv.x);
RzFloat *y = rz_il_evaluate_float(vm, fdiv.y);
RzFloatRMode mode = fdiv.rmode;
RzFloat *ret = rz_float_div(x, y, mode);
rz_float_free(x);
rz_float_free(y);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fmul(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFmul fmul = op->op.fmul;
RzFloat *x = rz_il_evaluate_float(vm, fmul.x);
RzFloat *y = rz_il_evaluate_float(vm, fmul.y);
RzFloatRMode mode = fmul.rmode;
RzFloat *ret = rz_float_mul(x, y, mode);
rz_float_free(x);
rz_float_free(y);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fmod(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFmod fmod = op->op.fmod;
RzFloat *x = rz_il_evaluate_float(vm, fmod.x);
RzFloat *y = rz_il_evaluate_float(vm, fmod.y);
RzFloatRMode mode = fmod.rmode;
RzFloat *ret = rz_float_mod(x, y, mode);
rz_float_free(x);
rz_float_free(y);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_fhypot(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
// TODO : float todo unimplemented
rz_return_val_if_fail(vm && op && type, NULL);
return NULL;
}
void *rz_il_handler_fpow(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
// TODO : float todo unimplemented
rz_return_val_if_fail(vm && op && type, NULL);
return NULL;
}
void *rz_il_handler_fmad(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFmad fmad = op->op.fmad;
RzFloat *x = rz_il_evaluate_float(vm, fmad.x);
RzFloat *y = rz_il_evaluate_float(vm, fmad.y);
RzFloat *z = rz_il_evaluate_float(vm, fmad.z);
RzFloatRMode mode = fmad.rmode;
RzFloat *ret = rz_float_fma(x, y, z, mode);
rz_float_free(x);
rz_float_free(y);
rz_float_free(z);
*type = RZ_IL_TYPE_PURE_FLOAT;
return ret;
}
void *rz_il_handler_frootn(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
// TODO : float todo unimplemented
rz_return_val_if_fail(vm && op && type, NULL);
return NULL;
}
void *rz_il_handler_fpown(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
// TODO : float todo unimplemented
rz_return_val_if_fail(vm && op && type, NULL);
return NULL;
}
void *rz_il_handler_fcompound(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
// TODO : float todo unimplemented
rz_return_val_if_fail(vm && op && type, NULL);
return NULL;
}