From 3e4c2e49320b6ddd905b38fc884ec47aa8da7748 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 20 Oct 2021 16:03:16 +0100 Subject: Support `conj` on array and matrix types --- src/llvm_backend_proc.cpp | 77 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 25 deletions(-) (limited to 'src/llvm_backend_proc.cpp') 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 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 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: { -- cgit v1.2.3