mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 07:08:48 +00:00
Fix Addressing for SOA on store; Add intrinsics.type_struct_field_count(T)
This commit is contained in:
@@ -5768,6 +5768,20 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BuiltinProc_type_struct_field_count:
|
||||||
|
operand->value = exact_value_i64(0);
|
||||||
|
if (operand->mode != Addressing_Type) {
|
||||||
|
error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name));
|
||||||
|
} else if (!is_type_struct(operand->type)) {
|
||||||
|
error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name));
|
||||||
|
} else {
|
||||||
|
Type *bt = base_type(operand->type);
|
||||||
|
operand->value = exact_value_i64(bt->Struct.fields.count);
|
||||||
|
}
|
||||||
|
operand->mode = Addressing_Constant;
|
||||||
|
operand->type = t_untyped_integer;
|
||||||
|
break;
|
||||||
|
|
||||||
case BuiltinProc_type_proc_parameter_count:
|
case BuiltinProc_type_proc_parameter_count:
|
||||||
operand->value = exact_value_i64(0);
|
operand->value = exact_value_i64(0);
|
||||||
if (operand->mode != Addressing_Type) {
|
if (operand->mode != Addressing_Type) {
|
||||||
|
|||||||
@@ -171,6 +171,8 @@ BuiltinProc__type_simple_boolean_end,
|
|||||||
|
|
||||||
BuiltinProc_type_is_specialization_of,
|
BuiltinProc_type_is_specialization_of,
|
||||||
|
|
||||||
|
BuiltinProc_type_struct_field_count,
|
||||||
|
|
||||||
BuiltinProc_type_proc_parameter_count,
|
BuiltinProc_type_proc_parameter_count,
|
||||||
BuiltinProc_type_proc_return_count,
|
BuiltinProc_type_proc_return_count,
|
||||||
|
|
||||||
@@ -357,6 +359,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
{STR_LIT("type_has_field"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("type_has_field"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
{STR_LIT("type_is_specialization_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("type_is_specialization_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
|
{STR_LIT("type_struct_field_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
{STR_LIT("type_proc_parameter_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("type_proc_parameter_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
{STR_LIT("type_proc_return_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
{STR_LIT("type_proc_return_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||||
|
|
||||||
|
|||||||
+23
-6
@@ -3932,22 +3932,39 @@ void ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
|||||||
Type *t = type_deref(ir_type(addr.addr));
|
Type *t = type_deref(ir_type(addr.addr));
|
||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
||||||
value = ir_emit_conv(proc, value, t->Struct.soa_elem);
|
Type *elem_type = t->Struct.soa_elem;
|
||||||
|
value = ir_emit_conv(proc, value, elem_type);
|
||||||
|
elem_type = base_type(elem_type);
|
||||||
|
|
||||||
irValue *index = addr.soa.index;
|
irValue *index = addr.soa.index;
|
||||||
if (index->kind != irValue_Constant || t->Struct.soa_kind != StructSoa_Fixed) {
|
if (index->kind != irValue_Constant || t->Struct.soa_kind != StructSoa_Fixed) {
|
||||||
Type *t = base_type(type_deref(ir_type(addr.addr)));
|
Type *t = base_type(type_deref(ir_type(addr.addr)));
|
||||||
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
||||||
i64 count = t->Struct.soa_count;
|
irValue *len = ir_soa_struct_len(proc, addr.addr);
|
||||||
irValue *len = ir_const_int(count);
|
|
||||||
ir_emit_bounds_check(proc, ast_token(addr.soa.index_expr), index, len);
|
ir_emit_bounds_check(proc, ast_token(addr.soa.index_expr), index, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, t->Struct.fields) {
|
isize field_count = 0;
|
||||||
|
|
||||||
|
switch (elem_type->kind) {
|
||||||
|
case Type_Struct:
|
||||||
|
field_count = elem_type->Struct.fields.count;
|
||||||
|
break;
|
||||||
|
case Type_Array:
|
||||||
|
field_count = elem_type->Array.count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (isize i = 0; i < field_count; i++) {
|
||||||
irValue *dst = ir_emit_struct_ep(proc, addr.addr, cast(i32)i);
|
irValue *dst = ir_emit_struct_ep(proc, addr.addr, cast(i32)i);
|
||||||
dst = ir_emit_array_ep(proc, dst, index);
|
|
||||||
irValue *src = ir_emit_struct_ev(proc, value, cast(i32)i);
|
irValue *src = ir_emit_struct_ev(proc, value, cast(i32)i);
|
||||||
ir_emit_store(proc, dst, src);
|
if (t->Struct.soa_kind == StructSoa_Fixed) {
|
||||||
|
dst = ir_emit_array_ep(proc, dst, index);
|
||||||
|
ir_emit_store(proc, dst, src);
|
||||||
|
} else {
|
||||||
|
irValue *field = ir_emit_load(proc, dst);
|
||||||
|
dst = ir_emit_ptr_offset(proc, field, index);
|
||||||
|
ir_emit_store(proc, dst, src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-6
@@ -406,22 +406,39 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
|||||||
Type *t = type_deref(addr.addr.type);
|
Type *t = type_deref(addr.addr.type);
|
||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
||||||
value = lb_emit_conv(p, value, t->Struct.soa_elem);
|
Type *elem_type = t->Struct.soa_elem;
|
||||||
|
value = lb_emit_conv(p, value, elem_type);
|
||||||
|
elem_type = base_type(elem_type);
|
||||||
|
|
||||||
lbValue index = addr.soa.index;
|
lbValue index = addr.soa.index;
|
||||||
if (!lb_is_const(index) || t->Struct.soa_kind != StructSoa_Fixed) {
|
if (!lb_is_const(index) || t->Struct.soa_kind != StructSoa_Fixed) {
|
||||||
Type *t = base_type(type_deref(addr.addr.type));
|
Type *t = base_type(type_deref(addr.addr.type));
|
||||||
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
|
||||||
i64 count = t->Struct.soa_count;
|
lbValue len = lb_soa_struct_len(p, addr.addr);
|
||||||
lbValue len = lb_const_int(p->module, t_int, count);
|
|
||||||
lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), index, len);
|
lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), index, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, t->Struct.fields) {
|
isize field_count = 0;
|
||||||
|
|
||||||
|
switch (elem_type->kind) {
|
||||||
|
case Type_Struct:
|
||||||
|
field_count = elem_type->Struct.fields.count;
|
||||||
|
break;
|
||||||
|
case Type_Array:
|
||||||
|
field_count = elem_type->Array.count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (isize i = 0; i < field_count; i++) {
|
||||||
lbValue dst = lb_emit_struct_ep(p, addr.addr, cast(i32)i);
|
lbValue dst = lb_emit_struct_ep(p, addr.addr, cast(i32)i);
|
||||||
dst = lb_emit_array_ep(p, dst, index);
|
|
||||||
lbValue src = lb_emit_struct_ev(p, value, cast(i32)i);
|
lbValue src = lb_emit_struct_ev(p, value, cast(i32)i);
|
||||||
lb_emit_store(p, dst, src);
|
if (t->Struct.soa_kind == StructSoa_Fixed) {
|
||||||
|
dst = lb_emit_array_ep(p, dst, index);
|
||||||
|
lb_emit_store(p, dst, src);
|
||||||
|
} else {
|
||||||
|
lbValue field = lb_emit_load(p, dst);
|
||||||
|
dst = lb_emit_ptr_offset(p, field, index);
|
||||||
|
lb_emit_store(p, dst, src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1865,6 +1865,9 @@ bool is_type_comparable(Type *t) {
|
|||||||
if (type_size_of(t) == 0) {
|
if (type_size_of(t) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (t->Struct.soa_kind != StructSoa_None) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (t->Struct.is_raw_union) {
|
if (t->Struct.is_raw_union) {
|
||||||
return is_type_simple_compare(t);
|
return is_type_simple_compare(t);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user