diff options
| author | gingerBill <bill@gingerbill.org> | 2021-10-20 16:03:16 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-10-20 16:03:16 +0100 |
| commit | 3e4c2e49320b6ddd905b38fc884ec47aa8da7748 (patch) | |
| tree | 67a9d1e0e6cade4b721a27179a728fac5cb79168 /src/llvm_backend_proc.cpp | |
| parent | 30c141ceb98d4b65418fb70c572f86cd701dd872 (diff) | |
Support `conj` on array and matrix types
Diffstat (limited to 'src/llvm_backend_proc.cpp')
| -rw-r--r-- | src/llvm_backend_proc.cpp | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 8686b3262..72ba3982c 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -725,6 +725,57 @@ lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> return lb_emit_call(p, proc, args); } +lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) { + lbValue res = {}; + Type *t = val.type; + if (is_type_complex(t)) { + res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false)); + lbValue real = lb_emit_struct_ev(p, val, 0); + lbValue imag = lb_emit_struct_ev(p, val, 1); + imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type); + lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real); + lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag); + } else if (is_type_quaternion(t)) { + // @QuaternionLayout + res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false)); + lbValue real = lb_emit_struct_ev(p, val, 3); + lbValue imag = lb_emit_struct_ev(p, val, 0); + lbValue jmag = lb_emit_struct_ev(p, val, 1); + lbValue kmag = lb_emit_struct_ev(p, val, 2); + imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type); + jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type); + kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type); + lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real); + lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag); + lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag); + lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag); + } else if (is_type_array_like(t)) { + res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true)); + Type *elem_type = base_array_type(t); + i64 count = get_array_type_count(t); + for (i64 i = 0; i < count; i++) { + lbValue dst = lb_emit_array_epi(p, res, i); + lbValue elem = lb_emit_struct_ev(p, val, cast(i32)i); + elem = lb_emit_conjugate(p, elem, elem_type); + lb_emit_store(p, dst, elem); + } + } else if (is_type_matrix(t)) { + Type *mt = base_type(t); + GB_ASSERT(mt->kind == Type_Matrix); + Type *elem_type = mt->Matrix.elem; + res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true)); + for (i64 j = 0; j < mt->Matrix.column_count; j++) { + for (i64 i = 0; i < mt->Matrix.row_count; i++) { + lbValue dst = lb_emit_matrix_epi(p, res, i, j); + lbValue elem = lb_emit_matrix_ev(p, val, i, j); + elem = lb_emit_conjugate(p, elem, elem_type); + lb_emit_store(p, dst, elem); + } + } + } + return lb_emit_load(p, res); +} + lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, bool use_copy_elision_hint) { lbModule *m = p->module; @@ -1117,31 +1168,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_conj: { lbValue val = lb_build_expr(p, ce->args[0]); - lbValue res = {}; - Type *t = val.type; - if (is_type_complex(t)) { - res = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false)); - lbValue real = lb_emit_struct_ev(p, val, 0); - lbValue imag = lb_emit_struct_ev(p, val, 1); - imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type); - lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real); - lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag); - } else if (is_type_quaternion(t)) { - // @QuaternionLayout - res = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false)); - lbValue real = lb_emit_struct_ev(p, val, 3); - lbValue imag = lb_emit_struct_ev(p, val, 0); - lbValue jmag = lb_emit_struct_ev(p, val, 1); - lbValue kmag = lb_emit_struct_ev(p, val, 2); - imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type); - jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type); - kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type); - lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real); - lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag); - lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag); - lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag); - } - return lb_emit_load(p, res); + return lb_emit_conjugate(p, val, tv.type); } case BuiltinProc_expand_to_tuple: { |