diff options
| author | gingerBill <bill@gingerbill.org> | 2023-07-19 23:27:06 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-07-19 23:27:06 +0100 |
| commit | a919828003c203b76060a5060d79b1e94a828ab7 (patch) | |
| tree | 1d9a408da85137e2c3d37b09b75a2e4fc2f02ea9 /src/tilde_const.cpp | |
| parent | 0bd33882b67952d80d7123a8af09ff902c96bb56 (diff) | |
Add complex and quaternion global stuff
Diffstat (limited to 'src/tilde_const.cpp')
| -rw-r--r-- | src/tilde_const.cpp | 461 |
1 files changed, 259 insertions, 202 deletions
diff --git a/src/tilde_const.cpp b/src/tilde_const.cpp index 616bf7833..ef3f38f09 100644 --- a/src/tilde_const.cpp +++ b/src/tilde_const.cpp @@ -139,12 +139,266 @@ gb_internal TB_Global *cg_global_const_string(cgModule *m, String const &str, Ty return global; } +gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast *value_compound, bool allow_local); -gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, ExactValue const &value, bool allow_local = true) { +gb_internal bool cg_global_const_add_region(cgModule *m, TB_Global *global, ExactValue const &value, Type *type, i64 offset, bool allow_local) { + GB_ASSERT(is_type_endian_little(type)); + GB_ASSERT(!is_type_different_to_arch_endianness(type)); + + i64 size = type_size_of(type); + if (value.kind != ExactValue_Invalid) { + switch (value.kind) { + case ExactValue_Bool: + { + bool *res = cast(bool *)tb_global_add_region(m->mod, global, offset, size); + *res = !!value.value_bool; + } + break; + + case ExactValue_Integer: + { + void *res = tb_global_add_region(m->mod, global, offset, size); + cg_write_big_int_at_ptr(res, &value.value_integer, type); + } + break; + + case ExactValue_Float: + { + f64 f = exact_value_to_f64(value); + void *res = tb_global_add_region(m->mod, global, offset, size); + switch (size) { + case 2: *(u16 *)res = f32_to_f16(cast(f32)f); break; + case 4: *(f32 *)res = cast(f32)f; break; + case 8: *(f64 *)res = cast(f64)f; break; + } + } + break; + + case ExactValue_Pointer: + { + void *res = tb_global_add_region(m->mod, global, offset, size); + *(u64 *)res = exact_value_to_u64(value); + } + break; + + case ExactValue_String: + { + TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_string(m, value.value_string, type); + tb_global_add_symbol_reloc(m->mod, global, offset, symbol); + } + break; + + case ExactValue_Typeid: + { + void *dst = tb_global_add_region(m->mod, global, offset, size); + u64 id = cg_typeid_as_u64(m, value.value_typeid); + cg_write_uint_at_ptr(dst, id, t_typeid); + } + break; + + case ExactValue_Compound: + { + TB_Global *nested_global = cg_global_const_comp_literal(m, type, value.value_compound, allow_local); + tb_global_add_symbol_reloc(m->mod, global, offset, cast(TB_Symbol *)nested_global); + } + break; + + case ExactValue_Procedure: + GB_PANIC("TODO(bill): nested procedure values/literals\n"); + break; + case ExactValue_Complex: + { + Complex128 c = {}; + if (value.value_complex) { + c = *value.value_complex; + } + void *res = tb_global_add_region(m->mod, global, offset, size); + switch (size) { + case 4: + ((u16 *)res)[0] = f32_to_f16(cast(f32)c.real); + ((u16 *)res)[1] = f32_to_f16(cast(f32)c.imag); + break; + case 8: + ((f32 *)res)[0] = cast(f32)c.real; + ((f32 *)res)[1] = cast(f32)c.imag; + break; + case 16: + ((f64 *)res)[0] = cast(f64)c.real; + ((f64 *)res)[1] = cast(f64)c.imag; + break; + } + } + break; + case ExactValue_Quaternion: + { + // @QuaternionLayout + Quaternion256 q = {}; + if (value.value_quaternion) { + q = *value.value_quaternion; + } + void *res = tb_global_add_region(m->mod, global, offset, size); + switch (size) { + case 8: + ((u16 *)res)[0] = f32_to_f16(cast(f32)q.imag); + ((u16 *)res)[1] = f32_to_f16(cast(f32)q.jmag); + ((u16 *)res)[2] = f32_to_f16(cast(f32)q.kmag); + ((u16 *)res)[3] = f32_to_f16(cast(f32)q.real); + break; + case 16: + ((f32 *)res)[0] = cast(f32)q.imag; + ((f32 *)res)[1] = cast(f32)q.jmag; + ((f32 *)res)[2] = cast(f32)q.kmag; + ((f32 *)res)[3] = cast(f32)q.real; + break; + case 32: + ((f64 *)res)[0] = cast(f64)q.imag; + ((f64 *)res)[1] = cast(f64)q.jmag; + ((f64 *)res)[2] = cast(f64)q.kmag; + ((f64 *)res)[3] = cast(f64)q.real; + break; + } + } + break; + default: + GB_PANIC("%s", type_to_string(type)); + break; + } + return true; + } + return false; +} + + +gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast *value_compound, bool allow_local) { + Type *original_type = type; + if (is_type_struct(type)) { + ast_node(cl, CompoundLit, value_compound); + + Type *bt = base_type(type); + + char name[32] = {}; + gb_snprintf(name, 31, "complit$%u", 1+m->const_nil_guid.fetch_add(1)); + TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, original_type), TB_LINKAGE_PRIVATE); + i64 size = type_size_of(original_type); + i64 align = type_align_of(original_type); + + // READ ONLY? + TB_ModuleSection *section = tb_module_get_rdata(m->mod); + if (cl->elems.count == 0/* || bt->Struct.is_raw_union*/) { + tb_global_set_storage(m->mod, section, global, size, align, 0); + return global; + } + + TEMPORARY_ALLOCATOR_GUARD(); + isize value_count = bt->Struct.fields.count; + // cgValue * values = gb_alloc_array(temporary_allocator(), cgValue, value_count); + bool * visited = gb_alloc_array(temporary_allocator(), bool, value_count); + tb_global_set_storage(m->mod, section, global, size, align, value_count); + + if (cl->elems[0]->kind == Ast_FieldValue) { + isize elem_count = cl->elems.count; + for (isize i = 0; i < elem_count; i++) { + ast_node(fv, FieldValue, cl->elems[i]); + String name = fv->field->Ident.token.string; + + TypeAndValue tav = fv->value->tav; + GB_ASSERT(tav.mode != Addressing_Invalid); + + Selection sel = lookup_field(type, name, false); + GB_ASSERT(!sel.indirect); + + Entity *f = bt->Struct.fields[sel.index[0]]; + i64 index = f->Variable.field_index; + if (elem_type_can_be_constant(f->type)) { + if (sel.index.count == 1) { + i64 offset = bt->Struct.offsets[index]; + if (cg_global_const_add_region(m, global, fv->value->tav.value, f->type, offset, allow_local)) { + visited[i] = true; + continue; + } + } else { + // if (!visited[index]) { + GB_PANIC("using struct fields"); + // values[index] = lb_const_value(m, f->type, {}, false).value; + // visited[index] = true; + // } + // unsigned idx_list_len = cast(unsigned)sel.index.count-1; + // unsigned *idx_list = gb_alloc_array(temporary_allocator(), unsigned, idx_list_len); + + // if (lb_is_nested_possibly_constant(type, sel, fv->value)) { + // bool is_constant = true; + // Type *cv_type = f->type; + // for (isize j = 1; j < sel.index.count; j++) { + // i32 index = sel.index[j]; + // Type *cvt = base_type(cv_type); + + // if (cvt->kind == Type_Struct) { + // if (cvt->Struct.is_raw_union) { + // // sanity check which should have been caught by `lb_is_nested_possibly_constant` + // is_constant = false; + // break; + // } + // cv_type = cvt->Struct.fields[index]->type; + + // if (is_type_struct(cvt)) { + // auto cv_field_remapping = lb_get_struct_remapping(m, cvt); + // unsigned remapped_index = cast(unsigned)cv_field_remapping[index]; + // idx_list[j-1] = remapped_index; + // } else { + // idx_list[j-1] = cast(unsigned)index; + // } + // } else if (cvt->kind == Type_Array) { + // cv_type = cvt->Array.elem; + + // idx_list[j-1] = cast(unsigned)index; + // } else { + // GB_PANIC("UNKNOWN TYPE: %s", type_to_string(cv_type)); + // } + // } + // if (is_constant) { + // LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local).value; + // GB_ASSERT(LLVMIsConstant(elem_value)); + // values[index] = LLVMConstInsertValue(values[index], elem_value, idx_list, idx_list_len); + // } + // } + } + } + } + } else { + for_array(i, cl->elems) { + i64 field_index = i; + Ast *elem = cl->elems[i]; + TypeAndValue tav = elem->tav; + Entity *f = bt->Struct.fields[field_index]; + if (!elem_type_can_be_constant(f->type)) { + continue; + } + + i64 offset = bt->Struct.offsets[field_index]; + + ExactValue value = {}; + if (tav.mode != Addressing_Invalid) { + value = tav.value; + } + if (cg_global_const_add_region(m, global, value, f->type, offset, allow_local)) { + visited[i] = true; + continue; + } + } + } + + return global; + } + + GB_PANIC("TODO(bill): constant compound literal for %s", type_to_string(type)); + return nullptr; +} + + +gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, ExactValue const &value, bool allow_local_ = true) { TB_Node *node = nullptr; - bool is_local = allow_local && p != nullptr; - gb_unused(is_local); + bool allow_local = allow_local_ && p != nullptr; TB_DataType dt = cg_data_type(type); @@ -169,8 +423,6 @@ gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, Exac break; } - Type *original_type = type; - switch (value.kind) { case ExactValue_Bool: GB_ASSERT(!TB_IS_VOID_TYPE(dt)); @@ -217,209 +469,14 @@ gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, Exac return cg_value(tb_inst_uint(p->func, dt, exact_value_to_u64(value)), type); case ExactValue_Compound: - if (is_type_struct(type)) { - ast_node(cl, CompoundLit, value.value_compound); - - if (cl->elems.count == 0) { - return cg_const_nil(m, p, original_type); - } - - Type *bt = base_type(type); - if (bt->Struct.is_raw_union) { - return cg_const_nil(m, p, original_type); - } - - TEMPORARY_ALLOCATOR_GUARD(); - - isize value_count = bt->Struct.fields.count; - cgValue * values = gb_alloc_array(temporary_allocator(), cgValue, value_count); - bool * visited = gb_alloc_array(temporary_allocator(), bool, value_count); - - - char name[32] = {}; - gb_snprintf(name, 31, "complit$%u", 1+m->const_nil_guid.fetch_add(1)); - TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, original_type), TB_LINKAGE_PRIVATE); - i64 size = type_size_of(original_type); - i64 align = type_align_of(original_type); - - // READ ONLY? - TB_ModuleSection *section = tb_module_get_rdata(m->mod); - tb_global_set_storage(m->mod, section, global, size, align, value_count); - - if (cl->elems[0]->kind == Ast_FieldValue) { - // isize elem_count = cl->elems.count; - // for (isize i = 0; i < elem_count; i++) { - // ast_node(fv, FieldValue, cl->elems[i]); - // String name = fv->field->Ident.token.string; - - // TypeAndValue tav = fv->value->tav; - // GB_ASSERT(tav.mode != Addressing_Invalid); - - // Selection sel = lookup_field(type, name, false); - // GB_ASSERT(!sel.indirect); - - // Entity *f = type->Struct.fields[sel.index[0]]; - // i32 index = field_remapping[f->Variable.field_index]; - // if (elem_type_can_be_constant(f->type)) { - // if (sel.index.count == 1) { - // values[index] = lb_const_value(m, f->type, tav.value, allow_local).value; - // visited[index] = true; - // } else { - // if (!visited[index]) { - // values[index] = lb_const_value(m, f->type, {}, false).value; - // visited[index] = true; - // } - // unsigned idx_list_len = cast(unsigned)sel.index.count-1; - // unsigned *idx_list = gb_alloc_array(temporary_allocator(), unsigned, idx_list_len); - - // if (lb_is_nested_possibly_constant(type, sel, fv->value)) { - // bool is_constant = true; - // Type *cv_type = f->type; - // for (isize j = 1; j < sel.index.count; j++) { - // i32 index = sel.index[j]; - // Type *cvt = base_type(cv_type); - - // if (cvt->kind == Type_Struct) { - // if (cvt->Struct.is_raw_union) { - // // sanity check which should have been caught by `lb_is_nested_possibly_constant` - // is_constant = false; - // break; - // } - // cv_type = cvt->Struct.fields[index]->type; - - // if (is_type_struct(cvt)) { - // auto cv_field_remapping = lb_get_struct_remapping(m, cvt); - // unsigned remapped_index = cast(unsigned)cv_field_remapping[index]; - // idx_list[j-1] = remapped_index; - // } else { - // idx_list[j-1] = cast(unsigned)index; - // } - // } else if (cvt->kind == Type_Array) { - // cv_type = cvt->Array.elem; - - // idx_list[j-1] = cast(unsigned)index; - // } else { - // GB_PANIC("UNKNOWN TYPE: %s", type_to_string(cv_type)); - // } - // } - // if (is_constant) { - // LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local).value; - // GB_ASSERT(LLVMIsConstant(elem_value)); - // values[index] = LLVMConstInsertValue(values[index], elem_value, idx_list, idx_list_len); - // } - // } - // } - // } - // } - } else { - for_array(i, cl->elems) { - i64 field_index = i; - Ast *elem = cl->elems[i]; - TypeAndValue tav = elem->tav; - Entity *f = bt->Struct.fields[field_index]; - if (!elem_type_can_be_constant(f->type)) { - continue; - } - - i64 offset = bt->Struct.offsets[field_index]; - i64 size = type_size_of(f->type); - - - ExactValue value = {}; - if (tav.mode != Addressing_Invalid) { - value = tav.value; - } - - GB_ASSERT(is_type_endian_little(f->type)); - GB_ASSERT(!is_type_different_to_arch_endianness(type)); - - - if (value.kind != ExactValue_Invalid) { - switch (value.kind) { - case ExactValue_Bool: - { - bool *res = cast(bool *)tb_global_add_region(m->mod, global, offset, size); - *res = !!value.value_bool; - } - break; - - case ExactValue_Integer: - { - void *res = tb_global_add_region(m->mod, global, offset, size); - cg_write_big_int_at_ptr(res, &value.value_integer, f->type); - } - break; - - case ExactValue_Float: - { - f64 f = exact_value_to_f64(value); - void *res = tb_global_add_region(m->mod, global, offset, size); - switch (size) { - case 2: *(u16 *)res = f32_to_f16(cast(f32)f); break; - case 4: *(f32 *)res = cast(f32)f; break; - case 8: *(f64 *)res = cast(f64)f; break; - } - } - break; - - case ExactValue_Pointer: - { - void *res = tb_global_add_region(m->mod, global, offset, size); - *(u64 *)res = exact_value_to_u64(value); - } - break; - - case ExactValue_String: - { - TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_string(m, value.value_string, f->type); - tb_global_add_symbol_reloc(m->mod, global, offset, symbol); - } - break; - - case ExactValue_Typeid: - { - void *dst = tb_global_add_region(m->mod, global, offset, size); - u64 id = cg_typeid_as_u64(m, value.value_typeid); - cg_write_uint_at_ptr(dst, id, t_typeid); - } - break; - - case ExactValue_Procedure: - GB_PANIC("TODO(bill): nested procedure values/literals\n"); - break; - case ExactValue_Compound: - GB_PANIC("TODO(bill): nested compound literals\n"); - break; - - case ExactValue_Complex: - GB_PANIC("TODO(bill): nested complex literals\n"); - break; - case ExactValue_Quaternion: - GB_PANIC("TODO(bill): nested quaternions literals\n"); - break; - default: - GB_PANIC("%s", type_to_string(f->type)); - break; - } - visited[i] = true; - continue; - } - - values[i] = cg_const_value(m, p, f->type, value, allow_local); - visited[i] = true; - } - } - - TB_Symbol *symbol = cast(TB_Symbol *)global; + { + TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_comp_literal(m, type, value.value_compound, allow_local); if (p) { TB_Node *node = tb_inst_get_symbol_address(p->func, symbol); return cg_lvalue_addr(node, type); } else { return cg_value(symbol, type); } - - } else { - GB_PANIC("TODO(bill): constant compound literal for %s", type_to_string(type)); } break; } |