summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/aot_emit_compare.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/aot_emit_compare.c')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/aot_emit_compare.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/aot_emit_compare.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/aot_emit_compare.c
new file mode 100644
index 000000000..a38263264
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/aot_emit_compare.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "aot_emit_compare.h"
+#include "../aot/aot_intrinsic.h"
+
+static bool
+int_cond_to_llvm_op(IntCond cond, LLVMIntPredicate *op)
+{
+ if (cond < INT_EQZ || cond > INT_GE_U)
+ return false;
+
+ switch (cond) {
+ case INT_EQZ:
+ case INT_EQ:
+ *op = LLVMIntEQ;
+ break;
+ case INT_NE:
+ *op = LLVMIntNE;
+ break;
+ case INT_LT_S:
+ *op = LLVMIntSLT;
+ break;
+ case INT_LT_U:
+ *op = LLVMIntULT;
+ break;
+ case INT_GT_S:
+ *op = LLVMIntSGT;
+ break;
+ case INT_GT_U:
+ *op = LLVMIntUGT;
+ break;
+ case INT_LE_S:
+ *op = LLVMIntSLE;
+ break;
+ case INT_LE_U:
+ *op = LLVMIntULE;
+ break;
+ case INT_GE_S:
+ *op = LLVMIntSGE;
+ break;
+ case INT_GE_U:
+ *op = LLVMIntUGE;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+float_cond_to_llvm_op(FloatCond cond, LLVMRealPredicate *op)
+{
+ if (cond < FLOAT_EQ || cond > FLOAT_GE)
+ return false;
+
+ switch (cond) {
+ case FLOAT_EQ:
+ *op = LLVMRealOEQ;
+ break;
+ case FLOAT_NE:
+ *op = LLVMRealUNE;
+ break;
+ case FLOAT_LT:
+ *op = LLVMRealOLT;
+ break;
+ case FLOAT_GT:
+ *op = LLVMRealOGT;
+ break;
+ case FLOAT_LE:
+ *op = LLVMRealOLE;
+ break;
+ case FLOAT_GE:
+ *op = LLVMRealOGE;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool
+aot_compile_op_i32_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ IntCond cond)
+{
+ LLVMIntPredicate op;
+ LLVMValueRef lhs, rhs, res;
+
+ if (!int_cond_to_llvm_op(cond, &op)) {
+ aot_set_last_error("invalid WASM condition opcode");
+ return false;
+ }
+
+ if (cond == INT_EQZ)
+ rhs = I32_ZERO;
+ else
+ POP_I32(rhs);
+
+ POP_I32(lhs);
+
+ if (!(res = LLVMBuildICmp(comp_ctx->builder, op, lhs, rhs, "i32_cmp"))) {
+ aot_set_last_error("llvm build compare failed.");
+ return false;
+ }
+
+ PUSH_COND(res);
+ return true;
+fail:
+ return false;
+}
+
+bool
+aot_compile_op_i64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ IntCond cond)
+{
+ LLVMIntPredicate op;
+ LLVMValueRef lhs, rhs, res;
+
+ if (!int_cond_to_llvm_op(cond, &op)) {
+ aot_set_last_error("invalid WASM condition opcode");
+ return false;
+ }
+
+ if (cond == INT_EQZ)
+ rhs = I64_CONST(0);
+ else
+ POP_I64(rhs);
+
+ POP_I64(lhs);
+
+ if (!(res = LLVMBuildICmp(comp_ctx->builder, op, lhs, rhs, "i64_cmp"))) {
+ aot_set_last_error("llvm build compare failed.");
+ return false;
+ }
+
+ PUSH_COND(res);
+ return true;
+fail:
+ return false;
+}
+
+bool
+aot_compile_op_f32_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ FloatCond cond)
+{
+ LLVMRealPredicate op;
+ LLVMValueRef lhs, rhs, res;
+
+ if (!float_cond_to_llvm_op(cond, &op)) {
+ aot_set_last_error("invalid WASM condition opcode");
+ return false;
+ }
+
+ POP_F32(rhs);
+ POP_F32(lhs);
+
+ if (comp_ctx->disable_llvm_intrinsics
+ && aot_intrinsic_check_capability(comp_ctx, "f32_cmp")) {
+ LLVMTypeRef param_types[3];
+ LLVMValueRef opcond = LLVMConstInt(I32_TYPE, cond, true);
+ param_types[0] = I32_TYPE;
+ param_types[1] = F32_TYPE;
+ param_types[2] = F32_TYPE;
+ res = aot_call_llvm_intrinsic(comp_ctx, func_ctx, "f32_cmp", I32_TYPE,
+ param_types, 3, opcond, lhs, rhs);
+ if (!res) {
+ goto fail;
+ }
+ res = LLVMBuildIntCast(comp_ctx->builder, res, INT1_TYPE, "bit_cast");
+ }
+ else {
+ res = LLVMBuildFCmp(comp_ctx->builder, op, lhs, rhs, "f32_cmp");
+ }
+
+ if (!res) {
+ aot_set_last_error("llvm build compare failed.");
+ return false;
+ }
+
+ PUSH_COND(res);
+ return true;
+fail:
+ return false;
+}
+
+bool
+aot_compile_op_f64_compare(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ FloatCond cond)
+{
+ LLVMRealPredicate op;
+ LLVMValueRef lhs, rhs, res;
+
+ if (!float_cond_to_llvm_op(cond, &op)) {
+ aot_set_last_error("invalid WASM condition opcode");
+ return false;
+ }
+
+ POP_F64(rhs);
+ POP_F64(lhs);
+
+ if (comp_ctx->disable_llvm_intrinsics
+ && aot_intrinsic_check_capability(comp_ctx, "f64_cmp")) {
+ LLVMTypeRef param_types[3];
+ LLVMValueRef opcond = LLVMConstInt(I32_TYPE, cond, true);
+ param_types[0] = I32_TYPE;
+ param_types[1] = F64_TYPE;
+ param_types[2] = F64_TYPE;
+ res = aot_call_llvm_intrinsic(comp_ctx, func_ctx, "f64_cmp", I32_TYPE,
+ param_types, 3, opcond, lhs, rhs);
+ if (!res) {
+ goto fail;
+ }
+ res = LLVMBuildIntCast(comp_ctx->builder, res, INT1_TYPE, "bit_cast");
+ }
+ else {
+ res = LLVMBuildFCmp(comp_ctx->builder, op, lhs, rhs, "f64_cmp");
+ }
+
+ if (!res) {
+ aot_set_last_error("llvm build compare failed.");
+ return false;
+ }
+
+ PUSH_COND(res);
+ return true;
+fail:
+ return false;
+}