summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_parametric.c
blob: df0b23a7acb1a298f9df6fbf412aef206df4ff06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright (C) 2019 Intel Corporation. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 */

#include "jit_emit_parametric.h"
#include "../jit_frontend.h"

static bool
pop_value_from_wasm_stack(JitCompContext *cc, bool is_32bit, JitReg *p_value,
                          uint8 *p_type)
{
    JitValue *jit_value;
    JitReg value;
    uint8 type;

    if (!jit_block_stack_top(&cc->block_stack)) {
        jit_set_last_error(cc, "WASM block stack underflow.");
        return false;
    }
    if (!jit_block_stack_top(&cc->block_stack)->value_stack.value_list_end) {
        jit_set_last_error(cc, "WASM data stack underflow.");
        return false;
    }

    jit_value = jit_value_stack_pop(
        &jit_block_stack_top(&cc->block_stack)->value_stack);
    type = jit_value->type;

    if (p_type != NULL) {
        *p_type = jit_value->type;
    }

    wasm_runtime_free(jit_value);

    /* is_32: i32, f32, ref.func, ref.extern, v128 */
    if (is_32bit
        && !(type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
#if WASM_ENABLE_REF_TYPES != 0
             || type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
#endif
             || type == VALUE_TYPE_V128)) {
        jit_set_last_error(cc, "invalid WASM stack data type.");
        return false;
    }
    /* !is_32: i64, f64 */
    if (!is_32bit && !(type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)) {
        jit_set_last_error(cc, "invalid WASM stack data type.");
        return false;
    }

    switch (type) {
        case VALUE_TYPE_I32:
#if WASM_ENABLE_REF_TYPES != 0
        case VALUE_TYPE_FUNCREF:
        case VALUE_TYPE_EXTERNREF:
#endif
            value = pop_i32(cc->jit_frame);
            break;
        case VALUE_TYPE_I64:
            value = pop_i64(cc->jit_frame);
            break;
        case VALUE_TYPE_F32:
            value = pop_f32(cc->jit_frame);
            break;
        case VALUE_TYPE_F64:
            value = pop_f64(cc->jit_frame);
            break;
        default:
            bh_assert(0);
            return false;
    }

    if (p_value != NULL) {
        *p_value = value;
    }
    return true;
}

bool
jit_compile_op_drop(JitCompContext *cc, bool is_drop_32)
{
    if (!pop_value_from_wasm_stack(cc, is_drop_32, NULL, NULL))
        return false;
    return true;
}

bool
jit_compile_op_select(JitCompContext *cc, bool is_select_32)
{
    JitReg val1, val2, cond, selected;
    uint8 val1_type, val2_type;

    POP_I32(cond);

    if (!pop_value_from_wasm_stack(cc, is_select_32, &val2, &val2_type)
        || !pop_value_from_wasm_stack(cc, is_select_32, &val1, &val1_type)) {
        return false;
    }

    if (val1_type != val2_type) {
        jit_set_last_error(cc, "invalid stack values with different type");
        return false;
    }

    switch (val1_type) {
        case VALUE_TYPE_I32:
            selected = jit_cc_new_reg_I32(cc);
            break;
        case VALUE_TYPE_I64:
            selected = jit_cc_new_reg_I64(cc);
            break;
        case VALUE_TYPE_F32:
            selected = jit_cc_new_reg_F32(cc);
            break;
        case VALUE_TYPE_F64:
            selected = jit_cc_new_reg_F64(cc);
            break;
        default:
            bh_assert(0);
            return false;
    }

    GEN_INSN(CMP, cc->cmp_reg, cond, NEW_CONST(I32, 0));
    GEN_INSN(SELECTNE, selected, cc->cmp_reg, val1, val2);
    PUSH(selected, val1_type);
    return true;
fail:
    return false;
}