diff options
| author | gingerBill <bill@gingerbill.org> | 2022-05-26 11:14:22 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-05-26 11:14:22 +0100 |
| commit | 7ec0236fbf55939ef46662a732b00908730f826b (patch) | |
| tree | 5ca74a442892c211c334d3d1d91eb242aeb3dafe /src | |
| parent | 0fd43c1a0b697ea919efdeef42427694f32692bf (diff) | |
Add `simd_reverse`
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_builtin.cpp | 13 | ||||
| -rw-r--r-- | src/checker_builtin_procs.hpp | 4 | ||||
| -rw-r--r-- | src/llvm_backend_proc.cpp | 16 | ||||
| -rw-r--r-- | src/types.cpp | 2 |
4 files changed, 35 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 74c28f4d2..edf84b152 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -912,6 +912,19 @@ bool check_builtin_simd_operation(CheckerContext *c, Operand *operand, Ast *call return true; } + case BuiltinProc_simd_reverse: + { + Operand x = {}; + check_expr(c, &x, ce->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; |