summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_conversion.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_conversion.c')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_conversion.c660
1 files changed, 660 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_conversion.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_conversion.c
new file mode 100644
index 000000000..8308a3ca9
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_conversion.c
@@ -0,0 +1,660 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "jit_emit_conversion.h"
+#include "jit_emit_exception.h"
+#include "jit_emit_function.h"
+#include "../jit_codegen.h"
+#include "../jit_frontend.h"
+
+#define F32_I32_S_MIN (-2147483904.0f)
+#define F32_I32_S_MAX (2147483648.0f)
+#define F32_I32_U_MIN (-1.0f)
+#define F32_I32_U_MAX (4294967296.0f)
+#define F32_I64_S_MIN (-9223373136366403584.0f)
+#define F32_I64_S_MAX (9223372036854775808.0f)
+#define F32_I64_U_MIN (-1.0f)
+#define F32_I64_U_MAX (18446744073709551616.0f)
+
+#define F64_I32_S_MIN (-2147483649.0)
+#define F64_I32_S_MAX (2147483648.0)
+#define F64_I32_U_MIN (-1.0)
+#define F64_I32_U_MAX (4294967296.0)
+#define F64_I64_S_MIN (-9223372036854777856.0)
+#define F64_I64_S_MAX (9223372036854775808.0)
+#define F64_I64_U_MIN (-1.0)
+#define F64_I64_U_MAX (18446744073709551616.0)
+
+#define FP_TO_INT(f_ty, i_ty, f_nm, i_nm) \
+ static i_ty i_nm##_trunc_##f_nm(f_ty fp)
+
+#define INT_TO_FP(i_ty, f_ty, i_nm, f_nm) \
+ static f_ty f_nm##_convert_##i_nm(i_ty i)
+
+#define FP_TO_INT_SAT(f_ty, i_ty, f_nm, i_nm) \
+ static i_ty i_nm##_trunc_##f_nm##_sat(f_ty fp)
+
+static int
+local_isnan(double x)
+{
+ return isnan(x);
+}
+
+static int
+local_isnanf(float x)
+{
+ return isnan(x);
+}
+
+#define RETURN_IF_NANF(fp) \
+ if (local_isnanf(fp)) { \
+ return 0; \
+ }
+
+#define RETURN_IF_NAN(fp) \
+ if (local_isnan(fp)) { \
+ return 0; \
+ }
+
+#define RETURN_IF_INF(fp, i_min, i_max) \
+ if (isinf(fp)) { \
+ return fp < 0 ? i_min : i_max; \
+ }
+
+#define RETURN_IF_MIN(fp, f_min, i_min) \
+ if (fp <= f_min) { \
+ return i_min; \
+ }
+
+#define RETURN_IF_MAX(fp, f_max, i_max) \
+ if (fp >= f_max) { \
+ return i_max; \
+ }
+
+FP_TO_INT_SAT(float, int32, f32, i32)
+{
+ RETURN_IF_NANF(fp)
+ RETURN_IF_INF(fp, INT32_MIN, INT32_MAX)
+ RETURN_IF_MIN(fp, F32_I32_S_MIN, INT32_MIN)
+ RETURN_IF_MAX(fp, F32_I32_S_MAX, INT32_MAX)
+ return (int32)fp;
+}
+
+FP_TO_INT_SAT(float, uint32, f32, u32)
+{
+ RETURN_IF_NANF(fp)
+ RETURN_IF_INF(fp, 0, UINT32_MAX)
+ RETURN_IF_MIN(fp, F32_I32_U_MIN, 0)
+ RETURN_IF_MAX(fp, F32_I32_U_MAX, UINT32_MAX)
+ return (uint32)fp;
+}
+
+FP_TO_INT_SAT(double, int32, f64, i32)
+{
+ RETURN_IF_NAN(fp)
+ RETURN_IF_INF(fp, INT32_MIN, INT32_MAX)
+ RETURN_IF_MIN(fp, F64_I32_S_MIN, INT32_MIN)
+ RETURN_IF_MAX(fp, F64_I32_S_MAX, INT32_MAX)
+ return (int32)fp;
+}
+
+FP_TO_INT_SAT(double, uint32, f64, u32)
+{
+ RETURN_IF_NAN(fp)
+ RETURN_IF_INF(fp, 0, UINT32_MAX)
+ RETURN_IF_MIN(fp, F64_I32_U_MIN, 0)
+ RETURN_IF_MAX(fp, F64_I32_U_MAX, UINT32_MAX)
+ return (uint32)fp;
+}
+
+FP_TO_INT_SAT(float, int64, f32, i64)
+{
+ RETURN_IF_NANF(fp)
+ RETURN_IF_INF(fp, INT64_MIN, INT64_MAX)
+ RETURN_IF_MIN(fp, F32_I64_S_MIN, INT64_MIN)
+ RETURN_IF_MAX(fp, F32_I64_S_MAX, INT64_MAX)
+ return (int64)fp;
+}
+
+FP_TO_INT(float, uint64, f32, u64)
+{
+ return (uint64)fp;
+}
+
+FP_TO_INT_SAT(float, uint64, f32, u64)
+{
+ RETURN_IF_NANF(fp)
+ RETURN_IF_INF(fp, 0, UINT64_MAX)
+ RETURN_IF_MIN(fp, F32_I64_U_MIN, 0)
+ RETURN_IF_MAX(fp, F32_I64_U_MAX, UINT64_MAX)
+ return (uint64)fp;
+}
+
+FP_TO_INT_SAT(double, int64, f64, i64)
+{
+ RETURN_IF_NANF(fp)
+ RETURN_IF_INF(fp, INT64_MIN, INT64_MAX)
+ RETURN_IF_MIN(fp, F64_I64_S_MIN, INT64_MIN)
+ RETURN_IF_MAX(fp, F64_I64_S_MAX, INT64_MAX)
+ return (int64)fp;
+}
+
+FP_TO_INT(double, uint64, f64, u64)
+{
+ return (uint64)fp;
+}
+
+FP_TO_INT_SAT(double, uint64, f64, u64)
+{
+ RETURN_IF_NANF(fp)
+ RETURN_IF_INF(fp, 0, UINT64_MAX)
+ RETURN_IF_MIN(fp, F64_I64_U_MIN, 0)
+ RETURN_IF_MAX(fp, F64_I64_U_MAX, UINT64_MAX)
+ return (uint64)fp;
+}
+
+INT_TO_FP(uint64, float, u64, f32)
+{
+ return (float)i;
+}
+
+INT_TO_FP(uint64, double, u64, f64)
+{
+ return (double)i;
+}
+
+bool
+jit_compile_op_i32_wrap_i64(JitCompContext *cc)
+{
+ JitReg num, res;
+
+ POP_I64(num);
+
+ res = jit_cc_new_reg_I32(cc);
+ GEN_INSN(I64TOI32, res, num);
+
+ PUSH_I32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+static bool
+jit_compile_check_value_range(JitCompContext *cc, JitReg value, JitReg min_fp,
+ JitReg max_fp)
+{
+ JitReg nan_ret = jit_cc_new_reg_I32(cc);
+ JitRegKind kind = jit_reg_kind(value);
+ bool emit_ret = false;
+
+ bh_assert(JIT_REG_KIND_F32 == kind || JIT_REG_KIND_F64 == kind);
+
+ /* If value is NaN, throw exception */
+ if (JIT_REG_KIND_F32 == kind)
+ emit_ret = jit_emit_callnative(cc, local_isnanf, nan_ret, &value, 1);
+ else
+ emit_ret = jit_emit_callnative(cc, local_isnan, nan_ret, &value, 1);
+ if (!emit_ret)
+ goto fail;
+
+ GEN_INSN(CMP, cc->cmp_reg, nan_ret, NEW_CONST(I32, 1));
+ if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER, JIT_OP_BEQ,
+ cc->cmp_reg, NULL))
+ goto fail;
+
+ /* If value is out of integer range, throw exception */
+ GEN_INSN(CMP, cc->cmp_reg, min_fp, value);
+ if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BGES, cc->cmp_reg,
+ NULL))
+ goto fail;
+
+ GEN_INSN(CMP, cc->cmp_reg, value, max_fp);
+ if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BGES, cc->cmp_reg,
+ NULL))
+ goto fail;
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i32_trunc_f32(JitCompContext *cc, bool sign, bool sat)
+{
+ JitReg value, res;
+
+ POP_F32(value);
+
+ res = jit_cc_new_reg_I32(cc);
+ if (!sat) {
+ JitReg min_fp = NEW_CONST(F32, sign ? F32_I32_S_MIN : F32_I32_U_MIN);
+ JitReg max_fp = NEW_CONST(F32, sign ? F32_I32_S_MAX : F32_I32_U_MAX);
+
+ if (!jit_compile_check_value_range(cc, value, min_fp, max_fp))
+ goto fail;
+
+ if (sign)
+ GEN_INSN(F32TOI32, res, value);
+ else
+ GEN_INSN(F32TOU32, res, value);
+ }
+ else {
+ if (!jit_emit_callnative(cc,
+ sign ? (void *)i32_trunc_f32_sat
+ : (void *)u32_trunc_f32_sat,
+ res, &value, 1))
+ goto fail;
+ }
+
+ PUSH_I32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i32_trunc_f64(JitCompContext *cc, bool sign, bool sat)
+{
+ JitReg value, res;
+
+ POP_F64(value);
+
+ res = jit_cc_new_reg_I32(cc);
+ if (!sat) {
+ JitReg min_fp = NEW_CONST(F64, sign ? F64_I32_S_MIN : F64_I32_U_MIN);
+ JitReg max_fp = NEW_CONST(F64, sign ? F64_I32_S_MAX : F64_I32_U_MAX);
+
+ if (!jit_compile_check_value_range(cc, value, min_fp, max_fp))
+ goto fail;
+
+ if (sign)
+ GEN_INSN(F64TOI32, res, value);
+ else
+ GEN_INSN(F64TOU32, res, value);
+ }
+ else {
+ if (!jit_emit_callnative(cc,
+ sign ? (void *)i32_trunc_f64_sat
+ : (void *)u32_trunc_f64_sat,
+ res, &value, 1))
+ goto fail;
+ }
+
+ PUSH_I32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i64_extend_i32(JitCompContext *cc, bool sign)
+{
+ JitReg num, res;
+
+ POP_I32(num);
+
+ res = jit_cc_new_reg_I64(cc);
+ if (sign)
+ GEN_INSN(I32TOI64, res, num);
+ else
+ GEN_INSN(U32TOI64, res, num);
+
+ PUSH_I64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i64_extend_i64(JitCompContext *cc, int8 bitwidth)
+{
+ JitReg value, tmp, res;
+
+ POP_I64(value);
+
+ tmp = jit_cc_new_reg_I32(cc);
+ res = jit_cc_new_reg_I64(cc);
+
+ switch (bitwidth) {
+ case 8:
+ {
+ GEN_INSN(I64TOI8, tmp, value);
+ GEN_INSN(I8TOI64, res, tmp);
+ break;
+ }
+ case 16:
+ {
+ GEN_INSN(I64TOI16, tmp, value);
+ GEN_INSN(I16TOI64, res, tmp);
+ break;
+ }
+ case 32:
+ {
+ GEN_INSN(I64TOI32, tmp, value);
+ GEN_INSN(I32TOI64, res, tmp);
+ break;
+ }
+ default:
+ {
+ bh_assert(0);
+ goto fail;
+ }
+ }
+
+ PUSH_I64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i32_extend_i32(JitCompContext *cc, int8 bitwidth)
+{
+ JitReg value, tmp, res;
+
+ POP_I32(value);
+
+ tmp = jit_cc_new_reg_I32(cc);
+ res = jit_cc_new_reg_I32(cc);
+
+ switch (bitwidth) {
+ case 8:
+ {
+ GEN_INSN(I32TOI8, tmp, value);
+ GEN_INSN(I8TOI32, res, tmp);
+ break;
+ }
+ case 16:
+ {
+ GEN_INSN(I32TOI16, tmp, value);
+ GEN_INSN(I16TOI32, res, tmp);
+ break;
+ }
+ default:
+ {
+ bh_assert(0);
+ goto fail;
+ }
+ }
+
+ PUSH_I32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i64_trunc_f32(JitCompContext *cc, bool sign, bool sat)
+{
+ JitReg value, res;
+
+ POP_F32(value);
+
+ res = jit_cc_new_reg_I64(cc);
+ if (!sat) {
+ JitReg min_fp = NEW_CONST(F32, sign ? F32_I64_S_MIN : F32_I64_U_MIN);
+ JitReg max_fp = NEW_CONST(F32, sign ? F32_I64_S_MAX : F32_I64_U_MAX);
+
+ if (!jit_compile_check_value_range(cc, value, min_fp, max_fp))
+ goto fail;
+
+ if (sign) {
+ GEN_INSN(F32TOI64, res, value);
+ }
+ else {
+ if (!jit_emit_callnative(cc, u64_trunc_f32, res, &value, 1))
+ goto fail;
+ }
+ }
+ else {
+ if (!jit_emit_callnative(cc,
+ sign ? (void *)i64_trunc_f32_sat
+ : (void *)u64_trunc_f32_sat,
+ res, &value, 1))
+ goto fail;
+ }
+
+ PUSH_I64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i64_trunc_f64(JitCompContext *cc, bool sign, bool sat)
+{
+ JitReg value, res;
+
+ POP_F64(value);
+
+ res = jit_cc_new_reg_I64(cc);
+ if (!sat) {
+ JitReg min_fp = NEW_CONST(F64, sign ? F64_I64_S_MIN : F64_I64_U_MIN);
+ JitReg max_fp = NEW_CONST(F64, sign ? F64_I64_S_MAX : F64_I64_U_MAX);
+
+ if (!jit_compile_check_value_range(cc, value, min_fp, max_fp))
+ goto fail;
+
+ if (sign) {
+ GEN_INSN(F64TOI64, res, value);
+ }
+ else {
+ if (!jit_emit_callnative(cc, u64_trunc_f64, res, &value, 1))
+ goto fail;
+ }
+ }
+ else {
+ if (!jit_emit_callnative(cc,
+ sign ? (void *)i64_trunc_f64_sat
+ : (void *)u64_trunc_f64_sat,
+ res, &value, 1))
+ goto fail;
+ }
+
+ PUSH_I64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f32_convert_i32(JitCompContext *cc, bool sign)
+{
+ JitReg value, res;
+
+ POP_I32(value);
+
+ res = jit_cc_new_reg_F32(cc);
+ if (sign) {
+ GEN_INSN(I32TOF32, res, value);
+ }
+ else {
+ GEN_INSN(U32TOF32, res, value);
+ }
+
+ PUSH_F32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f32_convert_i64(JitCompContext *cc, bool sign)
+{
+ JitReg value, res;
+
+ POP_I64(value);
+
+ res = jit_cc_new_reg_F32(cc);
+ if (sign) {
+ GEN_INSN(I64TOF32, res, value);
+ }
+ else {
+ if (!jit_emit_callnative(cc, f32_convert_u64, res, &value, 1)) {
+ goto fail;
+ }
+ }
+
+ PUSH_F32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f32_demote_f64(JitCompContext *cc)
+{
+ JitReg value, res;
+
+ POP_F64(value);
+
+ res = jit_cc_new_reg_F32(cc);
+ GEN_INSN(F64TOF32, res, value);
+
+ PUSH_F32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f64_convert_i32(JitCompContext *cc, bool sign)
+{
+ JitReg value, res;
+
+ POP_I32(value);
+
+ res = jit_cc_new_reg_F64(cc);
+ if (sign)
+ GEN_INSN(I32TOF64, res, value);
+ else
+ GEN_INSN(U32TOF64, res, value);
+
+ PUSH_F64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f64_convert_i64(JitCompContext *cc, bool sign)
+{
+ JitReg value, res;
+
+ POP_I64(value);
+
+ res = jit_cc_new_reg_F64(cc);
+ if (sign) {
+ GEN_INSN(I64TOF64, res, value);
+ }
+ else {
+ if (!jit_emit_callnative(cc, f64_convert_u64, res, &value, 1)) {
+ goto fail;
+ }
+ }
+
+ PUSH_F64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f64_promote_f32(JitCompContext *cc)
+{
+ JitReg value, res;
+
+ POP_F32(value);
+
+ res = jit_cc_new_reg_F64(cc);
+ GEN_INSN(F32TOF64, res, value);
+
+ PUSH_F64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i64_reinterpret_f64(JitCompContext *cc)
+{
+ JitReg value, res;
+
+ POP_F64(value);
+
+ res = jit_cc_new_reg_I64(cc);
+ GEN_INSN(F64CASTI64, res, value);
+
+ PUSH_I64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i32_reinterpret_f32(JitCompContext *cc)
+{
+ JitReg value, res;
+
+ POP_F32(value);
+
+ res = jit_cc_new_reg_I32(cc);
+ GEN_INSN(F32CASTI32, res, value);
+
+ PUSH_I32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f64_reinterpret_i64(JitCompContext *cc)
+{
+ JitReg value, res;
+
+ POP_I64(value);
+
+ res = jit_cc_new_reg_F64(cc);
+ GEN_INSN(I64CASTF64, res, value);
+
+ PUSH_F64(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f32_reinterpret_i32(JitCompContext *cc)
+{
+ JitReg value, res;
+
+ POP_I32(value);
+
+ res = jit_cc_new_reg_F32(cc);
+ GEN_INSN(I32CASTF32, res, value);
+
+ PUSH_F32(res);
+
+ return true;
+fail:
+ return false;
+}