aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp52
1 files changed, 46 insertions, 6 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index e6315e314..31c042264 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -3275,8 +3275,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
// boolean -> boolean/integer
if (is_type_boolean(src) && (is_type_boolean(dst) || is_type_integer(dst))) {
- GB_ASSERT(src != t_llvm_bool);
-
irValue *b = ir_emit(proc, ir_instr_binary_op(proc, Token_NotEq, value, v_zero, t_llvm_bool));
return ir_emit(proc, ir_instr_conv(proc, irConv_zext, b, t_llvm_bool, t));
}
@@ -4247,7 +4245,7 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) {
}
void ir_build_stmt_list(irProcedure *proc, Array<Ast *> stmts);
-
+void ir_build_assign_op(irProcedure *proc, irAddr const &lhs, irValue *value, TokenKind op);
bool is_double_pointer(Type *t) {
if (!is_type_pointer(t)) {
@@ -5610,8 +5608,9 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
Type *et = nullptr;
switch (bt->kind) {
- case Type_Array: et = bt->Array.elem; break;
- case Type_Slice: et = bt->Slice.elem; break;
+ case Type_Array: et = bt->Array.elem; break;
+ case Type_Slice: et = bt->Slice.elem; break;
+ case Type_BitSet: et = bt->BitSet.base_type; break;
}
String proc_name = {};
@@ -5821,7 +5820,42 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
ir_emit_store(proc, gep, fv);
}
}
+
+ break;
+ }
+
+ case Type_BitSet: {
+
+ i64 sz = type_size_of(type);
+ if (cl->elems.count > 0 && sz > 0) {
+ ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr)));
+
+ irValue *lower = ir_value_constant(t_int, exact_value_i64(bt->BitSet.min));
+ for_array(i, cl->elems) {
+ Ast *elem = cl->elems[i];
+ GB_ASSERT(elem->kind != Ast_FieldValue);
+
+ if (ir_is_elem_const(proc->module, elem, et)) {
+ continue;
+ }
+
+ irValue *expr = ir_build_expr(proc, elem);
+ GB_ASSERT(ir_type(expr)->kind != Type_Tuple);
+
+ Type *it = bit_set_to_int(bt);
+ irValue *e = ir_emit_conv(proc, expr, it);
+ e = ir_emit_arith(proc, Token_Sub, e, lower, it);
+ e = ir_emit_arith(proc, Token_Shl, v_one, e, it);
+
+ irValue *old_value = ir_emit_bitcast(proc, ir_emit_load(proc, v), it);
+ irValue *new_value = ir_emit_arith(proc, Token_Or, old_value, e, it);
+ new_value = ir_emit_bitcast(proc, new_value, type);
+ ir_emit_store(proc, v, new_value);
+ }
+ }
+ break;
}
+
}
return ir_addr(v);
@@ -8025,8 +8059,14 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
}
break;
}
- }
+ case Type_BitSet:
+ ir_emit_comment(proc, str_lit("Type_Info_Bit_Set"));
+ tag = ir_emit_conv(proc, variant_ptr, t_type_info_bit_set_ptr);
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->BitSet.base_type));
+ break;
+
+ }
if (tag != nullptr) {
Type *tag_type = type_deref(ir_type(tag));