summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_compare.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_compare.c')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_compare.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_compare.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_compare.c
new file mode 100644
index 000000000..d41249346
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_compare.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "jit_emit_compare.h"
+#include "jit_emit_function.h"
+#include "../jit_frontend.h"
+#include "../jit_codegen.h"
+
+static bool
+jit_compile_op_compare_integer(JitCompContext *cc, IntCond cond, bool is64Bit)
+{
+ JitReg lhs, rhs, res, const_zero, const_one;
+
+ if (cond < INT_EQZ || cond > INT_GE_U) {
+ jit_set_last_error(cc, "unsupported comparation operation");
+ goto fail;
+ }
+
+ res = jit_cc_new_reg_I32(cc);
+ const_zero = NEW_CONST(I32, 0);
+ const_one = NEW_CONST(I32, 1);
+
+ if (is64Bit) {
+ if (INT_EQZ == cond) {
+ rhs = NEW_CONST(I64, 0);
+ }
+ else {
+ POP_I64(rhs);
+ }
+ POP_I64(lhs);
+ }
+ else {
+ if (INT_EQZ == cond) {
+ rhs = NEW_CONST(I32, 0);
+ }
+ else {
+ POP_I32(rhs);
+ }
+ POP_I32(lhs);
+ }
+
+ GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
+ switch (cond) {
+ case INT_EQ:
+ case INT_EQZ:
+ {
+ GEN_INSN(SELECTEQ, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_NE:
+ {
+ GEN_INSN(SELECTNE, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_LT_S:
+ {
+ GEN_INSN(SELECTLTS, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_LT_U:
+ {
+ GEN_INSN(SELECTLTU, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_GT_S:
+ {
+ GEN_INSN(SELECTGTS, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_GT_U:
+ {
+ GEN_INSN(SELECTGTU, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_LE_S:
+ {
+ GEN_INSN(SELECTLES, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_LE_U:
+ {
+ GEN_INSN(SELECTLEU, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case INT_GE_S:
+ {
+ GEN_INSN(SELECTGES, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ default: /* INT_GE_U */
+ {
+ GEN_INSN(SELECTGEU, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ }
+
+ PUSH_I32(res);
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_i32_compare(JitCompContext *cc, IntCond cond)
+{
+ return jit_compile_op_compare_integer(cc, cond, false);
+}
+
+bool
+jit_compile_op_i64_compare(JitCompContext *cc, IntCond cond)
+{
+ return jit_compile_op_compare_integer(cc, cond, true);
+}
+
+static int32
+float_cmp_eq(float f1, float f2)
+{
+ if (isnan(f1) || isnan(f2))
+ return 0;
+
+ return f1 == f2;
+}
+
+static int32
+float_cmp_ne(float f1, float f2)
+{
+ if (isnan(f1) || isnan(f2))
+ return 1;
+
+ return f1 != f2;
+}
+
+static int32
+double_cmp_eq(double d1, double d2)
+{
+ if (isnan(d1) || isnan(d2))
+ return 0;
+
+ return d1 == d2;
+}
+
+static int32
+double_cmp_ne(double d1, double d2)
+{
+ if (isnan(d1) || isnan(d2))
+ return 1;
+
+ return d1 != d2;
+}
+
+static bool
+jit_compile_op_compare_float_point(JitCompContext *cc, FloatCond cond,
+ JitReg lhs, JitReg rhs)
+{
+ JitReg res, args[2], const_zero, const_one;
+ JitRegKind kind;
+ void *func;
+
+ if (cond == FLOAT_EQ || cond == FLOAT_NE) {
+ kind = jit_reg_kind(lhs);
+ if (cond == FLOAT_EQ)
+ func = (kind == JIT_REG_KIND_F32) ? (void *)float_cmp_eq
+ : (void *)double_cmp_eq;
+ else
+ func = (kind == JIT_REG_KIND_F32) ? (void *)float_cmp_ne
+ : (void *)double_cmp_ne;
+
+ res = jit_cc_new_reg_I32(cc);
+ args[0] = lhs;
+ args[1] = rhs;
+
+ if (!jit_emit_callnative(cc, func, res, args, 2)) {
+ goto fail;
+ }
+ }
+ else {
+ res = jit_cc_new_reg_I32(cc);
+ const_zero = NEW_CONST(I32, 0);
+ const_one = NEW_CONST(I32, 1);
+ switch (cond) {
+ case FLOAT_LT:
+ {
+ GEN_INSN(CMP, cc->cmp_reg, rhs, lhs);
+ GEN_INSN(SELECTGTS, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case FLOAT_GT:
+ {
+ GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
+ GEN_INSN(SELECTGTS, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case FLOAT_LE:
+ {
+ GEN_INSN(CMP, cc->cmp_reg, rhs, lhs);
+ GEN_INSN(SELECTGES, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ case FLOAT_GE:
+ {
+ GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
+ GEN_INSN(SELECTGES, res, cc->cmp_reg, const_one, const_zero);
+ break;
+ }
+ default:
+ {
+ bh_assert(!"unknown FloatCond");
+ goto fail;
+ }
+ }
+ }
+ PUSH_I32(res);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond)
+{
+ JitReg res, const_zero, const_one;
+ JitReg lhs, rhs;
+
+ POP_F32(rhs);
+ POP_F32(lhs);
+
+ if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
+ float32 lvalue = jit_cc_get_const_F32(cc, lhs);
+ float32 rvalue = jit_cc_get_const_F32(cc, rhs);
+
+ const_zero = NEW_CONST(I32, 0);
+ const_one = NEW_CONST(I32, 1);
+
+ switch (cond) {
+ case FLOAT_EQ:
+ {
+ res = (lvalue == rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_NE:
+ {
+ res = (lvalue != rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_LT:
+ {
+ res = (lvalue < rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_GT:
+ {
+ res = (lvalue > rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_LE:
+ {
+ res = (lvalue <= rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_GE:
+ {
+ res = (lvalue >= rvalue) ? const_one : const_zero;
+ break;
+ }
+ default:
+ {
+ bh_assert(!"unknown FloatCond");
+ goto fail;
+ }
+ }
+
+ PUSH_I32(res);
+ return true;
+ }
+
+ return jit_compile_op_compare_float_point(cc, cond, lhs, rhs);
+fail:
+ return false;
+}
+
+bool
+jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond)
+{
+ JitReg res, const_zero, const_one;
+ JitReg lhs, rhs;
+
+ POP_F64(rhs);
+ POP_F64(lhs);
+
+ if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) {
+ float64 lvalue = jit_cc_get_const_F64(cc, lhs);
+ float64 rvalue = jit_cc_get_const_F64(cc, rhs);
+
+ const_zero = NEW_CONST(I32, 0);
+ const_one = NEW_CONST(I32, 1);
+
+ switch (cond) {
+ case FLOAT_EQ:
+ {
+ res = (lvalue == rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_NE:
+ {
+ res = (lvalue != rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_LT:
+ {
+ res = (lvalue < rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_GT:
+ {
+ res = (lvalue > rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_LE:
+ {
+ res = (lvalue <= rvalue) ? const_one : const_zero;
+ break;
+ }
+ case FLOAT_GE:
+ {
+ res = (lvalue >= rvalue) ? const_one : const_zero;
+ break;
+ }
+ default:
+ {
+ bh_assert(!"unknown FloatCond");
+ goto fail;
+ }
+ }
+
+ PUSH_I32(res);
+ return true;
+ }
+
+ return jit_compile_op_compare_float_point(cc, cond, lhs, rhs);
+fail:
+ return false;
+}