diff options
| author | gingerBill <bill@gingerbill.org> | 2021-03-24 19:29:25 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-03-24 19:29:25 +0000 |
| commit | 7028797d5398699c2edbfd0ab1d83272bcdcd1ce (patch) | |
| tree | 0ef994f8cfcfce7b2070b73ba1a224be312c2a07 /src/llvm_backend.cpp | |
| parent | 6c9d3715d89964742c6c9b1aa05c0eccebc40f22 (diff) | |
Implement `soa_unzip`
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index db86a8dac..9ab2609e9 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -8281,6 +8281,33 @@ lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) { return lb_addr_load(p, res); } +lbValue lb_soa_unzip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) { + GB_ASSERT(ce->args.count == 1); + + lbValue arg = lb_build_expr(p, ce->args[0]); + Type *t = base_type(arg.type); + GB_ASSERT(is_type_soa_struct(t) && t->Struct.soa_kind == StructSoa_Slice); + + lbValue len = lb_soa_struct_len(p, arg); + + lbAddr res = lb_add_local_generated(p, tv.type, true); + if (is_type_tuple(tv.type)) { + lbValue rp = lb_addr_get_ptr(p, res); + for (i32 i = 0; i < cast(i32)(t->Struct.fields.count-1); i++) { + lbValue ptr = lb_emit_struct_ev(p, arg, i); + lbAddr dst = lb_addr(lb_emit_struct_ep(p, rp, i)); + lb_fill_slice(p, dst, ptr, len); + } + } else { + GB_ASSERT(is_type_slice(tv.type)); + lbValue ptr = lb_emit_struct_ev(p, arg, 0); + lb_fill_slice(p, res, ptr, len); + } + + return lb_addr_load(p, res); +} + + lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) { ast_node(ce, CallExpr, expr); @@ -8672,6 +8699,8 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_soa_zip: return lb_soa_zip(p, ce, tv); + case BuiltinProc_soa_unzip: + return lb_soa_unzip(p, ce, tv); // "Intrinsics" |