aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_proc.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-10-20 16:03:16 +0100
committergingerBill <bill@gingerbill.org>2021-10-20 16:03:16 +0100
commit3e4c2e49320b6ddd905b38fc884ec47aa8da7748 (patch)
tree67a9d1e0e6cade4b721a27179a728fac5cb79168 /src/llvm_backend_proc.cpp
parent30c141ceb98d4b65418fb70c572f86cd701dd872 (diff)
Support `conj` on array and matrix types
Diffstat (limited to 'src/llvm_backend_proc.cpp')
-rw-r--r--src/llvm_backend_proc.cpp77
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: {