authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-26 14:24:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-26 14:54:52-04:00
logdcfd15a7f0ed5159afad47915a11d1dd8315cbe8
treef582f0697e06ae95d9962d4720ac3573a8be4be6
parent631851f8b55b78363c9bc773230d9ee1e7122f5e
signaturelock-open Commit is signed but in an unrecognized format.

the last number in a packed ptr is host int bytes

See #1121

11 files changed, 124 insertions(+), 95 deletions(-)

src/all_types.hpp+7-10
...@@ -664,7 +664,7 @@ struct AstNodePointerType {...@@ -664,7 +664,7 @@ struct AstNodePointerType {
664 Token *star_token;664 Token *star_token;
665 AstNode *align_expr;665 AstNode *align_expr;
666 BigInt *bit_offset_start;666 BigInt *bit_offset_start;
667 BigInt *bit_offset_end;667 BigInt *host_int_bytes;
668 bool is_const;668 bool is_const;
669 bool is_volatile;669 bool is_volatile;
670 AstNode *op_expr;670 AstNode *op_expr;
...@@ -1020,8 +1020,8 @@ struct ZigTypePointer {...@@ -1020,8 +1020,8 @@ struct ZigTypePointer {
1020 ZigType *slice_parent;1020 ZigType *slice_parent;
1021 PtrLen ptr_len;1021 PtrLen ptr_len;
1022 uint32_t explicit_alignment; // 0 means use ABI alignment1022 uint32_t explicit_alignment; // 0 means use ABI alignment
1023 uint32_t bit_offset;1023 uint32_t bit_offset_in_host;
1024 uint32_t unaligned_bit_count;1024 uint32_t host_int_bytes; // size of host integer. 0 means no host integer; this field is aligned
1025 bool is_const;1025 bool is_const;
1026 bool is_volatile;1026 bool is_volatile;
1027};1027};
...@@ -1045,10 +1045,7 @@ struct TypeStructField {...@@ -1045,10 +1045,7 @@ struct TypeStructField {
1045 ZigType *type_entry;1045 ZigType *type_entry;
1046 size_t src_index;1046 size_t src_index;
1047 size_t gen_index;1047 size_t gen_index;
1048 // offset from the memory at gen_index1048 uint32_t bit_offset_in_host; // offset from the memory at gen_index
1049 size_t packed_bits_offset;
1050 size_t packed_bits_size;
1051 size_t unaligned_bit_count;
1052 AstNode *decl_node;1049 AstNode *decl_node;
1053};1050};
10541051
...@@ -1470,8 +1467,8 @@ struct TypeId {...@@ -1470,8 +1467,8 @@ struct TypeId {
1470 bool is_const;1467 bool is_const;
1471 bool is_volatile;1468 bool is_volatile;
1472 uint32_t alignment;1469 uint32_t alignment;
1473 uint32_t bit_offset;1470 uint32_t bit_offset_in_host;
1474 uint32_t unaligned_bit_count;1471 uint32_t host_int_bytes;
1475 } pointer;1472 } pointer;
1476 struct {1473 struct {
1477 ZigType *child_type;1474 ZigType *child_type;
...@@ -2510,7 +2507,7 @@ struct IrInstructionPtrType {...@@ -2510,7 +2507,7 @@ struct IrInstructionPtrType {
2510 IrInstruction *align_value;2507 IrInstruction *align_value;
2511 IrInstruction *child_type;2508 IrInstruction *child_type;
2512 uint32_t bit_offset_start;2509 uint32_t bit_offset_start;
2513 uint32_t bit_offset_end;2510 uint32_t host_int_bytes;
2514 PtrLen ptr_len;2511 PtrLen ptr_len;
2515 bool is_const;2512 bool is_const;
2516 bool is_volatile;2513 bool is_volatile;
src/analyze.cpp+39-26
...@@ -419,7 +419,7 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {...@@ -419,7 +419,7 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
419}419}
420420
421ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,421ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
422 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count)422 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset_in_host, uint32_t host_int_bytes)
423{423{
424 assert(!type_is_invalid(child_type));424 assert(!type_is_invalid(child_type));
425 assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);425 assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);
...@@ -430,23 +430,31 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -430,23 +430,31 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
430 byte_alignment = 0;430 byte_alignment = 0;
431 }431 }
432432
433 if (host_int_bytes != 0) {
434 uint32_t child_type_bits = type_size_bits(g, child_type);
435 if (host_int_bytes * 8 == child_type_bits) {
436 assert(bit_offset_in_host == 0);
437 host_int_bytes = 0;
438 }
439 }
440
433 TypeId type_id = {};441 TypeId type_id = {};
434 ZigType **parent_pointer = nullptr;442 ZigType **parent_pointer = nullptr;
435 if (unaligned_bit_count != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle) {443 if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle) {
436 type_id.id = ZigTypeIdPointer;444 type_id.id = ZigTypeIdPointer;
437 type_id.data.pointer.child_type = child_type;445 type_id.data.pointer.child_type = child_type;
438 type_id.data.pointer.is_const = is_const;446 type_id.data.pointer.is_const = is_const;
439 type_id.data.pointer.is_volatile = is_volatile;447 type_id.data.pointer.is_volatile = is_volatile;
440 type_id.data.pointer.alignment = byte_alignment;448 type_id.data.pointer.alignment = byte_alignment;
441 type_id.data.pointer.bit_offset = bit_offset;449 type_id.data.pointer.bit_offset_in_host = bit_offset_in_host;
442 type_id.data.pointer.unaligned_bit_count = unaligned_bit_count;450 type_id.data.pointer.host_int_bytes = host_int_bytes;
443 type_id.data.pointer.ptr_len = ptr_len;451 type_id.data.pointer.ptr_len = ptr_len;
444452
445 auto existing_entry = g->type_table.maybe_get(type_id);453 auto existing_entry = g->type_table.maybe_get(type_id);
446 if (existing_entry)454 if (existing_entry)
447 return existing_entry->value;455 return existing_entry->value;
448 } else {456 } else {
449 assert(bit_offset == 0);457 assert(bit_offset_in_host == 0);
450 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];458 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
451 if (*parent_pointer) {459 if (*parent_pointer) {
452 assert((*parent_pointer)->data.pointer.explicit_alignment == 0);460 assert((*parent_pointer)->data.pointer.explicit_alignment == 0);
...@@ -463,17 +471,17 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -463,17 +471,17 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
463 const char *const_str = is_const ? "const " : "";471 const char *const_str = is_const ? "const " : "";
464 const char *volatile_str = is_volatile ? "volatile " : "";472 const char *volatile_str = is_volatile ? "volatile " : "";
465 buf_resize(&entry->name, 0);473 buf_resize(&entry->name, 0);
466 if (unaligned_bit_count == 0 && byte_alignment == 0) {474 if (host_int_bytes == 0 && byte_alignment == 0) {
467 buf_appendf(&entry->name, "%s%s%s%s", star_str, const_str, volatile_str, buf_ptr(&child_type->name));475 buf_appendf(&entry->name, "%s%s%s%s", star_str, const_str, volatile_str, buf_ptr(&child_type->name));
468 } else if (unaligned_bit_count == 0) {476 } else if (host_int_bytes == 0) {
469 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s", star_str, byte_alignment,477 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s", star_str, byte_alignment,
470 const_str, volatile_str, buf_ptr(&child_type->name));478 const_str, volatile_str, buf_ptr(&child_type->name));
471 } else if (byte_alignment == 0) {479 } else if (byte_alignment == 0) {
472 buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str,480 buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str,
473 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));481 bit_offset_in_host, host_int_bytes, const_str, volatile_str, buf_ptr(&child_type->name));
474 } else {482 } else {
475 buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str, byte_alignment,483 buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str, byte_alignment,
476 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));484 bit_offset_in_host, host_int_bytes, const_str, volatile_str, buf_ptr(&child_type->name));
477 }485 }
478486
479 assert(child_type->id != ZigTypeIdInvalid);487 assert(child_type->id != ZigTypeIdInvalid);
...@@ -481,7 +489,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -481,7 +489,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
481 entry->zero_bits = !type_has_bits(child_type);489 entry->zero_bits = !type_has_bits(child_type);
482490
483 if (!entry->zero_bits) {491 if (!entry->zero_bits) {
484 if (is_const || is_volatile || unaligned_bit_count != 0 || byte_alignment != 0 ||492 if (is_const || is_volatile || host_int_bytes != 0 || byte_alignment != 0 ||
485 ptr_len != PtrLenSingle)493 ptr_len != PtrLenSingle)
486 {494 {
487 ZigType *peer_type = get_pointer_to_type(g, child_type, false);495 ZigType *peer_type = get_pointer_to_type(g, child_type, false);
...@@ -506,8 +514,8 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -506,8 +514,8 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
506 entry->data.pointer.is_const = is_const;514 entry->data.pointer.is_const = is_const;
507 entry->data.pointer.is_volatile = is_volatile;515 entry->data.pointer.is_volatile = is_volatile;
508 entry->data.pointer.explicit_alignment = byte_alignment;516 entry->data.pointer.explicit_alignment = byte_alignment;
509 entry->data.pointer.bit_offset = bit_offset;517 entry->data.pointer.bit_offset_in_host = bit_offset_in_host;
510 entry->data.pointer.unaligned_bit_count = unaligned_bit_count;518 entry->data.pointer.host_int_bytes = host_int_bytes;
511519
512 if (parent_pointer) {520 if (parent_pointer) {
513 *parent_pointer = entry;521 *parent_pointer = entry;
...@@ -2007,12 +2015,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2007,12 +2015,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
2007 size_t field_size_in_bits = type_size_bits(g, field_type);2015 size_t field_size_in_bits = type_size_bits(g, field_type);
2008 size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits;2016 size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits;
20092017
2010 type_struct_field->packed_bits_size = field_size_in_bits;
2011
2012 if (first_packed_bits_offset_misalign != SIZE_MAX) {2018 if (first_packed_bits_offset_misalign != SIZE_MAX) {
2013 // this field is not byte-aligned; it is part of the previous field with a bit offset2019 // this field is not byte-aligned; it is part of the previous field with a bit offset
2014 type_struct_field->packed_bits_offset = packed_bits_offset - first_packed_bits_offset_misalign;2020 type_struct_field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign;
2015 type_struct_field->unaligned_bit_count = field_size_in_bits;
20162021
2017 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;2022 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;
2018 LLVMTypeRef int_type_ref = LLVMIntType((unsigned)(full_bit_count));2023 LLVMTypeRef int_type_ref = LLVMIntType((unsigned)(full_bit_count));
...@@ -2025,13 +2030,11 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2025,13 +2030,11 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
2025 }2030 }
2026 } else if (8 * LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref) != field_size_in_bits) {2031 } else if (8 * LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref) != field_size_in_bits) {
2027 first_packed_bits_offset_misalign = packed_bits_offset;2032 first_packed_bits_offset_misalign = packed_bits_offset;
2028 type_struct_field->packed_bits_offset = 0;2033 type_struct_field->bit_offset_in_host = 0;
2029 type_struct_field->unaligned_bit_count = field_size_in_bits;
2030 } else {2034 } else {
2031 // This is a byte-aligned field (both start and end) in a packed struct.2035 // This is a byte-aligned field (both start and end) in a packed struct.
2032 element_types[gen_field_index] = field_type->type_ref;2036 element_types[gen_field_index] = field_type->type_ref;
2033 type_struct_field->packed_bits_offset = 0;2037 type_struct_field->bit_offset_in_host = 0;
2034 type_struct_field->unaligned_bit_count = 0;
2035 gen_field_index += 1;2038 gen_field_index += 1;
2036 }2039 }
2037 packed_bits_offset = next_packed_bits_offset;2040 packed_bits_offset = next_packed_bits_offset;
...@@ -2124,10 +2127,10 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2124,10 +2127,10 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
2124 uint64_t debug_align_in_bits;2127 uint64_t debug_align_in_bits;
2125 uint64_t debug_offset_in_bits;2128 uint64_t debug_offset_in_bits;
2126 if (packed) {2129 if (packed) {
2127 debug_size_in_bits = type_struct_field->packed_bits_size;2130 debug_size_in_bits = type_size_bits(g, type_struct_field->type_entry);
2128 debug_align_in_bits = 1;2131 debug_align_in_bits = 1;
2129 debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref,2132 debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref,
2130 (unsigned)gen_field_index) + type_struct_field->packed_bits_offset;2133 (unsigned)gen_field_index) + type_struct_field->bit_offset_in_host;
2131 } else {2134 } else {
2132 debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);2135 debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
2133 debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);2136 debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);
...@@ -6007,8 +6010,8 @@ uint32_t type_id_hash(TypeId x) {...@@ -6007,8 +6010,8 @@ uint32_t type_id_hash(TypeId x) {
6007 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +6010 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +
6008 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +6011 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +
6009 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +6012 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +
6010 (((uint32_t)x.data.pointer.bit_offset) ^ (uint32_t)2639019452) +6013 (((uint32_t)x.data.pointer.bit_offset_in_host) ^ (uint32_t)2639019452) +
6011 (((uint32_t)x.data.pointer.unaligned_bit_count) ^ (uint32_t)529908881);6014 (((uint32_t)x.data.pointer.host_int_bytes) ^ (uint32_t)529908881);
6012 case ZigTypeIdArray:6015 case ZigTypeIdArray:
6013 return hash_ptr(x.data.array.child_type) +6016 return hash_ptr(x.data.array.child_type) +
6014 ((uint32_t)x.data.array.size ^ (uint32_t)2122979968);6017 ((uint32_t)x.data.array.size ^ (uint32_t)2122979968);
...@@ -6055,8 +6058,8 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -6055,8 +6058,8 @@ bool type_id_eql(TypeId a, TypeId b) {
6055 a.data.pointer.is_const == b.data.pointer.is_const &&6058 a.data.pointer.is_const == b.data.pointer.is_const &&
6056 a.data.pointer.is_volatile == b.data.pointer.is_volatile &&6059 a.data.pointer.is_volatile == b.data.pointer.is_volatile &&
6057 a.data.pointer.alignment == b.data.pointer.alignment &&6060 a.data.pointer.alignment == b.data.pointer.alignment &&
6058 a.data.pointer.bit_offset == b.data.pointer.bit_offset &&6061 a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
6059 a.data.pointer.unaligned_bit_count == b.data.pointer.unaligned_bit_count;6062 a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;
6060 case ZigTypeIdArray:6063 case ZigTypeIdArray:
6061 return a.data.array.child_type == b.data.array.child_type &&6064 return a.data.array.child_type == b.data.array.child_type &&
6062 a.data.array.size == b.data.array.size;6065 a.data.array.size == b.data.array.size;
...@@ -6534,3 +6537,13 @@ bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {...@@ -6534,3 +6537,13 @@ bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {
6534 ty->id == ZigTypeIdUnreachable ||6537 ty->id == ZigTypeIdUnreachable ||
6535 get_codegen_ptr_type(ty) != nullptr);6538 get_codegen_ptr_type(ty) != nullptr);
6536}6539}
6540
6541uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field) {
6542 assert(struct_type->id == ZigTypeIdStruct);
6543 if (struct_type->data.structure.layout != ContainerLayoutPacked) {
6544 return 0;
6545 }
6546 LLVMTypeRef field_type = LLVMStructGetTypeAtIndex(struct_type->type_ref, field->gen_index);
6547 return LLVMStoreSizeOfType(g->target_data_ref, field_type);
6548}
6549
src/analyze.hpp+2
...@@ -216,4 +216,6 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty);...@@ -216,4 +216,6 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty);
216bool type_is_c_abi_int(CodeGen *g, ZigType *ty);216bool type_is_c_abi_int(CodeGen *g, ZigType *ty);
217bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id);217bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id);
218218
219uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field);
220
219#endif221#endif
src/ast_render.cpp+2-2
...@@ -635,7 +635,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -635,7 +635,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
635 fprintf(ar->f, "align(");635 fprintf(ar->f, "align(");
636 render_node_grouped(ar, node->data.pointer_type.align_expr);636 render_node_grouped(ar, node->data.pointer_type.align_expr);
637 if (node->data.pointer_type.bit_offset_start != nullptr) {637 if (node->data.pointer_type.bit_offset_start != nullptr) {
638 assert(node->data.pointer_type.bit_offset_end != nullptr);638 assert(node->data.pointer_type.host_int_bytes != nullptr);
639639
640 Buf offset_start_buf = BUF_INIT;640 Buf offset_start_buf = BUF_INIT;
641 buf_resize(&offset_start_buf, 0);641 buf_resize(&offset_start_buf, 0);
...@@ -643,7 +643,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -643,7 +643,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
643643
644 Buf offset_end_buf = BUF_INIT;644 Buf offset_end_buf = BUF_INIT;
645 buf_resize(&offset_end_buf, 0);645 buf_resize(&offset_end_buf, 0);
646 bigint_append_buf(&offset_end_buf, node->data.pointer_type.bit_offset_end, 10);646 bigint_append_buf(&offset_end_buf, node->data.pointer_type.host_int_bytes, 10);
647647
648 fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));648 fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));
649 }649 }
src/codegen.cpp+30-21
...@@ -1795,8 +1795,8 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty...@@ -1795,8 +1795,8 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
1795 return nullptr;1795 return nullptr;
1796 }1796 }
17971797
1798 uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;1798 uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
1799 if (unaligned_bit_count == 0) {1799 if (host_int_bytes == 0) {
1800 gen_store(g, value, ptr, ptr_type);1800 gen_store(g, value, ptr, ptr_type);
1801 return nullptr;1801 return nullptr;
1802 }1802 }
...@@ -1804,10 +1804,12 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty...@@ -1804,10 +1804,12 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
1804 bool big_endian = g->is_big_endian;1804 bool big_endian = g->is_big_endian;
18051805
1806 LLVMValueRef containing_int = gen_load(g, ptr, ptr_type, "");1806 LLVMValueRef containing_int = gen_load(g, ptr, ptr_type, "");
1807
1808 uint32_t bit_offset = ptr_type->data.pointer.bit_offset;
1809 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));1807 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
1810 uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - unaligned_bit_count : bit_offset;1808 assert(host_bit_count == host_int_bytes * 8);
1809 uint32_t size_in_bits = type_size_bits(g, child_type);
1810
1811 uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host;
1812 uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - size_in_bits : bit_offset;
1811 LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);1813 LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);
18121814
1813 LLVMValueRef mask_val = LLVMConstAllOnes(child_type->type_ref);1815 LLVMValueRef mask_val = LLVMConstAllOnes(child_type->type_ref);
...@@ -3209,18 +3211,20 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3209,18 +3211,20 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
3209 ZigType *ptr_type = instruction->ptr->value.type;3211 ZigType *ptr_type = instruction->ptr->value.type;
3210 assert(ptr_type->id == ZigTypeIdPointer);3212 assert(ptr_type->id == ZigTypeIdPointer);
32113213
3212 uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;3214 uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
3213 if (unaligned_bit_count == 0)3215 if (host_int_bytes == 0)
3214 return get_handle_value(g, ptr, child_type, ptr_type);3216 return get_handle_value(g, ptr, child_type, ptr_type);
32153217
3216 bool big_endian = g->is_big_endian;3218 bool big_endian = g->is_big_endian;
32173219
3218 assert(!handle_is_ptr(child_type));3220 assert(!handle_is_ptr(child_type));
3219 LLVMValueRef containing_int = gen_load(g, ptr, ptr_type, "");3221 LLVMValueRef containing_int = gen_load(g, ptr, ptr_type, "");
3220
3221 uint32_t bit_offset = ptr_type->data.pointer.bit_offset;
3222 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));3222 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
3223 uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - unaligned_bit_count : bit_offset;3223 assert(host_bit_count == host_int_bytes * 8);
3224 uint32_t size_in_bits = type_size_bits(g, child_type);
3225
3226 uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host;
3227 uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - size_in_bits : bit_offset;
32243228
3225 LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);3229 LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);
3226 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");3230 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
...@@ -3276,20 +3280,22 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3276,20 +3280,22 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
3276 array_type->data.array.len, false);3280 array_type->data.array.len, false);
3277 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);3281 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);
3278 }3282 }
3279 if (array_ptr_type->data.pointer.unaligned_bit_count != 0) {3283 if (array_ptr_type->data.pointer.host_int_bytes != 0) {
3280 return array_ptr_ptr;3284 return array_ptr_ptr;
3281 }3285 }
3282 ZigType *child_type = array_type->data.array.child_type;3286 ZigType *child_type = array_type->data.array.child_type;
3283 if (child_type->id == ZigTypeIdStruct &&3287 if (child_type->id == ZigTypeIdStruct &&
3284 child_type->data.structure.layout == ContainerLayoutPacked)3288 child_type->data.structure.layout == ContainerLayoutPacked)
3285 {3289 {
3286 size_t unaligned_bit_count = instruction->base.value.type->data.pointer.unaligned_bit_count;3290 ZigType *ptr_type = instruction->base.value.type;
3287 if (unaligned_bit_count != 0) {3291 size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
3292 if (host_int_bytes != 0) {
3293 uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type);
3288 LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0);3294 LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0);
3289 LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, "");3295 LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, "");
3290 assert(unaligned_bit_count % 8 == 0);3296 assert(size_in_bits % 8 == 0);
3291 LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->type_ref,3297 LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
3292 unaligned_bit_count / 8, false);3298 size_in_bits / 8, false);
3293 LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, "");3299 LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, "");
3294 LLVMValueRef indices[] = {3300 LLVMValueRef indices[] = {
3295 byte_offset3301 byte_offset
...@@ -3505,7 +3511,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa...@@ -3505,7 +3511,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
3505 return nullptr;3511 return nullptr;
35063512
3507 if (struct_ptr_type->id == ZigTypeIdPointer &&3513 if (struct_ptr_type->id == ZigTypeIdPointer &&
3508 struct_ptr_type->data.pointer.unaligned_bit_count != 0)3514 struct_ptr_type->data.pointer.host_int_bytes != 0)
3509 {3515 {
3510 return struct_ptr;3516 return struct_ptr;
3511 }3517 }
...@@ -4671,10 +4677,11 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,...@@ -4671,10 +4677,11 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,
4671 LLVMValueRef value = ir_llvm_value(g, field->value);4677 LLVMValueRef value = ir_llvm_value(g, field->value);
46724678
4673 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);4679 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
4680 uint32_t host_int_bytes = get_host_int_bytes(g, instruction->struct_type, type_struct_field);
46744681
4675 ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,4682 ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
4676 false, false, PtrLenSingle, field_align_bytes,4683 false, false, PtrLenSingle, field_align_bytes,
4677 (uint32_t)type_struct_field->packed_bits_offset, (uint32_t)type_struct_field->unaligned_bit_count);4684 (uint32_t)type_struct_field->bit_offset_in_host, host_int_bytes);
46784685
4679 gen_assign_raw(g, field_ptr, ptr_type, value);4686 gen_assign_raw(g, field_ptr, ptr_type, value);
4680 }4687 }
...@@ -5459,15 +5466,16 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -5459,15 +5466,16 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
5459 continue;5466 continue;
5460 }5467 }
5461 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, &const_val->data.x_struct.fields[i]);5468 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, &const_val->data.x_struct.fields[i]);
5469 uint32_t packed_bits_size = type_size_bits(g, field->type_entry);
5462 if (is_big_endian) {5470 if (is_big_endian) {
5463 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, field->packed_bits_size, false);5471 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false);
5464 val = LLVMConstShl(val, shift_amt);5472 val = LLVMConstShl(val, shift_amt);
5465 val = LLVMConstOr(val, child_val);5473 val = LLVMConstOr(val, child_val);
5466 } else {5474 } else {
5467 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false);5475 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false);
5468 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt);5476 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt);
5469 val = LLVMConstOr(val, child_val_shifted);5477 val = LLVMConstOr(val, child_val_shifted);
5470 used_bits += field->packed_bits_size;5478 used_bits += packed_bits_size;
5471 }5479 }
5472 }5480 }
5473 return val;5481 return val;
...@@ -5677,16 +5685,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -5677,16 +5685,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
5677 }5685 }
5678 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref,5686 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref,
5679 &const_val->data.x_struct.fields[i]);5687 &const_val->data.x_struct.fields[i]);
5688 uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry);
5680 if (is_big_endian) {5689 if (is_big_endian) {
5681 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref,5690 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref,
5682 it_field->packed_bits_size, false);5691 packed_bits_size, false);
5683 val = LLVMConstShl(val, shift_amt);5692 val = LLVMConstShl(val, shift_amt);
5684 val = LLVMConstOr(val, child_val);5693 val = LLVMConstOr(val, child_val);
5685 } else {5694 } else {
5686 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false);5695 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false);
5687 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt);5696 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt);
5688 val = LLVMConstOr(val, child_val_shifted);5697 val = LLVMConstOr(val, child_val_shifted);
5689 used_bits += it_field->packed_bits_size;5698 used_bits += packed_bits_size;
5690 }5699 }
5691 }5700 }
5692 fields[type_struct_field->gen_index] = val;5701 fields[type_struct_field->gen_index] = val;
src/ir.cpp+31-31
...@@ -1296,7 +1296,7 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru...@@ -1296,7 +1296,7 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru
12961296
1297static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node,1297static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
1298 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,1298 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,
1299 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t bit_offset_end)1299 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t host_int_bytes)
1300{1300{
1301 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node);1301 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node);
1302 ptr_type_of_instruction->align_value = align_value;1302 ptr_type_of_instruction->align_value = align_value;
...@@ -1305,7 +1305,7 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s...@@ -1305,7 +1305,7 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s
1305 ptr_type_of_instruction->is_volatile = is_volatile;1305 ptr_type_of_instruction->is_volatile = is_volatile;
1306 ptr_type_of_instruction->ptr_len = ptr_len;1306 ptr_type_of_instruction->ptr_len = ptr_len;
1307 ptr_type_of_instruction->bit_offset_start = bit_offset_start;1307 ptr_type_of_instruction->bit_offset_start = bit_offset_start;
1308 ptr_type_of_instruction->bit_offset_end = bit_offset_end;1308 ptr_type_of_instruction->host_int_bytes = host_int_bytes;
13091309
1310 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block);1310 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block);
1311 ir_ref_instruction(child_type, irb->current_basic_block);1311 ir_ref_instruction(child_type, irb->current_basic_block);
...@@ -5154,26 +5154,26 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode...@@ -5154,26 +5154,26 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
5154 bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start);5154 bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start);
5155 }5155 }
51565156
5157 uint32_t bit_offset_end = 0;5157 uint32_t host_int_bytes = 0;
5158 if (node->data.pointer_type.bit_offset_end != nullptr) {5158 if (node->data.pointer_type.host_int_bytes != nullptr) {
5159 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_end, 32, false)) {5159 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) {
5160 Buf *val_buf = buf_alloc();5160 Buf *val_buf = buf_alloc();
5161 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_end, 10);5161 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10);
5162 exec_add_error_node(irb->codegen, irb->exec, node,5162 exec_add_error_node(irb->codegen, irb->exec, node,
5163 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf)));5163 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf)));
5164 return irb->codegen->invalid_instruction;5164 return irb->codegen->invalid_instruction;
5165 }5165 }
5166 bit_offset_end = bigint_as_unsigned(node->data.pointer_type.bit_offset_end);5166 host_int_bytes = bigint_as_unsigned(node->data.pointer_type.host_int_bytes);
5167 }5167 }
51685168
5169 if ((bit_offset_start != 0 || bit_offset_end != 0) && bit_offset_start >= bit_offset_end) {5169 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) {
5170 exec_add_error_node(irb->codegen, irb->exec, node,5170 exec_add_error_node(irb->codegen, irb->exec, node,
5171 buf_sprintf("bit offset start must be less than bit offset end"));5171 buf_sprintf("bit offset starts after end of host integer"));
5172 return irb->codegen->invalid_instruction;5172 return irb->codegen->invalid_instruction;
5173 }5173 }
51745174
5175 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile,5175 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile,
5176 ptr_len, align_value, bit_offset_start, bit_offset_end);5176 ptr_len, align_value, bit_offset_start, host_int_bytes);
5177}5177}
51785178
5179static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,5179static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
...@@ -8600,8 +8600,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted...@@ -8600,8 +8600,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
8600 if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&8600 if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
8601 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&8601 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
8602 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&8602 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
8603 actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&8603 actual_type->data.pointer.bit_offset_in_host == wanted_type->data.pointer.bit_offset_in_host &&
8604 actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&8604 actual_type->data.pointer.host_int_bytes == wanted_type->data.pointer.host_int_bytes &&
8605 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type))8605 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type))
8606 {8606 {
8607 return result;8607 return result;
...@@ -8622,8 +8622,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted...@@ -8622,8 +8622,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
8622 }8622 }
8623 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&8623 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
8624 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&8624 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
8625 actual_ptr_type->data.pointer.bit_offset == wanted_ptr_type->data.pointer.bit_offset &&8625 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
8626 actual_ptr_type->data.pointer.unaligned_bit_count == wanted_ptr_type->data.pointer.unaligned_bit_count &&8626 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes &&
8627 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type))8627 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type))
8628 {8628 {
8629 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,8629 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
...@@ -11166,8 +11166,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11166,8 +11166,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11166 if (dest_ptr_type != nullptr &&11166 if (dest_ptr_type != nullptr &&
11167 (!actual_type->data.pointer.is_const || dest_ptr_type->data.pointer.is_const) &&11167 (!actual_type->data.pointer.is_const || dest_ptr_type->data.pointer.is_const) &&
11168 (!actual_type->data.pointer.is_volatile || dest_ptr_type->data.pointer.is_volatile) &&11168 (!actual_type->data.pointer.is_volatile || dest_ptr_type->data.pointer.is_volatile) &&
11169 actual_type->data.pointer.bit_offset == dest_ptr_type->data.pointer.bit_offset &&11169 actual_type->data.pointer.bit_offset_in_host == dest_ptr_type->data.pointer.bit_offset_in_host &&
11170 actual_type->data.pointer.unaligned_bit_count == dest_ptr_type->data.pointer.unaligned_bit_count &&11170 actual_type->data.pointer.host_int_bytes == dest_ptr_type->data.pointer.host_int_bytes &&
11171 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, dest_ptr_type))11171 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, dest_ptr_type))
11172 {11172 {
11173 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr);11173 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr);
...@@ -14359,7 +14359,7 @@ static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_ali...@@ -14359,7 +14359,7 @@ static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_ali
14359 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,14359 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14360 ptr_type->data.pointer.ptr_len,14360 ptr_type->data.pointer.ptr_len,
14361 new_align,14361 new_align,
14362 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);14362 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes);
14363}14363}
1436414364
14365static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) {14365static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) {
...@@ -14376,7 +14376,7 @@ static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) {...@@ -14376,7 +14376,7 @@ static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) {
14376 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,14376 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14377 ptr_len,14377 ptr_len,
14378 ptr_type->data.pointer.explicit_alignment,14378 ptr_type->data.pointer.explicit_alignment,
14379 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);14379 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes);
14380}14380}
1438114381
14382static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {14382static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
...@@ -14423,7 +14423,7 @@ static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionEle...@@ -14423,7 +14423,7 @@ static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionEle
14423 return ira->codegen->builtin_types.entry_invalid;14423 return ira->codegen->builtin_types.entry_invalid;
14424 }14424 }
14425 ZigType *child_type = array_type->data.array.child_type;14425 ZigType *child_type = array_type->data.array.child_type;
14426 if (ptr_type->data.pointer.unaligned_bit_count == 0) {14426 if (ptr_type->data.pointer.host_int_bytes == 0) {
14427 return_type = get_pointer_to_type_extra(ira->codegen, child_type,14427 return_type = get_pointer_to_type_extra(ira->codegen, child_type,
14428 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,14428 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14429 elem_ptr_instruction->ptr_len,14429 elem_ptr_instruction->ptr_len,
...@@ -14439,7 +14439,7 @@ static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionEle...@@ -14439,7 +14439,7 @@ static ZigType *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionEle
14439 return_type = get_pointer_to_type_extra(ira->codegen, child_type,14439 return_type = get_pointer_to_type_extra(ira->codegen, child_type,
14440 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,14440 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14441 elem_ptr_instruction->ptr_len,14441 elem_ptr_instruction->ptr_len,
14442 1, (uint32_t)bit_offset, (uint32_t)bit_width);14442 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes);
14443 }14443 }
14444 } else if (array_type->id == ZigTypeIdPointer) {14444 } else if (array_type->id == ZigTypeIdPointer) {
14445 if (array_type->data.pointer.ptr_len == PtrLenSingle) {14445 if (array_type->data.pointer.ptr_len == PtrLenSingle) {
...@@ -14740,10 +14740,10 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -14740,10 +14740,10 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
14740 if (field) {14740 if (field) {
14741 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);14741 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
14742 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);14742 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
14743 size_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset;14743 uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host;
14744 size_t ptr_unaligned_bit_count = container_ptr->value.type->data.pointer.unaligned_bit_count;14744 uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes;
14745 size_t unaligned_bit_count_for_result_type = (ptr_unaligned_bit_count == 0) ?14745 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
14746 field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry);14746 get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes;
14747 if (instr_is_comptime(container_ptr)) {14747 if (instr_is_comptime(container_ptr)) {
14748 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);14748 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
14749 if (!ptr_val)14749 if (!ptr_val)
...@@ -14758,8 +14758,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -14758,8 +14758,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
14758 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];14758 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
14759 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,14759 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
14760 is_const, is_volatile, PtrLenSingle, align_bytes,14760 is_const, is_volatile, PtrLenSingle, align_bytes,
14761 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),14761 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
14762 (uint32_t)unaligned_bit_count_for_result_type);14762 (uint32_t)host_int_bytes_for_result_type);
14763 IrInstruction *result = ir_get_const(ira, source_instr);14763 IrInstruction *result = ir_get_const(ira, source_instr);
14764 ConstExprValue *const_val = &result->value;14764 ConstExprValue *const_val = &result->value;
14765 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;14765 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
...@@ -14775,8 +14775,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -14775,8 +14775,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
14775 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,14775 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
14776 PtrLenSingle,14776 PtrLenSingle,
14777 align_bytes,14777 align_bytes,
14778 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),14778 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
14779 (uint32_t)unaligned_bit_count_for_result_type);14779 host_int_bytes_for_result_type);
14780 return result;14780 return result;
14781 } else {14781 } else {
14782 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,14782 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
...@@ -17135,7 +17135,7 @@ static ZigType *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira,...@@ -17135,7 +17135,7 @@ static ZigType *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira,
17135 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset)))17135 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset)))
17136 return ira->codegen->builtin_types.entry_invalid;17136 return ira->codegen->builtin_types.entry_invalid;
1713717137
17138 size_t bit_offset = byte_offset * 8 + field->packed_bits_offset;17138 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host;
17139 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);17139 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
17140 bigint_init_unsigned(&out_val->data.x_bigint, bit_offset);17140 bigint_init_unsigned(&out_val->data.x_bigint, bit_offset);
17141 return ira->codegen->builtin_types.entry_num_lit_int;17141 return ira->codegen->builtin_types.entry_num_lit_int;
...@@ -20758,7 +20758,7 @@ static ZigType *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtr...@@ -20758,7 +20758,7 @@ static ZigType *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtr
20758 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,20758 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
20759 instruction->is_const, instruction->is_volatile,20759 instruction->is_const, instruction->is_volatile,
20760 instruction->ptr_len, align_bytes,20760 instruction->ptr_len, align_bytes,
20761 instruction->bit_offset_start, instruction->bit_offset_end - instruction->bit_offset_start);20761 instruction->bit_offset_start, instruction->host_int_bytes);
2076220762
20763 return ira->codegen->builtin_types.entry_type;20763 return ira->codegen->builtin_types.entry_type;
20764}20764}
src/ir_print.cpp+1-1
...@@ -1015,7 +1015,7 @@ static void ir_print_ptr_type(IrPrint *irp, IrInstructionPtrType *instruction) {...@@ -1015,7 +1015,7 @@ static void ir_print_ptr_type(IrPrint *irp, IrInstructionPtrType *instruction) {
1015 }1015 }
1016 const char *const_str = instruction->is_const ? "const " : "";1016 const char *const_str = instruction->is_const ? "const " : "";
1017 const char *volatile_str = instruction->is_volatile ? "volatile " : "";1017 const char *volatile_str = instruction->is_volatile ? "volatile " : "";
1018 fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->bit_offset_end,1018 fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->host_int_bytes,
1019 const_str, volatile_str);1019 const_str, volatile_str);
1020 ir_print_other_instruction(irp, instruction->child_type);1020 ir_print_other_instruction(irp, instruction->child_type);
1021}1021}
src/parser.cpp+2-2
...@@ -1161,10 +1161,10 @@ static AstNode *ast_parse_pointer_type(ParseContext *pc, size_t *token_index, To...@@ -1161,10 +1161,10 @@ static AstNode *ast_parse_pointer_type(ParseContext *pc, size_t *token_index, To
1161 *token_index += 1;1161 *token_index += 1;
1162 Token *bit_offset_start_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);1162 Token *bit_offset_start_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
1163 ast_eat_token(pc, token_index, TokenIdColon);1163 ast_eat_token(pc, token_index, TokenIdColon);
1164 Token *bit_offset_end_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);1164 Token *host_int_bytes_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
11651165
1166 node->data.pointer_type.bit_offset_start = token_bigint(bit_offset_start_tok);1166 node->data.pointer_type.bit_offset_start = token_bigint(bit_offset_start_tok);
1167 node->data.pointer_type.bit_offset_end = token_bigint(bit_offset_end_tok);1167 node->data.pointer_type.host_int_bytes = token_bigint(host_int_bytes_tok);
1168 }1168 }
1169 ast_eat_token(pc, token_index, TokenIdRParen);1169 ast_eat_token(pc, token_index, TokenIdRParen);
1170 token = &pc->tokens->at(*token_index);1170 token = &pc->tokens->at(*token_index);
test/cases/align.zig+1-1
...@@ -40,7 +40,7 @@ const blah: packed struct {...@@ -40,7 +40,7 @@ const blah: packed struct {
40} = undefined;40} = undefined;
4141
42test "bit field alignment" {42test "bit field alignment" {
43 assert(@typeOf(&blah.b) == *align(1:3:6) const u3);43 assert(@typeOf(&blah.b) == *align(1:3:1) const u3);
44}44}
4545
46test "default alignment allows unspecified in type syntax" {46test "default alignment allows unspecified in type syntax" {
test/cases/eval.zig+8
...@@ -754,3 +754,11 @@ test "comptime bitwise operators" {...@@ -754,3 +754,11 @@ test "comptime bitwise operators" {
754 assert(~u128(0) == 0xffffffffffffffffffffffffffffffff);754 assert(~u128(0) == 0xffffffffffffffffffffffffffffffff);
755 }755 }
756}756}
757
758test "*align(1) u16 is the same as *align(1:0:2) u16" {
759 comptime {
760 assert(*align(1:0:2) u16 == *align(1) u16);
761 // TODO add parsing support for this syntax
762 //assert(*align(:0:2) u16 == *u16);
763 }
764}
test/compile_errors.zig+1-1
...@@ -3536,7 +3536,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3536,7 +3536,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3536 \\3536 \\
3537 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }3537 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
3538 ,3538 ,
3539 ".tmp_source.zig:8:26: error: expected type '*const u3', found '*align(:3:6) const u3'",3539 ".tmp_source.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",
3540 );3540 );
35413541
3542 cases.add(3542 cases.add(