summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_load_store.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_load_store.c')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_load_store.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_load_store.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_load_store.c
new file mode 100644
index 000000000..d166e954c
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/compilation/simd/simd_load_store.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "simd_common.h"
+#include "simd_load_store.h"
+#include "../aot_emit_exception.h"
+#include "../aot_emit_memory.h"
+#include "../../aot/aot_runtime.h"
+#include "../../interpreter/wasm_opcode.h"
+
+/* data_length in bytes */
+static LLVMValueRef
+simd_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
+ uint32 offset, uint32 data_length, LLVMTypeRef ptr_type,
+ LLVMTypeRef data_type)
+{
+ LLVMValueRef maddr, data;
+
+ if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset,
+ data_length))) {
+ HANDLE_FAILURE("aot_check_memory_overflow");
+ return NULL;
+ }
+
+ if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr, ptr_type,
+ "data_ptr"))) {
+ HANDLE_FAILURE("LLVMBuildBitCast");
+ return NULL;
+ }
+
+ if (!(data = LLVMBuildLoad2(comp_ctx->builder, data_type, maddr, "data"))) {
+ HANDLE_FAILURE("LLVMBuildLoad");
+ return NULL;
+ }
+
+ LLVMSetAlignment(data, 1);
+
+ return data;
+}
+
+bool
+aot_compile_simd_v128_load(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint32 align, uint32 offset)
+{
+ LLVMValueRef result;
+
+ if (!(result = simd_load(comp_ctx, func_ctx, align, offset, 16,
+ V128_PTR_TYPE, V128_TYPE))) {
+ return false;
+ }
+
+ PUSH_V128(result);
+
+ return true;
+fail:
+ return false;
+}
+
+bool
+aot_compile_simd_load_extend(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint8 opcode, uint32 align, uint32 offset)
+{
+ LLVMValueRef sub_vector, result;
+ uint32 opcode_index = opcode - SIMD_v128_load8x8_s;
+ bool signeds[] = { true, false, true, false, true, false };
+ LLVMTypeRef vector_types[] = {
+ V128_i16x8_TYPE, V128_i16x8_TYPE, V128_i32x4_TYPE,
+ V128_i32x4_TYPE, V128_i64x2_TYPE, V128_i64x2_TYPE,
+ };
+ LLVMTypeRef sub_vector_types[] = {
+ LLVMVectorType(INT8_TYPE, 8), LLVMVectorType(INT8_TYPE, 8),
+ LLVMVectorType(INT16_TYPE, 4), LLVMVectorType(INT16_TYPE, 4),
+ LLVMVectorType(I32_TYPE, 2), LLVMVectorType(I32_TYPE, 2),
+ };
+ LLVMTypeRef sub_vector_type, sub_vector_ptr_type;
+
+ bh_assert(opcode_index < 6);
+
+ sub_vector_type = sub_vector_types[opcode_index];
+
+ /* to vector ptr type */
+ if (!sub_vector_type
+ || !(sub_vector_ptr_type = LLVMPointerType(sub_vector_type, 0))) {
+ HANDLE_FAILURE("LLVMPointerType");
+ return false;
+ }
+
+ if (!(sub_vector = simd_load(comp_ctx, func_ctx, align, offset, 8,
+ sub_vector_ptr_type, sub_vector_type))) {
+ return false;
+ }
+
+ if (signeds[opcode_index]) {
+ if (!(result = LLVMBuildSExt(comp_ctx->builder, sub_vector,
+ vector_types[opcode_index], "vector"))) {
+ HANDLE_FAILURE("LLVMBuildSExt");
+ return false;
+ }
+ }
+ else {
+ if (!(result = LLVMBuildZExt(comp_ctx->builder, sub_vector,
+ vector_types[opcode_index], "vector"))) {
+ HANDLE_FAILURE("LLVMBuildZExt");
+ return false;
+ }
+ }
+
+ return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
+}
+
+bool
+aot_compile_simd_load_splat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint8 opcode, uint32 align, uint32 offset)
+{
+ uint32 opcode_index = opcode - SIMD_v128_load8_splat;
+ LLVMValueRef element, result;
+ LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE,
+ INT32_PTR_TYPE, INT64_PTR_TYPE };
+ LLVMTypeRef element_data_types[] = { INT8_TYPE, INT16_TYPE, I32_TYPE,
+ I64_TYPE };
+ uint32 data_lengths[] = { 1, 2, 4, 8 };
+ LLVMValueRef undefs[] = {
+ LLVM_CONST(i8x16_undef),
+ LLVM_CONST(i16x8_undef),
+ LLVM_CONST(i32x4_undef),
+ LLVM_CONST(i64x2_undef),
+ };
+ LLVMValueRef masks[] = {
+ LLVM_CONST(i32x16_zero),
+ LLVM_CONST(i32x8_zero),
+ LLVM_CONST(i32x4_zero),
+ LLVM_CONST(i32x2_zero),
+ };
+
+ bh_assert(opcode_index < 4);
+
+ if (!(element = simd_load(comp_ctx, func_ctx, align, offset,
+ data_lengths[opcode_index],
+ element_ptr_types[opcode_index],
+ element_data_types[opcode_index]))) {
+ return false;
+ }
+
+ if (!(result =
+ LLVMBuildInsertElement(comp_ctx->builder, undefs[opcode_index],
+ element, I32_ZERO, "base"))) {
+ HANDLE_FAILURE("LLVMBuildInsertElement");
+ return false;
+ }
+
+ if (!(result = LLVMBuildShuffleVector(comp_ctx->builder, result,
+ undefs[opcode_index],
+ masks[opcode_index], "vector"))) {
+ HANDLE_FAILURE("LLVMBuildShuffleVector");
+ return false;
+ }
+
+ return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
+}
+
+bool
+aot_compile_simd_load_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint8 opcode, uint32 align, uint32 offset,
+ uint8 lane_id)
+{
+ LLVMValueRef element, vector;
+ uint32 opcode_index = opcode - SIMD_v128_load8_lane;
+ uint32 data_lengths[] = { 1, 2, 4, 8 };
+ LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE,
+ INT32_PTR_TYPE, INT64_PTR_TYPE };
+ LLVMTypeRef element_data_types[] = { INT8_TYPE, INT16_TYPE, I32_TYPE,
+ I64_TYPE };
+ LLVMTypeRef vector_types[] = { V128_i8x16_TYPE, V128_i16x8_TYPE,
+ V128_i32x4_TYPE, V128_i64x2_TYPE };
+ LLVMValueRef lane = simd_lane_id_to_llvm_value(comp_ctx, lane_id);
+
+ bh_assert(opcode_index < 4);
+
+ if (!(vector = simd_pop_v128_and_bitcast(
+ comp_ctx, func_ctx, vector_types[opcode_index], "src"))) {
+ return false;
+ }
+
+ if (!(element = simd_load(comp_ctx, func_ctx, align, offset,
+ data_lengths[opcode_index],
+ element_ptr_types[opcode_index],
+ element_data_types[opcode_index]))) {
+ return false;
+ }
+
+ if (!(vector = LLVMBuildInsertElement(comp_ctx->builder, vector, element,
+ lane, "dst"))) {
+ HANDLE_FAILURE("LLVMBuildInsertElement");
+ return false;
+ }
+
+ return simd_bitcast_and_push_v128(comp_ctx, func_ctx, vector, "result");
+}
+
+bool
+aot_compile_simd_load_zero(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint8 opcode, uint32 align, uint32 offset)
+{
+ LLVMValueRef element, result, mask;
+ uint32 opcode_index = opcode - SIMD_v128_load32_zero;
+ uint32 data_lengths[] = { 4, 8 };
+ LLVMTypeRef element_ptr_types[] = { INT32_PTR_TYPE, INT64_PTR_TYPE };
+ LLVMTypeRef element_data_types[] = { I32_TYPE, I64_TYPE };
+ LLVMValueRef zero[] = {
+ LLVM_CONST(i32x4_vec_zero),
+ LLVM_CONST(i64x2_vec_zero),
+ };
+ LLVMValueRef undef[] = {
+ LLVM_CONST(i32x4_undef),
+ LLVM_CONST(i64x2_undef),
+ };
+ uint32 mask_length[] = { 4, 2 };
+ LLVMValueRef mask_element[][4] = {
+ { LLVM_CONST(i32_zero), LLVM_CONST(i32_four), LLVM_CONST(i32_five),
+ LLVM_CONST(i32_six) },
+ { LLVM_CONST(i32_zero), LLVM_CONST(i32_two) },
+ };
+
+ bh_assert(opcode_index < 2);
+
+ if (!(element = simd_load(comp_ctx, func_ctx, align, offset,
+ data_lengths[opcode_index],
+ element_ptr_types[opcode_index],
+ element_data_types[opcode_index]))) {
+ return false;
+ }
+
+ if (!(result =
+ LLVMBuildInsertElement(comp_ctx->builder, undef[opcode_index],
+ element, I32_ZERO, "vector"))) {
+ HANDLE_FAILURE("LLVMBuildInsertElement");
+ return false;
+ }
+
+ /* fill in other lanes with zero */
+ if (!(mask = LLVMConstVector(mask_element[opcode_index],
+ mask_length[opcode_index]))) {
+ HANDLE_FAILURE("LLConstVector");
+ return false;
+ }
+
+ if (!(result = LLVMBuildShuffleVector(comp_ctx->builder, result,
+ zero[opcode_index], mask,
+ "fill_in_zero"))) {
+ HANDLE_FAILURE("LLVMBuildShuffleVector");
+ return false;
+ }
+
+ return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
+}
+
+/* data_length in bytes */
+static bool
+simd_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 align,
+ uint32 offset, uint32 data_length, LLVMValueRef value,
+ LLVMTypeRef value_ptr_type)
+{
+ LLVMValueRef maddr, result;
+
+ if (!(maddr = aot_check_memory_overflow(comp_ctx, func_ctx, offset,
+ data_length)))
+ return false;
+
+ if (!(maddr = LLVMBuildBitCast(comp_ctx->builder, maddr, value_ptr_type,
+ "data_ptr"))) {
+ HANDLE_FAILURE("LLVMBuildBitCast");
+ return false;
+ }
+
+ if (!(result = LLVMBuildStore(comp_ctx->builder, value, maddr))) {
+ HANDLE_FAILURE("LLVMBuildStore");
+ return false;
+ }
+
+ LLVMSetAlignment(result, 1);
+
+ return true;
+}
+
+bool
+aot_compile_simd_v128_store(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint32 align, uint32 offset)
+{
+ LLVMValueRef value;
+
+ POP_V128(value);
+
+ return simd_store(comp_ctx, func_ctx, align, offset, 16, value,
+ V128_PTR_TYPE);
+fail:
+ return false;
+}
+
+bool
+aot_compile_simd_store_lane(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+ uint8 opcode, uint32 align, uint32 offset,
+ uint8 lane_id)
+{
+ LLVMValueRef element, vector;
+ uint32 data_lengths[] = { 1, 2, 4, 8 };
+ LLVMTypeRef element_ptr_types[] = { INT8_PTR_TYPE, INT16_PTR_TYPE,
+ INT32_PTR_TYPE, INT64_PTR_TYPE };
+ uint32 opcode_index = opcode - SIMD_v128_store8_lane;
+ LLVMTypeRef vector_types[] = { V128_i8x16_TYPE, V128_i16x8_TYPE,
+ V128_i32x4_TYPE, V128_i64x2_TYPE };
+ LLVMValueRef lane = simd_lane_id_to_llvm_value(comp_ctx, lane_id);
+
+ bh_assert(opcode_index < 4);
+
+ if (!(vector = simd_pop_v128_and_bitcast(
+ comp_ctx, func_ctx, vector_types[opcode_index], "src"))) {
+ return false;
+ }
+
+ if (!(element = LLVMBuildExtractElement(comp_ctx->builder, vector, lane,
+ "element"))) {
+ HANDLE_FAILURE("LLVMBuildExtractElement");
+ return false;
+ }
+
+ return simd_store(comp_ctx, func_ctx, align, offset,
+ data_lengths[opcode_index], element,
+ element_ptr_types[opcode_index]);
+}