From 01f431b01fea18b0844d0475839c68426e95fd2c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 9 Aug 2021 19:37:58 +0100 Subject: Unify semantics of the built-in `swizzle` procedure with the selector expression semantics e.g. `.xyz` --- src/llvm_backend_stmt.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src/llvm_backend_stmt.cpp') diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 324b408c7..a220995a3 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1801,6 +1801,51 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue y_loads[4] = {}; lbValue ops[4] = {}; + for (i32 i = 0; i < index_count; i++) { + lhs_ptrs[i] = lb_emit_array_epi(p, lhs.addr, indices[i]); + } + for (i32 i = 0; i < index_count; i++) { + x_loads[i] = lb_emit_load(p, lhs_ptrs[i]); + } + for (i32 i = 0; i < index_count; i++) { + y_loads[i].value = LLVMBuildExtractValue(p->builder, rhs.value, i, ""); + y_loads[i].type = elem_type; + } + for (i32 i = 0; i < index_count; i++) { + ops[i] = lb_emit_arith(p, op, x_loads[i], y_loads[i], elem_type); + } + for (i32 i = 0; i < index_count; i++) { + lb_emit_store(p, lhs_ptrs[i], ops[i]); + } + return; + } else if (lhs.kind == lbAddr_SwizzleLarge) { + GB_ASSERT(is_type_array(lhs_type)); + + struct ValueAndIndex { + lbValue value; + u32 index; + }; + + Type *bt = base_type(lhs_type); + GB_ASSERT(bt->kind == Type_Array); + + auto indices_handled = slice_make(temporary_allocator(), bt->Array.count); + auto indices = slice_make(temporary_allocator(), bt->Array.count); + i32 index_count = 0; + for_array(i, lhs.swizzle_large.indices) { + i32 index = lhs.swizzle_large.indices[i]; + if (indices_handled[index]) { + continue; + } + indices[index_count++] = index; + } + gb_sort_array(indices.data, index_count, gb_i32_cmp(0)); + + lbValue lhs_ptrs[4] = {}; + lbValue x_loads[4] = {}; + lbValue y_loads[4] = {}; + lbValue ops[4] = {}; + for (i32 i = 0; i < index_count; i++) { lhs_ptrs[i] = lb_emit_array_epi(p, lhs.addr, indices[i]); } -- cgit v1.2.3