aboutsummaryrefslogtreecommitdiff
path: root/src/tilde_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-07-28 14:57:04 +0100
committergingerBill <bill@gingerbill.org>2023-07-28 14:57:04 +0100
commitc39a3603720917d6970026e5c0595d468ea9b372 (patch)
tree47f9b81d6a37007aee82834df91bec311742ec9f /src/tilde_expr.cpp
parentf6d1724835489120ae4a3805495dafc97c86db80 (diff)
Update Tilde for the new TB_Passes approach
Diffstat (limited to 'src/tilde_expr.cpp')
-rw-r--r--src/tilde_expr.cpp42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp
index 1966dcd8e..fdd26e3db 100644
--- a/src/tilde_expr.cpp
+++ b/src/tilde_expr.cpp
@@ -304,6 +304,42 @@ gb_internal cgValue cg_emit_byte_swap(cgProcedure *p, cgValue value, Type *end_t
return cg_emit_transmute(p, value, end_type);
}
+gb_internal cgValue cg_emit_comp_records(cgProcedure *p, TokenKind op_kind, cgValue left, cgValue right, Type *type) {
+ GB_ASSERT((is_type_struct(type) || is_type_union(type)) && is_type_comparable(type));
+ cgValue left_ptr = cg_address_from_load_or_generate_local(p, left);
+ cgValue right_ptr = cg_address_from_load_or_generate_local(p, right);
+ cgValue res = {};
+ if (type_size_of(type) == 0) {
+ switch (op_kind) {
+ case Token_CmpEq:
+ return cg_const_bool(p, t_bool, true);
+ case Token_NotEq:
+ return cg_const_bool(p, t_bool, false);
+ }
+ GB_PANIC("invalid operator");
+ }
+ TEMPORARY_ALLOCATOR_GUARD();
+ if (is_type_simple_compare(type)) {
+ // TODO(bill): Test to see if this is actually faster!!!!
+ auto args = slice_make<cgValue>(temporary_allocator(), 3);
+ args[0] = cg_emit_conv(p, left_ptr, t_rawptr);
+ args[1] = cg_emit_conv(p, right_ptr, t_rawptr);
+ args[2] = cg_const_int(p, t_int, type_size_of(type));
+ res = cg_emit_runtime_call(p, "memory_equal", args);
+ } else {
+ cgProcedure *equal_proc = cg_equal_proc_for_type(p->module, type);
+ cgValue value = cg_value(tb_inst_get_symbol_address(p->func, equal_proc->symbol), equal_proc->type);
+ auto args = slice_make<cgValue>(temporary_allocator(), 2);
+ args[0] = cg_emit_conv(p, left_ptr, t_rawptr);
+ args[1] = cg_emit_conv(p, right_ptr, t_rawptr);
+ res = cg_emit_call(p, value, args);
+ }
+ if (op_kind == Token_NotEq) {
+ res = cg_emit_unary_arith(p, Token_Not, res, res.type);
+ }
+ return res;
+}
+
gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left, cgValue right) {
GB_ASSERT(gb_is_between(op_kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1));
@@ -440,13 +476,11 @@ gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left
}
if ((is_type_struct(a) || is_type_union(a)) && is_type_comparable(a)) {
- GB_PANIC("TODO(bill): cg_compare_records");
- // return cg_compare_records(p, op_kind, left, right, a);
+ return cg_emit_comp_records(p, op_kind, left, right, a);
}
if ((is_type_struct(b) || is_type_union(b)) && is_type_comparable(b)) {
- GB_PANIC("TODO(bill): cg_compare_records");
- // return cg_compare_records(p, op_kind, left, right, b);
+ return cg_emit_comp_records(p, op_kind, left, right, b);
}
if (is_type_string(a)) {