| ... | ... | @@ -7339,28 +7339,36 @@ pub const Constant = enum(u32) { |
| 7339 | 7339 | .positive_integer, |
| 7340 | 7340 | .negative_integer, |
| 7341 | 7341 | => |tag| { |
| 7342 | | const extra: *align(@alignOf(std.math.big.Limb)) Integer = |
| 7342 | const extra: *align(@alignOf(std.math.big.Limb)) const Integer = |
| 7343 | 7343 | @ptrCast(data.builder.constant_limbs.items[item.data..][0..Integer.limbs]); |
| 7344 | 7344 | const limbs = data.builder.constant_limbs |
| 7345 | 7345 | .items[item.data + Integer.limbs ..][0..extra.limbs_len]; |
| 7346 | 7346 | const bigint: std.math.big.int.Const = .{ |
| 7347 | 7347 | .limbs = limbs, |
| 7348 | | .positive = tag == .positive_integer, |
| 7348 | .positive = switch (tag) { |
| 7349 | .positive_integer => true, |
| 7350 | .negative_integer => false, |
| 7351 | else => unreachable, |
| 7352 | }, |
| 7349 | 7353 | }; |
| 7350 | 7354 | const ExpectedContents = extern struct { |
| 7351 | | string: [(64 * 8 / std.math.log2(10)) + 2]u8, |
| 7355 | const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); |
| 7356 | string: [ |
| 7357 | (std.math.big.int.Const{ |
| 7358 | .limbs = &([1]std.math.big.Limb{ |
| 7359 | std.math.maxInt(std.math.big.Limb), |
| 7360 | } ** expected_limbs), |
| 7361 | .positive = false, |
| 7362 | }).sizeInBaseUpperBound(10) |
| 7363 | ]u8, |
| 7352 | 7364 | limbs: [ |
| 7353 | | std.math.big.int.calcToStringLimbsBufferLen( |
| 7354 | | 64 / @sizeOf(std.math.big.Limb), |
| 7355 | | 10, |
| 7356 | | ) |
| 7365 | std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10) |
| 7357 | 7366 | ]std.math.big.Limb, |
| 7358 | 7367 | }; |
| 7359 | 7368 | var stack align(@alignOf(ExpectedContents)) = |
| 7360 | 7369 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.builder.gpa); |
| 7361 | 7370 | const allocator = stack.get(); |
| 7362 | | const str = bigint.toStringAlloc(allocator, 10, undefined) catch |
| 7363 | | return writer.writeAll("..."); |
| 7371 | const str = try bigint.toStringAlloc(allocator, 10, undefined); |
| 7364 | 7372 | defer allocator.free(str); |
| 7365 | 7373 | try writer.writeAll(str); |
| 7366 | 7374 | }, |
| ... | ... | @@ -9464,10 +9472,38 @@ pub fn print(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocato |
| 9464 | 9472 | try bw.flush(); |
| 9465 | 9473 | } |
| 9466 | 9474 | |
| 9475 | fn WriterWithErrors(comptime BackingWriter: type, comptime ExtraErrors: type) type { |
| 9476 | return struct { |
| 9477 | backing_writer: BackingWriter, |
| 9478 | |
| 9479 | pub const Error = BackingWriter.Error || ExtraErrors; |
| 9480 | pub const Writer = std.io.Writer(*const Self, Error, write); |
| 9481 | |
| 9482 | const Self = @This(); |
| 9483 | |
| 9484 | pub fn writer(self: *const Self) Writer { |
| 9485 | return .{ .context = self }; |
| 9486 | } |
| 9487 | |
| 9488 | pub fn write(self: *const Self, bytes: []const u8) Error!usize { |
| 9489 | return self.backing_writer.write(bytes); |
| 9490 | } |
| 9491 | }; |
| 9492 | } |
| 9493 | fn writerWithErrors( |
| 9494 | backing_writer: anytype, |
| 9495 | comptime ExtraErrors: type, |
| 9496 | ) WriterWithErrors(@TypeOf(backing_writer), ExtraErrors) { |
| 9497 | return .{ .backing_writer = backing_writer }; |
| 9498 | } |
| 9499 | |
| 9467 | 9500 | pub fn printUnbuffered( |
| 9468 | 9501 | self: *Builder, |
| 9469 | | writer: anytype, |
| 9470 | | ) (@TypeOf(writer).Error || Allocator.Error)!void { |
| 9502 | backing_writer: anytype, |
| 9503 | ) (@TypeOf(backing_writer).Error || Allocator.Error)!void { |
| 9504 | const writer_with_errors = writerWithErrors(backing_writer, Allocator.Error); |
| 9505 | const writer = writer_with_errors.writer(); |
| 9506 | |
| 9471 | 9507 | var need_newline = false; |
| 9472 | 9508 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; |
| 9473 | 9509 | defer metadata_formatter.map.deinit(self.gpa); |
| ... | ... | @@ -10344,12 +10380,17 @@ pub fn printUnbuffered( |
| 10344 | 10380 | const extra = self.metadataExtraData(Metadata.Enumerator, metadata_item.data); |
| 10345 | 10381 | |
| 10346 | 10382 | const ExpectedContents = extern struct { |
| 10347 | | string: [(64 * 8 / std.math.log2(10)) + 2]u8, |
| 10383 | const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); |
| 10384 | string: [ |
| 10385 | (std.math.big.int.Const{ |
| 10386 | .limbs = &([1]std.math.big.Limb{ |
| 10387 | std.math.maxInt(std.math.big.Limb), |
| 10388 | } ** expected_limbs), |
| 10389 | .positive = false, |
| 10390 | }).sizeInBaseUpperBound(10) |
| 10391 | ]u8, |
| 10348 | 10392 | limbs: [ |
| 10349 | | std.math.big.int.calcToStringLimbsBufferLen( |
| 10350 | | 64 / @sizeOf(std.math.big.Limb), |
| 10351 | | 10, |
| 10352 | | ) |
| 10393 | std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10) |
| 10353 | 10394 | ]std.math.big.Limb, |
| 10354 | 10395 | }; |
| 10355 | 10396 | var stack align(@alignOf(ExpectedContents)) = |
| ... | ... | @@ -10375,7 +10416,9 @@ pub fn printUnbuffered( |
| 10375 | 10416 | .value = str, |
| 10376 | 10417 | .isUnsigned = switch (kind) { |
| 10377 | 10418 | .enumerator_unsigned => true, |
| 10378 | | .enumerator_signed_positive, .enumerator_signed_negative => false, |
| 10419 | .enumerator_signed_positive, |
| 10420 | .enumerator_signed_negative, |
| 10421 | => false, |
| 10379 | 10422 | else => unreachable, |
| 10380 | 10423 | }, |
| 10381 | 10424 | }, writer); |
| ... | ... | @@ -13787,37 +13830,42 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13787 | 13830 | => |tag| { |
| 13788 | 13831 | const extra: *align(@alignOf(std.math.big.Limb)) Constant.Integer = |
| 13789 | 13832 | @ptrCast(self.constant_limbs.items[data..][0..Constant.Integer.limbs]); |
| 13790 | | const limbs = self.constant_limbs |
| 13791 | | .items[data + Constant.Integer.limbs ..][0..extra.limbs_len]; |
| 13792 | 13833 | const bigint: std.math.big.int.Const = .{ |
| 13793 | | .limbs = limbs, |
| 13794 | | .positive = tag == .positive_integer, |
| 13834 | .limbs = self.constant_limbs |
| 13835 | .items[data + Constant.Integer.limbs ..][0..extra.limbs_len], |
| 13836 | .positive = switch (tag) { |
| 13837 | .positive_integer => true, |
| 13838 | .negative_integer => false, |
| 13839 | else => unreachable, |
| 13840 | }, |
| 13795 | 13841 | }; |
| 13796 | | |
| 13797 | 13842 | const bit_count = extra.type.scalarBits(self); |
| 13798 | | if (bit_count <= 64) { |
| 13799 | | const val = bigint.to(i64) catch unreachable; |
| 13800 | | const emit_val = if (tag == .positive_integer) |
| 13801 | | @shlWithOverflow(val, 1)[0] |
| 13802 | | else |
| 13803 | | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); |
| 13804 | | try constants_block.writeAbbrev(Constants.Integer{ .value = @bitCast(emit_val) }); |
| 13805 | | } else { |
| 13806 | | const word_count = std.mem.alignForward(u24, bit_count, 64) / 64; |
| 13807 | | try record.ensureUnusedCapacity(self.gpa, word_count); |
| 13808 | | const buffer: [*]u8 = @ptrCast(record.items.ptr); |
| 13809 | | bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little); |
| 13810 | | |
| 13811 | | const signed_buffer: [*]i64 = @ptrCast(record.items.ptr); |
| 13812 | | for (signed_buffer[0..word_count], 0..) |val, i| { |
| 13813 | | signed_buffer[i] = if (val >= 0) |
| 13814 | | @shlWithOverflow(val, 1)[0] |
| 13843 | const val: i64 = if (bit_count <= 64) |
| 13844 | bigint.to(i64) catch unreachable |
| 13845 | else if (bigint.to(u64)) |val| |
| 13846 | @bitCast(val) |
| 13847 | else |_| { |
| 13848 | const limbs = try record.addManyAsSlice( |
| 13849 | self.gpa, |
| 13850 | std.math.divCeil(u24, bit_count, 64) catch unreachable, |
| 13851 | ); |
| 13852 | bigint.writeTwosComplement(std.mem.sliceAsBytes(limbs), .little); |
| 13853 | for (limbs) |*limb| { |
| 13854 | const val = std.mem.littleToNative(i64, @bitCast(limb.*)); |
| 13855 | limb.* = @bitCast(if (val >= 0) |
| 13856 | val << 1 | 0 |
| 13815 | 13857 | else |
| 13816 | | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); |
| 13858 | -%val << 1 | 1); |
| 13817 | 13859 | } |
| 13818 | | |
| 13819 | | try constants_block.writeUnabbrev(5, record.items.ptr[0..word_count]); |
| 13820 | | } |
| 13860 | try constants_block.writeUnabbrev(5, record.items); |
| 13861 | continue; |
| 13862 | }; |
| 13863 | try constants_block.writeAbbrev(Constants.Integer{ |
| 13864 | .value = @bitCast(if (val >= 0) |
| 13865 | val << 1 | 0 |
| 13866 | else |
| 13867 | -%val << 1 | 1), |
| 13868 | }); |
| 13821 | 13869 | }, |
| 13822 | 13870 | .half, |
| 13823 | 13871 | .bfloat, |
| ... | ... | @@ -14186,6 +14234,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14186 | 14234 | self.metadata_items.items(.tag)[1..], |
| 14187 | 14235 | self.metadata_items.items(.data)[1..], |
| 14188 | 14236 | ) |tag, data| { |
| 14237 | record.clearRetainingCapacity(); |
| 14189 | 14238 | switch (tag) { |
| 14190 | 14239 | .none => unreachable, |
| 14191 | 14240 | .file => { |
| ... | ... | @@ -14333,77 +14382,60 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14333 | 14382 | .enumerator_signed_positive, |
| 14334 | 14383 | .enumerator_signed_negative, |
| 14335 | 14384 | => |kind| { |
| 14336 | | const positive = switch (kind) { |
| 14337 | | .enumerator_unsigned, |
| 14338 | | .enumerator_signed_positive, |
| 14339 | | => true, |
| 14340 | | .enumerator_signed_negative => false, |
| 14341 | | else => unreachable, |
| 14342 | | }; |
| 14343 | | |
| 14344 | | const unsigned = switch (kind) { |
| 14345 | | .enumerator_unsigned => true, |
| 14346 | | .enumerator_signed_positive, |
| 14347 | | .enumerator_signed_negative, |
| 14348 | | => false, |
| 14349 | | else => unreachable, |
| 14350 | | }; |
| 14351 | | |
| 14352 | 14385 | const extra = self.metadataExtraData(Metadata.Enumerator, data); |
| 14353 | | |
| 14354 | | const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len]; |
| 14355 | | |
| 14356 | 14386 | const bigint: std.math.big.int.Const = .{ |
| 14357 | | .limbs = limbs, |
| 14358 | | .positive = positive, |
| 14387 | .limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len], |
| 14388 | .positive = switch (kind) { |
| 14389 | .enumerator_unsigned, |
| 14390 | .enumerator_signed_positive, |
| 14391 | => true, |
| 14392 | .enumerator_signed_negative => false, |
| 14393 | else => unreachable, |
| 14394 | }, |
| 14359 | 14395 | }; |
| 14360 | | |
| 14361 | | if (extra.bit_width <= 64) { |
| 14362 | | const val = bigint.to(i64) catch unreachable; |
| 14363 | | const emit_val = if (positive) |
| 14364 | | @shlWithOverflow(val, 1)[0] |
| 14365 | | else |
| 14366 | | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); |
| 14367 | | try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{ |
| 14368 | | .flags = .{ |
| 14369 | | .unsigned = unsigned, |
| 14370 | | }, |
| 14371 | | .bit_width = extra.bit_width, |
| 14372 | | .name = extra.name, |
| 14373 | | .value = @bitCast(emit_val), |
| 14374 | | }, metadata_adapter); |
| 14375 | | } else { |
| 14376 | | const word_count = std.mem.alignForward(u32, extra.bit_width, 64) / 64; |
| 14377 | | try record.ensureUnusedCapacity(self.gpa, 3 + word_count); |
| 14378 | | |
| 14379 | | const flags: MetadataBlock.Enumerator.Flags = .{ |
| 14380 | | .unsigned = unsigned, |
| 14381 | | }; |
| 14382 | | |
| 14383 | | const FlagsInt = @typeInfo(MetadataBlock.Enumerator.Flags).Struct.backing_integer.?; |
| 14384 | | |
| 14385 | | const flags_int: FlagsInt = @bitCast(flags); |
| 14386 | | |
| 14387 | | record.appendAssumeCapacity(@intCast(flags_int)); |
| 14388 | | record.appendAssumeCapacity(@intCast(extra.bit_width)); |
| 14396 | const flags: MetadataBlock.Enumerator.Flags = .{ |
| 14397 | .unsigned = switch (kind) { |
| 14398 | .enumerator_unsigned => true, |
| 14399 | .enumerator_signed_positive, |
| 14400 | .enumerator_signed_negative, |
| 14401 | => false, |
| 14402 | else => unreachable, |
| 14403 | }, |
| 14404 | }; |
| 14405 | const val: i64 = if (bigint.to(i64)) |val| |
| 14406 | val |
| 14407 | else |_| if (bigint.to(u64)) |val| |
| 14408 | @bitCast(val) |
| 14409 | else |_| { |
| 14410 | const limbs_len = std.math.divCeil(u32, extra.bit_width, 64) catch unreachable; |
| 14411 | try record.ensureTotalCapacity(self.gpa, 3 + limbs_len); |
| 14412 | record.appendAssumeCapacity(@as( |
| 14413 | @typeInfo(MetadataBlock.Enumerator.Flags).Struct.backing_integer.?, |
| 14414 | @bitCast(flags), |
| 14415 | )); |
| 14416 | record.appendAssumeCapacity(extra.bit_width); |
| 14389 | 14417 | record.appendAssumeCapacity(metadata_adapter.getMetadataStringIndex(extra.name)); |
| 14390 | | |
| 14391 | | const buffer: [*]u8 = @ptrCast(record.items.ptr); |
| 14392 | | bigint.writeTwosComplement(buffer[0..(word_count * 8)], .little); |
| 14393 | | |
| 14394 | | const signed_buffer: [*]i64 = @ptrCast(record.items.ptr); |
| 14395 | | for (signed_buffer[0..word_count], 0..) |val, i| { |
| 14396 | | signed_buffer[i] = if (val >= 0) |
| 14397 | | @shlWithOverflow(val, 1)[0] |
| 14418 | const limbs = record.addManyAsSliceAssumeCapacity(limbs_len); |
| 14419 | bigint.writeTwosComplement(std.mem.sliceAsBytes(limbs), .little); |
| 14420 | for (limbs) |*limb| { |
| 14421 | const val = std.mem.littleToNative(i64, @bitCast(limb.*)); |
| 14422 | limb.* = @bitCast(if (val >= 0) |
| 14423 | val << 1 | 0 |
| 14398 | 14424 | else |
| 14399 | | (@shlWithOverflow(@addWithOverflow(~val, 1)[0], 1)[0] | 1); |
| 14425 | -%val << 1 | 1); |
| 14400 | 14426 | } |
| 14401 | | |
| 14402 | | try metadata_block.writeUnabbrev( |
| 14403 | | MetadataBlock.Enumerator.id, |
| 14404 | | record.items.ptr[0..(3 + word_count)], |
| 14405 | | ); |
| 14406 | | } |
| 14427 | try metadata_block.writeUnabbrev(MetadataBlock.Enumerator.id, record.items); |
| 14428 | continue; |
| 14429 | }; |
| 14430 | try metadata_block.writeAbbrevAdapted(MetadataBlock.Enumerator{ |
| 14431 | .flags = flags, |
| 14432 | .bit_width = extra.bit_width, |
| 14433 | .name = extra.name, |
| 14434 | .value = @bitCast(if (val >= 0) |
| 14435 | val << 1 | 0 |
| 14436 | else |
| 14437 | -%val << 1 | 1), |
| 14438 | }, metadata_adapter); |
| 14407 | 14439 | }, |
| 14408 | 14440 | .subrange => { |
| 14409 | 14441 | const extra = self.metadataExtraData(Metadata.Subrange, data); |
| ... | ... | @@ -14491,7 +14523,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14491 | 14523 | }, metadata_adapter); |
| 14492 | 14524 | }, |
| 14493 | 14525 | } |
| 14494 | | record.clearRetainingCapacity(); |
| 14495 | 14526 | } |
| 14496 | 14527 | |
| 14497 | 14528 | // Write named metadata |
| ... | ... | @@ -14615,7 +14646,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14615 | 14646 | } |
| 14616 | 14647 | |
| 14617 | 14648 | pub fn getOffsetValueIndex(adapter: @This(), value: Value) u32 { |
| 14618 | | return @subWithOverflow(adapter.offset(), adapter.getValueIndex(value))[0]; |
| 14649 | return adapter.offset() -% adapter.getValueIndex(value); |
| 14619 | 14650 | } |
| 14620 | 14651 | |
| 14621 | 14652 | pub fn getOffsetValueSignedIndex(adapter: @This(), value: Value) i32 { |