summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_bool_reductions.c
blob: 4607d680aeddf5d9adce091babc28168c686543d (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
131
132
133
134
135
136
137
138
/*
 * Copyright (C) 2019 Intel Corporation. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 */

#include "simd_bool_reductions.h"
#include "simd_common.h"
#include "../aot_emit_exception.h"
#include "../../aot/aot_runtime.h"

enum integer_all_true {
    e_int_all_true_v16i8,
    e_int_all_true_v8i16,
    e_int_all_true_v4i32,
    e_int_all_true_v2i64,
};

static bool
simd_all_true(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
              enum integer_all_true itype)
{
    LLVMValueRef vector, result;
    LLVMTypeRef vector_i1_type;
    LLVMTypeRef vector_type[] = { V128_i8x16_TYPE, V128_i16x8_TYPE,
                                  V128_i32x4_TYPE, V128_i64x2_TYPE };
    uint32 lanes[] = { 16, 8, 4, 2 };
    const char *intrinsic[] = {
        "llvm.vector.reduce.and.v16i1",
        "llvm.vector.reduce.and.v8i1",
        "llvm.vector.reduce.and.v4i1",
        "llvm.vector.reduce.and.v2i1",
    };
    LLVMValueRef zero[] = {
        LLVM_CONST(i8x16_vec_zero),
        LLVM_CONST(i16x8_vec_zero),
        LLVM_CONST(i32x4_vec_zero),
        LLVM_CONST(i64x2_vec_zero),
    };

    if (!(vector_i1_type = LLVMVectorType(INT1_TYPE, lanes[itype]))) {
        HANDLE_FAILURE("LLVMVectorType");
        goto fail;
    }

    if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx,
                                             vector_type[itype], "vector"))) {
        goto fail;
    }

    /* compare with zero */
    if (!(result = LLVMBuildICmp(comp_ctx->builder, LLVMIntNE, vector,
                                 zero[itype], "ne_zero"))) {
        HANDLE_FAILURE("LLVMBuildICmp");
        goto fail;
    }

    /* check zero */
    if (!(result =
              aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic[itype],
                                      INT1_TYPE, &vector_i1_type, 1, result))) {
        goto fail;
    }

    if (!(result =
              LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
        HANDLE_FAILURE("LLVMBuildZExt");
        goto fail;
    }

    PUSH_I32(result);

    return true;
fail:
    return false;
}

bool
aot_compile_simd_i8x16_all_true(AOTCompContext *comp_ctx,
                                AOTFuncContext *func_ctx)
{
    return simd_all_true(comp_ctx, func_ctx, e_int_all_true_v16i8);
}

bool
aot_compile_simd_i16x8_all_true(AOTCompContext *comp_ctx,
                                AOTFuncContext *func_ctx)
{
    return simd_all_true(comp_ctx, func_ctx, e_int_all_true_v8i16);
}

bool
aot_compile_simd_i32x4_all_true(AOTCompContext *comp_ctx,
                                AOTFuncContext *func_ctx)
{
    return simd_all_true(comp_ctx, func_ctx, e_int_all_true_v4i32);
}

bool
aot_compile_simd_i64x2_all_true(AOTCompContext *comp_ctx,
                                AOTFuncContext *func_ctx)
{
    return simd_all_true(comp_ctx, func_ctx, e_int_all_true_v2i64);
}

bool
aot_compile_simd_v128_any_true(AOTCompContext *comp_ctx,
                               AOTFuncContext *func_ctx)
{
    LLVMTypeRef vector_type;
    LLVMValueRef vector, result;

    if (!(vector_type = LLVMVectorType(INT1_TYPE, 128))) {
        return false;
    }

    if (!(vector = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
                                             "vector"))) {
        goto fail;
    }

    if (!(result = aot_call_llvm_intrinsic(
              comp_ctx, func_ctx, "llvm.vector.reduce.or.v128i1", INT1_TYPE,
              &vector_type, 1, vector))) {
        goto fail;
    }

    if (!(result =
              LLVMBuildZExt(comp_ctx->builder, result, I32_TYPE, "to_i32"))) {
        HANDLE_FAILURE("LLVMBuildZExt");
        goto fail;
    }

    PUSH_I32(result);

    return true;
fail:
    return false;
}