From 7ec0236fbf55939ef46662a732b00908730f826b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 26 May 2022 11:14:22 +0100 Subject: [PATCH] Add `simd_reverse` --- core/intrinsics/intrinsics.odin | 2 ++ core/simd/simd.odin | 2 ++ src/check_builtin.cpp | 13 +++++++++++++ src/checker_builtin_procs.hpp | 4 ++++ src/llvm_backend_proc.cpp | 16 ++++++++++++++++ src/types.cpp | 2 ++ 6 files changed, 39 insertions(+) diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 13a185da0..a14488210 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -245,6 +245,8 @@ simd_floor :: proc(a: #simd[N]any_float) -> #simd[N]any_float --- simd_trunc :: proc(a: #simd[N]any_float) -> #simd[N]any_float --- simd_nearest :: proc(a: #simd[N]any_float) -> #simd[N]any_float --- +simd_reverse :: proc(a: #simd[N]T) -> #simd[N]T --- + // WASM targets only wasm_memory_grow :: proc(index, delta: uintptr) -> int --- wasm_memory_size :: proc(index: uintptr) -> int --- diff --git a/core/simd/simd.odin b/core/simd/simd.odin index 9c37c380c..060e32323 100644 --- a/core/simd/simd.odin +++ b/core/simd/simd.odin @@ -90,6 +90,8 @@ floor :: intrinsics.simd_floor trunc :: intrinsics.simd_trunc nearest :: intrinsics.simd_nearest +reverse :: intrinsics.simd_reverse + splat :: #force_inline proc "contextless" ($T: typeid/#simd[$LANES]$E, value: E) -> T { return T{0..args[0]); if (x.mode == Addressing_Invalid) { return false; } + + if (!is_type_simd_vector(x.type)) { + error(x.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); + return false; + } + operand->type = x.type; + operand->mode = Addressing_Value; + return true; + } default: GB_PANIC("Unhandled simd intrinsic: %.*s", LIT(builtin_name)); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index adb4e4624..22ee3d141 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -165,6 +165,8 @@ BuiltinProc__simd_begin, BuiltinProc_simd_floor, BuiltinProc_simd_trunc, BuiltinProc_simd_nearest, + + BuiltinProc_simd_reverse, BuiltinProc__simd_end, // Platform specific intrinsics @@ -433,6 +435,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("simd_floor"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("simd_trunc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("simd_nearest"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + + {STR_LIT("simd_reverse"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 88129ba5d..42f5a60fa 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1338,6 +1338,22 @@ lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const return res; } + case BuiltinProc_simd_reverse: + { + i64 count = get_array_type_count(arg0.type); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count); + LLVMTypeRef llvm_u32 = lb_type(m, t_u32); + for (i64 i = 0; i < count; i++) { + values[i] = LLVMConstInt(llvm_u32, count-1-i, false); + } + LLVMValueRef mask = LLVMConstVector(values, cast(unsigned)count); + + LLVMValueRef v = arg0.value; + res.value = LLVMBuildShuffleVector(p->builder, v, v, mask, ""); + return res; + } + + } GB_PANIC("Unhandled simd intrinsic: '%.*s'", LIT(builtin_procs[builtin_id].name)); diff --git a/src/types.cpp b/src/types.cpp index fccea2937..6f61015d3 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1598,6 +1598,8 @@ i64 get_array_type_count(Type *t) { return bt->Array.count; } else if (bt->kind == Type_EnumeratedArray) { return bt->EnumeratedArray.count; + } else if (bt->kind == Type_SimdVector) { + return bt->SimdVector.count; } GB_ASSERT(is_type_array_like(t)); return -1;