authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-06 19:20:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
log75900ec1b5a250935a6abe050a006738fba99e66
tree9d3dd571b59648a585c3ce5bcdb2dbb50a574d58
parent73720b6975e2650ece48cc5f38495c091360c6c9

stage2: move integer values to InternPool


16 files changed, 1168 insertions(+), 1727 deletions(-)

src/Air.zig+1
...@@ -913,6 +913,7 @@ pub const Inst = struct {...@@ -913,6 +913,7 @@ pub const Inst = struct {
913 zero_u8 = @enumToInt(InternPool.Index.zero_u8),913 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
914 one = @enumToInt(InternPool.Index.one),914 one = @enumToInt(InternPool.Index.one),
915 one_usize = @enumToInt(InternPool.Index.one_usize),915 one_usize = @enumToInt(InternPool.Index.one_usize),
916 negative_one = @enumToInt(InternPool.Index.negative_one),
916 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),917 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
917 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),918 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
918 void_value = @enumToInt(InternPool.Index.void_value),919 void_value = @enumToInt(InternPool.Index.void_value),
src/InternPool.zig+13-5
...@@ -390,6 +390,8 @@ pub const Index = enum(u32) {...@@ -390,6 +390,8 @@ pub const Index = enum(u32) {
390 one,390 one,
391 /// `1` (usize)391 /// `1` (usize)
392 one_usize,392 one_usize,
393 /// `-1` (comptime_int)
394 negative_one,
393 /// `std.builtin.CallingConvention.C`395 /// `std.builtin.CallingConvention.C`
394 calling_convention_c,396 calling_convention_c,
395 /// `std.builtin.CallingConvention.Inline`397 /// `std.builtin.CallingConvention.Inline`
...@@ -624,6 +626,11 @@ pub const static_keys = [_]Key{...@@ -624,6 +626,11 @@ pub const static_keys = [_]Key{
624 .storage = .{ .u64 = 1 },626 .storage = .{ .u64 = 1 },
625 } },627 } },
626628
629 .{ .int = .{
630 .ty = .comptime_int_type,
631 .storage = .{ .i64 = -1 },
632 } },
633
627 .{ .enum_tag = .{634 .{ .enum_tag = .{
628 .ty = .calling_convention_type,635 .ty = .calling_convention_type,
629 .tag = .{636 .tag = .{
...@@ -999,23 +1006,23 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -999,23 +1006,23 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
999 .type_error_union => @panic("TODO"),1006 .type_error_union => @panic("TODO"),
1000 .type_enum_simple => @panic("TODO"),1007 .type_enum_simple => @panic("TODO"),
1001 .simple_internal => @panic("TODO"),1008 .simple_internal => @panic("TODO"),
1002 .int_u32 => return .{ .int = .{1009 .int_u32 => .{ .int = .{
1003 .ty = .u32_type,1010 .ty = .u32_type,
1004 .storage = .{ .u64 = data },1011 .storage = .{ .u64 = data },
1005 } },1012 } },
1006 .int_i32 => return .{ .int = .{1013 .int_i32 => .{ .int = .{
1007 .ty = .i32_type,1014 .ty = .i32_type,
1008 .storage = .{ .i64 = @bitCast(i32, data) },1015 .storage = .{ .i64 = @bitCast(i32, data) },
1009 } },1016 } },
1010 .int_usize => return .{ .int = .{1017 .int_usize => .{ .int = .{
1011 .ty = .usize_type,1018 .ty = .usize_type,
1012 .storage = .{ .u64 = data },1019 .storage = .{ .u64 = data },
1013 } },1020 } },
1014 .int_comptime_int_u32 => return .{ .int = .{1021 .int_comptime_int_u32 => .{ .int = .{
1015 .ty = .comptime_int_type,1022 .ty = .comptime_int_type,
1016 .storage = .{ .u64 = data },1023 .storage = .{ .u64 = data },
1017 } },1024 } },
1018 .int_comptime_int_i32 => return .{ .int = .{1025 .int_comptime_int_i32 => .{ .int = .{
1019 .ty = .comptime_int_type,1026 .ty = .comptime_int_type,
1020 .storage = .{ .i64 = @bitCast(i32, data) },1027 .storage = .{ .i64 = @bitCast(i32, data) },
1021 } },1028 } },
...@@ -1137,6 +1144,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -1137,6 +1144,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
11371144
1138 .int => |int| b: {1145 .int => |int| b: {
1139 switch (int.ty) {1146 switch (int.ty) {
1147 .none => unreachable,
1140 .u32_type => switch (int.storage) {1148 .u32_type => switch (int.storage) {
1141 .big_int => |big_int| {1149 .big_int => |big_int| {
1142 if (big_int.to(u32)) |casted| {1150 if (big_int.to(u32)) |casted| {
src/Module.zig+50-23
...@@ -6597,7 +6597,7 @@ pub fn populateTestFunctions(...@@ -6597,7 +6597,7 @@ pub fn populateTestFunctions(
6597 field_vals.* = .{6597 field_vals.* = .{
6598 try Value.Tag.slice.create(arena, .{6598 try Value.Tag.slice.create(arena, .{
6599 .ptr = try Value.Tag.decl_ref.create(arena, test_name_decl_index),6599 .ptr = try Value.Tag.decl_ref.create(arena, test_name_decl_index),
6600 .len = try Value.Tag.int_u64.create(arena, test_name_slice.len),6600 .len = try mod.intValue(Type.usize, test_name_slice.len),
6601 }), // name6601 }), // name
6602 try Value.Tag.decl_ref.create(arena, test_decl_index), // func6602 try Value.Tag.decl_ref.create(arena, test_decl_index), // func
6603 Value.null, // async_frame_size6603 Value.null, // async_frame_size
...@@ -6628,7 +6628,7 @@ pub fn populateTestFunctions(...@@ -6628,7 +6628,7 @@ pub fn populateTestFunctions(
6628 new_var.* = decl.val.castTag(.variable).?.data.*;6628 new_var.* = decl.val.castTag(.variable).?.data.*;
6629 new_var.init = try Value.Tag.slice.create(arena, .{6629 new_var.init = try Value.Tag.slice.create(arena, .{
6630 .ptr = try Value.Tag.decl_ref.create(arena, array_decl_index),6630 .ptr = try Value.Tag.decl_ref.create(arena, array_decl_index),
6631 .len = try Value.Tag.int_u64.create(arena, mod.test_functions.count()),6631 .len = try mod.intValue(Type.usize, mod.test_functions.count()),
6632 });6632 });
6633 const new_val = try Value.Tag.variable.create(arena, new_var);6633 const new_val = try Value.Tag.variable.create(arena, new_var);
66346634
...@@ -6875,6 +6875,38 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {...@@ -6875,6 +6875,38 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
6875 return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true });6875 return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true });
6876}6876}
68776877
6878pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6879 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
6880 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
6881 var limbs_buffer: [4]usize = undefined;
6882 var big_int = BigIntMutable.init(&limbs_buffer, x);
6883 return intValue_big(mod, ty, big_int.toConst());
6884}
6885
6886pub fn intValue_big(mod: *Module, ty: Type, x: BigIntConst) Allocator.Error!Value {
6887 const i = try intern(mod, .{ .int = .{
6888 .ty = ty.ip_index,
6889 .storage = .{ .big_int = x },
6890 } });
6891 return i.toValue();
6892}
6893
6894pub fn intValue_u64(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
6895 const i = try intern(mod, .{ .int = .{
6896 .ty = ty.ip_index,
6897 .storage = .{ .u64 = x },
6898 } });
6899 return i.toValue();
6900}
6901
6902pub fn intValue_i64(mod: *Module, ty: Type, x: i64) Allocator.Error!Value {
6903 const i = try intern(mod, .{ .int = .{
6904 .ty = ty.ip_index,
6905 .storage = .{ .i64 = x },
6906 } });
6907 return i.toValue();
6908}
6909
6878pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {6910pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
6879 return intType(mod, .unsigned, Type.smallestUnsignedBits(max));6911 return intType(mod, .unsigned, Type.smallestUnsignedBits(max));
6880}6912}
...@@ -6907,32 +6939,27 @@ pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {...@@ -6907,32 +6939,27 @@ pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
6907/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.6939/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
6908pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {6940pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {
6909 assert(!val.isUndef());6941 assert(!val.isUndef());
6910 switch (val.tag()) {6942
6911 .int_big_positive => {6943 const key = mod.intern_pool.indexToKey(val.ip_index);
6912 const limbs = val.castTag(.int_big_positive).?.data;6944 switch (key.int.storage) {
6913 const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = true };6945 .i64 => |x| {
6914 return @intCast(u16, big.bitCountAbs() + @boolToInt(sign));6946 if (std.math.cast(u64, x)) |casted| return Type.smallestUnsignedBits(casted);
6915 },
6916 .int_big_negative => {
6917 const limbs = val.castTag(.int_big_negative).?.data;
6918 // Zero is still a possibility, in which case unsigned is fine
6919 for (limbs) |limb| {
6920 if (limb != 0) break;
6921 } else return 0; // val == 0
6922 assert(sign);
6923 const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = false };
6924 return @intCast(u16, big.bitCountTwosComp());
6925 },
6926 .int_i64 => {
6927 const x = val.castTag(.int_i64).?.data;
6928 if (x >= 0) return Type.smallestUnsignedBits(@intCast(u64, x));
6929 assert(sign);6947 assert(sign);
6948 // Protect against overflow in the following negation.
6949 if (x == std.math.minInt(i64)) return 64;
6930 return Type.smallestUnsignedBits(@intCast(u64, -x - 1)) + 1;6950 return Type.smallestUnsignedBits(@intCast(u64, -x - 1)) + 1;
6931 },6951 },
6932 else => {6952 .u64 => |x| {
6933 const x = val.toUnsignedInt(mod);
6934 return Type.smallestUnsignedBits(x) + @boolToInt(sign);6953 return Type.smallestUnsignedBits(x) + @boolToInt(sign);
6935 },6954 },
6955 .big_int => |big| {
6956 if (big.positive) return @intCast(u16, big.bitCountAbs() + @boolToInt(sign));
6957
6958 // Zero is still a possibility, in which case unsigned is fine
6959 if (big.eqZero()) return 0;
6960
6961 return @intCast(u16, big.bitCountTwosComp());
6962 },
6936 }6963 }
6937}6964}
69386965
src/RangeSet.zig+3-3
...@@ -35,8 +35,8 @@ pub fn add(...@@ -35,8 +35,8 @@ pub fn add(
35 src: SwitchProngSrc,35 src: SwitchProngSrc,
36) !?SwitchProngSrc {36) !?SwitchProngSrc {
37 for (self.ranges.items) |range| {37 for (self.ranges.items) |range| {
38 if (last.compareAll(.gte, range.first, ty, self.module) and38 if (last.compareScalar(.gte, range.first, ty, self.module) and
39 first.compareAll(.lte, range.last, ty, self.module))39 first.compareScalar(.lte, range.last, ty, self.module))
40 {40 {
41 return range.src; // They overlap.41 return range.src; // They overlap.
42 }42 }
...@@ -53,7 +53,7 @@ const LessThanContext = struct { ty: Type, module: *Module };...@@ -53,7 +53,7 @@ const LessThanContext = struct { ty: Type, module: *Module };
5353
54/// Assumes a and b do not overlap54/// Assumes a and b do not overlap
55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {
56 return a.first.compareAll(.lt, b.first, ctx.ty, ctx.module);56 return a.first.compareScalar(.lt, b.first, ctx.ty, ctx.module);
57}57}
5858
59pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {59pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
src/Sema.zig+298-440
...@@ -2995,7 +2995,6 @@ fn zirEnumDecl(...@@ -2995,7 +2995,6 @@ fn zirEnumDecl(
2995 var cur_bit_bag: u32 = undefined;2995 var cur_bit_bag: u32 = undefined;
2996 var field_i: u32 = 0;2996 var field_i: u32 = 0;
2997 var last_tag_val: ?Value = null;2997 var last_tag_val: ?Value = null;
2998 var tag_val_buf: Value.Payload.U64 = undefined;
2999 while (field_i < fields_len) : (field_i += 1) {2998 while (field_i < fields_len) : (field_i += 1) {
3000 if (field_i % 32 == 0) {2999 if (field_i % 32 == 0) {
3001 cur_bit_bag = sema.code.extra[bit_bag_index];3000 cur_bit_bag = sema.code.extra[bit_bag_index];
...@@ -3084,11 +3083,7 @@ fn zirEnumDecl(...@@ -3084,11 +3083,7 @@ fn zirEnumDecl(
3084 return sema.failWithOwnedErrorMsg(msg);3083 return sema.failWithOwnedErrorMsg(msg);
3085 }3084 }
3086 } else {3085 } else {
3087 tag_val_buf = .{3086 last_tag_val = try mod.intValue(enum_obj.tag_ty, field_i);
3088 .base = .{ .tag = .int_u64 },
3089 .data = field_i,
3090 };
3091 last_tag_val = Value.initPayload(&tag_val_buf.base);
3092 }3087 }
30933088
3094 if (!(try sema.intFitsInType(last_tag_val.?, enum_obj.tag_ty, null))) {3089 if (!(try sema.intFitsInType(last_tag_val.?, enum_obj.tag_ty, null))) {
...@@ -5180,16 +5175,23 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5180,16 +5175,23 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
5180 const tracy = trace(@src());5175 const tracy = trace(@src());
5181 defer tracy.end();5176 defer tracy.end();
51825177
5183 const arena = sema.arena;5178 const mod = sema.mod;
5184 const int = sema.code.instructions.items(.data)[inst].str;5179 const int = sema.code.instructions.items(.data)[inst].str;
5185 const byte_count = int.len * @sizeOf(std.math.big.Limb);5180 const byte_count = int.len * @sizeOf(std.math.big.Limb);
5186 const limb_bytes = sema.code.string_bytes[int.start..][0..byte_count];5181 const limb_bytes = sema.code.string_bytes[int.start..][0..byte_count];
5187 const limbs = try arena.alloc(std.math.big.Limb, int.len);5182
5183 // TODO: this allocation and copy is only needed because the limbs may be unaligned.
5184 // If ZIR is adjusted so that big int limbs are guaranteed to be aligned, these
5185 // two lines can be removed.
5186 const limbs = try sema.arena.alloc(std.math.big.Limb, int.len);
5188 @memcpy(mem.sliceAsBytes(limbs), limb_bytes);5187 @memcpy(mem.sliceAsBytes(limbs), limb_bytes);
51895188
5190 return sema.addConstant(5189 return sema.addConstant(
5191 Type.comptime_int,5190 Type.comptime_int,
5192 try Value.Tag.int_big_positive.create(arena, limbs),5191 try mod.intValue_big(Type.comptime_int, .{
5192 .limbs = limbs,
5193 .positive = true,
5194 }),
5193 );5195 );
5194}5196}
51955197
...@@ -8095,6 +8097,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8095,6 +8097,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8095 const tracy = trace(@src());8097 const tracy = trace(@src());
8096 defer tracy.end();8098 defer tracy.end();
80978099
8100 const mod = sema.mod;
8098 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;8101 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8099 const src = LazySrcLoc.nodeOffset(extra.node);8102 const src = LazySrcLoc.nodeOffset(extra.node);
8100 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };8103 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
...@@ -8107,12 +8110,13 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8107,12 +8110,13 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8107 }8110 }
8108 switch (val.tag()) {8111 switch (val.tag()) {
8109 .@"error" => {8112 .@"error" => {
8110 const payload = try sema.arena.create(Value.Payload.U64);8113 return sema.addConstant(
8111 payload.* = .{8114 Type.err_int,
8112 .base = .{ .tag = .int_u64 },8115 try mod.intValue(
8113 .data = (try sema.mod.getErrorValue(val.castTag(.@"error").?.data.name)).value,8116 Type.err_int,
8114 };8117 (try sema.mod.getErrorValue(val.castTag(.@"error").?.data.name)).value,
8115 return sema.addConstant(Type.err_int, Value.initPayload(&payload.base));8118 ),
8119 );
8116 },8120 },
81178121
8118 // This is not a valid combination with the type `anyerror`.8122 // This is not a valid combination with the type `anyerror`.
...@@ -8280,8 +8284,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8280,8 +8284,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8280 }8284 }
82818285
8282 if (try sema.resolveMaybeUndefVal(enum_tag)) |enum_tag_val| {8286 if (try sema.resolveMaybeUndefVal(enum_tag)) |enum_tag_val| {
8283 var buffer: Value.Payload.U64 = undefined;8287 const val = try enum_tag_val.enumToInt(enum_tag_ty, mod);
8284 const val = enum_tag_val.enumToInt(enum_tag_ty, &buffer);
8285 return sema.addConstant(int_tag_ty, try val.copy(sema.arena));8288 return sema.addConstant(int_tag_ty, try val.copy(sema.arena));
8286 }8289 }
82878290
...@@ -9685,7 +9688,7 @@ fn intCast(...@@ -9685,7 +9688,7 @@ fn intCast(
9685 // range shrinkage9688 // range shrinkage
9686 // requirement: int value fits into target type9689 // requirement: int value fits into target type
9687 if (wanted_value_bits < actual_value_bits) {9690 if (wanted_value_bits < actual_value_bits) {
9688 const dest_max_val_scalar = try dest_scalar_ty.maxInt(sema.arena, mod);9691 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod);
9689 const dest_max_val = if (is_vector)9692 const dest_max_val = if (is_vector)
9690 try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar)9693 try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar)
9691 else9694 else
...@@ -9946,7 +9949,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -9946,7 +9949,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
9946 }9949 }
99479950
9948 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {9951 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
9949 return sema.addConstant(dest_ty, try operand_val.floatCast(sema.arena, dest_ty, target));9952 return sema.addConstant(dest_ty, try operand_val.floatCast(sema.arena, dest_ty, mod));
9950 }9953 }
9951 if (dest_is_comptime_float) {9954 if (dest_is_comptime_float) {
9952 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_float'", .{});9955 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_float'", .{});
...@@ -10470,7 +10473,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10470,7 +10473,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10470 // Duplicate checking variables later also used for `inline else`.10473 // Duplicate checking variables later also used for `inline else`.
10471 var seen_enum_fields: []?Module.SwitchProngSrc = &.{};10474 var seen_enum_fields: []?Module.SwitchProngSrc = &.{};
10472 var seen_errors = SwitchErrorSet.init(gpa);10475 var seen_errors = SwitchErrorSet.init(gpa);
10473 var range_set = RangeSet.init(gpa, sema.mod);10476 var range_set = RangeSet.init(gpa, mod);
10474 var true_count: u8 = 0;10477 var true_count: u8 = 0;
10475 var false_count: u8 = 0;10478 var false_count: u8 = 0;
1047610479
...@@ -10596,11 +10599,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10596,11 +10599,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10596 .{field_name},10599 .{field_name},
10597 );10600 );
10598 }10601 }
10599 try sema.mod.errNoteNonLazy(10602 try mod.errNoteNonLazy(
10600 operand_ty.declSrcLoc(sema.mod),10603 operand_ty.declSrcLoc(mod),
10601 msg,10604 msg,
10602 "enum '{}' declared here",10605 "enum '{}' declared here",
10603 .{operand_ty.fmt(sema.mod)},10606 .{operand_ty.fmt(mod)},
10604 );10607 );
10605 break :msg msg;10608 break :msg msg;
10606 };10609 };
...@@ -10827,7 +10830,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10827,7 +10830,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10827 defer arena.deinit();10830 defer arena.deinit();
1082810831
10829 const min_int = try operand_ty.minInt(arena.allocator(), mod);10832 const min_int = try operand_ty.minInt(arena.allocator(), mod);
10830 const max_int = try operand_ty.maxInt(arena.allocator(), mod);10833 const max_int = try operand_ty.maxIntScalar(mod);
10831 if (try range_set.spans(min_int, max_int, operand_ty)) {10834 if (try range_set.spans(min_int, max_int, operand_ty)) {
10832 if (special_prong == .@"else") {10835 if (special_prong == .@"else") {
10833 return sema.fail(10836 return sema.fail(
...@@ -10926,13 +10929,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10926,13 +10929,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10926 block,10929 block,
10927 src,10930 src,
10928 "else prong required when switching on type '{}'",10931 "else prong required when switching on type '{}'",
10929 .{operand_ty.fmt(sema.mod)},10932 .{operand_ty.fmt(mod)},
10930 );10933 );
10931 }10934 }
1093210935
10933 var seen_values = ValueSrcMap.initContext(gpa, .{10936 var seen_values = ValueSrcMap.initContext(gpa, .{
10934 .ty = operand_ty,10937 .ty = operand_ty,
10935 .mod = sema.mod,10938 .mod = mod,
10936 });10939 });
10937 defer seen_values.deinit();10940 defer seen_values.deinit();
1093810941
...@@ -10996,7 +10999,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10996,7 +10999,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10996 .ComptimeFloat,10999 .ComptimeFloat,
10997 .Float,11000 .Float,
10998 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{11001 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
10999 operand_ty.fmt(sema.mod),11002 operand_ty.fmt(mod),
11000 }),11003 }),
11001 }11004 }
1100211005
...@@ -11054,7 +11057,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11054,7 +11057,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11054 const item = try sema.resolveInst(item_ref);11057 const item = try sema.resolveInst(item_ref);
11055 // Validation above ensured these will succeed.11058 // Validation above ensured these will succeed.
11056 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;11059 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;
11057 if (operand_val.eql(item_val, operand_ty, sema.mod)) {11060 if (operand_val.eql(item_val, operand_ty, mod)) {
11058 if (is_inline) child_block.inline_case_capture = operand;11061 if (is_inline) child_block.inline_case_capture = operand;
1105911062
11060 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);11063 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
...@@ -11080,7 +11083,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11080,7 +11083,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11080 const item = try sema.resolveInst(item_ref);11083 const item = try sema.resolveInst(item_ref);
11081 // Validation above ensured these will succeed.11084 // Validation above ensured these will succeed.
11082 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;11085 const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable;
11083 if (operand_val.eql(item_val, operand_ty, sema.mod)) {11086 if (operand_val.eql(item_val, operand_ty, mod)) {
11084 if (is_inline) child_block.inline_case_capture = operand;11087 if (is_inline) child_block.inline_case_capture = operand;
1108511088
11086 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);11089 if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand);
...@@ -11128,7 +11131,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11128,7 +11131,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11128 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {11131 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {
11129 return Air.Inst.Ref.unreachable_value;11132 return Air.Inst.Ref.unreachable_value;
11130 }11133 }
11131 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and11134 if (mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and
11132 (!operand_ty.isNonexhaustiveEnum() or union_originally))11135 (!operand_ty.isNonexhaustiveEnum() or union_originally))
11133 {11136 {
11134 try sema.zirDbgStmt(block, cond_dbg_node_index);11137 try sema.zirDbgStmt(block, cond_dbg_node_index);
...@@ -11182,7 +11185,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11182,7 +11185,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1118211185
11183 const analyze_body = if (union_originally) blk: {11186 const analyze_body = if (union_originally) blk: {
11184 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;11187 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
11185 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11188 const field_ty = maybe_union_ty.unionFieldType(item_val, mod);
11186 break :blk field_ty.zigTypeTag(mod) != .NoReturn;11189 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
11187 } else true;11190 } else true;
1118811191
...@@ -11245,9 +11248,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11245,9 +11248,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11245 const item_last_ref = try sema.resolveInst(last_ref);11248 const item_last_ref = try sema.resolveInst(last_ref);
11246 const item_last = sema.resolveConstValue(block, .unneeded, item_last_ref, undefined) catch unreachable;11249 const item_last = sema.resolveConstValue(block, .unneeded, item_last_ref, undefined) catch unreachable;
1124711250
11248 while (item.compareAll(.lte, item_last, operand_ty, sema.mod)) : ({11251 while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({
11249 // Previous validation has resolved any possible lazy values.11252 // Previous validation has resolved any possible lazy values.
11250 item = try sema.intAddScalar(item, Value.one);11253 item = try sema.intAddScalar(item, Value.one, operand_ty);
11251 }) {11254 }) {
11252 cases_len += 1;11255 cases_len += 1;
1125311256
...@@ -11260,7 +11263,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11260,7 +11263,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11260 if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {11263 if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {
11261 error.NeededSourceLocation => {11264 error.NeededSourceLocation => {
11262 const case_src = Module.SwitchProngSrc{ .range = .{ .prong = multi_i, .item = range_i } };11265 const case_src = Module.SwitchProngSrc{ .range = .{ .prong = multi_i, .item = range_i } };
11263 const decl = sema.mod.declPtr(case_block.src_decl);11266 const decl = mod.declPtr(case_block.src_decl);
11264 try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none));11267 try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none));
11265 unreachable;11268 unreachable;
11266 },11269 },
...@@ -11289,14 +11292,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11289,14 +11292,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1128911292
11290 const analyze_body = if (union_originally) blk: {11293 const analyze_body = if (union_originally) blk: {
11291 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;11294 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;
11292 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11295 const field_ty = maybe_union_ty.unionFieldType(item_val, mod);
11293 break :blk field_ty.zigTypeTag(mod) != .NoReturn;11296 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
11294 } else true;11297 } else true;
1129511298
11296 if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {11299 if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {
11297 error.NeededSourceLocation => {11300 error.NeededSourceLocation => {
11298 const case_src = Module.SwitchProngSrc{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } };11301 const case_src = Module.SwitchProngSrc{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } };
11299 const decl = sema.mod.declPtr(case_block.src_decl);11302 const decl = mod.declPtr(case_block.src_decl);
11300 try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none));11303 try sema.emitBackwardBranch(block, case_src.resolve(sema.gpa, decl, src_node_offset, .none));
11301 unreachable;11304 unreachable;
11302 },11305 },
...@@ -11333,7 +11336,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11333,7 +11336,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11333 for (items) |item_ref| {11336 for (items) |item_ref| {
11334 const item = try sema.resolveInst(item_ref);11337 const item = try sema.resolveInst(item_ref);
11335 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;11338 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
11336 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11339 const field_ty = maybe_union_ty.unionFieldType(item_val, mod);
11337 if (field_ty.zigTypeTag(mod) != .NoReturn) break true;11340 if (field_ty.zigTypeTag(mod) != .NoReturn) break true;
11338 } else false11341 } else false
11339 else11342 else
...@@ -11461,7 +11464,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11461,7 +11464,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11461 .Enum => {11464 .Enum => {
11462 if (operand_ty.isNonexhaustiveEnum() and !union_originally) {11465 if (operand_ty.isNonexhaustiveEnum() and !union_originally) {
11463 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{11466 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
11464 operand_ty.fmt(sema.mod),11467 operand_ty.fmt(mod),
11465 });11468 });
11466 }11469 }
11467 for (seen_enum_fields, 0..) |f, i| {11470 for (seen_enum_fields, 0..) |f, i| {
...@@ -11476,7 +11479,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11476,7 +11479,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11476 case_block.wip_capture_scope = child_block.wip_capture_scope;11479 case_block.wip_capture_scope = child_block.wip_capture_scope;
1147711480
11478 const analyze_body = if (union_originally) blk: {11481 const analyze_body = if (union_originally) blk: {
11479 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);11482 const field_ty = maybe_union_ty.unionFieldType(item_val, mod);
11480 break :blk field_ty.zigTypeTag(mod) != .NoReturn;11483 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
11481 } else true;11484 } else true;
1148211485
...@@ -11499,7 +11502,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11499,7 +11502,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11499 .ErrorSet => {11502 .ErrorSet => {
11500 if (operand_ty.isAnyError()) {11503 if (operand_ty.isAnyError()) {
11501 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{11504 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
11502 operand_ty.fmt(sema.mod),11505 operand_ty.fmt(mod),
11503 });11506 });
11504 }11507 }
11505 for (operand_ty.errorSetNames()) |error_name| {11508 for (operand_ty.errorSetNames()) |error_name| {
...@@ -11587,7 +11590,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11587,7 +11590,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11587 }11590 }
11588 },11591 },
11589 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{11592 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
11590 operand_ty.fmt(sema.mod),11593 operand_ty.fmt(mod),
11591 }),11594 }),
11592 };11595 };
1159311596
...@@ -11598,7 +11601,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11598,7 +11601,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11598 case_block.wip_capture_scope = wip_captures.scope;11601 case_block.wip_capture_scope = wip_captures.scope;
11599 case_block.inline_case_capture = .none;11602 case_block.inline_case_capture = .none;
1160011603
11601 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and11604 if (mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and
11602 operand_ty.zigTypeTag(mod) == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally))11605 operand_ty.zigTypeTag(mod) == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally))
11603 {11606 {
11604 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);11607 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);
...@@ -11679,7 +11682,7 @@ const RangeSetUnhandledIterator = struct {...@@ -11679,7 +11682,7 @@ const RangeSetUnhandledIterator = struct {
11679 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {11682 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
11680 const mod = sema.mod;11683 const mod = sema.mod;
11681 const min = try ty.minInt(sema.arena, mod);11684 const min = try ty.minInt(sema.arena, mod);
11682 const max = try ty.maxInt(sema.arena, mod);11685 const max = try ty.maxIntScalar(mod);
1168311686
11684 return RangeSetUnhandledIterator{11687 return RangeSetUnhandledIterator{
11685 .sema = sema,11688 .sema = sema,
...@@ -11693,19 +11696,19 @@ const RangeSetUnhandledIterator = struct {...@@ -11693,19 +11696,19 @@ const RangeSetUnhandledIterator = struct {
11693 fn next(it: *RangeSetUnhandledIterator) !?Value {11696 fn next(it: *RangeSetUnhandledIterator) !?Value {
11694 while (it.range_i < it.ranges.len) : (it.range_i += 1) {11697 while (it.range_i < it.ranges.len) : (it.range_i += 1) {
11695 if (!it.first) {11698 if (!it.first) {
11696 it.cur = try it.sema.intAdd(it.cur, Value.one, it.ty);11699 it.cur = try it.sema.intAddScalar(it.cur, Value.one, it.ty);
11697 }11700 }
11698 it.first = false;11701 it.first = false;
11699 if (it.cur.compareAll(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) {11702 if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) {
11700 return it.cur;11703 return it.cur;
11701 }11704 }
11702 it.cur = it.ranges[it.range_i].last;11705 it.cur = it.ranges[it.range_i].last;
11703 }11706 }
11704 if (!it.first) {11707 if (!it.first) {
11705 it.cur = try it.sema.intAdd(it.cur, Value.one, it.ty);11708 it.cur = try it.sema.intAddScalar(it.cur, Value.one, it.ty);
11706 }11709 }
11707 it.first = false;11710 it.first = false;
11708 if (it.cur.compareAll(.lte, it.max, it.ty, it.sema.mod)) {11711 if (it.cur.compareScalar(.lte, it.max, it.ty, it.sema.mod)) {
11709 return it.cur;11712 return it.cur;
11710 }11713 }
11711 return null;11714 return null;
...@@ -11750,7 +11753,7 @@ fn validateSwitchRange(...@@ -11750,7 +11753,7 @@ fn validateSwitchRange(
11750) CompileError!void {11753) CompileError!void {
11751 const first_val = (try sema.resolveSwitchItemVal(block, first_ref, src_node_offset, switch_prong_src, .first)).val;11754 const first_val = (try sema.resolveSwitchItemVal(block, first_ref, src_node_offset, switch_prong_src, .first)).val;
11752 const last_val = (try sema.resolveSwitchItemVal(block, last_ref, src_node_offset, switch_prong_src, .last)).val;11755 const last_val = (try sema.resolveSwitchItemVal(block, last_ref, src_node_offset, switch_prong_src, .last)).val;
11753 if (first_val.compareAll(.gt, last_val, operand_ty, sema.mod)) {11756 if (first_val.compareScalar(.gt, last_val, operand_ty, sema.mod)) {
11754 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), src_node_offset, .first);11757 const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), src_node_offset, .first);
11755 return sema.fail(block, src, "range start value is greater than the end value", .{});11758 return sema.fail(block, src, "range start value is greater than the end value", .{});
11756 }11759 }
...@@ -12208,16 +12211,11 @@ fn zirShl(...@@ -12208,16 +12211,11 @@ fn zirShl(
12208 return lhs;12211 return lhs;
12209 }12212 }
12210 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {12213 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {
12211 var bits_payload = Value.Payload.U64{12214 const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);
12212 .base = .{ .tag = .int_u64 },
12213 .data = scalar_ty.intInfo(mod).bits,
12214 };
12215 const bit_value = Value.initPayload(&bits_payload.base);
12216 if (rhs_ty.zigTypeTag(mod) == .Vector) {12215 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12217 var i: usize = 0;12216 var i: usize = 0;
12218 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {12217 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
12219 var elem_value_buf: Value.ElemValueBuffer = undefined;12218 const rhs_elem = try rhs_val.elemValue(sema.mod, i);
12220 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12221 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {12219 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
12222 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{12220 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
12223 rhs_elem.fmtValue(scalar_ty, sema.mod),12221 rhs_elem.fmtValue(scalar_ty, sema.mod),
...@@ -12236,8 +12234,7 @@ fn zirShl(...@@ -12236,8 +12234,7 @@ fn zirShl(
12236 if (rhs_ty.zigTypeTag(mod) == .Vector) {12234 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12237 var i: usize = 0;12235 var i: usize = 0;
12238 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {12236 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
12239 var elem_value_buf: Value.ElemValueBuffer = undefined;12237 const rhs_elem = try rhs_val.elemValue(sema.mod, i);
12240 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12241 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {12238 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {
12242 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{12239 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
12243 rhs_elem.fmtValue(scalar_ty, sema.mod),12240 rhs_elem.fmtValue(scalar_ty, sema.mod),
...@@ -12309,7 +12306,7 @@ fn zirShl(...@@ -12309,7 +12306,7 @@ fn zirShl(
12309 if (block.wantSafety()) {12306 if (block.wantSafety()) {
12310 const bit_count = scalar_ty.intInfo(mod).bits;12307 const bit_count = scalar_ty.intInfo(mod).bits;
12311 if (!std.math.isPowerOfTwo(bit_count)) {12308 if (!std.math.isPowerOfTwo(bit_count)) {
12312 const bit_count_val = try Value.Tag.int_u64.create(sema.arena, bit_count);12309 const bit_count_val = try mod.intValue(scalar_ty, bit_count);
1231312310
12314 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {12311 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
12315 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));12312 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
...@@ -12396,16 +12393,11 @@ fn zirShr(...@@ -12396,16 +12393,11 @@ fn zirShr(
12396 return lhs;12393 return lhs;
12397 }12394 }
12398 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {12395 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
12399 var bits_payload = Value.Payload.U64{12396 const bit_value = try mod.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits);
12400 .base = .{ .tag = .int_u64 },
12401 .data = scalar_ty.intInfo(mod).bits,
12402 };
12403 const bit_value = Value.initPayload(&bits_payload.base);
12404 if (rhs_ty.zigTypeTag(mod) == .Vector) {12397 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12405 var i: usize = 0;12398 var i: usize = 0;
12406 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {12399 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
12407 var elem_value_buf: Value.ElemValueBuffer = undefined;12400 const rhs_elem = try rhs_val.elemValue(sema.mod, i);
12408 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12409 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {12401 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
12410 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{12402 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
12411 rhs_elem.fmtValue(scalar_ty, sema.mod),12403 rhs_elem.fmtValue(scalar_ty, sema.mod),
...@@ -12424,8 +12416,7 @@ fn zirShr(...@@ -12424,8 +12416,7 @@ fn zirShr(
12424 if (rhs_ty.zigTypeTag(mod) == .Vector) {12416 if (rhs_ty.zigTypeTag(mod) == .Vector) {
12425 var i: usize = 0;12417 var i: usize = 0;
12426 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {12418 while (i < rhs_ty.vectorLen(mod)) : (i += 1) {
12427 var elem_value_buf: Value.ElemValueBuffer = undefined;12419 const rhs_elem = try rhs_val.elemValue(sema.mod, i);
12428 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12429 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {12420 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {
12430 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{12421 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
12431 rhs_elem.fmtValue(scalar_ty, sema.mod),12422 rhs_elem.fmtValue(scalar_ty, sema.mod),
...@@ -12465,7 +12456,7 @@ fn zirShr(...@@ -12465,7 +12456,7 @@ fn zirShr(
12465 if (block.wantSafety()) {12456 if (block.wantSafety()) {
12466 const bit_count = scalar_ty.intInfo(mod).bits;12457 const bit_count = scalar_ty.intInfo(mod).bits;
12467 if (!std.math.isPowerOfTwo(bit_count)) {12458 if (!std.math.isPowerOfTwo(bit_count)) {
12468 const bit_count_val = try Value.Tag.int_u64.create(sema.arena, bit_count);12459 const bit_count_val = try mod.intValue(scalar_ty, bit_count);
1246912460
12470 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {12461 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
12471 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));12462 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
...@@ -12587,10 +12578,9 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -12587,10 +12578,9 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
12587 return sema.addConstUndef(operand_type);12578 return sema.addConstUndef(operand_type);
12588 } else if (operand_type.zigTypeTag(mod) == .Vector) {12579 } else if (operand_type.zigTypeTag(mod) == .Vector) {
12589 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));12580 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod));
12590 var elem_val_buf: Value.ElemValueBuffer = undefined;
12591 const elems = try sema.arena.alloc(Value, vec_len);12581 const elems = try sema.arena.alloc(Value, vec_len);
12592 for (elems, 0..) |*elem, i| {12582 for (elems, 0..) |*elem, i| {
12593 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_val_buf);12583 const elem_val = try val.elemValue(sema.mod, i);
12594 elem.* = try elem_val.bitwiseNot(scalar_type, sema.arena, sema.mod);12584 elem.* = try elem_val.bitwiseNot(scalar_type, sema.arena, sema.mod);
12595 }12585 }
12596 return sema.addConstant(12586 return sema.addConstant(
...@@ -12695,6 +12685,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12695,6 +12685,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12695 const tracy = trace(@src());12685 const tracy = trace(@src());
12696 defer tracy.end();12686 defer tracy.end();
1269712687
12688 const mod = sema.mod;
12698 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;12689 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
12699 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;12690 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
12700 const lhs = try sema.resolveInst(extra.lhs);12691 const lhs = try sema.resolveInst(extra.lhs);
...@@ -12714,11 +12705,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12714,11 +12705,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1271412705
12715 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {12706 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {
12716 if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined);12707 if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined);
12717 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});12708 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});
12718 };12709 };
12719 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {12710 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {
12720 assert(!rhs_is_tuple);12711 assert(!rhs_is_tuple);
12721 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(sema.mod)});12712 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(mod)});
12722 };12713 };
1272312714
12724 const resolved_elem_ty = t: {12715 const resolved_elem_ty = t: {
...@@ -12780,8 +12771,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12780,8 +12771,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12780 ),12771 ),
12781 };12772 };
1278212773
12783 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, sema.mod);12774 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, mod);
12784 const mod = sema.mod;
12785 const ptr_addrspace = p: {12775 const ptr_addrspace = p: {
12786 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);12776 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod);
12787 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);12777 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod);
...@@ -12815,7 +12805,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12815,7 +12805,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12815 const lhs_elem_i = elem_i;12805 const lhs_elem_i = elem_i;
12816 const elem_ty = if (lhs_is_tuple) lhs_ty.structFieldType(lhs_elem_i) else lhs_info.elem_type;12806 const elem_ty = if (lhs_is_tuple) lhs_ty.structFieldType(lhs_elem_i) else lhs_info.elem_type;
12817 const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i) else Value.@"unreachable";12807 const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i) else Value.@"unreachable";
12818 const elem_val = if (elem_default_val.ip_index == .unreachable_value) try lhs_sub_val.elemValue(sema.mod, sema.arena, lhs_elem_i) else elem_default_val;12808 const elem_val = if (elem_default_val.ip_index == .unreachable_value) try lhs_sub_val.elemValue(mod, lhs_elem_i) else elem_default_val;
12819 const elem_val_inst = try sema.addConstant(elem_ty, elem_val);12809 const elem_val_inst = try sema.addConstant(elem_ty, elem_val);
12820 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded);12810 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded);
12821 const coerced_elem_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, coerced_elem_val_inst, "");12811 const coerced_elem_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, coerced_elem_val_inst, "");
...@@ -12825,7 +12815,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12825,7 +12815,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12825 const rhs_elem_i = elem_i - lhs_len;12815 const rhs_elem_i = elem_i - lhs_len;
12826 const elem_ty = if (rhs_is_tuple) rhs_ty.structFieldType(rhs_elem_i) else rhs_info.elem_type;12816 const elem_ty = if (rhs_is_tuple) rhs_ty.structFieldType(rhs_elem_i) else rhs_info.elem_type;
12827 const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i) else Value.@"unreachable";12817 const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i) else Value.@"unreachable";
12828 const elem_val = if (elem_default_val.ip_index == .unreachable_value) try rhs_sub_val.elemValue(sema.mod, sema.arena, rhs_elem_i) else elem_default_val;12818 const elem_val = if (elem_default_val.ip_index == .unreachable_value) try rhs_sub_val.elemValue(mod, rhs_elem_i) else elem_default_val;
12829 const elem_val_inst = try sema.addConstant(elem_ty, elem_val);12819 const elem_val_inst = try sema.addConstant(elem_ty, elem_val);
12830 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded);12820 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded);
12831 const coerced_elem_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, coerced_elem_val_inst, "");12821 const coerced_elem_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, coerced_elem_val_inst, "");
...@@ -12842,12 +12832,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12842,12 +12832,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12842 try sema.requireRuntimeBlock(block, src, runtime_src);12832 try sema.requireRuntimeBlock(block, src, runtime_src);
1284312833
12844 if (ptr_addrspace) |ptr_as| {12834 if (ptr_addrspace) |ptr_as| {
12845 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{12835 const alloc_ty = try Type.ptr(sema.arena, mod, .{
12846 .pointee_type = result_ty,12836 .pointee_type = result_ty,
12847 .@"addrspace" = ptr_as,12837 .@"addrspace" = ptr_as,
12848 });12838 });
12849 const alloc = try block.addTy(.alloc, alloc_ty);12839 const alloc = try block.addTy(.alloc, alloc_ty);
12850 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{12840 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
12851 .pointee_type = resolved_elem_ty,12841 .pointee_type = resolved_elem_ty,
12852 .@"addrspace" = ptr_as,12842 .@"addrspace" = ptr_as,
12853 });12843 });
...@@ -13009,6 +12999,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13009,6 +12999,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13009 const tracy = trace(@src());12999 const tracy = trace(@src());
13010 defer tracy.end();13000 defer tracy.end();
1301113001
13002 const mod = sema.mod;
13012 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;13003 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
13013 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13004 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13014 const lhs = try sema.resolveInst(extra.lhs);13005 const lhs = try sema.resolveInst(extra.lhs);
...@@ -13025,10 +13016,9 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13025,10 +13016,9 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13025 }13016 }
1302613017
13027 // Analyze the lhs first, to catch the case that someone tried to do exponentiation13018 // Analyze the lhs first, to catch the case that someone tried to do exponentiation
13028 const mod = sema.mod;
13029 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {13019 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
13030 const msg = msg: {13020 const msg = msg: {
13031 const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});13021 const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});
13032 errdefer msg.destroy(sema.gpa);13022 errdefer msg.destroy(sema.gpa);
13033 switch (lhs_ty.zigTypeTag(mod)) {13023 switch (lhs_ty.zigTypeTag(mod)) {
13034 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {13024 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
...@@ -13048,7 +13038,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13048,7 +13038,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13048 return sema.fail(block, rhs_src, "operation results in overflow", .{});13038 return sema.fail(block, rhs_src, "operation results in overflow", .{});
13049 const result_len = try sema.usizeCast(block, src, result_len_u64);13039 const result_len = try sema.usizeCast(block, src, result_len_u64);
1305013040
13051 const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, sema.mod);13041 const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, mod);
1305213042
13053 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;13043 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null;
13054 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);13044 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
...@@ -13065,7 +13055,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13065,7 +13055,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13065 // Optimization for the common pattern of a single element repeated N times, such13055 // Optimization for the common pattern of a single element repeated N times, such
13066 // as zero-filling a byte array.13056 // as zero-filling a byte array.
13067 if (lhs_len == 1) {13057 if (lhs_len == 1) {
13068 const elem_val = try lhs_sub_val.elemValue(sema.mod, sema.arena, 0);13058 const elem_val = try lhs_sub_val.elemValue(mod, 0);
13069 break :v try Value.Tag.repeated.create(sema.arena, elem_val);13059 break :v try Value.Tag.repeated.create(sema.arena, elem_val);
13070 }13060 }
1307113061
...@@ -13074,7 +13064,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13074,7 +13064,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13074 while (elem_i < result_len) {13064 while (elem_i < result_len) {
13075 var lhs_i: usize = 0;13065 var lhs_i: usize = 0;
13076 while (lhs_i < lhs_len) : (lhs_i += 1) {13066 while (lhs_i < lhs_len) : (lhs_i += 1) {
13077 const elem_val = try lhs_sub_val.elemValue(sema.mod, sema.arena, lhs_i);13067 const elem_val = try lhs_sub_val.elemValue(mod, lhs_i);
13078 element_vals[elem_i] = elem_val;13068 element_vals[elem_i] = elem_val;
13079 elem_i += 1;13069 elem_i += 1;
13080 }13070 }
...@@ -13090,12 +13080,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13090,12 +13080,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13090 try sema.requireRuntimeBlock(block, src, lhs_src);13080 try sema.requireRuntimeBlock(block, src, lhs_src);
1309113081
13092 if (ptr_addrspace) |ptr_as| {13082 if (ptr_addrspace) |ptr_as| {
13093 const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{13083 const alloc_ty = try Type.ptr(sema.arena, mod, .{
13094 .pointee_type = result_ty,13084 .pointee_type = result_ty,
13095 .@"addrspace" = ptr_as,13085 .@"addrspace" = ptr_as,
13096 });13086 });
13097 const alloc = try block.addTy(.alloc, alloc_ty);13087 const alloc = try block.addTy(.alloc, alloc_ty);
13098 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{13088 const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{
13099 .pointee_type = lhs_info.elem_type,13089 .pointee_type = lhs_info.elem_type,
13100 .@"addrspace" = ptr_as,13090 .@"addrspace" = ptr_as,
13101 });13091 });
...@@ -13797,7 +13787,7 @@ fn addDivIntOverflowSafety(...@@ -13797,7 +13787,7 @@ fn addDivIntOverflowSafety(
13797 }13787 }
1379813788
13799 const min_int = try resolved_type.minInt(sema.arena, mod);13789 const min_int = try resolved_type.minInt(sema.arena, mod);
13800 const neg_one_scalar = try Value.Tag.int_i64.create(sema.arena, -1);13790 const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1);
13801 const neg_one = if (resolved_type.zigTypeTag(mod) == .Vector)13791 const neg_one = if (resolved_type.zigTypeTag(mod) == .Vector)
13802 try Value.Tag.repeated.create(sema.arena, neg_one_scalar)13792 try Value.Tag.repeated.create(sema.arena, neg_one_scalar)
13803 else13793 else
...@@ -13806,12 +13796,12 @@ fn addDivIntOverflowSafety(...@@ -13806,12 +13796,12 @@ fn addDivIntOverflowSafety(
13806 // If the LHS is comptime-known to be not equal to the min int,13796 // If the LHS is comptime-known to be not equal to the min int,
13807 // no overflow is possible.13797 // no overflow is possible.
13808 if (maybe_lhs_val) |lhs_val| {13798 if (maybe_lhs_val) |lhs_val| {
13809 if (lhs_val.compareAll(.neq, min_int, resolved_type, mod)) return;13799 if (try lhs_val.compareAll(.neq, min_int, resolved_type, mod)) return;
13810 }13800 }
1381113801
13812 // If the RHS is comptime-known to not be equal to -1, no overflow is possible.13802 // If the RHS is comptime-known to not be equal to -1, no overflow is possible.
13813 if (maybe_rhs_val) |rhs_val| {13803 if (maybe_rhs_val) |rhs_val| {
13814 if (rhs_val.compareAll(.neq, neg_one, resolved_type, mod)) return;13804 if (try rhs_val.compareAll(.neq, neg_one, resolved_type, mod)) return;
13815 }13805 }
1381613806
13817 var ok: Air.Inst.Ref = .none;13807 var ok: Air.Inst.Ref = .none;
...@@ -14038,23 +14028,18 @@ fn intRem(...@@ -14038,23 +14028,18 @@ fn intRem(
14038 const mod = sema.mod;14028 const mod = sema.mod;
14039 if (ty.zigTypeTag(mod) == .Vector) {14029 if (ty.zigTypeTag(mod) == .Vector) {
14040 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));14030 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
14031 const scalar_ty = ty.scalarType(mod);
14041 for (result_data, 0..) |*scalar, i| {14032 for (result_data, 0..) |*scalar, i| {
14042 var lhs_buf: Value.ElemValueBuffer = undefined;14033 const lhs_elem = try lhs.elemValue(sema.mod, i);
14043 var rhs_buf: Value.ElemValueBuffer = undefined;14034 const rhs_elem = try rhs.elemValue(sema.mod, i);
14044 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);14035 scalar.* = try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty);
14045 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
14046 scalar.* = try sema.intRemScalar(lhs_elem, rhs_elem);
14047 }14036 }
14048 return Value.Tag.aggregate.create(sema.arena, result_data);14037 return Value.Tag.aggregate.create(sema.arena, result_data);
14049 }14038 }
14050 return sema.intRemScalar(lhs, rhs);14039 return sema.intRemScalar(lhs, rhs, ty);
14051}14040}
1405214041
14053fn intRemScalar(14042fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileError!Value {
14054 sema: *Sema,
14055 lhs: Value,
14056 rhs: Value,
14057) CompileError!Value {
14058 const mod = sema.mod;14043 const mod = sema.mod;
14059 // TODO is this a performance issue? maybe we should try the operation without14044 // TODO is this a performance issue? maybe we should try the operation without
14060 // resorting to BigInt first.14045 // resorting to BigInt first.
...@@ -14079,7 +14064,7 @@ fn intRemScalar(...@@ -14079,7 +14064,7 @@ fn intRemScalar(
14079 var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };14064 var result_q = math.big.int.Mutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
14080 var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };14065 var result_r = math.big.int.Mutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
14081 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);14066 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
14082 return Value.fromBigInt(sema.arena, result_r.toConst());14067 return mod.intValue_big(scalar_ty, result_r.toConst());
14083}14068}
1408414069
14085fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {14070fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -15063,7 +15048,7 @@ fn analyzePtrArithmetic(...@@ -15063,7 +15048,7 @@ fn analyzePtrArithmetic(
15063 .ptr_sub => addr - elem_size * offset_int,15048 .ptr_sub => addr - elem_size * offset_int,
15064 else => unreachable,15049 else => unreachable,
15065 };15050 };
15066 const new_ptr_val = try Value.Tag.int_u64.create(sema.arena, new_addr);15051 const new_ptr_val = try mod.intValue(new_ptr_ty, new_addr);
15067 return sema.addConstant(new_ptr_ty, new_ptr_val);15052 return sema.addConstant(new_ptr_ty, new_ptr_val);
15068 }15053 }
15069 if (air_tag == .ptr_sub) {15054 if (air_tag == .ptr_sub) {
...@@ -15826,9 +15811,9 @@ fn zirBuiltinSrc(...@@ -15826,9 +15811,9 @@ fn zirBuiltinSrc(
15826 // fn_name: [:0]const u8,15811 // fn_name: [:0]const u8,
15827 field_values[1] = func_name_val;15812 field_values[1] = func_name_val;
15828 // line: u3215813 // line: u32
15829 field_values[2] = try Value.Tag.runtime_value.create(sema.arena, try Value.Tag.int_u64.create(sema.arena, extra.line + 1));15814 field_values[2] = try Value.Tag.runtime_value.create(sema.arena, try mod.intValue(Type.u32, extra.line + 1));
15830 // column: u32,15815 // column: u32,
15831 field_values[3] = try Value.Tag.int_u64.create(sema.arena, extra.column + 1);15816 field_values[3] = try mod.intValue(Type.u32, extra.column + 1);
1583215817
15833 return sema.addConstant(15818 return sema.addConstant(
15834 try sema.getBuiltinType("SourceLocation"),15819 try sema.getBuiltinType("SourceLocation"),
...@@ -15977,7 +15962,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15977,7 +15962,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15977 );15962 );
15978 break :v try Value.Tag.slice.create(sema.arena, .{15963 break :v try Value.Tag.slice.create(sema.arena, .{
15979 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),15964 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
15980 .len = try Value.Tag.int_u64.create(sema.arena, param_vals.len),15965 .len = try mod.intValue(Type.usize, param_vals.len),
15981 });15966 });
15982 };15967 };
1598315968
...@@ -15994,7 +15979,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15994,7 +15979,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15994 // calling_convention: CallingConvention,15979 // calling_convention: CallingConvention,
15995 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)),15980 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)),
15996 // alignment: comptime_int,15981 // alignment: comptime_int,
15997 try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(mod)),15982 try mod.intValue(Type.comptime_int, ty.abiAlignment(mod)),
15998 // is_generic: bool,15983 // is_generic: bool,
15999 Value.makeBool(info.is_generic),15984 Value.makeBool(info.is_generic),
16000 // is_var_args: bool,15985 // is_var_args: bool,
...@@ -16022,7 +16007,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16022,7 +16007,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16022 @enumToInt(info.signedness),16007 @enumToInt(info.signedness),
16023 );16008 );
16024 // bits: comptime_int,16009 // bits: comptime_int,
16025 field_values[1] = try Value.Tag.int_u64.create(sema.arena, info.bits);16010 field_values[1] = try mod.intValue(Type.comptime_int, info.bits);
1602616011
16027 return sema.addConstant(16012 return sema.addConstant(
16028 type_info_ty,16013 type_info_ty,
...@@ -16035,7 +16020,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16035,7 +16020,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16035 .Float => {16020 .Float => {
16036 const field_values = try sema.arena.alloc(Value, 1);16021 const field_values = try sema.arena.alloc(Value, 1);
16037 // bits: comptime_int,16022 // bits: comptime_int,
16038 field_values[0] = try Value.Tag.int_u64.create(sema.arena, ty.bitSize(mod));16023 field_values[0] = try mod.intValue(Type.comptime_int, ty.bitSize(mod));
1603916024
16040 return sema.addConstant(16025 return sema.addConstant(
16041 type_info_ty,16026 type_info_ty,
...@@ -16048,7 +16033,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16048,7 +16033,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16048 .Pointer => {16033 .Pointer => {
16049 const info = ty.ptrInfo(mod);16034 const info = ty.ptrInfo(mod);
16050 const alignment = if (info.@"align" != 0)16035 const alignment = if (info.@"align" != 0)
16051 try Value.Tag.int_u64.create(sema.arena, info.@"align")16036 try mod.intValue(Type.comptime_int, info.@"align")
16052 else16037 else
16053 try info.pointee_type.lazyAbiAlignment(mod, sema.arena);16038 try info.pointee_type.lazyAbiAlignment(mod, sema.arena);
1605416039
...@@ -16084,7 +16069,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16084,7 +16069,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16084 const info = ty.arrayInfo(mod);16069 const info = ty.arrayInfo(mod);
16085 const field_values = try sema.arena.alloc(Value, 3);16070 const field_values = try sema.arena.alloc(Value, 3);
16086 // len: comptime_int,16071 // len: comptime_int,
16087 field_values[0] = try Value.Tag.int_u64.create(sema.arena, info.len);16072 field_values[0] = try mod.intValue(Type.comptime_int, info.len);
16088 // child: type,16073 // child: type,
16089 field_values[1] = try Value.Tag.ty.create(sema.arena, info.elem_type);16074 field_values[1] = try Value.Tag.ty.create(sema.arena, info.elem_type);
16090 // sentinel: ?*const anyopaque,16075 // sentinel: ?*const anyopaque,
...@@ -16102,7 +16087,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16102,7 +16087,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16102 const info = ty.arrayInfo(mod);16087 const info = ty.arrayInfo(mod);
16103 const field_values = try sema.arena.alloc(Value, 2);16088 const field_values = try sema.arena.alloc(Value, 2);
16104 // len: comptime_int,16089 // len: comptime_int,
16105 field_values[0] = try Value.Tag.int_u64.create(sema.arena, info.len);16090 field_values[0] = try mod.intValue(Type.comptime_int, info.len);
16106 // child: type,16091 // child: type,
16107 field_values[1] = try Value.Tag.ty.create(sema.arena, info.elem_type);16092 field_values[1] = try Value.Tag.ty.create(sema.arena, info.elem_type);
1610816093
...@@ -16202,7 +16187,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16202,7 +16187,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16202 const new_decl_val = try Value.Tag.decl_ref.create(sema.arena, new_decl);16187 const new_decl_val = try Value.Tag.decl_ref.create(sema.arena, new_decl);
16203 const slice_val = try Value.Tag.slice.create(sema.arena, .{16188 const slice_val = try Value.Tag.slice.create(sema.arena, .{
16204 .ptr = new_decl_val,16189 .ptr = new_decl_val,
16205 .len = try Value.Tag.int_u64.create(sema.arena, vals.len),16190 .len = try mod.intValue(Type.usize, vals.len),
16206 });16191 });
16207 break :v try Value.Tag.opt_payload.create(sema.arena, slice_val);16192 break :v try Value.Tag.opt_payload.create(sema.arena, slice_val);
16208 } else Value.null;16193 } else Value.null;
...@@ -16263,8 +16248,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16263,8 +16248,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16263 };16248 };
16264 const tag_val = Value.initPayload(&tag_val_payload.base);16249 const tag_val = Value.initPayload(&tag_val_payload.base);
1626516250
16266 var buffer: Value.Payload.U64 = undefined;16251 const int_val = try tag_val.enumToInt(ty, mod);
16267 const int_val = try tag_val.enumToInt(ty, &buffer).copy(fields_anon_decl.arena());
1626816252
16269 const name = enum_fields.keys()[i];16253 const name = enum_fields.keys()[i];
16270 const name_val = v: {16254 const name_val = v: {
...@@ -16379,7 +16363,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16379,7 +16363,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16379 // type: type,16363 // type: type,
16380 try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty),16364 try Value.Tag.ty.create(fields_anon_decl.arena(), field.ty),
16381 // alignment: comptime_int,16365 // alignment: comptime_int,
16382 try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment),16366 try mod.intValue(Type.comptime_int, alignment),
16383 };16367 };
16384 field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), union_field_fields);16368 field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), union_field_fields);
16385 }16369 }
...@@ -16398,7 +16382,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16398,7 +16382,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16398 );16382 );
16399 break :v try Value.Tag.slice.create(sema.arena, .{16383 break :v try Value.Tag.slice.create(sema.arena, .{
16400 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),16384 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
16401 .len = try Value.Tag.int_u64.create(sema.arena, union_field_vals.len),16385 .len = try mod.intValue(Type.usize, union_field_vals.len),
16402 });16386 });
16403 };16387 };
1640416388
...@@ -16476,7 +16460,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16476,7 +16460,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16476 );16460 );
16477 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{16461 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
16478 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),16462 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
16479 .len = try Value.Tag.int_u64.create(fields_anon_decl.arena(), bytes.len),16463 .len = try mod.intValue(Type.usize, bytes.len),
16480 });16464 });
16481 };16465 };
1648216466
...@@ -16518,7 +16502,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16518,7 +16502,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16518 );16502 );
16519 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{16503 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
16520 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),16504 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
16521 .len = try Value.Tag.int_u64.create(fields_anon_decl.arena(), bytes.len),16505 .len = try mod.intValue(Type.usize, bytes.len),
16522 });16506 });
16523 };16507 };
1652416508
...@@ -16540,7 +16524,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16540,7 +16524,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16540 // is_comptime: bool,16524 // is_comptime: bool,
16541 Value.makeBool(field.is_comptime),16525 Value.makeBool(field.is_comptime),
16542 // alignment: comptime_int,16526 // alignment: comptime_int,
16543 try Value.Tag.int_u64.create(fields_anon_decl.arena(), alignment),16527 try mod.intValue(Type.comptime_int, alignment),
16544 };16528 };
16545 field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);16529 field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);
16546 }16530 }
...@@ -16561,7 +16545,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16561,7 +16545,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16561 );16545 );
16562 break :v try Value.Tag.slice.create(sema.arena, .{16546 break :v try Value.Tag.slice.create(sema.arena, .{
16563 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),16547 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
16564 .len = try Value.Tag.int_u64.create(sema.arena, struct_field_vals.len),16548 .len = try mod.intValue(Type.usize, struct_field_vals.len),
16565 });16549 });
16566 };16550 };
1656716551
...@@ -16636,6 +16620,7 @@ fn typeInfoDecls(...@@ -16636,6 +16620,7 @@ fn typeInfoDecls(
16636 type_info_ty: Type,16620 type_info_ty: Type,
16637 opt_namespace: ?*Module.Namespace,16621 opt_namespace: ?*Module.Namespace,
16638) CompileError!Value {16622) CompileError!Value {
16623 const mod = sema.mod;
16639 var decls_anon_decl = try block.startAnonDecl();16624 var decls_anon_decl = try block.startAnonDecl();
16640 defer decls_anon_decl.deinit();16625 defer decls_anon_decl.deinit();
1664116626
...@@ -16646,9 +16631,9 @@ fn typeInfoDecls(...@@ -16646,9 +16631,9 @@ fn typeInfoDecls(
16646 type_info_ty.getNamespace().?,16631 type_info_ty.getNamespace().?,
16647 "Declaration",16632 "Declaration",
16648 )).?;16633 )).?;
16649 try sema.mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);16634 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
16650 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);16635 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
16651 const declaration_ty_decl = sema.mod.declPtr(declaration_ty_decl_index);16636 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
16652 break :t try declaration_ty_decl.val.toType().copy(decls_anon_decl.arena());16637 break :t try declaration_ty_decl.val.toType().copy(decls_anon_decl.arena());
16653 };16638 };
16654 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));16639 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));
...@@ -16676,7 +16661,7 @@ fn typeInfoDecls(...@@ -16676,7 +16661,7 @@ fn typeInfoDecls(
16676 );16661 );
16677 return try Value.Tag.slice.create(sema.arena, .{16662 return try Value.Tag.slice.create(sema.arena, .{
16678 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),16663 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
16679 .len = try Value.Tag.int_u64.create(sema.arena, decl_vals.items.len),16664 .len = try mod.intValue(Type.usize, decl_vals.items.len),
16680 });16665 });
16681}16666}
1668216667
...@@ -16713,7 +16698,7 @@ fn typeInfoNamespaceDecls(...@@ -16713,7 +16698,7 @@ fn typeInfoNamespaceDecls(
16713 );16698 );
16714 break :v try Value.Tag.slice.create(decls_anon_decl, .{16699 break :v try Value.Tag.slice.create(decls_anon_decl, .{
16715 .ptr = try Value.Tag.decl_ref.create(decls_anon_decl, new_decl),16700 .ptr = try Value.Tag.decl_ref.create(decls_anon_decl, new_decl),
16716 .len = try Value.Tag.int_u64.create(decls_anon_decl, bytes.len),16701 .len = try mod.intValue(Type.usize, bytes.len),
16717 });16702 });
16718 };16703 };
1671916704
...@@ -18620,10 +18605,9 @@ fn zirUnaryMath(...@@ -18620,10 +18605,9 @@ fn zirUnaryMath(
18620 if (val.isUndef())18605 if (val.isUndef())
18621 return sema.addConstUndef(result_ty);18606 return sema.addConstUndef(result_ty);
1862218607
18623 var elem_buf: Value.ElemValueBuffer = undefined;
18624 const elems = try sema.arena.alloc(Value, vec_len);18608 const elems = try sema.arena.alloc(Value, vec_len);
18625 for (elems, 0..) |*elem, i| {18609 for (elems, 0..) |*elem, i| {
18626 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);18610 const elem_val = try val.elemValue(sema.mod, i);
18627 elem.* = try eval(elem_val, scalar_ty, sema.arena, sema.mod);18611 elem.* = try eval(elem_val, scalar_ty, sema.arena, sema.mod);
18628 }18612 }
18629 return sema.addConstant(18613 return sema.addConstant(
...@@ -18717,7 +18701,12 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18717,7 +18701,12 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18717 return block.addUnOp(.tag_name, casted_operand);18701 return block.addUnOp(.tag_name, casted_operand);
18718}18702}
1871918703
18720fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {18704fn zirReify(
18705 sema: *Sema,
18706 block: *Block,
18707 extended: Zir.Inst.Extended.InstData,
18708 inst: Zir.Inst.Index,
18709) CompileError!Air.Inst.Ref {
18721 const mod = sema.mod;18710 const mod = sema.mod;
18722 const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small);18711 const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small);
18723 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;18712 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
...@@ -18730,7 +18719,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18730,7 +18719,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18730 const union_val = val.cast(Value.Payload.Union).?.data;18719 const union_val = val.cast(Value.Payload.Union).?.data;
18731 const target = mod.getTarget();18720 const target = mod.getTarget();
18732 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;18721 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
18733 if (union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);18722 if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
18734 switch (@intToEnum(std.builtin.TypeId, tag_index)) {18723 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
18735 .Type => return Air.Inst.Ref.type_type,18724 .Type => return Air.Inst.Ref.type_type,
18736 .Void => return Air.Inst.Ref.void_type,18725 .Void => return Air.Inst.Ref.void_type,
...@@ -18845,10 +18834,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18845,10 +18834,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18845 } else if (ptr_size == .C) {18834 } else if (ptr_size == .C) {
18846 if (!try sema.validateExternType(elem_ty, .other)) {18835 if (!try sema.validateExternType(elem_ty, .other)) {
18847 const msg = msg: {18836 const msg = msg: {
18848 const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});18837 const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});
18849 errdefer msg.destroy(sema.gpa);18838 errdefer msg.destroy(sema.gpa);
1885018839
18851 const src_decl = sema.mod.declPtr(block.src_decl);18840 const src_decl = mod.declPtr(block.src_decl);
18852 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), elem_ty, .other);18841 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), elem_ty, .other);
1885318842
18854 try sema.addDeclaredHereNote(msg, elem_ty);18843 try sema.addDeclaredHereNote(msg, elem_ty);
...@@ -18893,7 +18882,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18893,7 +18882,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18893 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;18882 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;
18894 } else null;18883 } else null;
1889518884
18896 const ty = try Type.array(sema.arena, len, sentinel, child_ty, sema.mod);18885 const ty = try Type.array(sema.arena, len, sentinel, child_ty, mod);
18897 return sema.addType(ty);18886 return sema.addType(ty);
18898 },18887 },
18899 .Optional => {18888 .Optional => {
...@@ -18938,13 +18927,12 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -18938,13 +18927,12 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
18938 try names.ensureUnusedCapacity(sema.arena, len);18927 try names.ensureUnusedCapacity(sema.arena, len);
18939 var i: usize = 0;18928 var i: usize = 0;
18940 while (i < len) : (i += 1) {18929 while (i < len) : (i += 1) {
18941 var buf: Value.ElemValueBuffer = undefined;18930 const elem_val = try slice_val.ptr.elemValue(mod, i);
18942 const elem_val = slice_val.ptr.elemValueBuffer(mod, i, &buf);
18943 const struct_val = elem_val.castTag(.aggregate).?.data;18931 const struct_val = elem_val.castTag(.aggregate).?.data;
18944 // TODO use reflection instead of magic numbers here18932 // TODO use reflection instead of magic numbers here
18945 // error_set: type,18933 // error_set: type,
18946 const name_val = struct_val[0];18934 const name_val = struct_val[0];
18947 const name_str = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, sema.mod);18935 const name_str = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, mod);
1894818936
18949 const kv = try mod.getErrorValue(name_str);18937 const kv = try mod.getErrorValue(name_str);
18950 const gop = names.getOrPutAssumeCapacity(kv.key);18938 const gop = names.getOrPutAssumeCapacity(kv.key);
...@@ -19061,7 +19049,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19061,7 +19049,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1906119049
19062 var field_i: usize = 0;19050 var field_i: usize = 0;
19063 while (field_i < fields_len) : (field_i += 1) {19051 while (field_i < fields_len) : (field_i += 1) {
19064 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, field_i);19052 const elem_val = try fields_val.elemValue(mod, field_i);
19065 const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;19053 const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;
19066 // TODO use reflection instead of magic numbers here19054 // TODO use reflection instead of magic numbers here
19067 // name: []const u819055 // name: []const u8
...@@ -19072,7 +19060,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19072,7 +19060,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19072 const field_name = try name_val.toAllocatedBytes(19060 const field_name = try name_val.toAllocatedBytes(
19073 Type.const_slice_u8,19061 Type.const_slice_u8,
19074 new_decl_arena_allocator,19062 new_decl_arena_allocator,
19075 sema.mod,19063 mod,
19076 );19064 );
1907719065
19078 if (!try sema.intFitsInType(value_val, enum_obj.tag_ty, null)) {19066 if (!try sema.intFitsInType(value_val, enum_obj.tag_ty, null)) {
...@@ -19183,7 +19171,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19183,7 +19171,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19183 Type.Tag.union_tagged19171 Type.Tag.union_tagged
19184 else if (layout != .Auto)19172 else if (layout != .Auto)
19185 Type.Tag.@"union"19173 Type.Tag.@"union"
19186 else switch (block.sema.mod.optimizeMode()) {19174 else switch (mod.optimizeMode()) {
19187 .Debug, .ReleaseSafe => Type.Tag.union_safety_tagged,19175 .Debug, .ReleaseSafe => Type.Tag.union_safety_tagged,
19188 .ReleaseFast, .ReleaseSmall => Type.Tag.@"union",19176 .ReleaseFast, .ReleaseSmall => Type.Tag.@"union",
19189 };19177 };
...@@ -19236,7 +19224,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19236,7 +19224,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1923619224
19237 var i: usize = 0;19225 var i: usize = 0;
19238 while (i < fields_len) : (i += 1) {19226 while (i < fields_len) : (i += 1) {
19239 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);19227 const elem_val = try fields_val.elemValue(mod, i);
19240 const field_struct_val = elem_val.castTag(.aggregate).?.data;19228 const field_struct_val = elem_val.castTag(.aggregate).?.data;
19241 // TODO use reflection instead of magic numbers here19229 // TODO use reflection instead of magic numbers here
19242 // name: []const u819230 // name: []const u8
...@@ -19249,7 +19237,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19249,7 +19237,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19249 const field_name = try name_val.toAllocatedBytes(19237 const field_name = try name_val.toAllocatedBytes(
19250 Type.const_slice_u8,19238 Type.const_slice_u8,
19251 new_decl_arena_allocator,19239 new_decl_arena_allocator,
19252 sema.mod,19240 mod,
19253 );19241 );
1925419242
19255 if (enum_field_names) |set| {19243 if (enum_field_names) |set| {
...@@ -19260,7 +19248,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19260,7 +19248,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19260 const enum_has_field = names.orderedRemove(field_name);19248 const enum_has_field = names.orderedRemove(field_name);
19261 if (!enum_has_field) {19249 if (!enum_has_field) {
19262 const msg = msg: {19250 const msg = msg: {
19263 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) });19251 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(mod) });
19264 errdefer msg.destroy(sema.gpa);19252 errdefer msg.destroy(sema.gpa);
19265 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);19253 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
19266 break :msg msg;19254 break :msg msg;
...@@ -19293,10 +19281,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19293,10 +19281,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19293 }19281 }
19294 if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) {19282 if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) {
19295 const msg = msg: {19283 const msg = msg: {
19296 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});19284 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
19297 errdefer msg.destroy(sema.gpa);19285 errdefer msg.destroy(sema.gpa);
1929819286
19299 const src_decl = sema.mod.declPtr(block.src_decl);19287 const src_decl = mod.declPtr(block.src_decl);
19300 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), field_ty, .union_field);19288 try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl), field_ty, .union_field);
1930119289
19302 try sema.addDeclaredHereNote(msg, field_ty);19290 try sema.addDeclaredHereNote(msg, field_ty);
...@@ -19305,10 +19293,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19305,10 +19293,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19305 return sema.failWithOwnedErrorMsg(msg);19293 return sema.failWithOwnedErrorMsg(msg);
19306 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty, mod))) {19294 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty, mod))) {
19307 const msg = msg: {19295 const msg = msg: {
19308 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});19296 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
19309 errdefer msg.destroy(sema.gpa);19297 errdefer msg.destroy(sema.gpa);
1931019298
19311 const src_decl = sema.mod.declPtr(block.src_decl);19299 const src_decl = mod.declPtr(block.src_decl);
19312 try sema.explainWhyTypeIsNotPacked(msg, src.toSrcLoc(src_decl), field_ty);19300 try sema.explainWhyTypeIsNotPacked(msg, src.toSrcLoc(src_decl), field_ty);
1931319301
19314 try sema.addDeclaredHereNote(msg, field_ty);19302 try sema.addDeclaredHereNote(msg, field_ty);
...@@ -19386,8 +19374,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -19386,8 +19374,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
19386 var noalias_bits: u32 = 0;19374 var noalias_bits: u32 = 0;
19387 var i: usize = 0;19375 var i: usize = 0;
19388 while (i < args_len) : (i += 1) {19376 while (i < args_len) : (i += 1) {
19389 var arg_buf: Value.ElemValueBuffer = undefined;19377 const arg = try args_slice_val.ptr.elemValue(mod, i);
19390 const arg = args_slice_val.ptr.elemValueBuffer(mod, i, &arg_buf);
19391 const arg_val = arg.castTag(.aggregate).?.data;19378 const arg_val = arg.castTag(.aggregate).?.data;
19392 // TODO use reflection instead of magic numbers here19379 // TODO use reflection instead of magic numbers here
19393 // is_generic: bool,19380 // is_generic: bool,
...@@ -19486,7 +19473,7 @@ fn reifyStruct(...@@ -19486,7 +19473,7 @@ fn reifyStruct(
19486 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);19473 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
19487 var i: usize = 0;19474 var i: usize = 0;
19488 while (i < fields_len) : (i += 1) {19475 while (i < fields_len) : (i += 1) {
19489 const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);19476 const elem_val = try fields_val.elemValue(sema.mod, i);
19490 const field_struct_val = elem_val.castTag(.aggregate).?.data;19477 const field_struct_val = elem_val.castTag(.aggregate).?.data;
19491 // TODO use reflection instead of magic numbers here19478 // TODO use reflection instead of magic numbers here
19492 // name: []const u819479 // name: []const u8
...@@ -19892,12 +19879,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19892,12 +19879,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19892 if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0)19879 if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0)
19893 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});19880 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});
1989419881
19895 const val_payload = try sema.arena.create(Value.Payload.U64);19882 return sema.addConstant(ptr_ty, try mod.intValue(ptr_ty, addr));
19896 val_payload.* = .{
19897 .base = .{ .tag = .int_u64 },
19898 .data = addr,
19899 };
19900 return sema.addConstant(ptr_ty, Value.initPayload(&val_payload.base));
19901 }19883 }
1990219884
19903 try sema.requireRuntimeBlock(block, src, operand_src);19885 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -19908,14 +19890,9 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19908,14 +19890,9 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19908 }19890 }
1990919891
19910 if (ptr_align > 1) {19892 if (ptr_align > 1) {
19911 const val_payload = try sema.arena.create(Value.Payload.U64);
19912 val_payload.* = .{
19913 .base = .{ .tag = .int_u64 },
19914 .data = ptr_align - 1,
19915 };
19916 const align_minus_1 = try sema.addConstant(19893 const align_minus_1 = try sema.addConstant(
19917 Type.usize,19894 Type.usize,
19918 Value.initPayload(&val_payload.base),19895 try mod.intValue(Type.usize, ptr_align - 1),
19919 );19896 );
19920 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);19897 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
19921 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);19898 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
...@@ -20254,10 +20231,9 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20254,10 +20231,9 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20254 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, sema.mod),20231 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, sema.mod),
20255 );20232 );
20256 }20233 }
20257 var elem_buf: Value.ElemValueBuffer = undefined;
20258 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen(mod));20234 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen(mod));
20259 for (elems, 0..) |*elem, i| {20235 for (elems, 0..) |*elem, i| {
20260 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20236 const elem_val = try val.elemValue(sema.mod, i);
20261 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, sema.mod);20237 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, sema.mod);
20262 }20238 }
20263 return sema.addConstant(20239 return sema.addConstant(
...@@ -20302,14 +20278,9 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -20302,14 +20278,9 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
20302 if (block.wantSafety() and dest_align > 1 and20278 if (block.wantSafety() and dest_align > 1 and
20303 try sema.typeHasRuntimeBits(ptr_info.pointee_type))20279 try sema.typeHasRuntimeBits(ptr_info.pointee_type))
20304 {20280 {
20305 const val_payload = try sema.arena.create(Value.Payload.U64);
20306 val_payload.* = .{
20307 .base = .{ .tag = .int_u64 },
20308 .data = dest_align - 1,
20309 };
20310 const align_minus_1 = try sema.addConstant(20281 const align_minus_1 = try sema.addConstant(
20311 Type.usize,20282 Type.usize,
20312 Value.initPayload(&val_payload.base),20283 try mod.intValue(Type.usize, dest_align - 1),
20313 );20284 );
20314 const actual_ptr = if (ptr_ty.isSlice(mod))20285 const actual_ptr = if (ptr_ty.isSlice(mod))
20315 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)20286 try sema.analyzeSlicePtr(block, ptr_src, ptr, ptr_ty)
...@@ -20359,13 +20330,12 @@ fn zirBitCount(...@@ -20359,13 +20330,12 @@ fn zirBitCount(
20359 if (try sema.resolveMaybeUndefVal(operand)) |val| {20330 if (try sema.resolveMaybeUndefVal(operand)) |val| {
20360 if (val.isUndef()) return sema.addConstUndef(result_ty);20331 if (val.isUndef()) return sema.addConstUndef(result_ty);
2036120332
20362 var elem_buf: Value.ElemValueBuffer = undefined;
20363 const elems = try sema.arena.alloc(Value, vec_len);20333 const elems = try sema.arena.alloc(Value, vec_len);
20364 const scalar_ty = operand_ty.scalarType(mod);20334 const scalar_ty = operand_ty.scalarType(mod);
20365 for (elems, 0..) |*elem, i| {20335 for (elems, 0..) |*elem, i| {
20366 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20336 const elem_val = try val.elemValue(sema.mod, i);
20367 const count = comptimeOp(elem_val, scalar_ty, mod);20337 const count = comptimeOp(elem_val, scalar_ty, mod);
20368 elem.* = try Value.Tag.int_u64.create(sema.arena, count);20338 elem.* = try mod.intValue(scalar_ty, count);
20369 }20339 }
20370 return sema.addConstant(20340 return sema.addConstant(
20371 result_ty,20341 result_ty,
...@@ -20429,10 +20399,9 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20429,10 +20399,9 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20429 return sema.addConstUndef(operand_ty);20399 return sema.addConstUndef(operand_ty);
2043020400
20431 const vec_len = operand_ty.vectorLen(mod);20401 const vec_len = operand_ty.vectorLen(mod);
20432 var elem_buf: Value.ElemValueBuffer = undefined;
20433 const elems = try sema.arena.alloc(Value, vec_len);20402 const elems = try sema.arena.alloc(Value, vec_len);
20434 for (elems, 0..) |*elem, i| {20403 for (elems, 0..) |*elem, i| {
20435 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20404 const elem_val = try val.elemValue(sema.mod, i);
20436 elem.* = try elem_val.byteSwap(operand_ty, mod, sema.arena);20405 elem.* = try elem_val.byteSwap(operand_ty, mod, sema.arena);
20437 }20406 }
20438 return sema.addConstant(20407 return sema.addConstant(
...@@ -20478,10 +20447,9 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -20478,10 +20447,9 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
20478 return sema.addConstUndef(operand_ty);20447 return sema.addConstUndef(operand_ty);
2047920448
20480 const vec_len = operand_ty.vectorLen(mod);20449 const vec_len = operand_ty.vectorLen(mod);
20481 var elem_buf: Value.ElemValueBuffer = undefined;
20482 const elems = try sema.arena.alloc(Value, vec_len);20450 const elems = try sema.arena.alloc(Value, vec_len);
20483 for (elems, 0..) |*elem, i| {20451 for (elems, 0..) |*elem, i| {
20484 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);20452 const elem_val = try val.elemValue(sema.mod, i);
20485 elem.* = try elem_val.bitReverse(scalar_ty, mod, sema.arena);20453 elem.* = try elem_val.bitReverse(scalar_ty, mod, sema.arena);
20486 }20454 }
20487 return sema.addConstant(20455 return sema.addConstant(
...@@ -21241,11 +21209,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -21241,11 +21209,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
21241 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {21209 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
21242 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);21210 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
2124321211
21244 var accum: Value = try operand_val.elemValue(mod, sema.arena, 0);21212 var accum: Value = try operand_val.elemValue(mod, 0);
21245 var elem_buf: Value.ElemValueBuffer = undefined;
21246 var i: u32 = 1;21213 var i: u32 = 1;
21247 while (i < vec_len) : (i += 1) {21214 while (i < vec_len) : (i += 1) {
21248 const elem_val = operand_val.elemValueBuffer(mod, i, &elem_buf);21215 const elem_val = try operand_val.elemValue(mod, i);
21249 switch (operation) {21216 switch (operation) {
21250 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod),21217 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod),
21251 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, mod),21218 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, mod),
...@@ -21359,8 +21326,7 @@ fn analyzeShuffle(...@@ -21359,8 +21326,7 @@ fn analyzeShuffle(
2135921326
21360 var i: usize = 0;21327 var i: usize = 0;
21361 while (i < mask_len) : (i += 1) {21328 while (i < mask_len) : (i += 1) {
21362 var buf: Value.ElemValueBuffer = undefined;21329 const elem = try mask.elemValue(sema.mod, i);
21363 const elem = mask.elemValueBuffer(sema.mod, i, &buf);
21364 if (elem.isUndef()) continue;21330 if (elem.isUndef()) continue;
21365 const int = elem.toSignedInt(mod);21331 const int = elem.toSignedInt(mod);
21366 var unsigned: u32 = undefined;21332 var unsigned: u32 = undefined;
...@@ -21398,8 +21364,7 @@ fn analyzeShuffle(...@@ -21398,8 +21364,7 @@ fn analyzeShuffle(
2139821364
21399 i = 0;21365 i = 0;
21400 while (i < mask_len) : (i += 1) {21366 while (i < mask_len) : (i += 1) {
21401 var buf: Value.ElemValueBuffer = undefined;21367 const mask_elem_val = try mask.elemValue(sema.mod, i);
21402 const mask_elem_val = mask.elemValueBuffer(sema.mod, i, &buf);
21403 if (mask_elem_val.isUndef()) {21368 if (mask_elem_val.isUndef()) {
21404 values[i] = Value.undef;21369 values[i] = Value.undef;
21405 continue;21370 continue;
...@@ -21407,9 +21372,9 @@ fn analyzeShuffle(...@@ -21407,9 +21372,9 @@ fn analyzeShuffle(
21407 const int = mask_elem_val.toSignedInt(mod);21372 const int = mask_elem_val.toSignedInt(mod);
21408 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);21373 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);
21409 if (int >= 0) {21374 if (int >= 0) {
21410 values[i] = try a_val.elemValue(sema.mod, sema.arena, unsigned);21375 values[i] = try a_val.elemValue(sema.mod, unsigned);
21411 } else {21376 } else {
21412 values[i] = try b_val.elemValue(sema.mod, sema.arena, unsigned);21377 values[i] = try b_val.elemValue(sema.mod, unsigned);
21413 }21378 }
21414 }21379 }
21415 const res_val = try Value.Tag.aggregate.create(sema.arena, values);21380 const res_val = try Value.Tag.aggregate.create(sema.arena, values);
...@@ -21430,7 +21395,7 @@ fn analyzeShuffle(...@@ -21430,7 +21395,7 @@ fn analyzeShuffle(
21430 const expand_mask_values = try sema.arena.alloc(Value, max_len);21395 const expand_mask_values = try sema.arena.alloc(Value, max_len);
21431 i = 0;21396 i = 0;
21432 while (i < min_len) : (i += 1) {21397 while (i < min_len) : (i += 1) {
21433 expand_mask_values[i] = try Value.Tag.int_u64.create(sema.arena, i);21398 expand_mask_values[i] = try mod.intValue(Type.comptime_int, i);
21434 }21399 }
21435 while (i < max_len) : (i += 1) {21400 while (i < max_len) : (i += 1) {
21436 expand_mask_values[i] = Value.negative_one;21401 expand_mask_values[i] = Value.negative_one;
...@@ -21509,15 +21474,14 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -21509,15 +21474,14 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
21509 if (maybe_b) |b_val| {21474 if (maybe_b) |b_val| {
21510 if (b_val.isUndef()) return sema.addConstUndef(vec_ty);21475 if (b_val.isUndef()) return sema.addConstUndef(vec_ty);
2151121476
21512 var buf: Value.ElemValueBuffer = undefined;
21513 const elems = try sema.gpa.alloc(Value, vec_len);21477 const elems = try sema.gpa.alloc(Value, vec_len);
21514 for (elems, 0..) |*elem, i| {21478 for (elems, 0..) |*elem, i| {
21515 const pred_elem_val = pred_val.elemValueBuffer(sema.mod, i, &buf);21479 const pred_elem_val = try pred_val.elemValue(sema.mod, i);
21516 const should_choose_a = pred_elem_val.toBool(mod);21480 const should_choose_a = pred_elem_val.toBool(mod);
21517 if (should_choose_a) {21481 if (should_choose_a) {
21518 elem.* = a_val.elemValueBuffer(sema.mod, i, &buf);21482 elem.* = try a_val.elemValue(sema.mod, i);
21519 } else {21483 } else {
21520 elem.* = b_val.elemValueBuffer(sema.mod, i, &buf);21484 elem.* = try b_val.elemValue(sema.mod, i);
21521 }21485 }
21522 }21486 }
2152321487
...@@ -22067,12 +22031,10 @@ fn analyzeMinMax(...@@ -22067,12 +22031,10 @@ fn analyzeMinMax(
22067 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);22031 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);
22068 continue;22032 continue;
22069 };22033 };
22070 var lhs_buf: Value.ElemValueBuffer = undefined;
22071 var rhs_buf: Value.ElemValueBuffer = undefined;
22072 const elems = try sema.arena.alloc(Value, vec_len);22034 const elems = try sema.arena.alloc(Value, vec_len);
22073 for (elems, 0..) |*elem, i| {22035 for (elems, 0..) |*elem, i| {
22074 const lhs_elem_val = cur_val.elemValueBuffer(mod, i, &lhs_buf);22036 const lhs_elem_val = try cur_val.elemValue(mod, i);
22075 const rhs_elem_val = operand_val.elemValueBuffer(mod, i, &rhs_buf);22037 const rhs_elem_val = try operand_val.elemValue(mod, i);
22076 elem.* = opFunc(lhs_elem_val, rhs_elem_val, mod);22038 elem.* = opFunc(lhs_elem_val, rhs_elem_val, mod);
22077 }22039 }
22078 cur_minmax = try sema.addConstant(22040 cur_minmax = try sema.addConstant(
...@@ -22105,10 +22067,10 @@ fn analyzeMinMax(...@@ -22105,10 +22067,10 @@ fn analyzeMinMax(
22105 if (len == 0) break :blk orig_ty;22067 if (len == 0) break :blk orig_ty;
22106 if (elem_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats22068 if (elem_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats
2210722069
22108 var cur_min: Value = try val.elemValue(mod, sema.arena, 0);22070 var cur_min: Value = try val.elemValue(mod, 0);
22109 var cur_max: Value = cur_min;22071 var cur_max: Value = cur_min;
22110 for (1..len) |idx| {22072 for (1..len) |idx| {
22111 const elem_val = try val.elemValue(mod, sema.arena, idx);22073 const elem_val = try val.elemValue(mod, idx);
22112 if (elem_val.isUndef()) break :blk orig_ty; // can't refine undef22074 if (elem_val.isUndef()) break :blk orig_ty; // can't refine undef
22113 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;22075 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;
22114 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;22076 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;
...@@ -23987,7 +23949,7 @@ fn fieldVal(...@@ -23987,7 +23949,7 @@ fn fieldVal(
23987 if (mem.eql(u8, field_name, "len")) {23949 if (mem.eql(u8, field_name, "len")) {
23988 return sema.addConstant(23950 return sema.addConstant(
23989 Type.usize,23951 Type.usize,
23990 try Value.Tag.int_u64.create(arena, inner_ty.arrayLen(mod)),23952 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
23991 );23953 );
23992 } else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) {23954 } else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) {
23993 const ptr_info = object_ty.ptrInfo(mod);23955 const ptr_info = object_ty.ptrInfo(mod);
...@@ -24179,7 +24141,7 @@ fn fieldPtr(...@@ -24179,7 +24141,7 @@ fn fieldPtr(
24179 defer anon_decl.deinit();24141 defer anon_decl.deinit();
24180 return sema.analyzeDeclRef(try anon_decl.finish(24142 return sema.analyzeDeclRef(try anon_decl.finish(
24181 Type.usize,24143 Type.usize,
24182 try Value.Tag.int_u64.create(anon_decl.arena(), inner_ty.arrayLen(mod)),24144 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
24183 0, // default alignment24145 0, // default alignment
24184 ));24146 ));
24185 } else {24147 } else {
...@@ -25352,7 +25314,7 @@ fn elemValArray(...@@ -25352,7 +25314,7 @@ fn elemValArray(
25352 }25314 }
25353 if (maybe_index_val) |index_val| {25315 if (maybe_index_val) |index_val| {
25354 const index = @intCast(usize, index_val.toUnsignedInt(mod));25316 const index = @intCast(usize, index_val.toUnsignedInt(mod));
25355 const elem_val = try array_val.elemValue(sema.mod, sema.arena, index);25317 const elem_val = try array_val.elemValue(mod, index);
25356 return sema.addConstant(elem_ty, elem_val);25318 return sema.addConstant(elem_ty, elem_val);
25357 }25319 }
25358 }25320 }
...@@ -25914,7 +25876,7 @@ fn coerceExtra(...@@ -25914,7 +25876,7 @@ fn coerceExtra(
25914 // we use a dummy pointer value with the required alignment.25876 // we use a dummy pointer value with the required alignment.
25915 const slice_val = try Value.Tag.slice.create(sema.arena, .{25877 const slice_val = try Value.Tag.slice.create(sema.arena, .{
25916 .ptr = if (dest_info.@"align" != 0)25878 .ptr = if (dest_info.@"align" != 0)
25917 try Value.Tag.int_u64.create(sema.arena, dest_info.@"align")25879 try mod.intValue(Type.usize, dest_info.@"align")
25918 else25880 else
25919 try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena),25881 try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena),
25920 .len = Value.zero,25882 .len = Value.zero,
...@@ -26022,7 +25984,7 @@ fn coerceExtra(...@@ -26022,7 +25984,7 @@ fn coerceExtra(
26022 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) {25984 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) {
26023 .ComptimeFloat => {25985 .ComptimeFloat => {
26024 const val = try sema.resolveConstValue(block, .unneeded, inst, "");25986 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
26025 const result_val = try val.floatCast(sema.arena, dest_ty, target);25987 const result_val = try val.floatCast(sema.arena, dest_ty, mod);
26026 return try sema.addConstant(dest_ty, result_val);25988 return try sema.addConstant(dest_ty, result_val);
26027 },25989 },
26028 .Float => {25990 .Float => {
...@@ -26030,7 +25992,7 @@ fn coerceExtra(...@@ -26030,7 +25992,7 @@ fn coerceExtra(
26030 return sema.addConstUndef(dest_ty);25992 return sema.addConstUndef(dest_ty);
26031 }25993 }
26032 if (try sema.resolveMaybeUndefVal(inst)) |val| {25994 if (try sema.resolveMaybeUndefVal(inst)) |val| {
26033 const result_val = try val.floatCast(sema.arena, dest_ty, target);25995 const result_val = try val.floatCast(sema.arena, dest_ty, mod);
26034 if (!val.eql(result_val, inst_ty, sema.mod)) {25996 if (!val.eql(result_val, inst_ty, sema.mod)) {
26035 return sema.fail(25997 return sema.fail(
26036 block,25998 block,
...@@ -27431,11 +27393,13 @@ fn storePtrVal(...@@ -27431,11 +27393,13 @@ fn storePtrVal(
27431 const buffer = try sema.gpa.alloc(u8, abi_size);27393 const buffer = try sema.gpa.alloc(u8, abi_size);
27432 defer sema.gpa.free(buffer);27394 defer sema.gpa.free(buffer);
27433 reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer) catch |err| switch (err) {27395 reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer) catch |err| switch (err) {
27396 error.OutOfMemory => return error.OutOfMemory,
27434 error.ReinterpretDeclRef => unreachable,27397 error.ReinterpretDeclRef => unreachable,
27435 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already27398 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already
27436 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(sema.mod)}),27399 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(sema.mod)}),
27437 };27400 };
27438 operand_val.writeToMemory(operand_ty, sema.mod, buffer[reinterpret.byte_offset..]) catch |err| switch (err) {27401 operand_val.writeToMemory(operand_ty, sema.mod, buffer[reinterpret.byte_offset..]) catch |err| switch (err) {
27402 error.OutOfMemory => return error.OutOfMemory,
27439 error.ReinterpretDeclRef => unreachable,27403 error.ReinterpretDeclRef => unreachable,
27440 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already27404 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already
27441 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(sema.mod)}),27405 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(sema.mod)}),
...@@ -27589,7 +27553,7 @@ fn beginComptimePtrMutation(...@@ -27589,7 +27553,7 @@ fn beginComptimePtrMutation(
27589 assert(bytes.len >= dest_len);27553 assert(bytes.len >= dest_len);
27590 const elems = try arena.alloc(Value, @intCast(usize, dest_len));27554 const elems = try arena.alloc(Value, @intCast(usize, dest_len));
27591 for (elems, 0..) |*elem, i| {27555 for (elems, 0..) |*elem, i| {
27592 elem.* = try Value.Tag.int_u64.create(arena, bytes[i]);27556 elem.* = try mod.intValue(elem_ty, bytes[i]);
27593 }27557 }
2759427558
27595 val_ptr.* = try Value.Tag.aggregate.create(arena, elems);27559 val_ptr.* = try Value.Tag.aggregate.create(arena, elems);
...@@ -27618,7 +27582,7 @@ fn beginComptimePtrMutation(...@@ -27618,7 +27582,7 @@ fn beginComptimePtrMutation(
27618 const bytes = sema.mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];27582 const bytes = sema.mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
27619 const elems = try arena.alloc(Value, @intCast(usize, dest_len));27583 const elems = try arena.alloc(Value, @intCast(usize, dest_len));
27620 for (bytes, 0..) |byte, i| {27584 for (bytes, 0..) |byte, i| {
27621 elems[i] = try Value.Tag.int_u64.create(arena, byte);27585 elems[i] = try mod.intValue(elem_ty, byte);
27622 }27586 }
27623 if (parent.ty.sentinel(mod)) |sent_val| {27587 if (parent.ty.sentinel(mod)) |sent_val| {
27624 assert(elems.len == bytes.len + 1);27588 assert(elems.len == bytes.len + 1);
...@@ -28111,7 +28075,7 @@ fn beginComptimePtrLoad(...@@ -28111,7 +28075,7 @@ fn beginComptimePtrLoad(
28111 maybe_array_ty: ?Type,28075 maybe_array_ty: ?Type,
28112) ComptimePtrLoadError!ComptimePtrLoadKit {28076) ComptimePtrLoadError!ComptimePtrLoadKit {
28113 const mod = sema.mod;28077 const mod = sema.mod;
28114 const target = sema.mod.getTarget();28078 const target = mod.getTarget();
2811528079
28116 var deref: ComptimePtrLoadKit = switch (ptr_val.ip_index) {28080 var deref: ComptimePtrLoadKit = switch (ptr_val.ip_index) {
28117 .null_value => {28081 .null_value => {
...@@ -28128,7 +28092,7 @@ fn beginComptimePtrLoad(...@@ -28128,7 +28092,7 @@ fn beginComptimePtrLoad(
28128 else => unreachable,28092 else => unreachable,
28129 };28093 };
28130 const is_mutable = ptr_val.tag() == .decl_ref_mut;28094 const is_mutable = ptr_val.tag() == .decl_ref_mut;
28131 const decl = sema.mod.declPtr(decl_index);28095 const decl = mod.declPtr(decl_index);
28132 const decl_tv = try decl.typedValue();28096 const decl_tv = try decl.typedValue();
28133 if (decl_tv.val.tagIsVariable()) return error.RuntimeLoad;28097 if (decl_tv.val.tagIsVariable()) return error.RuntimeLoad;
2813428098
...@@ -28150,7 +28114,7 @@ fn beginComptimePtrLoad(...@@ -28150,7 +28114,7 @@ fn beginComptimePtrLoad(
28150 // to succeed, meaning that elem ptrs of the same elem_ty are coalesced. Here we check that28114 // to succeed, meaning that elem ptrs of the same elem_ty are coalesced. Here we check that
28151 // our parent is not an elem_ptr with the same elem_ty, since that would be "unflattened"28115 // our parent is not an elem_ptr with the same elem_ty, since that would be "unflattened"
28152 if (elem_ptr.array_ptr.castTag(.elem_ptr)) |parent_elem_ptr| {28116 if (elem_ptr.array_ptr.castTag(.elem_ptr)) |parent_elem_ptr| {
28153 assert(!(parent_elem_ptr.data.elem_ty.eql(elem_ty, sema.mod)));28117 assert(!(parent_elem_ptr.data.elem_ty.eql(elem_ty, mod)));
28154 }28118 }
2815528119
28156 if (elem_ptr.index != 0) {28120 if (elem_ptr.index != 0) {
...@@ -28184,11 +28148,11 @@ fn beginComptimePtrLoad(...@@ -28184,11 +28148,11 @@ fn beginComptimePtrLoad(
28184 if (maybe_array_ty) |load_ty| {28148 if (maybe_array_ty) |load_ty| {
28185 // It's possible that we're loading a [N]T, in which case we'd like to slice28149 // It's possible that we're loading a [N]T, in which case we'd like to slice
28186 // the pointee array directly from our parent array.28150 // the pointee array directly from our parent array.
28187 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, sema.mod)) {28151 if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) {
28188 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));28152 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod));
28189 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{28153 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
28190 .ty = try Type.array(sema.arena, N, null, elem_ty, sema.mod),28154 .ty = try Type.array(sema.arena, N, null, elem_ty, mod),
28191 .val = try array_tv.val.sliceArray(sema.mod, sema.arena, elem_ptr.index, elem_ptr.index + N),28155 .val = try array_tv.val.sliceArray(mod, sema.arena, elem_ptr.index, elem_ptr.index + N),
28192 } else null;28156 } else null;
28193 break :blk deref;28157 break :blk deref;
28194 }28158 }
...@@ -28209,7 +28173,7 @@ fn beginComptimePtrLoad(...@@ -28209,7 +28173,7 @@ fn beginComptimePtrLoad(
28209 }28173 }
28210 deref.pointee = TypedValue{28174 deref.pointee = TypedValue{
28211 .ty = elem_ty,28175 .ty = elem_ty,
28212 .val = try array_tv.val.elemValue(sema.mod, sema.arena, elem_ptr.index),28176 .val = try array_tv.val.elemValue(mod, elem_ptr.index),
28213 };28177 };
28214 break :blk deref;28178 break :blk deref;
28215 },28179 },
...@@ -28329,12 +28293,6 @@ fn beginComptimePtrLoad(...@@ -28329,12 +28293,6 @@ fn beginComptimePtrLoad(
28329 break :blk try sema.beginComptimePtrLoad(block, src, opt_payload, null);28293 break :blk try sema.beginComptimePtrLoad(block, src, opt_payload, null);
28330 },28294 },
2833128295
28332 .zero,
28333 .one,
28334 .int_u64,
28335 .int_i64,
28336 .int_big_positive,
28337 .int_big_negative,
28338 .variable,28296 .variable,
28339 .extern_fn,28297 .extern_fn,
28340 .function,28298 .function,
...@@ -28342,7 +28300,10 @@ fn beginComptimePtrLoad(...@@ -28342,7 +28300,10 @@ fn beginComptimePtrLoad(
2834228300
28343 else => unreachable,28301 else => unreachable,
28344 },28302 },
28345 else => unreachable,28303 else => switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
28304 .int => return error.RuntimeLoad,
28305 else => unreachable,
28306 },
28346 };28307 };
2834728308
28348 if (deref.pointee) |tv| {28309 if (deref.pointee) |tv| {
...@@ -28373,9 +28334,9 @@ fn bitCast(...@@ -28373,9 +28334,9 @@ fn bitCast(
2837328334
28374 if (old_bits != dest_bits) {28335 if (old_bits != dest_bits) {
28375 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{28336 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{
28376 dest_ty.fmt(sema.mod),28337 dest_ty.fmt(mod),
28377 dest_bits,28338 dest_bits,
28378 old_ty.fmt(sema.mod),28339 old_ty.fmt(mod),
28379 old_bits,28340 old_bits,
28380 });28341 });
28381 }28342 }
...@@ -28407,6 +28368,7 @@ fn bitCastVal(...@@ -28407,6 +28368,7 @@ fn bitCastVal(
28407 const buffer = try sema.gpa.alloc(u8, abi_size);28368 const buffer = try sema.gpa.alloc(u8, abi_size);
28408 defer sema.gpa.free(buffer);28369 defer sema.gpa.free(buffer);
28409 val.writeToMemory(old_ty, mod, buffer) catch |err| switch (err) {28370 val.writeToMemory(old_ty, mod, buffer) catch |err| switch (err) {
28371 error.OutOfMemory => return error.OutOfMemory,
28410 error.ReinterpretDeclRef => return null,28372 error.ReinterpretDeclRef => return null,
28411 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already28373 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already
28412 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{old_ty.fmt(mod)}),28374 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{old_ty.fmt(mod)}),
...@@ -28427,7 +28389,7 @@ fn coerceArrayPtrToSlice(...@@ -28427,7 +28389,7 @@ fn coerceArrayPtrToSlice(
28427 const array_ty = ptr_array_ty.childType(mod);28389 const array_ty = ptr_array_ty.childType(mod);
28428 const slice_val = try Value.Tag.slice.create(sema.arena, .{28390 const slice_val = try Value.Tag.slice.create(sema.arena, .{
28429 .ptr = val,28391 .ptr = val,
28430 .len = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen(mod)),28392 .len = try mod.intValue(Type.usize, array_ty.arrayLen(mod)),
28431 });28393 });
28432 return sema.addConstant(dest_ty, slice_val);28394 return sema.addConstant(dest_ty, slice_val);
28433 }28395 }
...@@ -28781,7 +28743,7 @@ fn coerceArrayLike(...@@ -28781,7 +28743,7 @@ fn coerceArrayLike(
28781 for (element_vals, 0..) |*elem, i| {28743 for (element_vals, 0..) |*elem, i| {
28782 const index_ref = try sema.addConstant(28744 const index_ref = try sema.addConstant(
28783 Type.usize,28745 Type.usize,
28784 try Value.Tag.int_u64.create(sema.arena, i),28746 try mod.intValue(Type.usize, i),
28785 );28747 );
28786 const src = inst_src; // TODO better source location28748 const src = inst_src; // TODO better source location
28787 const elem_src = inst_src; // TODO better source location28749 const elem_src = inst_src; // TODO better source location
...@@ -29634,7 +29596,7 @@ fn analyzeSlice(...@@ -29634,7 +29596,7 @@ fn analyzeSlice(
29634 var end_is_len = uncasted_end_opt == .none;29596 var end_is_len = uncasted_end_opt == .none;
29635 const end = e: {29597 const end = e: {
29636 if (array_ty.zigTypeTag(mod) == .Array) {29598 if (array_ty.zigTypeTag(mod) == .Array) {
29637 const len_val = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen(mod));29599 const len_val = try mod.intValue(Type.usize, array_ty.arrayLen(mod));
2963829600
29639 if (!end_is_len) {29601 if (!end_is_len) {
29640 const end = if (by_length) end: {29602 const end = if (by_length) end: {
...@@ -29643,8 +29605,8 @@ fn analyzeSlice(...@@ -29643,8 +29605,8 @@ fn analyzeSlice(
29643 break :end try sema.coerce(block, Type.usize, uncasted_end, end_src);29605 break :end try sema.coerce(block, Type.usize, uncasted_end, end_src);
29644 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);29606 } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
29645 if (try sema.resolveMaybeUndefVal(end)) |end_val| {29607 if (try sema.resolveMaybeUndefVal(end)) |end_val| {
29646 const len_s_val = try Value.Tag.int_u64.create(29608 const len_s_val = try mod.intValue(
29647 sema.arena,29609 Type.usize,
29648 array_ty.arrayLenIncludingSentinel(mod),29610 array_ty.arrayLenIncludingSentinel(mod),
29649 );29611 );
29650 if (!(try sema.compareAll(end_val, .lte, len_s_val, Type.usize))) {29612 if (!(try sema.compareAll(end_val, .lte, len_s_val, Type.usize))) {
...@@ -29689,12 +29651,10 @@ fn analyzeSlice(...@@ -29689,12 +29651,10 @@ fn analyzeSlice(
29689 return sema.fail(block, src, "slice of undefined", .{});29651 return sema.fail(block, src, "slice of undefined", .{});
29690 }29652 }
29691 const has_sentinel = slice_ty.sentinel(mod) != null;29653 const has_sentinel = slice_ty.sentinel(mod) != null;
29692 var int_payload: Value.Payload.U64 = .{29654 const slice_len = slice_val.sliceLen(mod);
29693 .base = .{ .tag = .int_u64 },29655 const len_plus_sent = slice_len + @boolToInt(has_sentinel);
29694 .data = slice_val.sliceLen(mod) + @boolToInt(has_sentinel),29656 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);
29695 };29657 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
29696 const slice_len_val = Value.initPayload(&int_payload.base);
29697 if (!(try sema.compareAll(end_val, .lte, slice_len_val, Type.usize))) {
29698 const sentinel_label: []const u8 = if (has_sentinel)29658 const sentinel_label: []const u8 = if (has_sentinel)
29699 " +1 (sentinel)"29659 " +1 (sentinel)"
29700 else29660 else
...@@ -29712,13 +29672,10 @@ fn analyzeSlice(...@@ -29712,13 +29672,10 @@ fn analyzeSlice(
29712 );29672 );
29713 }29673 }
2971429674
29715 // If the slice has a sentinel, we subtract one so that29675 // If the slice has a sentinel, we consider end_is_len
29716 // end_is_len is only true if it equals the length WITHOUT29676 // is only true if it equals the length WITHOUT the
29717 // the sentinel, so we don't add a sentinel type.29677 // sentinel, so we don't add a sentinel type.
29718 if (has_sentinel) {29678 const slice_len_val = try mod.intValue(Type.usize, slice_len);
29719 int_payload.data -= 1;
29720 }
29721
29722 if (end_val.eql(slice_len_val, Type.usize, mod)) {29679 if (end_val.eql(slice_len_val, Type.usize, mod)) {
29723 end_is_len = true;29680 end_is_len = true;
29724 }29681 }
...@@ -30134,7 +30091,7 @@ fn cmpNumeric(...@@ -30134,7 +30091,7 @@ fn cmpNumeric(
30134 }30091 }
30135 }30092 }
3013630093
30137 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128));30094 var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, mod));
30138 defer bigint.deinit();30095 defer bigint.deinit();
30139 if (lhs_val.floatHasFraction()) {30096 if (lhs_val.floatHasFraction()) {
30140 if (lhs_is_signed) {30097 if (lhs_is_signed) {
...@@ -30193,7 +30150,7 @@ fn cmpNumeric(...@@ -30193,7 +30150,7 @@ fn cmpNumeric(
30193 }30150 }
30194 }30151 }
3019530152
30196 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128));30153 var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, mod));
30197 defer bigint.deinit();30154 defer bigint.deinit();
30198 if (rhs_val.floatHasFraction()) {30155 if (rhs_val.floatHasFraction()) {
30199 if (rhs_is_signed) {30156 if (rhs_is_signed) {
...@@ -31835,6 +31792,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {...@@ -31835,6 +31792,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
31835 .zero_u8 => unreachable,31792 .zero_u8 => unreachable,
31836 .one => unreachable,31793 .one => unreachable,
31837 .one_usize => unreachable,31794 .one_usize => unreachable,
31795 .negative_one => unreachable,
31838 .calling_convention_c => unreachable,31796 .calling_convention_c => unreachable,
31839 .calling_convention_inline => unreachable,31797 .calling_convention_inline => unreachable,
31840 .void_value => unreachable,31798 .void_value => unreachable,
...@@ -32462,11 +32420,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32462,11 +32420,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32462 }32420 }
3246332421
32464 if (fields_len > 0) {32422 if (fields_len > 0) {
32465 var field_count_val: Value.Payload.U64 = .{32423 const field_count_val = try mod.intValue(int_tag_ty, fields_len - 1);
32466 .base = .{ .tag = .int_u64 },32424 if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {
32467 .data = fields_len - 1,
32468 };
32469 if (!(try sema.intFitsInType(Value.initPayload(&field_count_val.base), int_tag_ty, null))) {
32470 const msg = msg: {32425 const msg = msg: {
32471 const msg = try sema.errMsg(&block_scope, tag_ty_src, "specified integer tag type cannot represent every field", .{});32426 const msg = try sema.errMsg(&block_scope, tag_ty_src, "specified integer tag type cannot represent every field", .{});
32472 errdefer msg.destroy(sema.gpa);32427 errdefer msg.destroy(sema.gpa);
...@@ -33207,7 +33162,8 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {...@@ -33207,7 +33162,8 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
33207}33162}
3320833163
33209fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref {33164fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref {
33210 return sema.addConstant(ty, try Value.Tag.int_u64.create(sema.arena, int));33165 const mod = sema.mod;
33166 return sema.addConstant(ty, try mod.intValue(ty, int));
33211}33167}
3321233168
33213fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref {33169fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref {
...@@ -33223,7 +33179,11 @@ pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref {...@@ -33223,7 +33179,11 @@ pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref {
33223 .tag = .interned,33179 .tag = .interned,
33224 .data = .{ .interned = val.ip_index },33180 .data = .{ .interned = val.ip_index },
33225 });33181 });
33226 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));33182 const result = Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));
33183 // This assertion can be removed when the `ty` parameter is removed from
33184 // this function thanks to the InternPool transition being complete.
33185 assert(Type.eql(sema.typeOf(result), ty, sema.mod));
33186 return result;
33227 }33187 }
33228 const ty_inst = try sema.addType(ty);33188 const ty_inst = try sema.addType(ty);
33229 try sema.air_values.append(gpa, val);33189 try sema.air_values.append(gpa, val);
...@@ -33833,19 +33793,18 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {...@@ -33833,19 +33793,18 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {
33833 const mod = sema.mod;33793 const mod = sema.mod;
33834 if (ty.zigTypeTag(mod) == .Vector) {33794 if (ty.zigTypeTag(mod) == .Vector) {
33835 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));33795 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
33796 const scalar_ty = ty.scalarType(mod);
33836 for (result_data, 0..) |*scalar, i| {33797 for (result_data, 0..) |*scalar, i| {
33837 var lhs_buf: Value.ElemValueBuffer = undefined;33798 const lhs_elem = try lhs.elemValue(mod, i);
33838 var rhs_buf: Value.ElemValueBuffer = undefined;33799 const rhs_elem = try rhs.elemValue(mod, i);
33839 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);33800 scalar.* = try sema.intAddScalar(lhs_elem, rhs_elem, scalar_ty);
33840 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
33841 scalar.* = try sema.intAddScalar(lhs_elem, rhs_elem);
33842 }33801 }
33843 return Value.Tag.aggregate.create(sema.arena, result_data);33802 return Value.Tag.aggregate.create(sema.arena, result_data);
33844 }33803 }
33845 return sema.intAddScalar(lhs, rhs);33804 return sema.intAddScalar(lhs, rhs, ty);
33846}33805}
3384733806
33848fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {33807fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
33849 const mod = sema.mod;33808 const mod = sema.mod;
33850 // TODO is this a performance issue? maybe we should try the operation without33809 // TODO is this a performance issue? maybe we should try the operation without
33851 // resorting to BigInt first.33810 // resorting to BigInt first.
...@@ -33859,7 +33818,7 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {...@@ -33859,7 +33818,7 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {
33859 );33818 );
33860 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };33819 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
33861 result_bigint.add(lhs_bigint, rhs_bigint);33820 result_bigint.add(lhs_bigint, rhs_bigint);
33862 return Value.fromBigInt(sema.arena, result_bigint.toConst());33821 return mod.intValue_big(scalar_ty, result_bigint.toConst());
33863}33822}
3386433823
33865/// Supports both floats and ints; handles undefined.33824/// Supports both floats and ints; handles undefined.
...@@ -33884,28 +33843,22 @@ fn numberAddWrapScalar(...@@ -33884,28 +33843,22 @@ fn numberAddWrapScalar(
33884 return overflow_result.wrapped_result;33843 return overflow_result.wrapped_result;
33885}33844}
3388633845
33887fn intSub(33846fn intSub(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {
33888 sema: *Sema,
33889 lhs: Value,
33890 rhs: Value,
33891 ty: Type,
33892) !Value {
33893 const mod = sema.mod;33847 const mod = sema.mod;
33894 if (ty.zigTypeTag(mod) == .Vector) {33848 if (ty.zigTypeTag(mod) == .Vector) {
33895 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));33849 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
33850 const scalar_ty = ty.scalarType(mod);
33896 for (result_data, 0..) |*scalar, i| {33851 for (result_data, 0..) |*scalar, i| {
33897 var lhs_buf: Value.ElemValueBuffer = undefined;33852 const lhs_elem = try lhs.elemValue(sema.mod, i);
33898 var rhs_buf: Value.ElemValueBuffer = undefined;33853 const rhs_elem = try rhs.elemValue(sema.mod, i);
33899 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);33854 scalar.* = try sema.intSubScalar(lhs_elem, rhs_elem, scalar_ty);
33900 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
33901 scalar.* = try sema.intSubScalar(lhs_elem, rhs_elem);
33902 }33855 }
33903 return Value.Tag.aggregate.create(sema.arena, result_data);33856 return Value.Tag.aggregate.create(sema.arena, result_data);
33904 }33857 }
33905 return sema.intSubScalar(lhs, rhs);33858 return sema.intSubScalar(lhs, rhs, ty);
33906}33859}
3390733860
33908fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {33861fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
33909 const mod = sema.mod;33862 const mod = sema.mod;
33910 // TODO is this a performance issue? maybe we should try the operation without33863 // TODO is this a performance issue? maybe we should try the operation without
33911 // resorting to BigInt first.33864 // resorting to BigInt first.
...@@ -33919,7 +33872,7 @@ fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {...@@ -33919,7 +33872,7 @@ fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {
33919 );33872 );
33920 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };33873 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
33921 result_bigint.sub(lhs_bigint, rhs_bigint);33874 result_bigint.sub(lhs_bigint, rhs_bigint);
33922 return Value.fromBigInt(sema.arena, result_bigint.toConst());33875 return mod.intValue_big(scalar_ty, result_bigint.toConst());
33923}33876}
3392433877
33925/// Supports both floats and ints; handles undefined.33878/// Supports both floats and ints; handles undefined.
...@@ -33954,10 +33907,8 @@ fn floatAdd(...@@ -33954,10 +33907,8 @@ fn floatAdd(
33954 if (float_type.zigTypeTag(mod) == .Vector) {33907 if (float_type.zigTypeTag(mod) == .Vector) {
33955 const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod));33908 const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod));
33956 for (result_data, 0..) |*scalar, i| {33909 for (result_data, 0..) |*scalar, i| {
33957 var lhs_buf: Value.ElemValueBuffer = undefined;33910 const lhs_elem = try lhs.elemValue(sema.mod, i);
33958 var rhs_buf: Value.ElemValueBuffer = undefined;33911 const rhs_elem = try rhs.elemValue(sema.mod, i);
33959 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
33960 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
33961 scalar.* = try sema.floatAddScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));33912 scalar.* = try sema.floatAddScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));
33962 }33913 }
33963 return Value.Tag.aggregate.create(sema.arena, result_data);33914 return Value.Tag.aggregate.create(sema.arena, result_data);
...@@ -33971,31 +33922,32 @@ fn floatAddScalar(...@@ -33971,31 +33922,32 @@ fn floatAddScalar(
33971 rhs: Value,33922 rhs: Value,
33972 float_type: Type,33923 float_type: Type,
33973) !Value {33924) !Value {
33925 const mod = sema.mod;
33974 const target = sema.mod.getTarget();33926 const target = sema.mod.getTarget();
33975 switch (float_type.floatBits(target)) {33927 switch (float_type.floatBits(target)) {
33976 16 => {33928 16 => {
33977 const lhs_val = lhs.toFloat(f16);33929 const lhs_val = lhs.toFloat(f16, mod);
33978 const rhs_val = rhs.toFloat(f16);33930 const rhs_val = rhs.toFloat(f16, mod);
33979 return Value.Tag.float_16.create(sema.arena, lhs_val + rhs_val);33931 return Value.Tag.float_16.create(sema.arena, lhs_val + rhs_val);
33980 },33932 },
33981 32 => {33933 32 => {
33982 const lhs_val = lhs.toFloat(f32);33934 const lhs_val = lhs.toFloat(f32, mod);
33983 const rhs_val = rhs.toFloat(f32);33935 const rhs_val = rhs.toFloat(f32, mod);
33984 return Value.Tag.float_32.create(sema.arena, lhs_val + rhs_val);33936 return Value.Tag.float_32.create(sema.arena, lhs_val + rhs_val);
33985 },33937 },
33986 64 => {33938 64 => {
33987 const lhs_val = lhs.toFloat(f64);33939 const lhs_val = lhs.toFloat(f64, mod);
33988 const rhs_val = rhs.toFloat(f64);33940 const rhs_val = rhs.toFloat(f64, mod);
33989 return Value.Tag.float_64.create(sema.arena, lhs_val + rhs_val);33941 return Value.Tag.float_64.create(sema.arena, lhs_val + rhs_val);
33990 },33942 },
33991 80 => {33943 80 => {
33992 const lhs_val = lhs.toFloat(f80);33944 const lhs_val = lhs.toFloat(f80, mod);
33993 const rhs_val = rhs.toFloat(f80);33945 const rhs_val = rhs.toFloat(f80, mod);
33994 return Value.Tag.float_80.create(sema.arena, lhs_val + rhs_val);33946 return Value.Tag.float_80.create(sema.arena, lhs_val + rhs_val);
33995 },33947 },
33996 128 => {33948 128 => {
33997 const lhs_val = lhs.toFloat(f128);33949 const lhs_val = lhs.toFloat(f128, mod);
33998 const rhs_val = rhs.toFloat(f128);33950 const rhs_val = rhs.toFloat(f128, mod);
33999 return Value.Tag.float_128.create(sema.arena, lhs_val + rhs_val);33951 return Value.Tag.float_128.create(sema.arena, lhs_val + rhs_val);
34000 },33952 },
34001 else => unreachable,33953 else => unreachable,
...@@ -34012,10 +33964,8 @@ fn floatSub(...@@ -34012,10 +33964,8 @@ fn floatSub(
34012 if (float_type.zigTypeTag(mod) == .Vector) {33964 if (float_type.zigTypeTag(mod) == .Vector) {
34013 const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod));33965 const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod));
34014 for (result_data, 0..) |*scalar, i| {33966 for (result_data, 0..) |*scalar, i| {
34015 var lhs_buf: Value.ElemValueBuffer = undefined;33967 const lhs_elem = try lhs.elemValue(sema.mod, i);
34016 var rhs_buf: Value.ElemValueBuffer = undefined;33968 const rhs_elem = try rhs.elemValue(sema.mod, i);
34017 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34018 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34019 scalar.* = try sema.floatSubScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));33969 scalar.* = try sema.floatSubScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));
34020 }33970 }
34021 return Value.Tag.aggregate.create(sema.arena, result_data);33971 return Value.Tag.aggregate.create(sema.arena, result_data);
...@@ -34029,31 +33979,32 @@ fn floatSubScalar(...@@ -34029,31 +33979,32 @@ fn floatSubScalar(
34029 rhs: Value,33979 rhs: Value,
34030 float_type: Type,33980 float_type: Type,
34031) !Value {33981) !Value {
33982 const mod = sema.mod;
34032 const target = sema.mod.getTarget();33983 const target = sema.mod.getTarget();
34033 switch (float_type.floatBits(target)) {33984 switch (float_type.floatBits(target)) {
34034 16 => {33985 16 => {
34035 const lhs_val = lhs.toFloat(f16);33986 const lhs_val = lhs.toFloat(f16, mod);
34036 const rhs_val = rhs.toFloat(f16);33987 const rhs_val = rhs.toFloat(f16, mod);
34037 return Value.Tag.float_16.create(sema.arena, lhs_val - rhs_val);33988 return Value.Tag.float_16.create(sema.arena, lhs_val - rhs_val);
34038 },33989 },
34039 32 => {33990 32 => {
34040 const lhs_val = lhs.toFloat(f32);33991 const lhs_val = lhs.toFloat(f32, mod);
34041 const rhs_val = rhs.toFloat(f32);33992 const rhs_val = rhs.toFloat(f32, mod);
34042 return Value.Tag.float_32.create(sema.arena, lhs_val - rhs_val);33993 return Value.Tag.float_32.create(sema.arena, lhs_val - rhs_val);
34043 },33994 },
34044 64 => {33995 64 => {
34045 const lhs_val = lhs.toFloat(f64);33996 const lhs_val = lhs.toFloat(f64, mod);
34046 const rhs_val = rhs.toFloat(f64);33997 const rhs_val = rhs.toFloat(f64, mod);
34047 return Value.Tag.float_64.create(sema.arena, lhs_val - rhs_val);33998 return Value.Tag.float_64.create(sema.arena, lhs_val - rhs_val);
34048 },33999 },
34049 80 => {34000 80 => {
34050 const lhs_val = lhs.toFloat(f80);34001 const lhs_val = lhs.toFloat(f80, mod);
34051 const rhs_val = rhs.toFloat(f80);34002 const rhs_val = rhs.toFloat(f80, mod);
34052 return Value.Tag.float_80.create(sema.arena, lhs_val - rhs_val);34003 return Value.Tag.float_80.create(sema.arena, lhs_val - rhs_val);
34053 },34004 },
34054 128 => {34005 128 => {
34055 const lhs_val = lhs.toFloat(f128);34006 const lhs_val = lhs.toFloat(f128, mod);
34056 const rhs_val = rhs.toFloat(f128);34007 const rhs_val = rhs.toFloat(f128, mod);
34057 return Value.Tag.float_128.create(sema.arena, lhs_val - rhs_val);34008 return Value.Tag.float_128.create(sema.arena, lhs_val - rhs_val);
34058 },34009 },
34059 else => unreachable,34010 else => unreachable,
...@@ -34071,10 +34022,8 @@ fn intSubWithOverflow(...@@ -34071,10 +34022,8 @@ fn intSubWithOverflow(
34071 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen(mod));34022 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
34072 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));34023 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
34073 for (result_data, 0..) |*scalar, i| {34024 for (result_data, 0..) |*scalar, i| {
34074 var lhs_buf: Value.ElemValueBuffer = undefined;34025 const lhs_elem = try lhs.elemValue(sema.mod, i);
34075 var rhs_buf: Value.ElemValueBuffer = undefined;34026 const rhs_elem = try rhs.elemValue(sema.mod, i);
34076 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34077 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34078 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod));34027 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod));
34079 overflowed_data[i] = of_math_result.overflow_bit;34028 overflowed_data[i] = of_math_result.overflow_bit;
34080 scalar.* = of_math_result.wrapped_result;34029 scalar.* = of_math_result.wrapped_result;
...@@ -34106,7 +34055,7 @@ fn intSubWithOverflowScalar(...@@ -34106,7 +34055,7 @@ fn intSubWithOverflowScalar(
34106 );34055 );
34107 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };34056 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
34108 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);34057 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
34109 const wrapped_result = try Value.fromBigInt(sema.arena, result_bigint.toConst());34058 const wrapped_result = try mod.intValue_big(ty, result_bigint.toConst());
34110 return Value.OverflowArithmeticResult{34059 return Value.OverflowArithmeticResult{
34111 .overflow_bit = Value.boolToInt(overflowed),34060 .overflow_bit = Value.boolToInt(overflowed),
34112 .wrapped_result = wrapped_result,34061 .wrapped_result = wrapped_result,
...@@ -34126,8 +34075,7 @@ fn floatToInt(...@@ -34126,8 +34075,7 @@ fn floatToInt(
34126 const elem_ty = float_ty.childType(mod);34075 const elem_ty = float_ty.childType(mod);
34127 const result_data = try sema.arena.alloc(Value, float_ty.vectorLen(mod));34076 const result_data = try sema.arena.alloc(Value, float_ty.vectorLen(mod));
34128 for (result_data, 0..) |*scalar, i| {34077 for (result_data, 0..) |*scalar, i| {
34129 var buf: Value.ElemValueBuffer = undefined;34078 const elem_val = try val.elemValue(sema.mod, i);
34130 const elem_val = val.elemValueBuffer(sema.mod, i, &buf);
34131 scalar.* = try sema.floatToIntScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod));34079 scalar.* = try sema.floatToIntScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod));
34132 }34080 }
34133 return Value.Tag.aggregate.create(sema.arena, result_data);34081 return Value.Tag.aggregate.create(sema.arena, result_data);
...@@ -34168,9 +34116,9 @@ fn floatToIntScalar(...@@ -34168,9 +34116,9 @@ fn floatToIntScalar(
34168 float_ty: Type,34116 float_ty: Type,
34169 int_ty: Type,34117 int_ty: Type,
34170) CompileError!Value {34118) CompileError!Value {
34171 const Limb = std.math.big.Limb;34119 const mod = sema.mod;
3417234120
34173 const float = val.toFloat(f128);34121 const float = val.toFloat(f128, mod);
34174 if (std.math.isNan(float)) {34122 if (std.math.isNan(float)) {
34175 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{34123 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{
34176 int_ty.fmt(sema.mod),34124 int_ty.fmt(sema.mod),
...@@ -34185,11 +34133,7 @@ fn floatToIntScalar(...@@ -34185,11 +34133,7 @@ fn floatToIntScalar(
34185 var big_int = try float128IntPartToBigInt(sema.arena, float);34133 var big_int = try float128IntPartToBigInt(sema.arena, float);
34186 defer big_int.deinit();34134 defer big_int.deinit();
3418734135
34188 const result_limbs = try sema.arena.dupe(Limb, big_int.toConst().limbs);34136 const result = try mod.intValue_big(int_ty, big_int.toConst());
34189 const result = if (!big_int.isPositive())
34190 try Value.Tag.int_big_negative.create(sema.arena, result_limbs)
34191 else
34192 try Value.Tag.int_big_positive.create(sema.arena, result_limbs);
3419334137
34194 if (!(try sema.intFitsInType(result, int_ty, null))) {34138 if (!(try sema.intFitsInType(result, int_ty, null))) {
34195 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{34139 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
...@@ -34209,8 +34153,8 @@ fn intFitsInType(...@@ -34209,8 +34153,8 @@ fn intFitsInType(
34209 ty: Type,34153 ty: Type,
34210 vector_index: ?*usize,34154 vector_index: ?*usize,
34211) CompileError!bool {34155) CompileError!bool {
34156 if (ty.ip_index == .comptime_int_type) return true;
34212 const mod = sema.mod;34157 const mod = sema.mod;
34213 const target = mod.getTarget();
34214 switch (val.ip_index) {34158 switch (val.ip_index) {
34215 .undef,34159 .undef,
34216 .zero,34160 .zero,
...@@ -34218,103 +34162,26 @@ fn intFitsInType(...@@ -34218,103 +34162,26 @@ fn intFitsInType(
34218 .zero_u8,34162 .zero_u8,
34219 => return true,34163 => return true,
3422034164
34221 .one,
34222 .one_usize,
34223 => switch (ty.zigTypeTag(mod)) {
34224 .Int => {
34225 const info = ty.intInfo(mod);
34226 return switch (info.signedness) {
34227 .signed => info.bits >= 2,
34228 .unsigned => info.bits >= 1,
34229 };
34230 },
34231 .ComptimeInt => return true,
34232 else => unreachable,
34233 },
34234
34235 .none => switch (val.tag()) {34165 .none => switch (val.tag()) {
34236 .zero => return true,34166 .lazy_align => {
3423734167 const info = ty.intInfo(mod);
34238 .one => switch (ty.zigTypeTag(mod)) {34168 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
34239 .Int => {34169 // If it is u16 or bigger we know the alignment fits without resolving it.
34240 const info = ty.intInfo(mod);34170 if (info.bits >= max_needed_bits) return true;
34241 return switch (info.signedness) {34171 const x = try sema.typeAbiAlignment(val.castTag(.lazy_align).?.data);
34242 .signed => info.bits >= 2,34172 if (x == 0) return true;
34243 .unsigned => info.bits >= 1,34173 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
34244 };34174 return info.bits >= actual_needed_bits;
34245 },
34246 .ComptimeInt => return true,
34247 else => unreachable,
34248 },
34249
34250 .lazy_align => switch (ty.zigTypeTag(mod)) {
34251 .Int => {
34252 const info = ty.intInfo(mod);
34253 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
34254 // If it is u16 or bigger we know the alignment fits without resolving it.
34255 if (info.bits >= max_needed_bits) return true;
34256 const x = try sema.typeAbiAlignment(val.castTag(.lazy_align).?.data);
34257 if (x == 0) return true;
34258 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
34259 return info.bits >= actual_needed_bits;
34260 },
34261 .ComptimeInt => return true,
34262 else => unreachable,
34263 },
34264 .lazy_size => switch (ty.zigTypeTag(mod)) {
34265 .Int => {
34266 const info = ty.intInfo(mod);
34267 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
34268 // If it is u64 or bigger we know the size fits without resolving it.
34269 if (info.bits >= max_needed_bits) return true;
34270 const x = try sema.typeAbiSize(val.castTag(.lazy_size).?.data);
34271 if (x == 0) return true;
34272 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
34273 return info.bits >= actual_needed_bits;
34274 },
34275 .ComptimeInt => return true,
34276 else => unreachable,
34277 },
34278
34279 .int_u64 => switch (ty.zigTypeTag(mod)) {
34280 .Int => {
34281 const x = val.castTag(.int_u64).?.data;
34282 if (x == 0) return true;
34283 const info = ty.intInfo(mod);
34284 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
34285 return info.bits >= needed_bits;
34286 },
34287 .ComptimeInt => return true,
34288 else => unreachable,
34289 },
34290 .int_i64 => switch (ty.zigTypeTag(mod)) {
34291 .Int => {
34292 const x = val.castTag(.int_i64).?.data;
34293 if (x == 0) return true;
34294 const info = ty.intInfo(mod);
34295 if (info.signedness == .unsigned and x < 0)
34296 return false;
34297 var buffer: Value.BigIntSpace = undefined;
34298 return (try val.toBigIntAdvanced(&buffer, mod, sema)).fitsInTwosComp(info.signedness, info.bits);
34299 },
34300 .ComptimeInt => return true,
34301 else => unreachable,
34302 },
34303 .int_big_positive => switch (ty.zigTypeTag(mod)) {
34304 .Int => {
34305 const info = ty.intInfo(mod);
34306 return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
34307 },
34308 .ComptimeInt => return true,
34309 else => unreachable,
34310 },34175 },
34311 .int_big_negative => switch (ty.zigTypeTag(mod)) {34176 .lazy_size => {
34312 .Int => {34177 const info = ty.intInfo(mod);
34313 const info = ty.intInfo(mod);34178 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
34314 return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);34179 // If it is u64 or bigger we know the size fits without resolving it.
34315 },34180 if (info.bits >= max_needed_bits) return true;
34316 .ComptimeInt => return true,34181 const x = try sema.typeAbiSize(val.castTag(.lazy_size).?.data);
34317 else => unreachable,34182 if (x == 0) return true;
34183 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
34184 return info.bits >= actual_needed_bits;
34318 },34185 },
3431934186
34320 .the_only_possible_value => {34187 .the_only_possible_value => {
...@@ -34327,17 +34194,14 @@ fn intFitsInType(...@@ -34327,17 +34194,14 @@ fn intFitsInType(
34327 .decl_ref,34194 .decl_ref,
34328 .function,34195 .function,
34329 .variable,34196 .variable,
34330 => switch (ty.zigTypeTag(mod)) {34197 => {
34331 .Int => {34198 const info = ty.intInfo(mod);
34332 const info = ty.intInfo(mod);34199 const target = mod.getTarget();
34333 const ptr_bits = target.ptrBitWidth();34200 const ptr_bits = target.ptrBitWidth();
34334 return switch (info.signedness) {34201 return switch (info.signedness) {
34335 .signed => info.bits > ptr_bits,34202 .signed => info.bits > ptr_bits,
34336 .unsigned => info.bits >= ptr_bits,34203 .unsigned => info.bits >= ptr_bits,
34337 };34204 };
34338 },
34339 .ComptimeInt => return true,
34340 else => unreachable,
34341 },34205 },
3434234206
34343 .aggregate => {34207 .aggregate => {
...@@ -34354,22 +34218,22 @@ fn intFitsInType(...@@ -34354,22 +34218,22 @@ fn intFitsInType(
34354 else => unreachable,34218 else => unreachable,
34355 },34219 },
3435634220
34357 else => @panic("TODO"),34221 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
34222 .int => |int| {
34223 const info = ty.intInfo(mod);
34224 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
34225 const big_int = int.storage.toBigInt(&buffer);
34226 return big_int.fitsInTwosComp(info.signedness, info.bits);
34227 },
34228 else => unreachable,
34229 },
34358 }34230 }
34359}34231}
3436034232
34361fn intInRange(34233fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
34362 sema: *Sema,34234 const mod = sema.mod;
34363 tag_ty: Type,
34364 int_val: Value,
34365 end: usize,
34366) !bool {
34367 if (!(try int_val.compareAllWithZeroAdvanced(.gte, sema))) return false;34235 if (!(try int_val.compareAllWithZeroAdvanced(.gte, sema))) return false;
34368 var end_payload: Value.Payload.U64 = .{34236 const end_val = try mod.intValue(tag_ty, end);
34369 .base = .{ .tag = .int_u64 },
34370 .data = end,
34371 };
34372 const end_val = Value.initPayload(&end_payload.base);
34373 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;34237 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
34374 return true;34238 return true;
34375}34239}
...@@ -34426,10 +34290,8 @@ fn intAddWithOverflow(...@@ -34426,10 +34290,8 @@ fn intAddWithOverflow(
34426 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen(mod));34290 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
34427 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));34291 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
34428 for (result_data, 0..) |*scalar, i| {34292 for (result_data, 0..) |*scalar, i| {
34429 var lhs_buf: Value.ElemValueBuffer = undefined;34293 const lhs_elem = try lhs.elemValue(sema.mod, i);
34430 var rhs_buf: Value.ElemValueBuffer = undefined;34294 const rhs_elem = try rhs.elemValue(sema.mod, i);
34431 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34432 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34433 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod));34295 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod));
34434 overflowed_data[i] = of_math_result.overflow_bit;34296 overflowed_data[i] = of_math_result.overflow_bit;
34435 scalar.* = of_math_result.wrapped_result;34297 scalar.* = of_math_result.wrapped_result;
...@@ -34461,7 +34323,7 @@ fn intAddWithOverflowScalar(...@@ -34461,7 +34323,7 @@ fn intAddWithOverflowScalar(
34461 );34323 );
34462 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };34324 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
34463 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);34325 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
34464 const result = try Value.fromBigInt(sema.arena, result_bigint.toConst());34326 const result = try mod.intValue_big(ty, result_bigint.toConst());
34465 return Value.OverflowArithmeticResult{34327 return Value.OverflowArithmeticResult{
34466 .overflow_bit = Value.boolToInt(overflowed),34328 .overflow_bit = Value.boolToInt(overflowed),
34467 .wrapped_result = result,34329 .wrapped_result = result,
...@@ -34483,10 +34345,8 @@ fn compareAll(...@@ -34483,10 +34345,8 @@ fn compareAll(
34483 if (ty.zigTypeTag(mod) == .Vector) {34345 if (ty.zigTypeTag(mod) == .Vector) {
34484 var i: usize = 0;34346 var i: usize = 0;
34485 while (i < ty.vectorLen(mod)) : (i += 1) {34347 while (i < ty.vectorLen(mod)) : (i += 1) {
34486 var lhs_buf: Value.ElemValueBuffer = undefined;34348 const lhs_elem = try lhs.elemValue(sema.mod, i);
34487 var rhs_buf: Value.ElemValueBuffer = undefined;34349 const rhs_elem = try rhs.elemValue(sema.mod, i);
34488 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34489 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34490 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {34350 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {
34491 return false;34351 return false;
34492 }34352 }
...@@ -34532,10 +34392,8 @@ fn compareVector(...@@ -34532,10 +34392,8 @@ fn compareVector(
34532 assert(ty.zigTypeTag(mod) == .Vector);34392 assert(ty.zigTypeTag(mod) == .Vector);
34533 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));34393 const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod));
34534 for (result_data, 0..) |*scalar, i| {34394 for (result_data, 0..) |*scalar, i| {
34535 var lhs_buf: Value.ElemValueBuffer = undefined;34395 const lhs_elem = try lhs.elemValue(sema.mod, i);
34536 var rhs_buf: Value.ElemValueBuffer = undefined;34396 const rhs_elem = try rhs.elemValue(sema.mod, i);
34537 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
34538 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34539 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));34397 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));
34540 scalar.* = Value.makeBool(res_bool);34398 scalar.* = Value.makeBool(res_bool);
34541 }34399 }
src/TypedValue.zig+9-12
...@@ -41,8 +41,8 @@ pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, mod: *Module) void {...@@ -41,8 +41,8 @@ pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, mod: *Module) void {
41 return tv.val.hash(tv.ty, hasher, mod);41 return tv.val.hash(tv.ty, hasher, mod);
42}42}
4343
44pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {44pub fn enumToInt(tv: TypedValue, mod: *Module) Allocator.Error!Value {
45 return tv.val.enumToInt(tv.ty, buffer);45 return tv.val.enumToInt(tv.ty, mod);
46}46}
4747
48const max_aggregate_items = 100;48const max_aggregate_items = 100;
...@@ -157,14 +157,8 @@ pub fn print(...@@ -157,14 +157,8 @@ pub fn print(
157157
158 return writer.writeAll(" }");158 return writer.writeAll(" }");
159 },159 },
160 .zero => return writer.writeAll("0"),
161 .one => return writer.writeAll("1"),
162 .the_only_possible_value => return writer.writeAll("0"),160 .the_only_possible_value => return writer.writeAll("0"),
163 .ty => return val.castTag(.ty).?.data.print(writer, mod),161 .ty => return val.castTag(.ty).?.data.print(writer, mod),
164 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
165 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
166 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
167 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
168 .lazy_align => {162 .lazy_align => {
169 const sub_ty = val.castTag(.lazy_align).?.data;163 const sub_ty = val.castTag(.lazy_align).?.data;
170 const x = sub_ty.abiAlignment(mod);164 const x = sub_ty.abiAlignment(mod);
...@@ -313,8 +307,9 @@ pub fn print(...@@ -313,8 +307,9 @@ pub fn print(
313307
314 var i: u32 = 0;308 var i: u32 = 0;
315 while (i < max_len) : (i += 1) {309 while (i < max_len) : (i += 1) {
316 var elem_buf: Value.ElemValueBuffer = undefined;310 const elem_val = payload.ptr.elemValue(mod, i) catch |err| switch (err) {
317 const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);311 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
312 };
318 if (elem_val.isUndef()) break :str;313 if (elem_val.isUndef()) break :str;
319 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;314 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;
320 }315 }
...@@ -330,10 +325,12 @@ pub fn print(...@@ -330,10 +325,12 @@ pub fn print(
330 var i: u32 = 0;325 var i: u32 = 0;
331 while (i < max_len) : (i += 1) {326 while (i < max_len) : (i += 1) {
332 if (i != 0) try writer.writeAll(", ");327 if (i != 0) try writer.writeAll(", ");
333 var buf: Value.ElemValueBuffer = undefined;328 const elem_val = payload.ptr.elemValue(mod, i) catch |err| switch (err) {
329 error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic
330 };
334 try print(.{331 try print(.{
335 .ty = elem_ty,332 .ty = elem_ty,
336 .val = payload.ptr.elemValueBuffer(mod, i, &buf),333 .val = elem_val,
337 }, writer, level - 1, mod);334 }, writer, level - 1, mod);
338 }335 }
339 if (len > max_aggregate_items) {336 if (len > max_aggregate_items) {
src/Zir.zig+1
...@@ -2120,6 +2120,7 @@ pub const Inst = struct {...@@ -2120,6 +2120,7 @@ pub const Inst = struct {
2120 zero_u8 = @enumToInt(InternPool.Index.zero_u8),2120 zero_u8 = @enumToInt(InternPool.Index.zero_u8),
2121 one = @enumToInt(InternPool.Index.one),2121 one = @enumToInt(InternPool.Index.one),
2122 one_usize = @enumToInt(InternPool.Index.one_usize),2122 one_usize = @enumToInt(InternPool.Index.one_usize),
2123 negative_one = @enumToInt(InternPool.Index.negative_one),
2123 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),2124 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
2124 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),2125 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
2125 void_value = @enumToInt(InternPool.Index.void_value),2126 void_value = @enumToInt(InternPool.Index.void_value),
src/arch/wasm/CodeGen.zig+17-19
...@@ -3083,20 +3083,21 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3083,20 +3083,21 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3083 },3083 },
3084 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },3084 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
3085 .Float => switch (ty.floatBits(func.target)) {3085 .Float => switch (ty.floatBits(func.target)) {
3086 16 => return WValue{ .imm32 = @bitCast(u16, val.toFloat(f16)) },3086 16 => return WValue{ .imm32 = @bitCast(u16, val.toFloat(f16, mod)) },
3087 32 => return WValue{ .float32 = val.toFloat(f32) },3087 32 => return WValue{ .float32 = val.toFloat(f32, mod) },
3088 64 => return WValue{ .float64 = val.toFloat(f64) },3088 64 => return WValue{ .float64 = val.toFloat(f64, mod) },
3089 else => unreachable,3089 else => unreachable,
3090 },3090 },
3091 .Pointer => switch (val.ip_index) {3091 .Pointer => return switch (val.ip_index) {
3092 .null_value => return WValue{ .imm32 = 0 },3092 .null_value => WValue{ .imm32 = 0 },
3093 .none => switch (val.tag()) {3093 .none => switch (val.tag()) {
3094 .field_ptr, .elem_ptr, .opt_payload_ptr => return func.lowerParentPtr(val, 0),3094 .field_ptr, .elem_ptr, .opt_payload_ptr => func.lowerParentPtr(val, 0),
3095 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
3096 .zero => return WValue{ .imm32 = 0 },
3097 else => return func.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}),3095 else => return func.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}),
3098 },3096 },
3099 else => unreachable,3097 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
3098 .int => |int| WValue{ .imm32 = @intCast(u32, int.storage.u64) },
3099 else => unreachable,
3100 },
3100 },3101 },
3101 .Enum => {3102 .Enum => {
3102 if (val.castTag(.enum_field_index)) |field_index| {3103 if (val.castTag(.enum_field_index)) |field_index| {
...@@ -3137,7 +3138,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3137,7 +3138,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3137 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3138 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3138 // We use the error type directly as the type.3139 // We use the error type directly as the type.
3139 const is_pl = val.errorUnionIsPayload();3140 const is_pl = val.errorUnionIsPayload();
3140 const err_val = if (!is_pl) val else Value.initTag(.zero);3141 const err_val = if (!is_pl) val else Value.zero;
3141 return func.lowerConstant(err_val, error_type);3142 return func.lowerConstant(err_val, error_type);
3142 }3143 }
3143 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});3144 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
...@@ -3160,11 +3161,10 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3160,11 +3161,10 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3160 assert(struct_obj.layout == .Packed);3161 assert(struct_obj.layout == .Packed);
3161 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer3162 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3162 val.writeToPackedMemory(ty, func.bin_file.base.options.module.?, &buf, 0) catch unreachable;3163 val.writeToPackedMemory(ty, func.bin_file.base.options.module.?, &buf, 0) catch unreachable;
3163 var payload: Value.Payload.U64 = .{3164 const int_val = try mod.intValue(
3164 .base = .{ .tag = .int_u64 },3165 struct_obj.backing_int_ty,
3165 .data = std.mem.readIntLittle(u64, &buf),3166 std.mem.readIntLittle(u64, &buf),
3166 };3167 );
3167 const int_val = Value.initPayload(&payload.base);
3168 return func.lowerConstant(int_val, struct_obj.backing_int_ty);3168 return func.lowerConstant(int_val, struct_obj.backing_int_ty);
3169 },3169 },
3170 .Vector => {3170 .Vector => {
...@@ -4899,8 +4899,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4899,8 +4899,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4899 const result = try func.allocStack(inst_ty);4899 const result = try func.allocStack(inst_ty);
49004900
4901 for (0..mask_len) |index| {4901 for (0..mask_len) |index| {
4902 var buf: Value.ElemValueBuffer = undefined;4902 const value = (try mask.elemValue(mod, index)).toSignedInt(mod);
4903 const value = mask.elemValueBuffer(mod, index, &buf).toSignedInt(mod);
49044903
4905 try func.emitWValue(result);4904 try func.emitWValue(result);
49064905
...@@ -4920,8 +4919,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4920,8 +4919,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49204919
4921 var lanes = std.mem.asBytes(operands[1..]);4920 var lanes = std.mem.asBytes(operands[1..]);
4922 for (0..@intCast(usize, mask_len)) |index| {4921 for (0..@intCast(usize, mask_len)) |index| {
4923 var buf: Value.ElemValueBuffer = undefined;4922 const mask_elem = (try mask.elemValue(mod, index)).toSignedInt(mod);
4924 const mask_elem = mask.elemValueBuffer(mod, index, &buf).toSignedInt(mod);
4925 const base_index = if (mask_elem >= 0)4923 const base_index = if (mask_elem >= 0)
4926 @intCast(u8, @intCast(i64, elem_size) * mask_elem)4924 @intCast(u8, @intCast(i64, elem_size) * mask_elem)
4927 else4925 else
src/arch/x86_64/CodeGen.zig+3-19
...@@ -2757,11 +2757,8 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2757,11 +2757,8 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2757 dst_ty.fmt(self.bin_file.options.module.?),2757 dst_ty.fmt(self.bin_file.options.module.?),
2758 });2758 });
27592759
2760 var mask_pl = Value.Payload.U64{2760 const elem_ty = src_ty.childType(mod);
2761 .base = .{ .tag = .int_u64 },2761 const mask_val = try mod.intValue(elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - dst_info.bits));
2762 .data = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - dst_info.bits),
2763 };
2764 const mask_val = Value.initPayload(&mask_pl.base);
27652762
2766 var splat_pl = Value.Payload.SubValue{2763 var splat_pl = Value.Payload.SubValue{
2767 .base = .{ .tag = .repeated },2764 .base = .{ .tag = .repeated },
...@@ -4906,18 +4903,6 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -4906,18 +4903,6 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4906 defer arena.deinit();4903 defer arena.deinit();
49074904
4908 const ExpectedContents = struct {4905 const ExpectedContents = struct {
4909 scalar: union {
4910 i64: Value.Payload.I64,
4911 big: struct {
4912 limbs: [
4913 @max(
4914 std.math.big.int.Managed.default_capacity,
4915 std.math.big.int.calcTwosCompLimbCount(128),
4916 )
4917 ]std.math.big.Limb,
4918 pl: Value.Payload.BigInt,
4919 },
4920 },
4921 repeated: Value.Payload.SubValue,4906 repeated: Value.Payload.SubValue,
4922 };4907 };
4923 var stack align(@alignOf(ExpectedContents)) =4908 var stack align(@alignOf(ExpectedContents)) =
...@@ -11429,8 +11414,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11429,8 +11414,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11429 const field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?);11414 const field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?);
11430 var tag_pl = Value.Payload.U32{ .base = .{ .tag = .enum_field_index }, .data = field_index };11415 var tag_pl = Value.Payload.U32{ .base = .{ .tag = .enum_field_index }, .data = field_index };
11431 const tag_val = Value.initPayload(&tag_pl.base);11416 const tag_val = Value.initPayload(&tag_pl.base);
11432 var tag_int_pl: Value.Payload.U64 = undefined;11417 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);
11433 const tag_int_val = tag_val.enumToInt(tag_ty, &tag_int_pl);
11434 const tag_int = tag_int_val.toUnsignedInt(mod);11418 const tag_int = tag_int_val.toUnsignedInt(mod);
11435 const tag_off = if (layout.tag_align < layout.payload_align)11419 const tag_off = if (layout.tag_align < layout.payload_align)
11436 @intCast(i32, layout.payload_size)11420 @intCast(i32, layout.payload_size)
src/codegen.zig+31-34
...@@ -214,15 +214,15 @@ pub fn generateSymbol(...@@ -214,15 +214,15 @@ pub fn generateSymbol(
214 },214 },
215 .Float => {215 .Float => {
216 switch (typed_value.ty.floatBits(target)) {216 switch (typed_value.ty.floatBits(target)) {
217 16 => writeFloat(f16, typed_value.val.toFloat(f16), target, endian, try code.addManyAsArray(2)),217 16 => writeFloat(f16, typed_value.val.toFloat(f16, mod), target, endian, try code.addManyAsArray(2)),
218 32 => writeFloat(f32, typed_value.val.toFloat(f32), target, endian, try code.addManyAsArray(4)),218 32 => writeFloat(f32, typed_value.val.toFloat(f32, mod), target, endian, try code.addManyAsArray(4)),
219 64 => writeFloat(f64, typed_value.val.toFloat(f64), target, endian, try code.addManyAsArray(8)),219 64 => writeFloat(f64, typed_value.val.toFloat(f64, mod), target, endian, try code.addManyAsArray(8)),
220 80 => {220 80 => {
221 writeFloat(f80, typed_value.val.toFloat(f80), target, endian, try code.addManyAsArray(10));221 writeFloat(f80, typed_value.val.toFloat(f80, mod), target, endian, try code.addManyAsArray(10));
222 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;222 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
223 try code.appendNTimes(0, abi_size - 10);223 try code.appendNTimes(0, abi_size - 10);
224 },224 },
225 128 => writeFloat(f128, typed_value.val.toFloat(f128), target, endian, try code.addManyAsArray(16)),225 128 => writeFloat(f128, typed_value.val.toFloat(f128, mod), target, endian, try code.addManyAsArray(16)),
226 else => unreachable,226 else => unreachable,
227 }227 }
228 return Result.ok;228 return Result.ok;
...@@ -328,20 +328,6 @@ pub fn generateSymbol(...@@ -328,20 +328,6 @@ pub fn generateSymbol(
328 return Result.ok;328 return Result.ok;
329 },329 },
330 .none => switch (typed_value.val.tag()) {330 .none => switch (typed_value.val.tag()) {
331 .zero, .one, .int_u64, .int_big_positive => {
332 switch (target.ptrBitWidth()) {
333 32 => {
334 const x = typed_value.val.toUnsignedInt(mod);
335 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
336 },
337 64 => {
338 const x = typed_value.val.toUnsignedInt(mod);
339 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
340 },
341 else => unreachable,
342 }
343 return Result.ok;
344 },
345 .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(331 .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(
346 bin_file,332 bin_file,
347 src_loc,333 src_loc,
...@@ -399,7 +385,23 @@ pub fn generateSymbol(...@@ -399,7 +385,23 @@ pub fn generateSymbol(
399 ),385 ),
400 },386 },
401 },387 },
402 else => unreachable,388 else => switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
389 .int => {
390 switch (target.ptrBitWidth()) {
391 32 => {
392 const x = typed_value.val.toUnsignedInt(mod);
393 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
394 },
395 64 => {
396 const x = typed_value.val.toUnsignedInt(mod);
397 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
398 },
399 else => unreachable,
400 }
401 return Result.ok;
402 },
403 else => unreachable,
404 },
403 },405 },
404 .Int => {406 .Int => {
405 const info = typed_value.ty.intInfo(mod);407 const info = typed_value.ty.intInfo(mod);
...@@ -449,8 +451,7 @@ pub fn generateSymbol(...@@ -449,8 +451,7 @@ pub fn generateSymbol(
449 return Result.ok;451 return Result.ok;
450 },452 },
451 .Enum => {453 .Enum => {
452 var int_buffer: Value.Payload.U64 = undefined;454 const int_val = try typed_value.enumToInt(mod);
453 const int_val = typed_value.enumToInt(&int_buffer);
454455
455 const info = typed_value.ty.intInfo(mod);456 const info = typed_value.ty.intInfo(mod);
456 if (info.bits <= 8) {457 if (info.bits <= 8) {
...@@ -674,7 +675,7 @@ pub fn generateSymbol(...@@ -674,7 +675,7 @@ pub fn generateSymbol(
674 const is_payload = typed_value.val.errorUnionIsPayload();675 const is_payload = typed_value.val.errorUnionIsPayload();
675676
676 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
677 const err_val = if (is_payload) Value.initTag(.zero) else typed_value.val;678 const err_val = if (is_payload) Value.zero else typed_value.val;
678 return generateSymbol(bin_file, src_loc, .{679 return generateSymbol(bin_file, src_loc, .{
679 .ty = error_ty,680 .ty = error_ty,
680 .val = err_val,681 .val = err_val,
...@@ -689,7 +690,7 @@ pub fn generateSymbol(...@@ -689,7 +690,7 @@ pub fn generateSymbol(
689 if (error_align > payload_align) {690 if (error_align > payload_align) {
690 switch (try generateSymbol(bin_file, src_loc, .{691 switch (try generateSymbol(bin_file, src_loc, .{
691 .ty = error_ty,692 .ty = error_ty,
692 .val = if (is_payload) Value.initTag(.zero) else typed_value.val,693 .val = if (is_payload) Value.zero else typed_value.val,
693 }, code, debug_output, reloc_info)) {694 }, code, debug_output, reloc_info)) {
694 .ok => {},695 .ok => {},
695 .fail => |em| return Result{ .fail = em },696 .fail => |em| return Result{ .fail = em },
...@@ -721,7 +722,7 @@ pub fn generateSymbol(...@@ -721,7 +722,7 @@ pub fn generateSymbol(
721 const begin = code.items.len;722 const begin = code.items.len;
722 switch (try generateSymbol(bin_file, src_loc, .{723 switch (try generateSymbol(bin_file, src_loc, .{
723 .ty = error_ty,724 .ty = error_ty,
724 .val = if (is_payload) Value.initTag(.zero) else typed_value.val,725 .val = if (is_payload) Value.zero else typed_value.val,
725 }, code, debug_output, reloc_info)) {726 }, code, debug_output, reloc_info)) {
726 .ok => {},727 .ok => {},
727 .fail => |em| return Result{ .fail = em },728 .fail => |em| return Result{ .fail = em },
...@@ -961,13 +962,9 @@ fn lowerDeclRef(...@@ -961,13 +962,9 @@ fn lowerDeclRef(
961 }962 }
962963
963 // generate length964 // generate length
964 var slice_len: Value.Payload.U64 = .{
965 .base = .{ .tag = .int_u64 },
966 .data = typed_value.val.sliceLen(mod),
967 };
968 switch (try generateSymbol(bin_file, src_loc, .{965 switch (try generateSymbol(bin_file, src_loc, .{
969 .ty = Type.usize,966 .ty = Type.usize,
970 .val = Value.initPayload(&slice_len.base),967 .val = try mod.intValue(Type.usize, typed_value.val.sliceLen(mod)),
971 }, code, debug_output, reloc_info)) {968 }, code, debug_output, reloc_info)) {
972 .ok => {},969 .ok => {},
973 .fail => |em| return Result{ .fail = em },970 .fail => |em| return Result{ .fail = em },
...@@ -1196,13 +1193,13 @@ pub fn genTypedValue(...@@ -1196,13 +1193,13 @@ pub fn genTypedValue(
1196 .null_value => {1193 .null_value => {
1197 return GenResult.mcv(.{ .immediate = 0 });1194 return GenResult.mcv(.{ .immediate = 0 });
1198 },1195 },
1199 .none => switch (typed_value.val.tag()) {1196 .none => {},
1200 .int_u64 => {1197 else => switch (mod.intern_pool.indexToKey(typed_value.val.ip_index)) {
1198 .int => {
1201 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) });1199 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) });
1202 },1200 },
1203 else => {},1201 else => {},
1204 },1202 },
1205 else => {},
1206 },1203 },
1207 },1204 },
1208 .Int => {1205 .Int => {
...@@ -1283,7 +1280,7 @@ pub fn genTypedValue(...@@ -1283,7 +1280,7 @@ pub fn genTypedValue(
12831280
1284 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {1281 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
1285 // We use the error type directly as the type.1282 // We use the error type directly as the type.
1286 const err_val = if (!is_pl) typed_value.val else Value.initTag(.zero);1283 const err_val = if (!is_pl) typed_value.val else Value.zero;
1287 return genTypedValue(bin_file, src_loc, .{1284 return genTypedValue(bin_file, src_loc, .{
1288 .ty = error_type,1285 .ty = error_type,
1289 .val = err_val,1286 .val = err_val,
src/codegen/c.zig+85-155
...@@ -568,11 +568,7 @@ pub const DeclGen = struct {...@@ -568,11 +568,7 @@ pub const DeclGen = struct {
568 var buf: Type.SlicePtrFieldTypeBuffer = undefined;568 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
569 try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer);569 try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer);
570570
571 var len_pl: Value.Payload.U64 = .{571 const len_val = try mod.intValue(Type.usize, val.sliceLen(mod));
572 .base = .{ .tag = .int_u64 },
573 .data = val.sliceLen(mod),
574 };
575 const len_val = Value.initPayload(&len_pl.base);
576572
577 if (location == .StaticInitializer) {573 if (location == .StaticInitializer) {
578 return writer.print(", {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val, .Other)});574 return writer.print(", {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val, .Other)});
...@@ -596,11 +592,17 @@ pub const DeclGen = struct {...@@ -596,11 +592,17 @@ pub const DeclGen = struct {
596 if (need_typecast) try writer.writeByte(')');592 if (need_typecast) try writer.writeByte(')');
597 }593 }
598594
599 // Renders a "parent" pointer by recursing to the root decl/variable595 /// Renders a "parent" pointer by recursing to the root decl/variable
600 // that its contents are defined with respect to.596 /// that its contents are defined with respect to.
601 //597 ///
602 // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr598 /// Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr
603 fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void {599 fn renderParentPtr(
600 dg: *DeclGen,
601 writer: anytype,
602 ptr_val: Value,
603 ptr_ty: Type,
604 location: ValueRenderLocation,
605 ) error{ OutOfMemory, AnalysisFail }!void {
604 const mod = dg.module;606 const mod = dg.module;
605607
606 if (!ptr_ty.isSlice(mod)) {608 if (!ptr_ty.isSlice(mod)) {
...@@ -608,8 +610,11 @@ pub const DeclGen = struct {...@@ -608,8 +610,11 @@ pub const DeclGen = struct {
608 try dg.renderType(writer, ptr_ty);610 try dg.renderType(writer, ptr_ty);
609 try writer.writeByte(')');611 try writer.writeByte(')');
610 }612 }
613 if (ptr_val.ip_index != .none) switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
614 .int => try writer.print("{x}", .{try dg.fmtIntLiteral(Type.usize, ptr_val, .Other)}),
615 else => unreachable,
616 };
611 switch (ptr_val.tag()) {617 switch (ptr_val.tag()) {
612 .int_u64, .one => try writer.print("{x}", .{try dg.fmtIntLiteral(Type.usize, ptr_val, .Other)}),
613 .decl_ref_mut, .decl_ref, .variable => {618 .decl_ref_mut, .decl_ref, .variable => {
614 const decl_index = switch (ptr_val.tag()) {619 const decl_index = switch (ptr_val.tag()) {
615 .decl_ref => ptr_val.castTag(.decl_ref).?.data,620 .decl_ref => ptr_val.castTag(.decl_ref).?.data,
...@@ -661,11 +666,7 @@ pub const DeclGen = struct {...@@ -661,11 +666,7 @@ pub const DeclGen = struct {
661 u8_ptr_pl.data.pointee_type = Type.u8;666 u8_ptr_pl.data.pointee_type = Type.u8;
662 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);667 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
663668
664 var byte_offset_pl = Value.Payload.U64{669 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
665 .base = .{ .tag = .int_u64 },
666 .data = byte_offset,
667 };
668 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
669670
670 try writer.writeAll("((");671 try writer.writeAll("((");
671 try dg.renderType(writer, u8_ptr_ty);672 try dg.renderType(writer, u8_ptr_ty);
...@@ -891,7 +892,7 @@ pub const DeclGen = struct {...@@ -891,7 +892,7 @@ pub const DeclGen = struct {
891 },892 },
892 .Array, .Vector => {893 .Array, .Vector => {
893 const ai = ty.arrayInfo(mod);894 const ai = ty.arrayInfo(mod);
894 if (ai.elem_type.eql(Type.u8, dg.module)) {895 if (ai.elem_type.eql(Type.u8, mod)) {
895 var literal = stringLiteral(writer);896 var literal = stringLiteral(writer);
896 try literal.start();897 try literal.start();
897 const c_len = ty.arrayLenIncludingSentinel(mod);898 const c_len = ty.arrayLenIncludingSentinel(mod);
...@@ -949,7 +950,7 @@ pub const DeclGen = struct {...@@ -949,7 +950,7 @@ pub const DeclGen = struct {
949 },950 },
950 .Float => {951 .Float => {
951 const bits = ty.floatBits(target);952 const bits = ty.floatBits(target);
952 const f128_val = val.toFloat(f128);953 const f128_val = val.toFloat(f128, mod);
953954
954 // All unsigned ints matching float types are pre-allocated.955 // All unsigned ints matching float types are pre-allocated.
955 const repr_ty = mod.intType(.unsigned, bits) catch unreachable;956 const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
...@@ -963,21 +964,15 @@ pub const DeclGen = struct {...@@ -963,21 +964,15 @@ pub const DeclGen = struct {
963 };964 };
964965
965 switch (bits) {966 switch (bits) {
966 16 => repr_val_big.set(@bitCast(u16, val.toFloat(f16))),967 16 => repr_val_big.set(@bitCast(u16, val.toFloat(f16, mod))),
967 32 => repr_val_big.set(@bitCast(u32, val.toFloat(f32))),968 32 => repr_val_big.set(@bitCast(u32, val.toFloat(f32, mod))),
968 64 => repr_val_big.set(@bitCast(u64, val.toFloat(f64))),969 64 => repr_val_big.set(@bitCast(u64, val.toFloat(f64, mod))),
969 80 => repr_val_big.set(@bitCast(u80, val.toFloat(f80))),970 80 => repr_val_big.set(@bitCast(u80, val.toFloat(f80, mod))),
970 128 => repr_val_big.set(@bitCast(u128, f128_val)),971 128 => repr_val_big.set(@bitCast(u128, f128_val)),
971 else => unreachable,972 else => unreachable,
972 }973 }
973974
974 var repr_val_pl = Value.Payload.BigInt{975 const repr_val = try mod.intValue_big(repr_ty, repr_val_big.toConst());
975 .base = .{
976 .tag = if (repr_val_big.positive) .int_big_positive else .int_big_negative,
977 },
978 .data = repr_val_big.limbs[0..repr_val_big.len],
979 };
980 const repr_val = Value.initPayload(&repr_val_pl.base);
981976
982 try writer.writeAll("zig_cast_");977 try writer.writeAll("zig_cast_");
983 try dg.renderTypeForBuiltinFnName(writer, ty);978 try dg.renderTypeForBuiltinFnName(writer, ty);
...@@ -988,10 +983,10 @@ pub const DeclGen = struct {...@@ -988,10 +983,10 @@ pub const DeclGen = struct {
988 try dg.renderTypeForBuiltinFnName(writer, ty);983 try dg.renderTypeForBuiltinFnName(writer, ty);
989 try writer.writeByte('(');984 try writer.writeByte('(');
990 switch (bits) {985 switch (bits) {
991 16 => try writer.print("{x}", .{val.toFloat(f16)}),986 16 => try writer.print("{x}", .{val.toFloat(f16, mod)}),
992 32 => try writer.print("{x}", .{val.toFloat(f32)}),987 32 => try writer.print("{x}", .{val.toFloat(f32, mod)}),
993 64 => try writer.print("{x}", .{val.toFloat(f64)}),988 64 => try writer.print("{x}", .{val.toFloat(f64, mod)}),
994 80 => try writer.print("{x}", .{val.toFloat(f80)}),989 80 => try writer.print("{x}", .{val.toFloat(f80, mod)}),
995 128 => try writer.print("{x}", .{f128_val}),990 128 => try writer.print("{x}", .{f128_val}),
996 else => unreachable,991 else => unreachable,
997 }992 }
...@@ -1031,10 +1026,10 @@ pub const DeclGen = struct {...@@ -1031,10 +1026,10 @@ pub const DeclGen = struct {
1031 if (std.math.isNan(f128_val)) switch (bits) {1026 if (std.math.isNan(f128_val)) switch (bits) {
1032 // We only actually need to pass the significand, but it will get1027 // We only actually need to pass the significand, but it will get
1033 // properly masked anyway, so just pass the whole value.1028 // properly masked anyway, so just pass the whole value.
1034 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, val.toFloat(f16))}),1029 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, val.toFloat(f16, mod))}),
1035 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, val.toFloat(f32))}),1030 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, val.toFloat(f32, mod))}),
1036 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, val.toFloat(f64))}),1031 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, val.toFloat(f64, mod))}),
1037 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, val.toFloat(f80))}),1032 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, val.toFloat(f80, mod))}),
1038 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, f128_val)}),1033 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, f128_val)}),
1039 else => unreachable,1034 else => unreachable,
1040 };1035 };
...@@ -1060,19 +1055,6 @@ pub const DeclGen = struct {...@@ -1060,19 +1055,6 @@ pub const DeclGen = struct {
1060 try writer.writeAll(")NULL)");1055 try writer.writeAll(")NULL)");
1061 },1056 },
1062 .none => switch (val.tag()) {1057 .none => switch (val.tag()) {
1063 .zero => if (ty.isSlice(mod)) {
1064 var slice_pl = Value.Payload.Slice{
1065 .base = .{ .tag = .slice },
1066 .data = .{ .ptr = val, .len = Value.undef },
1067 };
1068 const slice_val = Value.initPayload(&slice_pl.base);
1069
1070 return dg.renderValue(writer, ty, slice_val, location);
1071 } else {
1072 try writer.writeAll("((");
1073 try dg.renderType(writer, ty);
1074 try writer.writeAll(")NULL)");
1075 },
1076 .variable => {1058 .variable => {
1077 const decl = val.castTag(.variable).?.data.owner_decl;1059 const decl = val.castTag(.variable).?.data.owner_decl;
1078 return dg.renderDeclValue(writer, ty, val, decl, location);1060 return dg.renderDeclValue(writer, ty, val, decl, location);
...@@ -1101,7 +1083,7 @@ pub const DeclGen = struct {...@@ -1101,7 +1083,7 @@ pub const DeclGen = struct {
1101 const extern_fn = val.castTag(.extern_fn).?.data;1083 const extern_fn = val.castTag(.extern_fn).?.data;
1102 try dg.renderDeclName(writer, extern_fn.owner_decl, 0);1084 try dg.renderDeclName(writer, extern_fn.owner_decl, 0);
1103 },1085 },
1104 .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => {1086 .lazy_align, .lazy_size => {
1105 try writer.writeAll("((");1087 try writer.writeAll("((");
1106 try dg.renderType(writer, ty);1088 try dg.renderType(writer, ty);
1107 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});1089 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
...@@ -1116,7 +1098,14 @@ pub const DeclGen = struct {...@@ -1116,7 +1098,14 @@ pub const DeclGen = struct {
11161098
1117 else => unreachable,1099 else => unreachable,
1118 },1100 },
1119 else => unreachable,1101 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1102 .int => {
1103 try writer.writeAll("((");
1104 try dg.renderType(writer, ty);
1105 return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
1106 },
1107 else => unreachable,
1108 },
1120 },1109 },
1121 .Array, .Vector => {1110 .Array, .Vector => {
1122 if (location == .FunctionArgument) {1111 if (location == .FunctionArgument) {
...@@ -1155,7 +1144,7 @@ pub const DeclGen = struct {...@@ -1155,7 +1144,7 @@ pub const DeclGen = struct {
1155 .bytes => val.castTag(.bytes).?.data,1144 .bytes => val.castTag(.bytes).?.data,
1156 .str_lit => bytes: {1145 .str_lit => bytes: {
1157 const str_lit = val.castTag(.str_lit).?.data;1146 const str_lit = val.castTag(.str_lit).?.data;
1158 break :bytes dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];1147 break :bytes mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
1159 },1148 },
1160 else => unreachable,1149 else => unreachable,
1161 };1150 };
...@@ -1170,21 +1159,18 @@ pub const DeclGen = struct {...@@ -1170,21 +1159,18 @@ pub const DeclGen = struct {
1170 else => {},1159 else => {},
1171 }1160 }
1172 // Fall back to generic implementation.1161 // Fall back to generic implementation.
1173 var arena = std.heap.ArenaAllocator.init(dg.gpa);
1174 defer arena.deinit();
1175 const arena_allocator = arena.allocator();
11761162
1177 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal1163 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal
1178 const max_string_initializer_len = 65535;1164 const max_string_initializer_len = 65535;
11791165
1180 const ai = ty.arrayInfo(mod);1166 const ai = ty.arrayInfo(mod);
1181 if (ai.elem_type.eql(Type.u8, dg.module)) {1167 if (ai.elem_type.eql(Type.u8, mod)) {
1182 if (ai.len <= max_string_initializer_len) {1168 if (ai.len <= max_string_initializer_len) {
1183 var literal = stringLiteral(writer);1169 var literal = stringLiteral(writer);
1184 try literal.start();1170 try literal.start();
1185 var index: usize = 0;1171 var index: usize = 0;
1186 while (index < ai.len) : (index += 1) {1172 while (index < ai.len) : (index += 1) {
1187 const elem_val = try val.elemValue(dg.module, arena_allocator, index);1173 const elem_val = try val.elemValue(mod, index);
1188 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));1174 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
1189 try literal.writeChar(elem_val_u8);1175 try literal.writeChar(elem_val_u8);
1190 }1176 }
...@@ -1198,7 +1184,7 @@ pub const DeclGen = struct {...@@ -1198,7 +1184,7 @@ pub const DeclGen = struct {
1198 var index: usize = 0;1184 var index: usize = 0;
1199 while (index < ai.len) : (index += 1) {1185 while (index < ai.len) : (index += 1) {
1200 if (index != 0) try writer.writeByte(',');1186 if (index != 0) try writer.writeByte(',');
1201 const elem_val = try val.elemValue(dg.module, arena_allocator, index);1187 const elem_val = try val.elemValue(mod, index);
1202 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));1188 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
1203 try writer.print("'\\x{x}'", .{elem_val_u8});1189 try writer.print("'\\x{x}'", .{elem_val_u8});
1204 }1190 }
...@@ -1213,7 +1199,7 @@ pub const DeclGen = struct {...@@ -1213,7 +1199,7 @@ pub const DeclGen = struct {
1213 var index: usize = 0;1199 var index: usize = 0;
1214 while (index < ai.len) : (index += 1) {1200 while (index < ai.len) : (index += 1) {
1215 if (index != 0) try writer.writeByte(',');1201 if (index != 0) try writer.writeByte(',');
1216 const elem_val = try val.elemValue(dg.module, arena_allocator, index);1202 const elem_val = try val.elemValue(mod, index);
1217 try dg.renderValue(writer, ai.elem_type, elem_val, initializer_type);1203 try dg.renderValue(writer, ai.elem_type, elem_val, initializer_type);
1218 }1204 }
1219 if (ai.sentinel) |s| {1205 if (ai.sentinel) |s| {
...@@ -1361,8 +1347,7 @@ pub const DeclGen = struct {...@@ -1361,8 +1347,7 @@ pub const DeclGen = struct {
1361 const bits = Type.smallestUnsignedBits(int_info.bits - 1);1347 const bits = Type.smallestUnsignedBits(int_info.bits - 1);
1362 const bit_offset_ty = try mod.intType(.unsigned, bits);1348 const bit_offset_ty = try mod.intType(.unsigned, bits);
13631349
1364 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };1350 var bit_offset: u64 = 0;
1365 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
13661351
1367 var eff_num_fields: usize = 0;1352 var eff_num_fields: usize = 0;
1368 for (0..field_vals.len) |field_i| {1353 for (0..field_vals.len) |field_i| {
...@@ -1394,12 +1379,13 @@ pub const DeclGen = struct {...@@ -1394,12 +1379,13 @@ pub const DeclGen = struct {
1394 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;1379 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13951380
1396 const cast_context = IntCastContext{ .value = .{ .value = field_val } };1381 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
1397 if (bit_offset_val_pl.data != 0) {1382 if (bit_offset != 0) {
1398 try writer.writeAll("zig_shl_");1383 try writer.writeAll("zig_shl_");
1399 try dg.renderTypeForBuiltinFnName(writer, ty);1384 try dg.renderTypeForBuiltinFnName(writer, ty);
1400 try writer.writeByte('(');1385 try writer.writeByte('(');
1401 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);1386 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
1402 try writer.writeAll(", ");1387 try writer.writeAll(", ");
1388 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
1403 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);1389 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1404 try writer.writeByte(')');1390 try writer.writeByte(')');
1405 } else {1391 } else {
...@@ -1409,7 +1395,7 @@ pub const DeclGen = struct {...@@ -1409,7 +1395,7 @@ pub const DeclGen = struct {
1409 if (needs_closing_paren) try writer.writeByte(')');1395 if (needs_closing_paren) try writer.writeByte(')');
1410 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");1396 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
14111397
1412 bit_offset_val_pl.data += field_ty.bitSize(mod);1398 bit_offset += field_ty.bitSize(mod);
1413 needs_closing_paren = true;1399 needs_closing_paren = true;
1414 eff_index += 1;1400 eff_index += 1;
1415 }1401 }
...@@ -1427,15 +1413,16 @@ pub const DeclGen = struct {...@@ -1427,15 +1413,16 @@ pub const DeclGen = struct {
1427 try dg.renderType(writer, ty);1413 try dg.renderType(writer, ty);
1428 try writer.writeByte(')');1414 try writer.writeByte(')');
14291415
1430 if (bit_offset_val_pl.data != 0) {1416 if (bit_offset != 0) {
1431 try dg.renderValue(writer, field_ty, field_val, .Other);1417 try dg.renderValue(writer, field_ty, field_val, .Other);
1432 try writer.writeAll(" << ");1418 try writer.writeAll(" << ");
1419 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
1433 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);1420 try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
1434 } else {1421 } else {
1435 try dg.renderValue(writer, field_ty, field_val, .Other);1422 try dg.renderValue(writer, field_ty, field_val, .Other);
1436 }1423 }
14371424
1438 bit_offset_val_pl.data += field_ty.bitSize(mod);1425 bit_offset += field_ty.bitSize(mod);
1439 empty = false;1426 empty = false;
1440 }1427 }
1441 try writer.writeByte(')');1428 try writer.writeByte(')');
...@@ -1451,7 +1438,7 @@ pub const DeclGen = struct {...@@ -1451,7 +1438,7 @@ pub const DeclGen = struct {
1451 try writer.writeByte(')');1438 try writer.writeByte(')');
1452 }1439 }
14531440
1454 const field_i = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;1441 const field_i = ty.unionTagFieldIndex(union_obj.tag, mod).?;
1455 const field_ty = ty.unionFields().values()[field_i].ty;1442 const field_ty = ty.unionFields().values()[field_i].ty;
1456 const field_name = ty.unionFields().keys()[field_i];1443 const field_name = ty.unionFields().keys()[field_i];
1457 if (ty.containerLayout() == .Packed) {1444 if (ty.containerLayout() == .Packed) {
...@@ -1951,10 +1938,10 @@ pub const DeclGen = struct {...@@ -1951,10 +1938,10 @@ pub const DeclGen = struct {
19511938
1952 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});1939 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});
19531940
1954 var bits_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = int_info.bits };1941 const bits_ty = if (is_big) Type.u16 else Type.u8;
1955 try writer.print(", {}", .{try dg.fmtIntLiteral(1942 try writer.print(", {}", .{try dg.fmtIntLiteral(
1956 if (is_big) Type.u16 else Type.u8,1943 bits_ty,
1957 Value.initPayload(&bits_pl.base),1944 try mod.intValue(bits_ty, int_info.bits),
1958 .FunctionArgument,1945 .FunctionArgument,
1959 )});1946 )});
1960 }1947 }
...@@ -2495,8 +2482,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2495,8 +2482,7 @@ pub fn genErrDecls(o: *Object) !void {
2495 for (mod.error_name_list.items, 0..) |name, value| {2482 for (mod.error_name_list.items, 0..) |name, value| {
2496 if (value != 0) try writer.writeByte(',');2483 if (value != 0) try writer.writeByte(',');
24972484
2498 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };2485 const len_val = try mod.intValue(Type.usize, name.len);
2499 const len_val = Value.initPayload(&len_pl.base);
25002486
2501 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{2487 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2502 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),2488 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),
...@@ -2548,8 +2534,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2548,8 +2534,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2548 };2534 };
2549 const tag_val = Value.initPayload(&tag_pl.base);2535 const tag_val = Value.initPayload(&tag_pl.base);
25502536
2551 var int_pl: Value.Payload.U64 = undefined;2537 const int_val = try tag_val.enumToInt(enum_ty, mod);
2552 const int_val = tag_val.enumToInt(enum_ty, &int_pl);
25532538
2554 const name_ty = try mod.arrayType(.{2539 const name_ty = try mod.arrayType(.{
2555 .len = name.len,2540 .len = name.len,
...@@ -2560,8 +2545,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2560,8 +2545,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2560 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };2545 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };
2561 const name_val = Value.initPayload(&name_pl.base);2546 const name_val = Value.initPayload(&name_pl.base);
25622547
2563 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };2548 const len_val = try mod.intValue(Type.usize, name.len);
2564 const len_val = Value.initPayload(&len_pl.base);
25652549
2566 try w.print(" case {}: {{\n static ", .{2550 try w.print(" case {}: {{\n static ", .{
2567 try o.dg.fmtIntLiteral(enum_ty, int_val, .Other),2551 try o.dg.fmtIntLiteral(enum_ty, int_val, .Other),
...@@ -3396,12 +3380,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3396,12 +3380,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3396 const host_ty = try mod.intType(.unsigned, host_bits);3380 const host_ty = try mod.intType(.unsigned, host_bits);
33973381
3398 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3382 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
33993383 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.bit_offset);
3400 var bit_offset_val_pl: Value.Payload.U64 = .{
3401 .base = .{ .tag = .int_u64 },
3402 .data = ptr_info.bit_offset,
3403 };
3404 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
34053384
3406 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));3385 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));
34073386
...@@ -3563,14 +3542,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3563,14 +3542,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3563 try v.elem(f, writer);3542 try v.elem(f, writer);
3564 } else switch (dest_int_info.signedness) {3543 } else switch (dest_int_info.signedness) {
3565 .unsigned => {3544 .unsigned => {
3566 var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa);3545 const mask_val = try inst_scalar_ty.maxIntScalar(mod);
3567 defer arena.deinit();
3568
3569 const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };
3570 var stack align(@alignOf(ExpectedContents)) =
3571 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
3572
3573 const mask_val = try inst_scalar_ty.maxInt(stack.get(), mod);
3574 try writer.writeAll("zig_and_");3546 try writer.writeAll("zig_and_");
3575 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);3547 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
3576 try writer.writeByte('(');3548 try writer.writeByte('(');
...@@ -3581,11 +3553,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3581,11 +3553,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3581 .signed => {3553 .signed => {
3582 const c_bits = toCIntBits(scalar_int_info.bits) orelse3554 const c_bits = toCIntBits(scalar_int_info.bits) orelse
3583 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});3555 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3584 var shift_pl = Value.Payload.U64{3556 const shift_val = try mod.intValue(Type.u8, c_bits - dest_bits);
3585 .base = .{ .tag = .int_u64 },
3586 .data = c_bits - dest_bits,
3587 };
3588 const shift_val = Value.initPayload(&shift_pl.base);
35893557
3590 try writer.writeAll("zig_shr_");3558 try writer.writeAll("zig_shr_");
3591 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);3559 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
...@@ -3705,12 +3673,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3705,12 +3673,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3705 const host_ty = try mod.intType(.unsigned, host_bits);3673 const host_ty = try mod.intType(.unsigned, host_bits);
37063674
3707 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));3675 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
37083676 const bit_offset_val = try mod.intValue(bit_offset_ty, ptr_info.bit_offset);
3709 var bit_offset_val_pl: Value.Payload.U64 = .{
3710 .base = .{ .tag = .int_u64 },
3711 .data = ptr_info.bit_offset,
3712 };
3713 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
37143677
3715 const src_bits = src_ty.bitSize(mod);3678 const src_bits = src_ty.bitSize(mod);
37163679
...@@ -3725,11 +3688,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3725,11 +3688,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3725 try mask.shiftLeft(&mask, ptr_info.bit_offset);3688 try mask.shiftLeft(&mask, ptr_info.bit_offset);
3726 try mask.bitNotWrap(&mask, .unsigned, host_bits);3689 try mask.bitNotWrap(&mask, .unsigned, host_bits);
37273690
3728 var mask_pl = Value.Payload.BigInt{3691 const mask_val = try mod.intValue_big(host_ty, mask.toConst());
3729 .base = .{ .tag = .int_big_positive },
3730 .data = mask.limbs[0..mask.len()],
3731 };
3732 const mask_val = Value.initPayload(&mask_pl.base);
37333692
3734 try f.writeCValueDeref(writer, ptr_val);3693 try f.writeCValueDeref(writer, ptr_val);
3735 try v.elem(f, writer);3694 try v.elem(f, writer);
...@@ -5356,11 +5315,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5356,11 +5315,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5356 u8_ptr_pl.data.pointee_type = Type.u8;5315 u8_ptr_pl.data.pointee_type = Type.u8;
5357 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);5316 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
53585317
5359 var byte_offset_pl = Value.Payload.U64{5318 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
5360 .base = .{ .tag = .int_u64 },
5361 .data = byte_offset,
5362 };
5363 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
53645319
5365 try writer.writeAll("((");5320 try writer.writeAll("((");
5366 try f.renderType(writer, u8_ptr_ty);5321 try f.renderType(writer, u8_ptr_ty);
...@@ -5412,11 +5367,7 @@ fn fieldPtr(...@@ -5412,11 +5367,7 @@ fn fieldPtr(
5412 u8_ptr_pl.data.pointee_type = Type.u8;5367 u8_ptr_pl.data.pointee_type = Type.u8;
5413 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);5368 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
54145369
5415 var byte_offset_pl = Value.Payload.U64{5370 const byte_offset_val = try mod.intValue(Type.usize, byte_offset);
5416 .base = .{ .tag = .int_u64 },
5417 .data = byte_offset,
5418 };
5419 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
54205371
5421 try writer.writeAll("((");5372 try writer.writeAll("((");
5422 try f.renderType(writer, u8_ptr_ty);5373 try f.renderType(writer, u8_ptr_ty);
...@@ -5466,11 +5417,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5466,11 +5417,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54665417
5467 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));5418 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
54685419
5469 var bit_offset_val_pl: Value.Payload.U64 = .{5420 const bit_offset = struct_obj.packedFieldBitOffset(mod, extra.field_index);
5470 .base = .{ .tag = .int_u64 },5421 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
5471 .data = struct_obj.packedFieldBitOffset(mod, extra.field_index),
5472 };
5473 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
54745422
5475 const field_int_signedness = if (inst_ty.isAbiInt(mod))5423 const field_int_signedness = if (inst_ty.isAbiInt(mod))
5476 inst_ty.intInfo(mod).signedness5424 inst_ty.intInfo(mod).signedness
...@@ -5492,13 +5440,13 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5492,13 +5440,13 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5492 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);5440 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5493 try writer.writeByte('(');5441 try writer.writeByte('(');
5494 }5442 }
5495 if (bit_offset_val_pl.data > 0) {5443 if (bit_offset > 0) {
5496 try writer.writeAll("zig_shr_");5444 try writer.writeAll("zig_shr_");
5497 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);5445 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5498 try writer.writeByte('(');5446 try writer.writeByte('(');
5499 }5447 }
5500 try f.writeCValue(writer, struct_byval, .Other);5448 try f.writeCValue(writer, struct_byval, .Other);
5501 if (bit_offset_val_pl.data > 0) {5449 if (bit_offset > 0) {
5502 try writer.writeAll(", ");5450 try writer.writeAll(", ");
5503 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);5451 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5504 try writer.writeByte(')');5452 try writer.writeByte(')');
...@@ -5854,9 +5802,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5854,9 +5802,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5854 } else try f.writeCValue(writer, operand, .Initializer);5802 } else try f.writeCValue(writer, operand, .Initializer);
5855 try writer.writeAll("; ");5803 try writer.writeAll("; ");
58565804
5857 const array_len = array_ty.arrayLen(mod);5805 const len_val = try mod.intValue(Type.usize, array_ty.arrayLen(mod));
5858 var len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = array_len };
5859 const len_val = Value.initPayload(&len_pl.base);
5860 try f.writeCValueMember(writer, local, .{ .identifier = "len" });5806 try f.writeCValueMember(writer, local, .{ .identifier = "len" });
5861 try writer.print(" = {};\n", .{try f.fmtIntLiteral(Type.usize, len_val)});5807 try writer.print(" = {};\n", .{try f.fmtIntLiteral(Type.usize, len_val)});
58625808
...@@ -6632,26 +6578,17 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6632,26 +6578,17 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6632 const local = try f.allocLocal(inst, inst_ty);6578 const local = try f.allocLocal(inst, inst_ty);
6633 try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands6579 try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands
6634 for (0..extra.mask_len) |index| {6580 for (0..extra.mask_len) |index| {
6635 var dst_pl = Value.Payload.U64{
6636 .base = .{ .tag = .int_u64 },
6637 .data = @intCast(u64, index),
6638 };
6639
6640 try f.writeCValue(writer, local, .Other);6581 try f.writeCValue(writer, local, .Other);
6641 try writer.writeByte('[');6582 try writer.writeByte('[');
6642 try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&dst_pl.base), .Other);6583 try f.object.dg.renderValue(writer, Type.usize, try mod.intValue(Type.usize, index), .Other);
6643 try writer.writeAll("] = ");6584 try writer.writeAll("] = ");
66446585
6645 var buf: Value.ElemValueBuffer = undefined;6586 const mask_elem = (try mask.elemValue(mod, index)).toSignedInt(mod);
6646 const mask_elem = mask.elemValueBuffer(mod, index, &buf).toSignedInt(mod);6587 const src_val = try mod.intValue(Type.usize, @intCast(u64, mask_elem ^ mask_elem >> 63));
6647 var src_pl = Value.Payload.U64{
6648 .base = .{ .tag = .int_u64 },
6649 .data = @intCast(u64, mask_elem ^ mask_elem >> 63),
6650 };
66516588
6652 try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other);6589 try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other);
6653 try writer.writeByte('[');6590 try writer.writeByte('[');
6654 try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&src_pl.base), .Other);6591 try f.object.dg.renderValue(writer, Type.usize, src_val, .Other);
6655 try writer.writeAll("];\n");6592 try writer.writeAll("];\n");
6656 }6593 }
66576594
...@@ -6730,8 +6667,6 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6730,8 +6667,6 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6730 defer arena.deinit();6667 defer arena.deinit();
67316668
6732 const ExpectedContents = union {6669 const ExpectedContents = union {
6733 u: Value.Payload.U64,
6734 i: Value.Payload.I64,
6735 f16: Value.Payload.Float_16,6670 f16: Value.Payload.Float_16,
6736 f32: Value.Payload.Float_32,6671 f32: Value.Payload.Float_32,
6737 f64: Value.Payload.Float_64,6672 f64: Value.Payload.Float_64,
...@@ -6746,13 +6681,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6746,13 +6681,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6746 .And => switch (scalar_ty.zigTypeTag(mod)) {6681 .And => switch (scalar_ty.zigTypeTag(mod)) {
6747 .Bool => Value.one,6682 .Bool => Value.one,
6748 else => switch (scalar_ty.intInfo(mod).signedness) {6683 else => switch (scalar_ty.intInfo(mod).signedness) {
6749 .unsigned => try scalar_ty.maxInt(stack.get(), mod),6684 .unsigned => try scalar_ty.maxIntScalar(mod),
6750 .signed => Value.negative_one,6685 .signed => Value.negative_one,
6751 },6686 },
6752 },6687 },
6753 .Min => switch (scalar_ty.zigTypeTag(mod)) {6688 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6754 .Bool => Value.one,6689 .Bool => Value.one,
6755 .Int => try scalar_ty.maxInt(stack.get(), mod),6690 .Int => try scalar_ty.maxIntScalar(mod),
6756 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),6691 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
6757 else => unreachable,6692 else => unreachable,
6758 },6693 },
...@@ -6879,8 +6814,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6879,8 +6814,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68796814
6880 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));6815 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
68816816
6882 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };6817 var bit_offset: u64 = 0;
6883 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
68846818
6885 var empty = true;6819 var empty = true;
6886 for (0..elements.len) |field_i| {6820 for (0..elements.len) |field_i| {
...@@ -6925,12 +6859,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6925,12 +6859,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6925 }6859 }
69266860
6927 try writer.writeAll(", ");6861 try writer.writeAll(", ");
6862 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
6928 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);6863 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
6929 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);6864 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
6930 try writer.writeByte(')');6865 try writer.writeByte(')');
6931 if (!empty) try writer.writeByte(')');6866 if (!empty) try writer.writeByte(')');
69326867
6933 bit_offset_val_pl.data += field_ty.bitSize(mod);6868 bit_offset += field_ty.bitSize(mod);
6934 empty = false;6869 empty = false;
6935 }6870 }
69366871
...@@ -6976,8 +6911,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6976,8 +6911,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6976 };6911 };
6977 const tag_val = Value.initPayload(&tag_pl.base);6912 const tag_val = Value.initPayload(&tag_pl.base);
69786913
6979 var int_pl: Value.Payload.U64 = undefined;6914 const int_val = try tag_val.enumToInt(tag_ty, mod);
6980 const int_val = tag_val.enumToInt(tag_ty, &int_pl);
69816915
6982 const a = try Assignment.start(f, writer, tag_ty);6916 const a = try Assignment.start(f, writer, tag_ty);
6983 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });6917 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
...@@ -7640,10 +7574,6 @@ fn formatIntLiteral(...@@ -7640,10 +7574,6 @@ fn formatIntLiteral(
7640 c_limb_int_info.signedness = .unsigned;7574 c_limb_int_info.signedness = .unsigned;
7641 c_limb_cty = c_limb_info.cty;7575 c_limb_cty = c_limb_info.cty;
7642 }7576 }
7643 var c_limb_val_pl = Value.Payload.BigInt{
7644 .base = .{ .tag = if (c_limb_mut.positive) .int_big_positive else .int_big_negative },
7645 .data = c_limb_mut.limbs[0..c_limb_mut.len],
7646 };
76477577
7648 if (limb_offset > 0) try writer.writeAll(", ");7578 if (limb_offset > 0) try writer.writeAll(", ");
7649 try formatIntLiteral(.{7579 try formatIntLiteral(.{
...@@ -7651,7 +7581,7 @@ fn formatIntLiteral(...@@ -7651,7 +7581,7 @@ fn formatIntLiteral(
7651 .int_info = c_limb_int_info,7581 .int_info = c_limb_int_info,
7652 .kind = data.kind,7582 .kind = data.kind,
7653 .cty = c_limb_cty,7583 .cty = c_limb_cty,
7654 .val = Value.initPayload(&c_limb_val_pl.base),7584 .val = try mod.intValue_big(Type.comptime_int, c_limb_mut.toConst()),
7655 }, fmt, options, writer);7585 }, fmt, options, writer);
7656 }7586 }
7657 }7587 }
...@@ -7750,7 +7680,7 @@ const Vectorize = struct {...@@ -7750,7 +7680,7 @@ const Vectorize = struct {
7750 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {7680 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
7751 const mod = f.object.dg.module;7681 const mod = f.object.dg.module;
7752 return if (ty.zigTypeTag(mod) == .Vector) index: {7682 return if (ty.zigTypeTag(mod) == .Vector) index: {
7753 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen(mod) };7683 const len_val = try mod.intValue(Type.usize, ty.vectorLen(mod));
77547684
7755 const local = try f.allocLocal(inst, Type.usize);7685 const local = try f.allocLocal(inst, Type.usize);
77567686
...@@ -7759,7 +7689,7 @@ const Vectorize = struct {...@@ -7759,7 +7689,7 @@ const Vectorize = struct {
7759 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, Value.zero)});7689 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, Value.zero)});
7760 try f.writeCValue(writer, local, .Other);7690 try f.writeCValue(writer, local, .Other);
7761 try writer.print(" < {d}; ", .{7691 try writer.print(" < {d}; ", .{
7762 try f.fmtIntLiteral(Type.usize, Value.initPayload(&len_pl.base)),7692 try f.fmtIntLiteral(Type.usize, len_val),
7763 });7693 });
7764 try f.writeCValue(writer, local, .Other);7694 try f.writeCValue(writer, local, .Other);
7765 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, Value.one)});7695 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, Value.one)});
src/codegen/llvm.zig+38-67
...@@ -12,6 +12,7 @@ const link = @import("../link.zig");...@@ -12,6 +12,7 @@ const link = @import("../link.zig");
12const Compilation = @import("../Compilation.zig");12const Compilation = @import("../Compilation.zig");
13const build_options = @import("build_options");13const build_options = @import("build_options");
14const Module = @import("../Module.zig");14const Module = @import("../Module.zig");
15const InternPool = @import("../InternPool.zig");
15const Package = @import("../Package.zig");16const Package = @import("../Package.zig");
16const TypedValue = @import("../TypedValue.zig");17const TypedValue = @import("../TypedValue.zig");
17const Air = @import("../Air.zig");18const Air = @import("../Air.zig");
...@@ -1535,8 +1536,7 @@ pub const Object = struct {...@@ -1535,8 +1536,7 @@ pub const Object = struct {
1535 defer gpa.free(field_name_z);1536 defer gpa.free(field_name_z);
15361537
1537 buf_field_index.data = @intCast(u32, i);1538 buf_field_index.data = @intCast(u32, i);
1538 var buf_u64: Value.Payload.U64 = undefined;1539 const field_int_val = try field_index_val.enumToInt(ty, mod);
1539 const field_int_val = field_index_val.enumToInt(ty, &buf_u64);
15401540
1541 var bigint_space: Value.BigIntSpace = undefined;1541 var bigint_space: Value.BigIntSpace = undefined;
1542 const bigint = field_int_val.toBigInt(&bigint_space, mod);1542 const bigint = field_int_val.toBigInt(&bigint_space, mod);
...@@ -3255,8 +3255,6 @@ pub const DeclGen = struct {...@@ -3255,8 +3255,6 @@ pub const DeclGen = struct {
3255 const llvm_type = try dg.lowerType(tv.ty);3255 const llvm_type = try dg.lowerType(tv.ty);
3256 return if (tv.val.toBool(mod)) llvm_type.constAllOnes() else llvm_type.constNull();3256 return if (tv.val.toBool(mod)) llvm_type.constAllOnes() else llvm_type.constNull();
3257 },3257 },
3258 // TODO this duplicates code with Pointer but they should share the handling
3259 // of the tv.val.tag() and then Int should do extra constPtrToInt on top
3260 .Int => switch (tv.val.ip_index) {3258 .Int => switch (tv.val.ip_index) {
3261 .none => switch (tv.val.tag()) {3259 .none => switch (tv.val.tag()) {
3262 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),3260 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),
...@@ -3277,8 +3275,7 @@ pub const DeclGen = struct {...@@ -3277,8 +3275,7 @@ pub const DeclGen = struct {
3277 },3275 },
3278 },3276 },
3279 .Enum => {3277 .Enum => {
3280 var int_buffer: Value.Payload.U64 = undefined;3278 const int_val = try tv.enumToInt(mod);
3281 const int_val = tv.enumToInt(&int_buffer);
32823279
3283 var bigint_space: Value.BigIntSpace = undefined;3280 var bigint_space: Value.BigIntSpace = undefined;
3284 const bigint = int_val.toBigInt(&bigint_space, mod);3281 const bigint = int_val.toBigInt(&bigint_space, mod);
...@@ -3307,25 +3304,25 @@ pub const DeclGen = struct {...@@ -3307,25 +3304,25 @@ pub const DeclGen = struct {
3307 const llvm_ty = try dg.lowerType(tv.ty);3304 const llvm_ty = try dg.lowerType(tv.ty);
3308 switch (tv.ty.floatBits(target)) {3305 switch (tv.ty.floatBits(target)) {
3309 16 => {3306 16 => {
3310 const repr = @bitCast(u16, tv.val.toFloat(f16));3307 const repr = @bitCast(u16, tv.val.toFloat(f16, mod));
3311 const llvm_i16 = dg.context.intType(16);3308 const llvm_i16 = dg.context.intType(16);
3312 const int = llvm_i16.constInt(repr, .False);3309 const int = llvm_i16.constInt(repr, .False);
3313 return int.constBitCast(llvm_ty);3310 return int.constBitCast(llvm_ty);
3314 },3311 },
3315 32 => {3312 32 => {
3316 const repr = @bitCast(u32, tv.val.toFloat(f32));3313 const repr = @bitCast(u32, tv.val.toFloat(f32, mod));
3317 const llvm_i32 = dg.context.intType(32);3314 const llvm_i32 = dg.context.intType(32);
3318 const int = llvm_i32.constInt(repr, .False);3315 const int = llvm_i32.constInt(repr, .False);
3319 return int.constBitCast(llvm_ty);3316 return int.constBitCast(llvm_ty);
3320 },3317 },
3321 64 => {3318 64 => {
3322 const repr = @bitCast(u64, tv.val.toFloat(f64));3319 const repr = @bitCast(u64, tv.val.toFloat(f64, mod));
3323 const llvm_i64 = dg.context.intType(64);3320 const llvm_i64 = dg.context.intType(64);
3324 const int = llvm_i64.constInt(repr, .False);3321 const int = llvm_i64.constInt(repr, .False);
3325 return int.constBitCast(llvm_ty);3322 return int.constBitCast(llvm_ty);
3326 },3323 },
3327 80 => {3324 80 => {
3328 const float = tv.val.toFloat(f80);3325 const float = tv.val.toFloat(f80, mod);
3329 const repr = std.math.break_f80(float);3326 const repr = std.math.break_f80(float);
3330 const llvm_i80 = dg.context.intType(80);3327 const llvm_i80 = dg.context.intType(80);
3331 var x = llvm_i80.constInt(repr.exp, .False);3328 var x = llvm_i80.constInt(repr.exp, .False);
...@@ -3338,7 +3335,7 @@ pub const DeclGen = struct {...@@ -3338,7 +3335,7 @@ pub const DeclGen = struct {
3338 }3335 }
3339 },3336 },
3340 128 => {3337 128 => {
3341 var buf: [2]u64 = @bitCast([2]u64, tv.val.toFloat(f128));3338 var buf: [2]u64 = @bitCast([2]u64, tv.val.toFloat(f128, mod));
3342 // LLVM seems to require that the lower half of the f128 be placed first3339 // LLVM seems to require that the lower half of the f128 be placed first
3343 // in the buffer.3340 // in the buffer.
3344 if (native_endian == .Big) {3341 if (native_endian == .Big) {
...@@ -3388,7 +3385,7 @@ pub const DeclGen = struct {...@@ -3388,7 +3385,7 @@ pub const DeclGen = struct {
3388 };3385 };
3389 return dg.context.constStruct(&fields, fields.len, .False);3386 return dg.context.constStruct(&fields, fields.len, .False);
3390 },3387 },
3391 .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => {3388 .lazy_align, .lazy_size => {
3392 const llvm_usize = try dg.lowerType(Type.usize);3389 const llvm_usize = try dg.lowerType(Type.usize);
3393 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(mod), .False);3390 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(mod), .False);
3394 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));3391 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
...@@ -3396,10 +3393,6 @@ pub const DeclGen = struct {...@@ -3396,10 +3393,6 @@ pub const DeclGen = struct {
3396 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {3393 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
3397 return dg.lowerParentPtr(tv.val, tv.ty.ptrInfo(mod).bit_offset % 8 == 0);3394 return dg.lowerParentPtr(tv.val, tv.ty.ptrInfo(mod).bit_offset % 8 == 0);
3398 },3395 },
3399 .zero => {
3400 const llvm_type = try dg.lowerType(tv.ty);
3401 return llvm_type.constNull();
3402 },
3403 .opt_payload => {3396 .opt_payload => {
3404 const payload = tv.val.castTag(.opt_payload).?.data;3397 const payload = tv.val.castTag(.opt_payload).?.data;
3405 return dg.lowerParentPtr(payload, tv.ty.ptrInfo(mod).bit_offset % 8 == 0);3398 return dg.lowerParentPtr(payload, tv.ty.ptrInfo(mod).bit_offset % 8 == 0);
...@@ -3408,7 +3401,10 @@ pub const DeclGen = struct {...@@ -3408,7 +3401,10 @@ pub const DeclGen = struct {
3408 tv.ty.fmtDebug(), tag,3401 tv.ty.fmtDebug(), tag,
3409 }),3402 }),
3410 },3403 },
3411 else => unreachable,3404 else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
3405 .int => |int| return lowerIntAsPtr(dg, int),
3406 else => unreachable,
3407 },
3412 },3408 },
3413 .Array => switch (tv.val.tag()) {3409 .Array => switch (tv.val.tag()) {
3414 .bytes => {3410 .bytes => {
...@@ -3592,7 +3588,7 @@ pub const DeclGen = struct {...@@ -3592,7 +3588,7 @@ pub const DeclGen = struct {
35923588
3593 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3589 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3594 // We use the error type directly as the type.3590 // We use the error type directly as the type.
3595 const err_val = if (!is_pl) tv.val else Value.initTag(.zero);3591 const err_val = if (!is_pl) tv.val else Value.zero;
3596 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });3592 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
3597 }3593 }
35983594
...@@ -3600,7 +3596,7 @@ pub const DeclGen = struct {...@@ -3600,7 +3596,7 @@ pub const DeclGen = struct {
3600 const error_align = Type.anyerror.abiAlignment(mod);3596 const error_align = Type.anyerror.abiAlignment(mod);
3601 const llvm_error_value = try dg.lowerValue(.{3597 const llvm_error_value = try dg.lowerValue(.{
3602 .ty = Type.anyerror,3598 .ty = Type.anyerror,
3603 .val = if (is_pl) Value.initTag(.zero) else tv.val,3599 .val = if (is_pl) Value.zero else tv.val,
3604 });3600 });
3605 const llvm_payload_value = try dg.lowerValue(.{3601 const llvm_payload_value = try dg.lowerValue(.{
3606 .ty = payload_type,3602 .ty = payload_type,
...@@ -3882,14 +3878,9 @@ pub const DeclGen = struct {...@@ -3882,14 +3878,9 @@ pub const DeclGen = struct {
3882 const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len);3878 const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len);
3883 defer dg.gpa.free(llvm_elems);3879 defer dg.gpa.free(llvm_elems);
3884 for (llvm_elems, 0..) |*elem, i| {3880 for (llvm_elems, 0..) |*elem, i| {
3885 var byte_payload: Value.Payload.U64 = .{
3886 .base = .{ .tag = .int_u64 },
3887 .data = bytes[i],
3888 };
3889
3890 elem.* = try dg.lowerValue(.{3881 elem.* = try dg.lowerValue(.{
3891 .ty = elem_ty,3882 .ty = elem_ty,
3892 .val = Value.initPayload(&byte_payload.base),3883 .val = try mod.intValue(elem_ty, bytes[i]),
3893 });3884 });
3894 }3885 }
3895 return llvm.constVector(3886 return llvm.constVector(
...@@ -3940,14 +3931,9 @@ pub const DeclGen = struct {...@@ -3940,14 +3931,9 @@ pub const DeclGen = struct {
3940 const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len);3931 const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len);
3941 defer dg.gpa.free(llvm_elems);3932 defer dg.gpa.free(llvm_elems);
3942 for (llvm_elems, 0..) |*elem, i| {3933 for (llvm_elems, 0..) |*elem, i| {
3943 var byte_payload: Value.Payload.U64 = .{
3944 .base = .{ .tag = .int_u64 },
3945 .data = bytes[i],
3946 };
3947
3948 elem.* = try dg.lowerValue(.{3934 elem.* = try dg.lowerValue(.{
3949 .ty = elem_ty,3935 .ty = elem_ty,
3950 .val = Value.initPayload(&byte_payload.base),3936 .val = try mod.intValue(elem_ty, bytes[i]),
3951 });3937 });
3952 }3938 }
3953 return llvm.constVector(3939 return llvm.constVector(
...@@ -3974,6 +3960,13 @@ pub const DeclGen = struct {...@@ -3974,6 +3960,13 @@ pub const DeclGen = struct {
3974 }3960 }
3975 }3961 }
39763962
3963 fn lowerIntAsPtr(dg: *DeclGen, int: InternPool.Key.Int) *llvm.Value {
3964 var bigint_space: Value.BigIntSpace = undefined;
3965 const bigint = int.storage.toBigInt(&bigint_space);
3966 const llvm_int = lowerBigInt(dg, Type.usize, bigint);
3967 return llvm_int.constIntToPtr(dg.context.pointerType(0));
3968 }
3969
3977 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {3970 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
3978 const mod = dg.module;3971 const mod = dg.module;
3979 const int_info = ty.intInfo(mod);3972 const int_info = ty.intInfo(mod);
...@@ -4018,6 +4011,10 @@ pub const DeclGen = struct {...@@ -4018,6 +4011,10 @@ pub const DeclGen = struct {
4018 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {4011 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
4019 const mod = dg.module;4012 const mod = dg.module;
4020 const target = mod.getTarget();4013 const target = mod.getTarget();
4014 if (ptr_val.ip_index != .none) switch (mod.intern_pool.indexToKey(ptr_val.ip_index)) {
4015 .int => |int| return lowerIntAsPtr(dg, int),
4016 else => unreachable,
4017 };
4021 switch (ptr_val.tag()) {4018 switch (ptr_val.tag()) {
4022 .decl_ref_mut => {4019 .decl_ref_mut => {
4023 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;4020 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
...@@ -4031,18 +4028,6 @@ pub const DeclGen = struct {...@@ -4031,18 +4028,6 @@ pub const DeclGen = struct {
4031 const decl = ptr_val.castTag(.variable).?.data.owner_decl;4028 const decl = ptr_val.castTag(.variable).?.data.owner_decl;
4032 return dg.lowerParentPtrDecl(ptr_val, decl);4029 return dg.lowerParentPtrDecl(ptr_val, decl);
4033 },4030 },
4034 .int_i64 => {
4035 const int = ptr_val.castTag(.int_i64).?.data;
4036 const llvm_usize = try dg.lowerType(Type.usize);
4037 const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False);
4038 return llvm_int.constIntToPtr(dg.context.pointerType(0));
4039 },
4040 .int_u64 => {
4041 const int = ptr_val.castTag(.int_u64).?.data;
4042 const llvm_usize = try dg.lowerType(Type.usize);
4043 const llvm_int = llvm_usize.constInt(int, .False);
4044 return llvm_int.constIntToPtr(dg.context.pointerType(0));
4045 },
4046 .field_ptr => {4031 .field_ptr => {
4047 const field_ptr = ptr_val.castTag(.field_ptr).?.data;4032 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
4048 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, byte_aligned);4033 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, byte_aligned);
...@@ -4185,10 +4170,6 @@ pub const DeclGen = struct {...@@ -4185,10 +4170,6 @@ pub const DeclGen = struct {
4185 if (tv.ty.isSlice(mod)) {4170 if (tv.ty.isSlice(mod)) {
4186 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4171 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4187 const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod);4172 const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod);
4188 var slice_len: Value.Payload.U64 = .{
4189 .base = .{ .tag = .int_u64 },
4190 .data = tv.val.sliceLen(mod),
4191 };
4192 const fields: [2]*llvm.Value = .{4173 const fields: [2]*llvm.Value = .{
4193 try self.lowerValue(.{4174 try self.lowerValue(.{
4194 .ty = ptr_ty,4175 .ty = ptr_ty,
...@@ -4196,7 +4177,7 @@ pub const DeclGen = struct {...@@ -4196,7 +4177,7 @@ pub const DeclGen = struct {
4196 }),4177 }),
4197 try self.lowerValue(.{4178 try self.lowerValue(.{
4198 .ty = Type.usize,4179 .ty = Type.usize,
4199 .val = Value.initPayload(&slice_len.base),4180 .val = try mod.intValue(Type.usize, tv.val.sliceLen(mod)),
4200 }),4181 }),
4201 };4182 };
4202 return self.context.constStruct(&fields, fields.len, .False);4183 return self.context.constStruct(&fields, fields.len, .False);
...@@ -8507,8 +8488,7 @@ pub const FuncGen = struct {...@@ -8507,8 +8488,7 @@ pub const FuncGen = struct {
8507 const dest_slice = try self.resolveInst(bin_op.lhs);8488 const dest_slice = try self.resolveInst(bin_op.lhs);
8508 const ptr_ty = self.typeOf(bin_op.lhs);8489 const ptr_ty = self.typeOf(bin_op.lhs);
8509 const elem_ty = self.typeOf(bin_op.rhs);8490 const elem_ty = self.typeOf(bin_op.rhs);
8510 const module = self.dg.module;8491 const target = mod.getTarget();
8511 const target = module.getTarget();
8512 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8492 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8513 const u8_llvm_ty = self.context.intType(8);8493 const u8_llvm_ty = self.context.intType(8);
8514 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);8494 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
...@@ -8526,7 +8506,7 @@ pub const FuncGen = struct {...@@ -8526,7 +8506,7 @@ pub const FuncGen = struct {
8526 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8506 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8527 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8507 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
85288508
8529 if (safety and module.comp.bin_file.options.valgrind) {8509 if (safety and mod.comp.bin_file.options.valgrind) {
8530 self.valgrindMarkUndef(dest_ptr, len);8510 self.valgrindMarkUndef(dest_ptr, len);
8531 }8511 }
8532 return null;8512 return null;
...@@ -8536,8 +8516,7 @@ pub const FuncGen = struct {...@@ -8536,8 +8516,7 @@ pub const FuncGen = struct {
8536 // repeating byte pattern, for example, `@as(u64, 0)` has a8516 // repeating byte pattern, for example, `@as(u64, 0)` has a
8537 // repeating byte pattern of 0 bytes. In such case, the memset8517 // repeating byte pattern of 0 bytes. In such case, the memset
8538 // intrinsic can be used.8518 // intrinsic can be used.
8539 var value_buffer: Value.Payload.U64 = undefined;8519 if (try elem_val.hasRepeatedByteRepr(elem_ty, mod)) |byte_val| {
8540 if (try elem_val.hasRepeatedByteRepr(elem_ty, module, &value_buffer)) |byte_val| {
8541 const fill_byte = try self.resolveValue(.{8520 const fill_byte = try self.resolveValue(.{
8542 .ty = Type.u8,8521 .ty = Type.u8,
8543 .val = byte_val,8522 .val = byte_val,
...@@ -8829,16 +8808,10 @@ pub const FuncGen = struct {...@@ -8829,16 +8808,10 @@ pub const FuncGen = struct {
88298808
8830 for (names) |name| {8809 for (names) |name| {
8831 const err_int = mod.global_error_set.get(name).?;8810 const err_int = mod.global_error_set.get(name).?;
8832 const this_tag_int_value = int: {8811 const this_tag_int_value = try self.dg.lowerValue(.{
8833 var tag_val_payload: Value.Payload.U64 = .{8812 .ty = Type.err_int,
8834 .base = .{ .tag = .int_u64 },8813 .val = try mod.intValue(Type.err_int, err_int),
8835 .data = err_int,8814 });
8836 };
8837 break :int try self.dg.lowerValue(.{
8838 .ty = Type.err_int,
8839 .val = Value.initPayload(&tag_val_payload.base),
8840 });
8841 };
8842 switch_instr.addCase(this_tag_int_value, valid_block);8815 switch_instr.addCase(this_tag_int_value, valid_block);
8843 }8816 }
8844 self.builder.positionBuilderAtEnd(valid_block);8817 self.builder.positionBuilderAtEnd(valid_block);
...@@ -9122,8 +9095,7 @@ pub const FuncGen = struct {...@@ -9122,8 +9095,7 @@ pub const FuncGen = struct {
9122 const llvm_i32 = self.context.intType(32);9095 const llvm_i32 = self.context.intType(32);
91239096
9124 for (values, 0..) |*val, i| {9097 for (values, 0..) |*val, i| {
9125 var buf: Value.ElemValueBuffer = undefined;9098 const elem = try mask.elemValue(mod, i);
9126 const elem = mask.elemValueBuffer(mod, i, &buf);
9127 if (elem.isUndef()) {9099 if (elem.isUndef()) {
9128 val.* = llvm_i32.getUndef();9100 val.* = llvm_i32.getUndef();
9129 } else {9101 } else {
...@@ -9457,8 +9429,7 @@ pub const FuncGen = struct {...@@ -9457,8 +9429,7 @@ pub const FuncGen = struct {
9457 .data = @intCast(u32, enum_field_index),9429 .data = @intCast(u32, enum_field_index),
9458 };9430 };
9459 const tag_val = Value.initPayload(&tag_val_payload.base);9431 const tag_val = Value.initPayload(&tag_val_payload.base);
9460 var int_payload: Value.Payload.U64 = undefined;9432 const tag_int_val = try tag_val.enumToInt(tag_ty, mod);
9461 const tag_int_val = tag_val.enumToInt(tag_ty, &int_payload);
9462 break :blk tag_int_val.toUnsignedInt(mod);9433 break :blk tag_int_val.toUnsignedInt(mod);
9463 };9434 };
9464 if (layout.payload_size == 0) {9435 if (layout.payload_size == 0) {
src/codegen/spirv.zig+23-23
...@@ -555,15 +555,15 @@ pub const DeclGen = struct {...@@ -555,15 +555,15 @@ pub const DeclGen = struct {
555 // TODO: Swap endianess if the compiler is big endian.555 // TODO: Swap endianess if the compiler is big endian.
556 switch (ty.floatBits(target)) {556 switch (ty.floatBits(target)) {
557 16 => {557 16 => {
558 const float_bits = val.toFloat(f16);558 const float_bits = val.toFloat(f16, mod);
559 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);559 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);
560 },560 },
561 32 => {561 32 => {
562 const float_bits = val.toFloat(f32);562 const float_bits = val.toFloat(f32, mod);
563 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);563 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);
564 },564 },
565 64 => {565 64 => {
566 const float_bits = val.toFloat(f64);566 const float_bits = val.toFloat(f64, mod);
567 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);567 try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]);
568 },568 },
569 else => unreachable,569 else => unreachable,
...@@ -584,7 +584,7 @@ pub const DeclGen = struct {...@@ -584,7 +584,7 @@ pub const DeclGen = struct {
584 // TODO: Properly lower function pointers. For now we are going to hack around it and584 // TODO: Properly lower function pointers. For now we are going to hack around it and
585 // just generate an empty pointer. Function pointers are represented by usize for now,585 // just generate an empty pointer. Function pointers are represented by usize for now,
586 // though.586 // though.
587 try self.addInt(Type.usize, Value.initTag(.zero));587 try self.addInt(Type.usize, Value.zero);
588 // TODO: Add dependency588 // TODO: Add dependency
589 return;589 return;
590 },590 },
...@@ -743,8 +743,7 @@ pub const DeclGen = struct {...@@ -743,8 +743,7 @@ pub const DeclGen = struct {
743 try self.addUndef(padding);743 try self.addUndef(padding);
744 },744 },
745 .Enum => {745 .Enum => {
746 var int_val_buffer: Value.Payload.U64 = undefined;746 const int_val = try val.enumToInt(ty, mod);
747 const int_val = val.enumToInt(ty, &int_val_buffer);
748747
749 const int_ty = ty.intTagType();748 const int_ty = ty.intTagType();
750749
...@@ -787,22 +786,24 @@ pub const DeclGen = struct {...@@ -787,22 +786,24 @@ pub const DeclGen = struct {
787786
788 try self.addUndef(layout.padding);787 try self.addUndef(layout.padding);
789 },788 },
790 .ErrorSet => switch (val.tag()) {789 .ErrorSet => switch (val.ip_index) {
791 .@"error" => {790 .none => switch (val.tag()) {
792 const err_name = val.castTag(.@"error").?.data.name;791 .@"error" => {
793 const kv = try dg.module.getErrorValue(err_name);792 const err_name = val.castTag(.@"error").?.data.name;
794 try self.addConstInt(u16, @intCast(u16, kv.value));793 const kv = try dg.module.getErrorValue(err_name);
794 try self.addConstInt(u16, @intCast(u16, kv.value));
795 },
796 else => unreachable,
795 },797 },
796 .zero => {798 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
797 // Unactivated error set.799 .int => |int| try self.addConstInt(u16, @intCast(u16, int.storage.u64)),
798 try self.addConstInt(u16, 0);800 else => unreachable,
799 },801 },
800 else => unreachable,
801 },802 },
802 .ErrorUnion => {803 .ErrorUnion => {
803 const payload_ty = ty.errorUnionPayload();804 const payload_ty = ty.errorUnionPayload();
804 const is_pl = val.errorUnionIsPayload();805 const is_pl = val.errorUnionIsPayload();
805 const error_val = if (!is_pl) val else Value.initTag(.zero);806 const error_val = if (!is_pl) val else Value.zero;
806807
807 const eu_layout = dg.errorUnionLayout(payload_ty);808 const eu_layout = dg.errorUnionLayout(payload_ty);
808 if (!eu_layout.payload_has_bits) {809 if (!eu_layout.payload_has_bits) {
...@@ -993,9 +994,9 @@ pub const DeclGen = struct {...@@ -993,9 +994,9 @@ pub const DeclGen = struct {
993 .indirect => return try self.spv.constInt(result_ty_ref, @boolToInt(val.toBool(mod))),994 .indirect => return try self.spv.constInt(result_ty_ref, @boolToInt(val.toBool(mod))),
994 },995 },
995 .Float => return switch (ty.floatBits(target)) {996 .Float => return switch (ty.floatBits(target)) {
996 16 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float16 = val.toFloat(f16) } } }),997 16 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float16 = val.toFloat(f16, mod) } } }),
997 32 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float32 = val.toFloat(f32) } } }),998 32 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float32 = val.toFloat(f32, mod) } } }),
998 64 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float64 = val.toFloat(f64) } } }),999 64 => try self.spv.resolveId(.{ .float = .{ .ty = result_ty_ref, .value = .{ .float64 = val.toFloat(f64, mod) } } }),
999 80, 128 => unreachable, // TODO1000 80, 128 => unreachable, // TODO
1000 else => unreachable,1001 else => unreachable,
1001 },1002 },
...@@ -1531,6 +1532,7 @@ pub const DeclGen = struct {...@@ -1531,6 +1532,7 @@ pub const DeclGen = struct {
1531 }1532 }
15321533
1533 fn genDecl(self: *DeclGen) !void {1534 fn genDecl(self: *DeclGen) !void {
1535 if (true) @panic("TODO: update SPIR-V backend for InternPool changes");
1534 const mod = self.module;1536 const mod = self.module;
1535 const decl = mod.declPtr(self.decl_index);1537 const decl = mod.declPtr(self.decl_index);
1536 const spv_decl_index = try self.resolveDecl(self.decl_index);1538 const spv_decl_index = try self.resolveDecl(self.decl_index);
...@@ -2087,8 +2089,7 @@ pub const DeclGen = struct {...@@ -2087,8 +2089,7 @@ pub const DeclGen = struct {
20872089
2088 var i: usize = 0;2090 var i: usize = 0;
2089 while (i < mask_len) : (i += 1) {2091 while (i < mask_len) : (i += 1) {
2090 var buf: Value.ElemValueBuffer = undefined;2092 const elem = try mask.elemValue(self.module, i);
2091 const elem = mask.elemValueBuffer(self.module, i, &buf);
2092 if (elem.isUndef()) {2093 if (elem.isUndef()) {
2093 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);2094 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);
2094 } else {2095 } else {
...@@ -3146,9 +3147,8 @@ pub const DeclGen = struct {...@@ -3146,9 +3147,8 @@ pub const DeclGen = struct {
3146 const int_val = switch (cond_ty.zigTypeTag(mod)) {3147 const int_val = switch (cond_ty.zigTypeTag(mod)) {
3147 .Int => if (cond_ty.isSignedInt(mod)) @bitCast(u64, value.toSignedInt(mod)) else value.toUnsignedInt(mod),3148 .Int => if (cond_ty.isSignedInt(mod)) @bitCast(u64, value.toSignedInt(mod)) else value.toUnsignedInt(mod),
3148 .Enum => blk: {3149 .Enum => blk: {
3149 var int_buffer: Value.Payload.U64 = undefined;
3150 // TODO: figure out of cond_ty is correct (something with enum literals)3150 // TODO: figure out of cond_ty is correct (something with enum literals)
3151 break :blk value.enumToInt(cond_ty, &int_buffer).toUnsignedInt(mod); // TODO: composite integer constants3151 break :blk (try value.enumToInt(cond_ty, mod)).toUnsignedInt(mod); // TODO: composite integer constants
3152 },3152 },
3153 else => unreachable,3153 else => unreachable,
3154 };3154 };
src/link/Dwarf.zig+1-2
...@@ -421,8 +421,7 @@ pub const DeclState = struct {...@@ -421,8 +421,7 @@ pub const DeclState = struct {
421 const value = vals.keys()[field_i];421 const value = vals.keys()[field_i];
422 // TODO do not assume a 64bit enum value - could be bigger.422 // TODO do not assume a 64bit enum value - could be bigger.
423 // See https://github.com/ziglang/zig/issues/645423 // See https://github.com/ziglang/zig/issues/645
424 var int_buffer: Value.Payload.U64 = undefined;424 const field_int_val = try value.enumToInt(ty, mod);
425 const field_int_val = value.enumToInt(ty, &int_buffer);
426 break :value @bitCast(u64, field_int_val.toSignedInt(mod));425 break :value @bitCast(u64, field_int_val.toSignedInt(mod));
427 } else @intCast(u64, field_i);426 } else @intCast(u64, field_i);
428 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);427 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
src/type.zig+38-51
...@@ -2077,10 +2077,10 @@ pub const Type = struct {...@@ -2077,10 +2077,10 @@ pub const Type = struct {
2077 }2077 }
20782078
2079 /// May capture a reference to `ty`.2079 /// May capture a reference to `ty`.
2080 pub fn lazyAbiAlignment(ty: Type, mod: *const Module, arena: Allocator) !Value {2080 pub fn lazyAbiAlignment(ty: Type, mod: *Module, arena: Allocator) !Value {
2081 switch (try ty.abiAlignmentAdvanced(mod, .{ .lazy = arena })) {2081 switch (try ty.abiAlignmentAdvanced(mod, .{ .lazy = arena })) {
2082 .val => |val| return val,2082 .val => |val| return val,
2083 .scalar => |x| return Value.Tag.int_u64.create(arena, x),2083 .scalar => |x| return mod.intValue(ty, x),
2084 }2084 }
2085 }2085 }
20862086
...@@ -2468,10 +2468,10 @@ pub const Type = struct {...@@ -2468,10 +2468,10 @@ pub const Type = struct {
2468 }2468 }
24692469
2470 /// May capture a reference to `ty`.2470 /// May capture a reference to `ty`.
2471 pub fn lazyAbiSize(ty: Type, mod: *const Module, arena: Allocator) !Value {2471 pub fn lazyAbiSize(ty: Type, mod: *Module, arena: Allocator) !Value {
2472 switch (try ty.abiSizeAdvanced(mod, .{ .lazy = arena })) {2472 switch (try ty.abiSizeAdvanced(mod, .{ .lazy = arena })) {
2473 .val => |val| return val,2473 .val => |val| return val,
2474 .scalar => |x| return Value.Tag.int_u64.create(arena, x),2474 .scalar => |x| return mod.intValue(ty, x),
2475 }2475 }
2476 }2476 }
24772477
...@@ -4310,8 +4310,8 @@ pub const Type = struct {...@@ -4310,8 +4310,8 @@ pub const Type = struct {
4310 }4310 }
43114311
4312 // Works for vectors and vectors of integers.4312 // Works for vectors and vectors of integers.
4313 pub fn minInt(ty: Type, arena: Allocator, mod: *const Module) !Value {4313 pub fn minInt(ty: Type, arena: Allocator, mod: *Module) !Value {
4314 const scalar = try minIntScalar(ty.scalarType(mod), arena, mod);4314 const scalar = try minIntScalar(ty.scalarType(mod), mod);
4315 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {4315 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
4316 return Value.Tag.repeated.create(arena, scalar);4316 return Value.Tag.repeated.create(arena, scalar);
4317 } else {4317 } else {
...@@ -4319,38 +4319,28 @@ pub const Type = struct {...@@ -4319,38 +4319,28 @@ pub const Type = struct {
4319 }4319 }
4320 }4320 }
43214321
4322 /// Asserts that self.zigTypeTag(mod) == .Int.4322 /// Asserts that the type is an integer.
4323 pub fn minIntScalar(ty: Type, arena: Allocator, mod: *const Module) !Value {4323 pub fn minIntScalar(ty: Type, mod: *Module) !Value {
4324 assert(ty.zigTypeTag(mod) == .Int);
4325 const info = ty.intInfo(mod);4324 const info = ty.intInfo(mod);
43264325 if (info.signedness == .unsigned) return Value.zero;
4327 if (info.bits == 0) {4326 if (info.bits == 0) return Value.negative_one;
4328 return Value.initTag(.the_only_possible_value);
4329 }
4330
4331 if (info.signedness == .unsigned) {
4332 return Value.zero;
4333 }
43344327
4335 if (std.math.cast(u6, info.bits - 1)) |shift| {4328 if (std.math.cast(u6, info.bits - 1)) |shift| {
4336 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);4329 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
4337 return Value.Tag.int_i64.create(arena, n);4330 return mod.intValue(Type.comptime_int, n);
4338 }4331 }
43394332
4340 var res = try std.math.big.int.Managed.init(arena);4333 var res = try std.math.big.int.Managed.init(mod.gpa);
4334 defer res.deinit();
4335
4341 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);4336 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);
43424337
4343 const res_const = res.toConst();4338 return mod.intValue_big(Type.comptime_int, res.toConst());
4344 if (res_const.positive) {
4345 return Value.Tag.int_big_positive.create(arena, res_const.limbs);
4346 } else {
4347 return Value.Tag.int_big_negative.create(arena, res_const.limbs);
4348 }
4349 }4339 }
43504340
4351 // Works for vectors and vectors of integers.4341 // Works for vectors and vectors of integers.
4352 pub fn maxInt(ty: Type, arena: Allocator, mod: *const Module) !Value {4342 pub fn maxInt(ty: Type, arena: Allocator, mod: *Module) !Value {
4353 const scalar = try maxIntScalar(ty.scalarType(mod), arena, mod);4343 const scalar = try maxIntScalar(ty.scalarType(mod), mod);
4354 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {4344 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
4355 return Value.Tag.repeated.create(arena, scalar);4345 return Value.Tag.repeated.create(arena, scalar);
4356 } else {4346 } else {
...@@ -4358,41 +4348,39 @@ pub const Type = struct {...@@ -4358,41 +4348,39 @@ pub const Type = struct {
4358 }4348 }
4359 }4349 }
43604350
4361 /// Asserts that self.zigTypeTag() == .Int.4351 /// Asserts that the type is an integer.
4362 pub fn maxIntScalar(self: Type, arena: Allocator, mod: *const Module) !Value {4352 pub fn maxIntScalar(self: Type, mod: *Module) !Value {
4363 assert(self.zigTypeTag(mod) == .Int);
4364 const info = self.intInfo(mod);4353 const info = self.intInfo(mod);
43654354
4366 if (info.bits == 0) {4355 switch (info.bits) {
4367 return Value.initTag(.the_only_possible_value);4356 0 => return switch (info.signedness) {
4368 }4357 .signed => Value.negative_one,
43694358 .unsigned => Value.zero,
4370 switch (info.bits - @boolToInt(info.signedness == .signed)) {4359 },
4371 0 => return Value.zero,4360 1 => return switch (info.signedness) {
4372 1 => return Value.one,4361 .signed => Value.zero,
4362 .unsigned => Value.one,
4363 },
4373 else => {},4364 else => {},
4374 }4365 }
43754366
4376 if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) {4367 if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) {
4377 .signed => {4368 .signed => {
4378 const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift);4369 const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift);
4379 return Value.Tag.int_i64.create(arena, n);4370 return mod.intValue(Type.comptime_int, n);
4380 },4371 },
4381 .unsigned => {4372 .unsigned => {
4382 const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift);4373 const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift);
4383 return Value.Tag.int_u64.create(arena, n);4374 return mod.intValue(Type.comptime_int, n);
4384 },4375 },
4385 };4376 };
43864377
4387 var res = try std.math.big.int.Managed.init(arena);4378 var res = try std.math.big.int.Managed.init(mod.gpa);
4379 defer res.deinit();
4380
4388 try res.setTwosCompIntLimit(.max, info.signedness, info.bits);4381 try res.setTwosCompIntLimit(.max, info.signedness, info.bits);
43894382
4390 const res_const = res.toConst();4383 return mod.intValue_big(Type.comptime_int, res.toConst());
4391 if (res_const.positive) {
4392 return Value.Tag.int_big_positive.create(arena, res_const.limbs);
4393 } else {
4394 return Value.Tag.int_big_negative.create(arena, res_const.limbs);
4395 }
4396 }4384 }
43974385
4398 /// Asserts the type is an enum or a union.4386 /// Asserts the type is an enum or a union.
...@@ -4497,12 +4485,11 @@ pub const Type = struct {...@@ -4497,12 +4485,11 @@ pub const Type = struct {
4497 const S = struct {4485 const S = struct {
4498 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize {4486 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize {
4499 if (int_val.compareAllWithZero(.lt, m)) return null;4487 if (int_val.compareAllWithZero(.lt, m)) return null;
4500 var end_payload: Value.Payload.U64 = .{4488 const end_val = m.intValue(int_ty, end) catch |err| switch (err) {
4501 .base = .{ .tag = .int_u64 },4489 // TODO: eliminate this failure condition
4502 .data = end,4490 error.OutOfMemory => @panic("OOM"),
4503 };4491 };
4504 const end_val = Value.initPayload(&end_payload.base);4492 if (int_val.compareScalar(.gte, end_val, int_ty, m)) return null;
4505 if (int_val.compareAll(.gte, end_val, int_ty, m)) return null;
4506 return @intCast(usize, int_val.toUnsignedInt(m));4493 return @intCast(usize, int_val.toUnsignedInt(m));
4507 }4494 }
4508 };4495 };
src/value.zig+557-874
...@@ -33,8 +33,6 @@ pub const Value = struct {...@@ -33,8 +33,6 @@ pub const Value = struct {
33 // Keep in sync with tools/stage2_pretty_printers_common.py33 // Keep in sync with tools/stage2_pretty_printers_common.py
34 pub const Tag = enum(usize) {34 pub const Tag = enum(usize) {
35 // The first section of this enum are tags that require no payload.35 // The first section of this enum are tags that require no payload.
36 zero,
37 one,
38 /// The only possible value for a particular type, which is stored externally.36 /// The only possible value for a particular type, which is stored externally.
39 the_only_possible_value,37 the_only_possible_value,
4038
...@@ -43,10 +41,6 @@ pub const Value = struct {...@@ -43,10 +41,6 @@ pub const Value = struct {
43 // After this, the tag requires a payload.41 // After this, the tag requires a payload.
4442
45 ty,43 ty,
46 int_u64,
47 int_i64,
48 int_big_positive,
49 int_big_negative,
50 function,44 function,
51 extern_fn,45 extern_fn,
52 /// A comptime-known pointer can point to the address of a global46 /// A comptime-known pointer can point to the address of a global
...@@ -129,17 +123,11 @@ pub const Value = struct {...@@ -129,17 +123,11 @@ pub const Value = struct {
129123
130 pub fn Type(comptime t: Tag) type {124 pub fn Type(comptime t: Tag) type {
131 return switch (t) {125 return switch (t) {
132 .zero,
133 .one,
134 .the_only_possible_value,126 .the_only_possible_value,
135 .empty_struct_value,127 .empty_struct_value,
136 .empty_array,128 .empty_array,
137 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),129 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
138130
139 .int_big_positive,
140 .int_big_negative,
141 => Payload.BigInt,
142
143 .extern_fn => Payload.ExternFn,131 .extern_fn => Payload.ExternFn,
144132
145 .decl_ref => Payload.Decl,133 .decl_ref => Payload.Decl,
...@@ -169,8 +157,6 @@ pub const Value = struct {...@@ -169,8 +157,6 @@ pub const Value = struct {
169 .lazy_size,157 .lazy_size,
170 => Payload.Ty,158 => Payload.Ty,
171159
172 .int_u64 => Payload.U64,
173 .int_i64 => Payload.I64,
174 .function => Payload.Function,160 .function => Payload.Function,
175 .variable => Payload.Variable,161 .variable => Payload.Variable,
176 .decl_ref_mut => Payload.DeclRefMut,162 .decl_ref_mut => Payload.DeclRefMut,
...@@ -281,8 +267,6 @@ pub const Value = struct {...@@ -281,8 +267,6 @@ pub const Value = struct {
281 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },267 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
282 };268 };
283 } else switch (self.legacy.ptr_otherwise.tag) {269 } else switch (self.legacy.ptr_otherwise.tag) {
284 .zero,
285 .one,
286 .the_only_possible_value,270 .the_only_possible_value,
287 .empty_array,271 .empty_array,
288 .empty_struct_value,272 .empty_struct_value,
...@@ -300,20 +284,6 @@ pub const Value = struct {...@@ -300,20 +284,6 @@ pub const Value = struct {
300 .legacy = .{ .ptr_otherwise = &new_payload.base },284 .legacy = .{ .ptr_otherwise = &new_payload.base },
301 };285 };
302 },286 },
303 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),
304 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),
305 .int_big_positive, .int_big_negative => {
306 const old_payload = self.cast(Payload.BigInt).?;
307 const new_payload = try arena.create(Payload.BigInt);
308 new_payload.* = .{
309 .base = .{ .tag = self.legacy.ptr_otherwise.tag },
310 .data = try arena.dupe(std.math.big.Limb, old_payload.data),
311 };
312 return Value{
313 .ip_index = .none,
314 .legacy = .{ .ptr_otherwise = &new_payload.base },
315 };
316 },
317 .function => return self.copyPayloadShallow(arena, Payload.Function),287 .function => return self.copyPayloadShallow(arena, Payload.Function),
318 .extern_fn => return self.copyPayloadShallow(arena, Payload.ExternFn),288 .extern_fn => return self.copyPayloadShallow(arena, Payload.ExternFn),
319 .variable => return self.copyPayloadShallow(arena, Payload.Variable),289 .variable => return self.copyPayloadShallow(arena, Payload.Variable),
...@@ -525,8 +495,6 @@ pub const Value = struct {...@@ -525,8 +495,6 @@ pub const Value = struct {
525 .@"union" => {495 .@"union" => {
526 return out_stream.writeAll("(union value)");496 return out_stream.writeAll("(union value)");
527 },497 },
528 .zero => return out_stream.writeAll("0"),
529 .one => return out_stream.writeAll("1"),
530 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),498 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
531 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),499 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
532 .lazy_align => {500 .lazy_align => {
...@@ -539,10 +507,6 @@ pub const Value = struct {...@@ -539,10 +507,6 @@ pub const Value = struct {
539 try val.castTag(.lazy_size).?.data.dump("", options, out_stream);507 try val.castTag(.lazy_size).?.data.dump("", options, out_stream);
540 return try out_stream.writeAll(")");508 return try out_stream.writeAll(")");
541 },509 },
542 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, out_stream),
543 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),
544 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
545 .int_big_negative => return out_stream.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
546 .runtime_value => return out_stream.writeAll("[runtime value]"),510 .runtime_value => return out_stream.writeAll("[runtime value]"),
547 .function => return out_stream.print("(function decl={d})", .{val.castTag(.function).?.data.owner_decl}),511 .function => return out_stream.print("(function decl={d})", .{val.castTag(.function).?.data.owner_decl}),
548 .extern_fn => return out_stream.writeAll("(extern function)"),512 .extern_fn => return out_stream.writeAll("(extern function)"),
...@@ -661,9 +625,8 @@ pub const Value = struct {...@@ -661,9 +625,8 @@ pub const Value = struct {
661625
662 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, mod: *Module) ![]u8 {626 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, mod: *Module) ![]u8 {
663 const result = try allocator.alloc(u8, @intCast(usize, len));627 const result = try allocator.alloc(u8, @intCast(usize, len));
664 var elem_value_buf: ElemValueBuffer = undefined;
665 for (result, 0..) |*elem, i| {628 for (result, 0..) |*elem, i| {
666 const elem_val = val.elemValueBuffer(mod, i, &elem_value_buf);629 const elem_val = try val.elemValue(mod, i);
667 elem.* = @intCast(u8, elem_val.toUnsignedInt(mod));630 elem.* = @intCast(u8, elem_val.toUnsignedInt(mod));
668 }631 }
669 return result;632 return result;
...@@ -695,7 +658,7 @@ pub const Value = struct {...@@ -695,7 +658,7 @@ pub const Value = struct {
695 }658 }
696 }659 }
697660
698 pub fn enumToInt(val: Value, ty: Type, buffer: *Payload.U64) Value {661 pub fn enumToInt(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
699 const field_index = switch (val.tag()) {662 const field_index = switch (val.tag()) {
700 .enum_field_index => val.castTag(.enum_field_index).?.data,663 .enum_field_index => val.castTag(.enum_field_index).?.data,
701 .the_only_possible_value => blk: {664 .the_only_possible_value => blk: {
...@@ -717,11 +680,7 @@ pub const Value = struct {...@@ -717,11 +680,7 @@ pub const Value = struct {
717 return enum_full.values.keys()[field_index];680 return enum_full.values.keys()[field_index];
718 } else {681 } else {
719 // Field index and integer values are the same.682 // Field index and integer values are the same.
720 buffer.* = .{683 return mod.intValue(enum_full.tag_ty, field_index);
721 .base = .{ .tag = .int_u64 },
722 .data = field_index,
723 };
724 return Value.initPayload(&buffer.base);
725 }684 }
726 },685 },
727 .enum_numbered => {686 .enum_numbered => {
...@@ -730,20 +689,13 @@ pub const Value = struct {...@@ -730,20 +689,13 @@ pub const Value = struct {
730 return enum_obj.values.keys()[field_index];689 return enum_obj.values.keys()[field_index];
731 } else {690 } else {
732 // Field index and integer values are the same.691 // Field index and integer values are the same.
733 buffer.* = .{692 return mod.intValue(enum_obj.tag_ty, field_index);
734 .base = .{ .tag = .int_u64 },
735 .data = field_index,
736 };
737 return Value.initPayload(&buffer.base);
738 }693 }
739 },694 },
740 .enum_simple => {695 .enum_simple => {
741 // Field index and integer values are the same.696 // Field index and integer values are the same.
742 buffer.* = .{697 const tag_ty = ty.intTagType();
743 .base = .{ .tag = .int_u64 },698 return mod.intValue(tag_ty, field_index);
744 .data = field_index,
745 };
746 return Value.initPayload(&buffer.base);
747 },699 },
748 else => unreachable,700 else => unreachable,
749 }701 }
...@@ -802,12 +754,9 @@ pub const Value = struct {...@@ -802,12 +754,9 @@ pub const Value = struct {
802 .undef => unreachable,754 .undef => unreachable,
803 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),755 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),
804 .none => switch (val.tag()) {756 .none => switch (val.tag()) {
805 .zero,
806 .the_only_possible_value, // i0, u0757 .the_only_possible_value, // i0, u0
807 => BigIntMutable.init(&space.limbs, 0).toConst(),758 => BigIntMutable.init(&space.limbs, 0).toConst(),
808759
809 .one => BigIntMutable.init(&space.limbs, 1).toConst(),
810
811 .enum_field_index => {760 .enum_field_index => {
812 const index = val.castTag(.enum_field_index).?.data;761 const index = val.castTag(.enum_field_index).?.data;
813 return BigIntMutable.init(&space.limbs, index).toConst();762 return BigIntMutable.init(&space.limbs, index).toConst();
...@@ -816,11 +765,6 @@ pub const Value = struct {...@@ -816,11 +765,6 @@ pub const Value = struct {
816 const sub_val = val.castTag(.runtime_value).?.data;765 const sub_val = val.castTag(.runtime_value).?.data;
817 return sub_val.toBigIntAdvanced(space, mod, opt_sema);766 return sub_val.toBigIntAdvanced(space, mod, opt_sema);
818 },767 },
819 .int_u64 => BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
820 .int_i64 => BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
821 .int_big_positive => val.castTag(.int_big_positive).?.asBigInt(),
822 .int_big_negative => val.castTag(.int_big_negative).?.asBigInt(),
823
824 .lazy_align => {768 .lazy_align => {
825 const ty = val.castTag(.lazy_align).?.data;769 const ty = val.castTag(.lazy_align).?.data;
826 if (opt_sema) |sema| {770 if (opt_sema) |sema| {
...@@ -869,17 +813,9 @@ pub const Value = struct {...@@ -869,17 +813,9 @@ pub const Value = struct {
869 .bool_true => return 1,813 .bool_true => return 1,
870 .undef => unreachable,814 .undef => unreachable,
871 .none => switch (val.tag()) {815 .none => switch (val.tag()) {
872 .zero,
873 .the_only_possible_value, // i0, u0816 .the_only_possible_value, // i0, u0
874 => return 0,817 => return 0,
875818
876 .one => return 1,
877
878 .int_u64 => return val.castTag(.int_u64).?.data,
879 .int_i64 => return @intCast(u64, val.castTag(.int_i64).?.data),
880 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null,
881 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
882
883 .lazy_align => {819 .lazy_align => {
884 const ty = val.castTag(.lazy_align).?.data;820 const ty = val.castTag(.lazy_align).?.data;
885 if (opt_sema) |sema| {821 if (opt_sema) |sema| {
...@@ -922,17 +858,9 @@ pub const Value = struct {...@@ -922,17 +858,9 @@ pub const Value = struct {
922 .bool_true => return 1,858 .bool_true => return 1,
923 .undef => unreachable,859 .undef => unreachable,
924 .none => switch (val.tag()) {860 .none => switch (val.tag()) {
925 .zero,
926 .the_only_possible_value, // i0, u0861 .the_only_possible_value, // i0, u0
927 => return 0,862 => return 0,
928863
929 .one => return 1,
930
931 .int_u64 => return @intCast(i64, val.castTag(.int_u64).?.data),
932 .int_i64 => return val.castTag(.int_i64).?.data,
933 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
934 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
935
936 .lazy_align => {864 .lazy_align => {
937 const ty = val.castTag(.lazy_align).?.data;865 const ty = val.castTag(.lazy_align).?.data;
938 return @intCast(i64, ty.abiAlignment(mod));866 return @intCast(i64, ty.abiAlignment(mod));
...@@ -959,22 +887,7 @@ pub const Value = struct {...@@ -959,22 +887,7 @@ pub const Value = struct {
959 return switch (val.ip_index) {887 return switch (val.ip_index) {
960 .bool_true => true,888 .bool_true => true,
961 .bool_false => false,889 .bool_false => false,
962 .none => switch (val.tag()) {890 .none => unreachable,
963 .one => true,
964 .zero => false,
965
966 .int_u64 => switch (val.castTag(.int_u64).?.data) {
967 0 => false,
968 1 => true,
969 else => unreachable,
970 },
971 .int_i64 => switch (val.castTag(.int_i64).?.data) {
972 0 => false,
973 1 => true,
974 else => unreachable,
975 },
976 else => unreachable,
977 },
978 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {891 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
979 .int => |int| switch (int.storage) {892 .int => |int| switch (int.storage) {
980 .big_int => |big_int| !big_int.eqZero(),893 .big_int => |big_int| !big_int.eqZero(),
...@@ -1004,6 +917,7 @@ pub const Value = struct {...@@ -1004,6 +917,7 @@ pub const Value = struct {
1004 ReinterpretDeclRef,917 ReinterpretDeclRef,
1005 IllDefinedMemoryLayout,918 IllDefinedMemoryLayout,
1006 Unimplemented,919 Unimplemented,
920 OutOfMemory,
1007 }!void {921 }!void {
1008 const target = mod.getTarget();922 const target = mod.getTarget();
1009 const endian = target.cpu.arch.endian();923 const endian = target.cpu.arch.endian();
...@@ -1022,16 +936,14 @@ pub const Value = struct {...@@ -1022,16 +936,14 @@ pub const Value = struct {
1022 const bits = int_info.bits;936 const bits = int_info.bits;
1023 const byte_count = (bits + 7) / 8;937 const byte_count = (bits + 7) / 8;
1024938
1025 var enum_buffer: Payload.U64 = undefined;939 const int_val = try val.enumToInt(ty, mod);
1026 const int_val = val.enumToInt(ty, &enum_buffer);
1027940
1028 if (byte_count <= @sizeOf(u64)) {941 if (byte_count <= @sizeOf(u64)) {
1029 const int: u64 = switch (int_val.tag()) {942 const ip_key = mod.intern_pool.indexToKey(int_val.ip_index);
1030 .zero => 0,943 const int: u64 = switch (ip_key.int.storage) {
1031 .one => 1,944 .u64 => |x| x,
1032 .int_u64 => int_val.castTag(.int_u64).?.data,945 .i64 => |x| @bitCast(u64, x),
1033 .int_i64 => @bitCast(u64, int_val.castTag(.int_i64).?.data),946 .big_int => unreachable,
1034 else => unreachable,
1035 };947 };
1036 for (buffer[0..byte_count], 0..) |_, i| switch (endian) {948 for (buffer[0..byte_count], 0..) |_, i| switch (endian) {
1037 .Little => buffer[i] = @truncate(u8, (int >> @intCast(u6, (8 * i)))),949 .Little => buffer[i] = @truncate(u8, (int >> @intCast(u6, (8 * i)))),
...@@ -1044,11 +956,11 @@ pub const Value = struct {...@@ -1044,11 +956,11 @@ pub const Value = struct {
1044 }956 }
1045 },957 },
1046 .Float => switch (ty.floatBits(target)) {958 .Float => switch (ty.floatBits(target)) {
1047 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(u16, val.toFloat(f16)), endian),959 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(u16, val.toFloat(f16, mod)), endian),
1048 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(u32, val.toFloat(f32)), endian),960 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(u32, val.toFloat(f32, mod)), endian),
1049 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(u64, val.toFloat(f64)), endian),961 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(u64, val.toFloat(f64, mod)), endian),
1050 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(u80, val.toFloat(f80)), endian),962 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(u80, val.toFloat(f80, mod)), endian),
1051 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(u128, val.toFloat(f128)), endian),963 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(u128, val.toFloat(f128, mod)), endian),
1052 else => unreachable,964 else => unreachable,
1053 },965 },
1054 .Array => {966 .Array => {
...@@ -1056,10 +968,9 @@ pub const Value = struct {...@@ -1056,10 +968,9 @@ pub const Value = struct {
1056 const elem_ty = ty.childType(mod);968 const elem_ty = ty.childType(mod);
1057 const elem_size = @intCast(usize, elem_ty.abiSize(mod));969 const elem_size = @intCast(usize, elem_ty.abiSize(mod));
1058 var elem_i: usize = 0;970 var elem_i: usize = 0;
1059 var elem_value_buf: ElemValueBuffer = undefined;
1060 var buf_off: usize = 0;971 var buf_off: usize = 0;
1061 while (elem_i < len) : (elem_i += 1) {972 while (elem_i < len) : (elem_i += 1) {
1062 const elem_val = val.elemValueBuffer(mod, elem_i, &elem_value_buf);973 const elem_val = try val.elemValue(mod, elem_i);
1063 try elem_val.writeToMemory(elem_ty, mod, buffer[buf_off..]);974 try elem_val.writeToMemory(elem_ty, mod, buffer[buf_off..]);
1064 buf_off += elem_size;975 buf_off += elem_size;
1065 }976 }
...@@ -1122,7 +1033,13 @@ pub const Value = struct {...@@ -1122,7 +1033,13 @@ pub const Value = struct {
1122 ///1033 ///
1123 /// Both the start and the end of the provided buffer must be tight, since1034 /// Both the start and the end of the provided buffer must be tight, since
1124 /// big-endian packed memory layouts start at the end of the buffer.1035 /// big-endian packed memory layouts start at the end of the buffer.
1125 pub fn writeToPackedMemory(val: Value, ty: Type, mod: *Module, buffer: []u8, bit_offset: usize) error{ReinterpretDeclRef}!void {1036 pub fn writeToPackedMemory(
1037 val: Value,
1038 ty: Type,
1039 mod: *Module,
1040 buffer: []u8,
1041 bit_offset: usize,
1042 ) error{ ReinterpretDeclRef, OutOfMemory }!void {
1126 const target = mod.getTarget();1043 const target = mod.getTarget();
1127 const endian = target.cpu.arch.endian();1044 const endian = target.cpu.arch.endian();
1128 if (val.isUndef()) {1045 if (val.isUndef()) {
...@@ -1147,16 +1064,14 @@ pub const Value = struct {...@@ -1147,16 +1064,14 @@ pub const Value = struct {
1147 const bits = ty.intInfo(mod).bits;1064 const bits = ty.intInfo(mod).bits;
1148 const abi_size = @intCast(usize, ty.abiSize(mod));1065 const abi_size = @intCast(usize, ty.abiSize(mod));
11491066
1150 var enum_buffer: Payload.U64 = undefined;1067 const int_val = try val.enumToInt(ty, mod);
1151 const int_val = val.enumToInt(ty, &enum_buffer);
11521068
1153 if (abi_size == 0) return;1069 if (abi_size == 0) return;
1154 if (abi_size <= @sizeOf(u64)) {1070 if (abi_size <= @sizeOf(u64)) {
1155 const int: u64 = switch (int_val.tag()) {1071 const ip_key = mod.intern_pool.indexToKey(int_val.ip_index);
1156 .zero => 0,1072 const int: u64 = switch (ip_key.int.storage) {
1157 .one => 1,1073 .u64 => |x| x,
1158 .int_u64 => int_val.castTag(.int_u64).?.data,1074 .i64 => |x| @bitCast(u64, x),
1159 .int_i64 => @bitCast(u64, int_val.castTag(.int_i64).?.data),
1160 else => unreachable,1075 else => unreachable,
1161 };1076 };
1162 std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian);1077 std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian);
...@@ -1167,11 +1082,11 @@ pub const Value = struct {...@@ -1167,11 +1082,11 @@ pub const Value = struct {
1167 }1082 }
1168 },1083 },
1169 .Float => switch (ty.floatBits(target)) {1084 .Float => switch (ty.floatBits(target)) {
1170 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(u16, val.toFloat(f16)), endian),1085 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(u16, val.toFloat(f16, mod)), endian),
1171 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(u32, val.toFloat(f32)), endian),1086 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(u32, val.toFloat(f32, mod)), endian),
1172 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(u64, val.toFloat(f64)), endian),1087 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(u64, val.toFloat(f64, mod)), endian),
1173 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(u80, val.toFloat(f80)), endian),1088 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(u80, val.toFloat(f80, mod)), endian),
1174 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(u128, val.toFloat(f128)), endian),1089 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(u128, val.toFloat(f128, mod)), endian),
1175 else => unreachable,1090 else => unreachable,
1176 },1091 },
1177 .Vector => {1092 .Vector => {
...@@ -1181,11 +1096,10 @@ pub const Value = struct {...@@ -1181,11 +1096,10 @@ pub const Value = struct {
11811096
1182 var bits: u16 = 0;1097 var bits: u16 = 0;
1183 var elem_i: usize = 0;1098 var elem_i: usize = 0;
1184 var elem_value_buf: ElemValueBuffer = undefined;
1185 while (elem_i < len) : (elem_i += 1) {1099 while (elem_i < len) : (elem_i += 1) {
1186 // On big-endian systems, LLVM reverses the element order of vectors by default1100 // On big-endian systems, LLVM reverses the element order of vectors by default
1187 const tgt_elem_i = if (endian == .Big) len - elem_i - 1 else elem_i;1101 const tgt_elem_i = if (endian == .Big) len - elem_i - 1 else elem_i;
1188 const elem_val = val.elemValueBuffer(mod, tgt_elem_i, &elem_value_buf);1102 const elem_val = try val.elemValue(mod, tgt_elem_i);
1189 try elem_val.writeToPackedMemory(elem_ty, mod, buffer, bit_offset + bits);1103 try elem_val.writeToPackedMemory(elem_ty, mod, buffer, bit_offset + bits);
1190 bits += elem_bit_size;1104 bits += elem_bit_size;
1191 }1105 }
...@@ -1264,11 +1178,13 @@ pub const Value = struct {...@@ -1264,11 +1178,13 @@ pub const Value = struct {
1264 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u641178 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64
1265 .signed => {1179 .signed => {
1266 const val = std.mem.readVarInt(i64, buffer[0..byte_count], endian);1180 const val = std.mem.readVarInt(i64, buffer[0..byte_count], endian);
1267 return Value.Tag.int_i64.create(arena, (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits));1181 const result = (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits);
1182 return mod.intValue(ty, result);
1268 },1183 },
1269 .unsigned => {1184 .unsigned => {
1270 const val = std.mem.readVarInt(u64, buffer[0..byte_count], endian);1185 const val = std.mem.readVarInt(u64, buffer[0..byte_count], endian);
1271 return Value.Tag.int_u64.create(arena, (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits));1186 const result = (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits);
1187 return mod.intValue(ty, result);
1272 },1188 },
1273 } else { // Slow path, we have to construct a big-int1189 } else { // Slow path, we have to construct a big-int
1274 const Limb = std.math.big.Limb;1190 const Limb = std.math.big.Limb;
...@@ -1277,7 +1193,7 @@ pub const Value = struct {...@@ -1277,7 +1193,7 @@ pub const Value = struct {
12771193
1278 var bigint = BigIntMutable.init(limbs_buffer, 0);1194 var bigint = BigIntMutable.init(limbs_buffer, 0);
1279 bigint.readTwosComplement(buffer[0..byte_count], bits, endian, int_info.signedness);1195 bigint.readTwosComplement(buffer[0..byte_count], bits, endian, int_info.signedness);
1280 return fromBigInt(arena, bigint.toConst());1196 return mod.intValue_big(ty, bigint.toConst());
1281 }1197 }
1282 },1198 },
1283 .Float => switch (ty.floatBits(target)) {1199 .Float => switch (ty.floatBits(target)) {
...@@ -1381,8 +1297,8 @@ pub const Value = struct {...@@ -1381,8 +1297,8 @@ pub const Value = struct {
1381 const bits = int_info.bits;1297 const bits = int_info.bits;
1382 if (bits == 0) return Value.zero;1298 if (bits == 0) return Value.zero;
1383 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u641299 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64
1384 .signed => return Value.Tag.int_i64.create(arena, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),1300 .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)),
1385 .unsigned => return Value.Tag.int_u64.create(arena, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),1301 .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)),
1386 } else { // Slow path, we have to construct a big-int1302 } else { // Slow path, we have to construct a big-int
1387 const Limb = std.math.big.Limb;1303 const Limb = std.math.big.Limb;
1388 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);1304 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);
...@@ -1390,7 +1306,7 @@ pub const Value = struct {...@@ -1390,7 +1306,7 @@ pub const Value = struct {
13901306
1391 var bigint = BigIntMutable.init(limbs_buffer, 0);1307 var bigint = BigIntMutable.init(limbs_buffer, 0);
1392 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);1308 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);
1393 return fromBigInt(arena, bigint.toConst());1309 return mod.intValue_big(ty, bigint.toConst());
1394 }1310 }
1395 },1311 },
1396 .Float => switch (ty.floatBits(target)) {1312 .Float => switch (ty.floatBits(target)) {
...@@ -1444,32 +1360,29 @@ pub const Value = struct {...@@ -1444,32 +1360,29 @@ pub const Value = struct {
1444 }1360 }
14451361
1446 /// Asserts that the value is a float or an integer.1362 /// Asserts that the value is a float or an integer.
1447 pub fn toFloat(val: Value, comptime T: type) T {1363 pub fn toFloat(val: Value, comptime T: type, mod: *const Module) T {
1448 return switch (val.tag()) {1364 return switch (val.ip_index) {
1449 .float_16 => @floatCast(T, val.castTag(.float_16).?.data),1365 .none => switch (val.tag()) {
1450 .float_32 => @floatCast(T, val.castTag(.float_32).?.data),1366 .float_16 => @floatCast(T, val.castTag(.float_16).?.data),
1451 .float_64 => @floatCast(T, val.castTag(.float_64).?.data),1367 .float_32 => @floatCast(T, val.castTag(.float_32).?.data),
1452 .float_80 => @floatCast(T, val.castTag(.float_80).?.data),1368 .float_64 => @floatCast(T, val.castTag(.float_64).?.data),
1453 .float_128 => @floatCast(T, val.castTag(.float_128).?.data),1369 .float_80 => @floatCast(T, val.castTag(.float_80).?.data),
14541370 .float_128 => @floatCast(T, val.castTag(.float_128).?.data),
1455 .zero => 0,1371
1456 .one => 1,1372 else => unreachable,
1457 .int_u64 => {
1458 if (T == f80) {
1459 @panic("TODO we can't lower this properly on non-x86 llvm backend yet");
1460 }
1461 return @intToFloat(T, val.castTag(.int_u64).?.data);
1462 },1373 },
1463 .int_i64 => {1374 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1464 if (T == f80) {1375 .int => |int| switch (int.storage) {
1465 @panic("TODO we can't lower this properly on non-x86 llvm backend yet");1376 .big_int => |big_int| @floatCast(T, bigIntToFloat(big_int.limbs, big_int.positive)),
1466 }1377 inline .u64, .i64 => |x| {
1467 return @intToFloat(T, val.castTag(.int_i64).?.data);1378 if (T == f80) {
1379 @panic("TODO we can't lower this properly on non-x86 llvm backend yet");
1380 }
1381 return @intToFloat(T, x);
1382 },
1383 },
1384 else => unreachable,
1468 },1385 },
1469
1470 .int_big_positive => @floatCast(T, bigIntToFloat(val.castTag(.int_big_positive).?.data, true)),
1471 .int_big_negative => @floatCast(T, bigIntToFloat(val.castTag(.int_big_negative).?.data, false)),
1472 else => unreachable,
1473 };1386 };
1474 }1387 }
14751388
...@@ -1498,24 +1411,6 @@ pub const Value = struct {...@@ -1498,24 +1411,6 @@ pub const Value = struct {
1498 .bool_false => ty_bits,1411 .bool_false => ty_bits,
1499 .bool_true => ty_bits - 1,1412 .bool_true => ty_bits - 1,
1500 .none => switch (val.tag()) {1413 .none => switch (val.tag()) {
1501 .zero => ty_bits,
1502 .one => ty_bits - 1,
1503
1504 .int_u64 => {
1505 const big = @clz(val.castTag(.int_u64).?.data);
1506 return big + ty_bits - 64;
1507 },
1508 .int_i64 => {
1509 @panic("TODO implement i64 Value clz");
1510 },
1511 .int_big_positive => {
1512 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1513 return bigint.clz(ty_bits);
1514 },
1515 .int_big_negative => {
1516 @panic("TODO implement int_big_negative Value clz");
1517 },
1518
1519 .the_only_possible_value => {1414 .the_only_possible_value => {
1520 assert(ty_bits == 0);1415 assert(ty_bits == 0);
1521 return ty_bits;1416 return ty_bits;
...@@ -1546,24 +1441,6 @@ pub const Value = struct {...@@ -1546,24 +1441,6 @@ pub const Value = struct {
1546 .bool_false => ty_bits,1441 .bool_false => ty_bits,
1547 .bool_true => 0,1442 .bool_true => 0,
1548 .none => switch (val.tag()) {1443 .none => switch (val.tag()) {
1549 .zero => ty_bits,
1550 .one => 0,
1551
1552 .int_u64 => {
1553 const big = @ctz(val.castTag(.int_u64).?.data);
1554 return if (big == 64) ty_bits else big;
1555 },
1556 .int_i64 => {
1557 @panic("TODO implement i64 Value ctz");
1558 },
1559 .int_big_positive => {
1560 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1561 return bigint.ctz();
1562 },
1563 .int_big_negative => {
1564 @panic("TODO implement int_big_negative Value ctz");
1565 },
1566
1567 .the_only_possible_value => {1444 .the_only_possible_value => {
1568 assert(ty_bits == 0);1445 assert(ty_bits == 0);
1569 return ty_bits;1446 return ty_bits;
...@@ -1596,20 +1473,7 @@ pub const Value = struct {...@@ -1596,20 +1473,7 @@ pub const Value = struct {
1596 switch (val.ip_index) {1473 switch (val.ip_index) {
1597 .bool_false => return 0,1474 .bool_false => return 0,
1598 .bool_true => return 1,1475 .bool_true => return 1,
1599 .none => switch (val.tag()) {1476 .none => unreachable,
1600 .zero => return 0,
1601 .one => return 1,
1602
1603 .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
1604
1605 else => {
1606 const info = ty.intInfo(mod);
1607
1608 var buffer: Value.BigIntSpace = undefined;
1609 const int = val.toBigInt(&buffer, mod);
1610 return @intCast(u64, int.popCount(info.bits));
1611 },
1612 },
1613 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {1477 else => switch (mod.intern_pool.indexToKey(val.ip_index)) {
1614 .int => |int| {1478 .int => |int| {
1615 const info = ty.intInfo(mod);1479 const info = ty.intInfo(mod);
...@@ -1622,7 +1486,7 @@ pub const Value = struct {...@@ -1622,7 +1486,7 @@ pub const Value = struct {
1622 }1486 }
1623 }1487 }
16241488
1625 pub fn bitReverse(val: Value, ty: Type, mod: *const Module, arena: Allocator) !Value {1489 pub fn bitReverse(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
1626 assert(!val.isUndef());1490 assert(!val.isUndef());
16271491
1628 const info = ty.intInfo(mod);1492 const info = ty.intInfo(mod);
...@@ -1637,10 +1501,10 @@ pub const Value = struct {...@@ -1637,10 +1501,10 @@ pub const Value = struct {
1637 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1501 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1638 result_bigint.bitReverse(operand_bigint, info.signedness, info.bits);1502 result_bigint.bitReverse(operand_bigint, info.signedness, info.bits);
16391503
1640 return fromBigInt(arena, result_bigint.toConst());1504 return mod.intValue_big(ty, result_bigint.toConst());
1641 }1505 }
16421506
1643 pub fn byteSwap(val: Value, ty: Type, mod: *const Module, arena: Allocator) !Value {1507 pub fn byteSwap(val: Value, ty: Type, mod: *Module, arena: Allocator) !Value {
1644 assert(!val.isUndef());1508 assert(!val.isUndef());
16451509
1646 const info = ty.intInfo(mod);1510 const info = ty.intInfo(mod);
...@@ -1658,7 +1522,7 @@ pub const Value = struct {...@@ -1658,7 +1522,7 @@ pub const Value = struct {
1658 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };1522 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
1659 result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8);1523 result_bigint.byteSwap(operand_bigint, info.signedness, info.bits / 8);
16601524
1661 return fromBigInt(arena, result_bigint.toConst());1525 return mod.intValue_big(ty, result_bigint.toConst());
1662 }1526 }
16631527
1664 /// Asserts the value is an integer and not undefined.1528 /// Asserts the value is an integer and not undefined.
...@@ -1669,19 +1533,7 @@ pub const Value = struct {...@@ -1669,19 +1533,7 @@ pub const Value = struct {
1669 .bool_false => 0,1533 .bool_false => 0,
1670 .bool_true => 1,1534 .bool_true => 1,
1671 .none => switch (self.tag()) {1535 .none => switch (self.tag()) {
1672 .zero,1536 .the_only_possible_value => 0,
1673 .the_only_possible_value,
1674 => 0,
1675
1676 .one => 1,
1677
1678 .int_u64 => {
1679 const x = self.castTag(.int_u64).?.data;
1680 if (x == 0) return 0;
1681 return @intCast(usize, std.math.log2(x) + 1);
1682 },
1683 .int_big_positive => self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(),
1684 .int_big_negative => self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
16851537
1686 .decl_ref_mut,1538 .decl_ref_mut,
1687 .comptime_field_ptr,1539 .comptime_field_ptr,
...@@ -1715,13 +1567,14 @@ pub const Value = struct {...@@ -1715,13 +1567,14 @@ pub const Value = struct {
17151567
1716 /// Converts an integer or a float to a float. May result in a loss of information.1568 /// Converts an integer or a float to a float. May result in a loss of information.
1717 /// Caller can find out by equality checking the result against the operand.1569 /// Caller can find out by equality checking the result against the operand.
1718 pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type, target: Target) !Value {1570 pub fn floatCast(self: Value, arena: Allocator, dest_ty: Type, mod: *const Module) !Value {
1571 const target = mod.getTarget();
1719 switch (dest_ty.floatBits(target)) {1572 switch (dest_ty.floatBits(target)) {
1720 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16)),1573 16 => return Value.Tag.float_16.create(arena, self.toFloat(f16, mod)),
1721 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32)),1574 32 => return Value.Tag.float_32.create(arena, self.toFloat(f32, mod)),
1722 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64)),1575 64 => return Value.Tag.float_64.create(arena, self.toFloat(f64, mod)),
1723 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80)),1576 80 => return Value.Tag.float_80.create(arena, self.toFloat(f80, mod)),
1724 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128)),1577 128 => return Value.Tag.float_128.create(arena, self.toFloat(f128, mod)),
1725 else => unreachable,1578 else => unreachable,
1726 }1579 }
1727 }1580 }
...@@ -1729,10 +1582,6 @@ pub const Value = struct {...@@ -1729,10 +1582,6 @@ pub const Value = struct {
1729 /// Asserts the value is a float1582 /// Asserts the value is a float
1730 pub fn floatHasFraction(self: Value) bool {1583 pub fn floatHasFraction(self: Value) bool {
1731 return switch (self.tag()) {1584 return switch (self.tag()) {
1732 .zero,
1733 .one,
1734 => false,
1735
1736 .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0,1585 .float_16 => @rem(self.castTag(.float_16).?.data, 1) != 0,
1737 .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0,1586 .float_32 => @rem(self.castTag(.float_32).?.data, 1) != 0,
1738 .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0,1587 .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0,
...@@ -1757,11 +1606,8 @@ pub const Value = struct {...@@ -1757,11 +1606,8 @@ pub const Value = struct {
1757 .bool_false => return .eq,1606 .bool_false => return .eq,
1758 .bool_true => return .gt,1607 .bool_true => return .gt,
1759 .none => return switch (lhs.tag()) {1608 .none => return switch (lhs.tag()) {
1760 .zero,1609 .the_only_possible_value => .eq,
1761 .the_only_possible_value,
1762 => .eq,
17631610
1764 .one,
1765 .decl_ref,1611 .decl_ref,
1766 .decl_ref_mut,1612 .decl_ref_mut,
1767 .comptime_field_ptr,1613 .comptime_field_ptr,
...@@ -1777,10 +1623,6 @@ pub const Value = struct {...@@ -1777,10 +1623,6 @@ pub const Value = struct {
1777 const val = lhs.castTag(.runtime_value).?.data;1623 const val = lhs.castTag(.runtime_value).?.data;
1778 return val.orderAgainstZeroAdvanced(mod, opt_sema);1624 return val.orderAgainstZeroAdvanced(mod, opt_sema);
1779 },1625 },
1780 .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
1781 .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
1782 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
1783 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
17841626
1785 .lazy_align => {1627 .lazy_align => {
1786 const ty = lhs.castTag(.lazy_align).?.data;1628 const ty = lhs.castTag(.lazy_align).?.data;
...@@ -1878,8 +1720,8 @@ pub const Value = struct {...@@ -1878,8 +1720,8 @@ pub const Value = struct {
1878 }1720 }
1879 }1721 }
1880 if (lhs_float or rhs_float) {1722 if (lhs_float or rhs_float) {
1881 const lhs_f128 = lhs.toFloat(f128);1723 const lhs_f128 = lhs.toFloat(f128, mod);
1882 const rhs_f128 = rhs.toFloat(f128);1724 const rhs_f128 = rhs.toFloat(f128, mod);
1883 return std.math.order(lhs_f128, rhs_f128);1725 return std.math.order(lhs_f128, rhs_f128);
1884 }1726 }
18851727
...@@ -1929,15 +1771,13 @@ pub const Value = struct {...@@ -1929,15 +1771,13 @@ pub const Value = struct {
19291771
1930 /// Asserts the values are comparable. Both operands have type `ty`.1772 /// Asserts the values are comparable. Both operands have type `ty`.
1931 /// For vectors, returns true if comparison is true for ALL elements.1773 /// For vectors, returns true if comparison is true for ALL elements.
1932 pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool {1774 pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) !bool {
1933 if (ty.zigTypeTag(mod) == .Vector) {1775 if (ty.zigTypeTag(mod) == .Vector) {
1934 var i: usize = 0;1776 const scalar_ty = ty.scalarType(mod);
1935 while (i < ty.vectorLen(mod)) : (i += 1) {1777 for (0..ty.vectorLen(mod)) |i| {
1936 var lhs_buf: Value.ElemValueBuffer = undefined;1778 const lhs_elem = try lhs.elemValue(mod, i);
1937 var rhs_buf: Value.ElemValueBuffer = undefined;1779 const rhs_elem = try rhs.elemValue(mod, i);
1938 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);1780 if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, mod)) {
1939 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
1940 if (!compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod), mod)) {
1941 return false;1781 return false;
1942 }1782 }
1943 }1783 }
...@@ -2203,10 +2043,8 @@ pub const Value = struct {...@@ -2203,10 +2043,8 @@ pub const Value = struct {
2203 return a_type.eql(b_type, mod);2043 return a_type.eql(b_type, mod);
2204 },2044 },
2205 .Enum => {2045 .Enum => {
2206 var buf_a: Payload.U64 = undefined;2046 const a_val = try a.enumToInt(ty, mod);
2207 var buf_b: Payload.U64 = undefined;2047 const b_val = try b.enumToInt(ty, mod);
2208 const a_val = a.enumToInt(ty, &buf_a);
2209 const b_val = b.enumToInt(ty, &buf_b);
2210 const int_ty = ty.intTagType();2048 const int_ty = ty.intTagType();
2211 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);2049 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);
2212 },2050 },
...@@ -2214,11 +2052,9 @@ pub const Value = struct {...@@ -2214,11 +2052,9 @@ pub const Value = struct {
2214 const len = ty.arrayLen(mod);2052 const len = ty.arrayLen(mod);
2215 const elem_ty = ty.childType(mod);2053 const elem_ty = ty.childType(mod);
2216 var i: usize = 0;2054 var i: usize = 0;
2217 var a_buf: ElemValueBuffer = undefined;
2218 var b_buf: ElemValueBuffer = undefined;
2219 while (i < len) : (i += 1) {2055 while (i < len) : (i += 1) {
2220 const a_elem = elemValueBuffer(a, mod, i, &a_buf);2056 const a_elem = try elemValue(a, mod, i);
2221 const b_elem = elemValueBuffer(b, mod, i, &b_buf);2057 const b_elem = try elemValue(b, mod, i);
2222 if (!(try eqlAdvanced(a_elem, elem_ty, b_elem, elem_ty, mod, opt_sema))) {2058 if (!(try eqlAdvanced(a_elem, elem_ty, b_elem, elem_ty, mod, opt_sema))) {
2223 return false;2059 return false;
2224 }2060 }
...@@ -2282,17 +2118,17 @@ pub const Value = struct {...@@ -2282,17 +2118,17 @@ pub const Value = struct {
2282 },2118 },
2283 .Float => {2119 .Float => {
2284 switch (ty.floatBits(target)) {2120 switch (ty.floatBits(target)) {
2285 16 => return @bitCast(u16, a.toFloat(f16)) == @bitCast(u16, b.toFloat(f16)),2121 16 => return @bitCast(u16, a.toFloat(f16, mod)) == @bitCast(u16, b.toFloat(f16, mod)),
2286 32 => return @bitCast(u32, a.toFloat(f32)) == @bitCast(u32, b.toFloat(f32)),2122 32 => return @bitCast(u32, a.toFloat(f32, mod)) == @bitCast(u32, b.toFloat(f32, mod)),
2287 64 => return @bitCast(u64, a.toFloat(f64)) == @bitCast(u64, b.toFloat(f64)),2123 64 => return @bitCast(u64, a.toFloat(f64, mod)) == @bitCast(u64, b.toFloat(f64, mod)),
2288 80 => return @bitCast(u80, a.toFloat(f80)) == @bitCast(u80, b.toFloat(f80)),2124 80 => return @bitCast(u80, a.toFloat(f80, mod)) == @bitCast(u80, b.toFloat(f80, mod)),
2289 128 => return @bitCast(u128, a.toFloat(f128)) == @bitCast(u128, b.toFloat(f128)),2125 128 => return @bitCast(u128, a.toFloat(f128, mod)) == @bitCast(u128, b.toFloat(f128, mod)),
2290 else => unreachable,2126 else => unreachable,
2291 }2127 }
2292 },2128 },
2293 .ComptimeFloat => {2129 .ComptimeFloat => {
2294 const a_float = a.toFloat(f128);2130 const a_float = a.toFloat(f128, mod);
2295 const b_float = b.toFloat(f128);2131 const b_float = b.toFloat(f128, mod);
22962132
2297 const a_nan = std.math.isNan(a_float);2133 const a_nan = std.math.isNan(a_float);
2298 const b_nan = std.math.isNan(b_float);2134 const b_nan = std.math.isNan(b_float);
...@@ -2354,16 +2190,16 @@ pub const Value = struct {...@@ -2354,16 +2190,16 @@ pub const Value = struct {
2354 .Float => {2190 .Float => {
2355 // For hash/eql purposes, we treat floats as their IEEE integer representation.2191 // For hash/eql purposes, we treat floats as their IEEE integer representation.
2356 switch (ty.floatBits(mod.getTarget())) {2192 switch (ty.floatBits(mod.getTarget())) {
2357 16 => std.hash.autoHash(hasher, @bitCast(u16, val.toFloat(f16))),2193 16 => std.hash.autoHash(hasher, @bitCast(u16, val.toFloat(f16, mod))),
2358 32 => std.hash.autoHash(hasher, @bitCast(u32, val.toFloat(f32))),2194 32 => std.hash.autoHash(hasher, @bitCast(u32, val.toFloat(f32, mod))),
2359 64 => std.hash.autoHash(hasher, @bitCast(u64, val.toFloat(f64))),2195 64 => std.hash.autoHash(hasher, @bitCast(u64, val.toFloat(f64, mod))),
2360 80 => std.hash.autoHash(hasher, @bitCast(u80, val.toFloat(f80))),2196 80 => std.hash.autoHash(hasher, @bitCast(u80, val.toFloat(f80, mod))),
2361 128 => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128))),2197 128 => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128, mod))),
2362 else => unreachable,2198 else => unreachable,
2363 }2199 }
2364 },2200 },
2365 .ComptimeFloat => {2201 .ComptimeFloat => {
2366 const float = val.toFloat(f128);2202 const float = val.toFloat(f128, mod);
2367 const is_nan = std.math.isNan(float);2203 const is_nan = std.math.isNan(float);
2368 std.hash.autoHash(hasher, is_nan);2204 std.hash.autoHash(hasher, is_nan);
2369 if (!is_nan) {2205 if (!is_nan) {
...@@ -2387,9 +2223,11 @@ pub const Value = struct {...@@ -2387,9 +2223,11 @@ pub const Value = struct {
2387 const len = ty.arrayLen(mod);2223 const len = ty.arrayLen(mod);
2388 const elem_ty = ty.childType(mod);2224 const elem_ty = ty.childType(mod);
2389 var index: usize = 0;2225 var index: usize = 0;
2390 var elem_value_buf: ElemValueBuffer = undefined;
2391 while (index < len) : (index += 1) {2226 while (index < len) : (index += 1) {
2392 const elem_val = val.elemValueBuffer(mod, index, &elem_value_buf);2227 const elem_val = val.elemValue(mod, index) catch |err| switch (err) {
2228 // Will be solved when arrays and vectors get migrated to the intern pool.
2229 error.OutOfMemory => @panic("OOM"),
2230 };
2393 elem_val.hash(elem_ty, hasher, mod);2231 elem_val.hash(elem_ty, hasher, mod);
2394 }2232 }
2395 },2233 },
...@@ -2438,8 +2276,8 @@ pub const Value = struct {...@@ -2438,8 +2276,8 @@ pub const Value = struct {
2438 hasher.update(val.getError().?);2276 hasher.update(val.getError().?);
2439 },2277 },
2440 .Enum => {2278 .Enum => {
2441 var enum_space: Payload.U64 = undefined;2279 // This panic will go away when enum values move to be stored in the intern pool.
2442 const int_val = val.enumToInt(ty, &enum_space);2280 const int_val = val.enumToInt(ty, mod) catch @panic("OOM");
2443 hashInt(int_val, hasher, mod);2281 hashInt(int_val, hasher, mod);
2444 },2282 },
2445 .Union => {2283 .Union => {
...@@ -2494,7 +2332,7 @@ pub const Value = struct {...@@ -2494,7 +2332,7 @@ pub const Value = struct {
2494 .Type => {2332 .Type => {
2495 val.toType().hashWithHasher(hasher, mod);2333 val.toType().hashWithHasher(hasher, mod);
2496 },2334 },
2497 .Float, .ComptimeFloat => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128))),2335 .Float, .ComptimeFloat => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128, mod))),
2498 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {2336 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {
2499 .slice => {2337 .slice => {
2500 const slice = val.castTag(.slice).?.data;2338 const slice = val.castTag(.slice).?.data;
...@@ -2508,9 +2346,11 @@ pub const Value = struct {...@@ -2508,9 +2346,11 @@ pub const Value = struct {
2508 const len = ty.arrayLen(mod);2346 const len = ty.arrayLen(mod);
2509 const elem_ty = ty.childType(mod);2347 const elem_ty = ty.childType(mod);
2510 var index: usize = 0;2348 var index: usize = 0;
2511 var elem_value_buf: ElemValueBuffer = undefined;
2512 while (index < len) : (index += 1) {2349 while (index < len) : (index += 1) {
2513 const elem_val = val.elemValueBuffer(mod, index, &elem_value_buf);2350 const elem_val = val.elemValue(mod, index) catch |err| switch (err) {
2351 // Will be solved when arrays and vectors get migrated to the intern pool.
2352 error.OutOfMemory => @panic("OOM"),
2353 };
2514 elem_val.hashUncoerced(elem_ty, hasher, mod);2354 elem_val.hashUncoerced(elem_ty, hasher, mod);
2515 }2355 }
2516 },2356 },
...@@ -2661,12 +2501,6 @@ pub const Value = struct {...@@ -2661,12 +2501,6 @@ pub const Value = struct {
2661 hashPtr(opt_ptr.container_ptr, hasher, mod);2501 hashPtr(opt_ptr.container_ptr, hasher, mod);
2662 },2502 },
26632503
2664 .zero,
2665 .one,
2666 .int_u64,
2667 .int_i64,
2668 .int_big_positive,
2669 .int_big_negative,
2670 .the_only_possible_value,2504 .the_only_possible_value,
2671 .lazy_align,2505 .lazy_align,
2672 .lazy_size,2506 .lazy_size,
...@@ -2720,23 +2554,7 @@ pub const Value = struct {...@@ -2720,23 +2554,7 @@ pub const Value = struct {
27202554
2721 /// Asserts the value is a single-item pointer to an array, or an array,2555 /// Asserts the value is a single-item pointer to an array, or an array,
2722 /// or an unknown-length pointer, and returns the element value at the index.2556 /// or an unknown-length pointer, and returns the element value at the index.
2723 pub fn elemValue(val: Value, mod: *Module, arena: Allocator, index: usize) !Value {2557 pub fn elemValue(val: Value, mod: *Module, index: usize) Allocator.Error!Value {
2724 return elemValueAdvanced(val, mod, index, arena, undefined);
2725 }
2726
2727 pub const ElemValueBuffer = Payload.U64;
2728
2729 pub fn elemValueBuffer(val: Value, mod: *Module, index: usize, buffer: *ElemValueBuffer) Value {
2730 return elemValueAdvanced(val, mod, index, null, buffer) catch unreachable;
2731 }
2732
2733 pub fn elemValueAdvanced(
2734 val: Value,
2735 mod: *Module,
2736 index: usize,
2737 arena: ?Allocator,
2738 buffer: *ElemValueBuffer,
2739 ) error{OutOfMemory}!Value {
2740 switch (val.ip_index) {2558 switch (val.ip_index) {
2741 .undef => return Value.undef,2559 .undef => return Value.undef,
2742 .none => switch (val.tag()) {2560 .none => switch (val.tag()) {
...@@ -2751,43 +2569,27 @@ pub const Value = struct {...@@ -2751,43 +2569,27 @@ pub const Value = struct {
27512569
2752 .bytes => {2570 .bytes => {
2753 const byte = val.castTag(.bytes).?.data[index];2571 const byte = val.castTag(.bytes).?.data[index];
2754 if (arena) |a| {2572 return mod.intValue(Type.u8, byte);
2755 return Tag.int_u64.create(a, byte);
2756 } else {
2757 buffer.* = .{
2758 .base = .{ .tag = .int_u64 },
2759 .data = byte,
2760 };
2761 return initPayload(&buffer.base);
2762 }
2763 },2573 },
2764 .str_lit => {2574 .str_lit => {
2765 const str_lit = val.castTag(.str_lit).?.data;2575 const str_lit = val.castTag(.str_lit).?.data;
2766 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];2576 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
2767 const byte = bytes[index];2577 const byte = bytes[index];
2768 if (arena) |a| {2578 return mod.intValue(Type.u8, byte);
2769 return Tag.int_u64.create(a, byte);
2770 } else {
2771 buffer.* = .{
2772 .base = .{ .tag = .int_u64 },
2773 .data = byte,
2774 };
2775 return initPayload(&buffer.base);
2776 }
2777 },2579 },
27782580
2779 // No matter the index; all the elements are the same!2581 // No matter the index; all the elements are the same!
2780 .repeated => return val.castTag(.repeated).?.data,2582 .repeated => return val.castTag(.repeated).?.data,
27812583
2782 .aggregate => return val.castTag(.aggregate).?.data[index],2584 .aggregate => return val.castTag(.aggregate).?.data[index],
2783 .slice => return val.castTag(.slice).?.data.ptr.elemValueAdvanced(mod, index, arena, buffer),2585 .slice => return val.castTag(.slice).?.data.ptr.elemValue(mod, index),
27842586
2785 .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer),2587 .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValue(mod, index),
2786 .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer),2588 .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValue(mod, index),
2787 .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValueAdvanced(mod, index, arena, buffer),2589 .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValue(mod, index),
2788 .elem_ptr => {2590 .elem_ptr => {
2789 const data = val.castTag(.elem_ptr).?.data;2591 const data = val.castTag(.elem_ptr).?.data;
2790 return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer);2592 return data.array_ptr.elemValue(mod, index + data.index);
2791 },2593 },
2792 .field_ptr => {2594 .field_ptr => {
2793 const data = val.castTag(.field_ptr).?.data;2595 const data = val.castTag(.field_ptr).?.data;
...@@ -2795,7 +2597,7 @@ pub const Value = struct {...@@ -2795,7 +2597,7 @@ pub const Value = struct {
2795 const container_decl = mod.declPtr(decl_index);2597 const container_decl = mod.declPtr(decl_index);
2796 const field_type = data.container_ty.structFieldType(data.field_index);2598 const field_type = data.container_ty.structFieldType(data.field_index);
2797 const field_val = container_decl.val.fieldValue(field_type, mod, data.field_index);2599 const field_val = container_decl.val.fieldValue(field_type, mod, data.field_index);
2798 return field_val.elemValueAdvanced(mod, index, arena, buffer);2600 return field_val.elemValue(mod, index);
2799 } else unreachable;2601 } else unreachable;
2800 },2602 },
28012603
...@@ -2803,11 +2605,11 @@ pub const Value = struct {...@@ -2803,11 +2605,11 @@ pub const Value = struct {
2803 // to have only one possible value itself.2605 // to have only one possible value itself.
2804 .the_only_possible_value => return val,2606 .the_only_possible_value => return val,
28052607
2806 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.elemValueAdvanced(mod, index, arena, buffer),2608 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.elemValue(mod, index),
2807 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.elemValueAdvanced(mod, index, arena, buffer),2609 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.elemValue(mod, index),
28082610
2809 .opt_payload => return val.castTag(.opt_payload).?.data.elemValueAdvanced(mod, index, arena, buffer),2611 .opt_payload => return val.castTag(.opt_payload).?.data.elemValue(mod, index),
2810 .eu_payload => return val.castTag(.eu_payload).?.data.elemValueAdvanced(mod, index, arena, buffer),2612 .eu_payload => return val.castTag(.eu_payload).?.data.elemValue(mod, index),
28112613
2812 else => unreachable,2614 else => unreachable,
2813 },2615 },
...@@ -3004,7 +2806,7 @@ pub const Value = struct {...@@ -3004,7 +2806,7 @@ pub const Value = struct {
3004 /// TODO: check for cases such as array that is not marked undef but all the element2806 /// TODO: check for cases such as array that is not marked undef but all the element
3005 /// values are marked undef, or struct that is not marked undef but all fields are marked2807 /// values are marked undef, or struct that is not marked undef but all fields are marked
3006 /// undef, etc.2808 /// undef, etc.
3007 pub fn anyUndef(self: Value, mod: *Module) bool {2809 pub fn anyUndef(self: Value, mod: *Module) !bool {
3008 switch (self.ip_index) {2810 switch (self.ip_index) {
3009 .undef => return true,2811 .undef => return true,
3010 .none => switch (self.tag()) {2812 .none => switch (self.tag()) {
...@@ -3012,18 +2814,16 @@ pub const Value = struct {...@@ -3012,18 +2814,16 @@ pub const Value = struct {
3012 const payload = self.castTag(.slice).?;2814 const payload = self.castTag(.slice).?;
3013 const len = payload.data.len.toUnsignedInt(mod);2815 const len = payload.data.len.toUnsignedInt(mod);
30142816
3015 var elem_value_buf: ElemValueBuffer = undefined;2817 for (0..len) |i| {
3016 var i: usize = 0;2818 const elem_val = try payload.data.ptr.elemValue(mod, i);
3017 while (i < len) : (i += 1) {2819 if (try elem_val.anyUndef(mod)) return true;
3018 const elem_val = payload.data.ptr.elemValueBuffer(mod, i, &elem_value_buf);
3019 if (elem_val.anyUndef(mod)) return true;
3020 }2820 }
3021 },2821 },
30222822
3023 .aggregate => {2823 .aggregate => {
3024 const payload = self.castTag(.aggregate).?;2824 const payload = self.castTag(.aggregate).?;
3025 for (payload.data) |val| {2825 for (payload.data) |val| {
3026 if (val.anyUndef(mod)) return true;2826 if (try val.anyUndef(mod)) return true;
3027 }2827 }
3028 },2828 },
3029 else => {},2829 else => {},
...@@ -3036,35 +2836,37 @@ pub const Value = struct {...@@ -3036,35 +2836,37 @@ pub const Value = struct {
30362836
3037 /// Asserts the value is not undefined and not unreachable.2837 /// Asserts the value is not undefined and not unreachable.
3038 /// Integer value 0 is considered null because of C pointers.2838 /// Integer value 0 is considered null because of C pointers.
3039 pub fn isNull(self: Value, mod: *const Module) bool {2839 pub fn isNull(val: Value, mod: *const Module) bool {
3040 return switch (self.ip_index) {2840 return switch (val.ip_index) {
3041 .undef => unreachable,2841 .undef => unreachable,
3042 .unreachable_value => unreachable,2842 .unreachable_value => unreachable,
3043 .null_value => true,2843
3044 .none => switch (self.tag()) {2844 .null_value,
2845 .zero,
2846 .zero_usize,
2847 .zero_u8,
2848 => true,
2849
2850 .none => switch (val.tag()) {
3045 .opt_payload => false,2851 .opt_payload => false,
30462852
3047 // If it's not one of those two tags then it must be a C pointer value,2853 // If it's not one of those two tags then it must be a C pointer value,
3048 // in which case the value 0 is null and other values are non-null.2854 // in which case the value 0 is null and other values are non-null.
30492855
3050 .zero,2856 .the_only_possible_value => true,
3051 .the_only_possible_value,
3052 => true,
3053
3054 .one => false,
3055
3056 .int_u64,
3057 .int_i64,
3058 .int_big_positive,
3059 .int_big_negative,
3060 => self.orderAgainstZero(mod).compare(.eq),
30612857
3062 .inferred_alloc => unreachable,2858 .inferred_alloc => unreachable,
3063 .inferred_alloc_comptime => unreachable,2859 .inferred_alloc_comptime => unreachable,
30642860
3065 else => false,2861 else => false,
3066 },2862 },
3067 else => false,2863 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
2864 .int => |int| switch (int.storage) {
2865 .big_int => |big_int| big_int.eqZero(),
2866 inline .u64, .i64 => |x| x == 0,
2867 },
2868 else => unreachable,
2869 },
3068 };2870 };
3069 }2871 }
30702872
...@@ -3078,17 +2880,13 @@ pub const Value = struct {...@@ -3078,17 +2880,13 @@ pub const Value = struct {
3078 .unreachable_value => unreachable,2880 .unreachable_value => unreachable,
3079 .none => switch (self.tag()) {2881 .none => switch (self.tag()) {
3080 .@"error" => self.castTag(.@"error").?.data.name,2882 .@"error" => self.castTag(.@"error").?.data.name,
3081 .int_u64 => @panic("TODO"),2883 .eu_payload => null,
3082 .int_i64 => @panic("TODO"),2884
3083 .int_big_positive => @panic("TODO"),
3084 .int_big_negative => @panic("TODO"),
3085 .one => @panic("TODO"),
3086 .inferred_alloc => unreachable,2885 .inferred_alloc => unreachable,
3087 .inferred_alloc_comptime => unreachable,2886 .inferred_alloc_comptime => unreachable,
30882887 else => unreachable,
3089 else => null,
3090 },2888 },
3091 else => null,2889 else => unreachable,
3092 };2890 };
3093 }2891 }
30942892
...@@ -3147,10 +2945,10 @@ pub const Value = struct {...@@ -3147,10 +2945,10 @@ pub const Value = struct {
3147 pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {2945 pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {
3148 if (int_ty.zigTypeTag(mod) == .Vector) {2946 if (int_ty.zigTypeTag(mod) == .Vector) {
3149 const result_data = try arena.alloc(Value, int_ty.vectorLen(mod));2947 const result_data = try arena.alloc(Value, int_ty.vectorLen(mod));
2948 const scalar_ty = float_ty.scalarType(mod);
3150 for (result_data, 0..) |*scalar, i| {2949 for (result_data, 0..) |*scalar, i| {
3151 var buf: Value.ElemValueBuffer = undefined;2950 const elem_val = try val.elemValue(mod, i);
3152 const elem_val = val.elemValueBuffer(mod, i, &buf);2951 scalar.* = try intToFloatScalar(elem_val, arena, scalar_ty, mod, opt_sema);
3153 scalar.* = try intToFloatScalar(elem_val, arena, float_ty.scalarType(mod), mod, opt_sema);
3154 }2952 }
3155 return Value.Tag.aggregate.create(arena, result_data);2953 return Value.Tag.aggregate.create(arena, result_data);
3156 }2954 }
...@@ -3162,24 +2960,7 @@ pub const Value = struct {...@@ -3162,24 +2960,7 @@ pub const Value = struct {
3162 switch (val.ip_index) {2960 switch (val.ip_index) {
3163 .undef => return val,2961 .undef => return val,
3164 .none => switch (val.tag()) {2962 .none => switch (val.tag()) {
3165 .zero, .one => return val,2963 .the_only_possible_value => return Value.zero, // for i0, u0
3166 .the_only_possible_value => return Value.initTag(.zero), // for i0, u0
3167 .int_u64 => {
3168 return intToFloatInner(val.castTag(.int_u64).?.data, arena, float_ty, target);
3169 },
3170 .int_i64 => {
3171 return intToFloatInner(val.castTag(.int_i64).?.data, arena, float_ty, target);
3172 },
3173 .int_big_positive => {
3174 const limbs = val.castTag(.int_big_positive).?.data;
3175 const float = bigIntToFloat(limbs, true);
3176 return floatToValue(float, arena, float_ty, target);
3177 },
3178 .int_big_negative => {
3179 const limbs = val.castTag(.int_big_negative).?.data;
3180 const float = bigIntToFloat(limbs, false);
3181 return floatToValue(float, arena, float_ty, target);
3182 },
3183 .lazy_align => {2964 .lazy_align => {
3184 const ty = val.castTag(.lazy_align).?.data;2965 const ty = val.castTag(.lazy_align).?.data;
3185 if (opt_sema) |sema| {2966 if (opt_sema) |sema| {
...@@ -3198,7 +2979,16 @@ pub const Value = struct {...@@ -3198,7 +2979,16 @@ pub const Value = struct {
3198 },2979 },
3199 else => unreachable,2980 else => unreachable,
3200 },2981 },
3201 else => unreachable,2982 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
2983 .int => |int| switch (int.storage) {
2984 .big_int => |big_int| {
2985 const float = bigIntToFloat(big_int.limbs, big_int.positive);
2986 return floatToValue(float, arena, float_ty, target);
2987 },
2988 inline .u64, .i64 => |x| intToFloatInner(x, arena, float_ty, target),
2989 },
2990 else => unreachable,
2991 },
3202 }2992 }
3203 }2993 }
32042994
...@@ -3238,22 +3028,6 @@ pub const Value = struct {...@@ -3238,22 +3028,6 @@ pub const Value = struct {
3238 wrapped_result: Value,3028 wrapped_result: Value,
3239 };3029 };
32403030
3241 pub fn fromBigInt(arena: Allocator, big_int: BigIntConst) !Value {
3242 if (big_int.positive) {
3243 if (big_int.to(u64)) |x| {
3244 return Value.Tag.int_u64.create(arena, x);
3245 } else |_| {
3246 return Value.Tag.int_big_positive.create(arena, big_int.limbs);
3247 }
3248 } else {
3249 if (big_int.to(i64)) |x| {
3250 return Value.Tag.int_i64.create(arena, x);
3251 } else |_| {
3252 return Value.Tag.int_big_negative.create(arena, big_int.limbs);
3253 }
3254 }
3255 }
3256
3257 /// Supports (vectors of) integers only; asserts neither operand is undefined.3031 /// Supports (vectors of) integers only; asserts neither operand is undefined.
3258 pub fn intAddSat(3032 pub fn intAddSat(
3259 lhs: Value,3033 lhs: Value,
...@@ -3264,12 +3038,11 @@ pub const Value = struct {...@@ -3264,12 +3038,11 @@ pub const Value = struct {
3264 ) !Value {3038 ) !Value {
3265 if (ty.zigTypeTag(mod) == .Vector) {3039 if (ty.zigTypeTag(mod) == .Vector) {
3266 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3040 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3041 const scalar_ty = ty.scalarType(mod);
3267 for (result_data, 0..) |*scalar, i| {3042 for (result_data, 0..) |*scalar, i| {
3268 var lhs_buf: Value.ElemValueBuffer = undefined;3043 const lhs_elem = try lhs.elemValue(mod, i);
3269 var rhs_buf: Value.ElemValueBuffer = undefined;3044 const rhs_elem = try rhs.elemValue(mod, i);
3270 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3045 scalar.* = try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);
3271 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3272 scalar.* = try intAddSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
3273 }3046 }
3274 return Value.Tag.aggregate.create(arena, result_data);3047 return Value.Tag.aggregate.create(arena, result_data);
3275 }3048 }
...@@ -3299,7 +3072,7 @@ pub const Value = struct {...@@ -3299,7 +3072,7 @@ pub const Value = struct {
3299 );3072 );
3300 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3073 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
3301 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);3074 result_bigint.addSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
3302 return fromBigInt(arena, result_bigint.toConst());3075 return mod.intValue_big(ty, result_bigint.toConst());
3303 }3076 }
33043077
3305 /// Supports (vectors of) integers only; asserts neither operand is undefined.3078 /// Supports (vectors of) integers only; asserts neither operand is undefined.
...@@ -3312,12 +3085,11 @@ pub const Value = struct {...@@ -3312,12 +3085,11 @@ pub const Value = struct {
3312 ) !Value {3085 ) !Value {
3313 if (ty.zigTypeTag(mod) == .Vector) {3086 if (ty.zigTypeTag(mod) == .Vector) {
3314 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3087 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3088 const scalar_ty = ty.scalarType(mod);
3315 for (result_data, 0..) |*scalar, i| {3089 for (result_data, 0..) |*scalar, i| {
3316 var lhs_buf: Value.ElemValueBuffer = undefined;3090 const lhs_elem = try lhs.elemValue(mod, i);
3317 var rhs_buf: Value.ElemValueBuffer = undefined;3091 const rhs_elem = try rhs.elemValue(mod, i);
3318 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3092 scalar.* = try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);
3319 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3320 scalar.* = try intSubSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
3321 }3093 }
3322 return Value.Tag.aggregate.create(arena, result_data);3094 return Value.Tag.aggregate.create(arena, result_data);
3323 }3095 }
...@@ -3347,7 +3119,7 @@ pub const Value = struct {...@@ -3347,7 +3119,7 @@ pub const Value = struct {
3347 );3119 );
3348 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3120 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
3349 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);3121 result_bigint.subSat(lhs_bigint, rhs_bigint, info.signedness, info.bits);
3350 return fromBigInt(arena, result_bigint.toConst());3122 return mod.intValue_big(ty, result_bigint.toConst());
3351 }3123 }
33523124
3353 pub fn intMulWithOverflow(3125 pub fn intMulWithOverflow(
...@@ -3360,12 +3132,11 @@ pub const Value = struct {...@@ -3360,12 +3132,11 @@ pub const Value = struct {
3360 if (ty.zigTypeTag(mod) == .Vector) {3132 if (ty.zigTypeTag(mod) == .Vector) {
3361 const overflowed_data = try arena.alloc(Value, ty.vectorLen(mod));3133 const overflowed_data = try arena.alloc(Value, ty.vectorLen(mod));
3362 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3134 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3135 const scalar_ty = ty.scalarType(mod);
3363 for (result_data, 0..) |*scalar, i| {3136 for (result_data, 0..) |*scalar, i| {
3364 var lhs_buf: Value.ElemValueBuffer = undefined;3137 const lhs_elem = try lhs.elemValue(mod, i);
3365 var rhs_buf: Value.ElemValueBuffer = undefined;3138 const rhs_elem = try rhs.elemValue(mod, i);
3366 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3139 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod);
3367 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3368 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
3369 overflowed_data[i] = of_math_result.overflow_bit;3140 overflowed_data[i] = of_math_result.overflow_bit;
3370 scalar.* = of_math_result.wrapped_result;3141 scalar.* = of_math_result.wrapped_result;
3371 }3142 }
...@@ -3408,7 +3179,7 @@ pub const Value = struct {...@@ -3408,7 +3179,7 @@ pub const Value = struct {
34083179
3409 return OverflowArithmeticResult{3180 return OverflowArithmeticResult{
3410 .overflow_bit = boolToInt(overflowed),3181 .overflow_bit = boolToInt(overflowed),
3411 .wrapped_result = try fromBigInt(arena, result_bigint.toConst()),3182 .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()),
3412 };3183 };
3413 }3184 }
34143185
...@@ -3423,10 +3194,8 @@ pub const Value = struct {...@@ -3423,10 +3194,8 @@ pub const Value = struct {
3423 if (ty.zigTypeTag(mod) == .Vector) {3194 if (ty.zigTypeTag(mod) == .Vector) {
3424 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3195 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3425 for (result_data, 0..) |*scalar, i| {3196 for (result_data, 0..) |*scalar, i| {
3426 var lhs_buf: Value.ElemValueBuffer = undefined;3197 const lhs_elem = try lhs.elemValue(mod, i);
3427 var rhs_buf: Value.ElemValueBuffer = undefined;3198 const rhs_elem = try rhs.elemValue(mod, i);
3428 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3429 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3430 scalar.* = try numberMulWrapScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);3199 scalar.* = try numberMulWrapScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
3431 }3200 }
3432 return Value.Tag.aggregate.create(arena, result_data);3201 return Value.Tag.aggregate.create(arena, result_data);
...@@ -3467,10 +3236,8 @@ pub const Value = struct {...@@ -3467,10 +3236,8 @@ pub const Value = struct {
3467 if (ty.zigTypeTag(mod) == .Vector) {3236 if (ty.zigTypeTag(mod) == .Vector) {
3468 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3237 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3469 for (result_data, 0..) |*scalar, i| {3238 for (result_data, 0..) |*scalar, i| {
3470 var lhs_buf: Value.ElemValueBuffer = undefined;3239 const lhs_elem = try lhs.elemValue(mod, i);
3471 var rhs_buf: Value.ElemValueBuffer = undefined;3240 const rhs_elem = try rhs.elemValue(mod, i);
3472 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3473 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3474 scalar.* = try intMulSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);3241 scalar.* = try intMulSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
3475 }3242 }
3476 return Value.Tag.aggregate.create(arena, result_data);3243 return Value.Tag.aggregate.create(arena, result_data);
...@@ -3510,7 +3277,7 @@ pub const Value = struct {...@@ -3510,7 +3277,7 @@ pub const Value = struct {
3510 );3277 );
3511 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena);3278 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, arena);
3512 result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits);3279 result_bigint.saturate(result_bigint.toConst(), info.signedness, info.bits);
3513 return fromBigInt(arena, result_bigint.toConst());3280 return mod.intValue_big(ty, result_bigint.toConst());
3514 }3281 }
35153282
3516 /// Supports both floats and ints; handles undefined.3283 /// Supports both floats and ints; handles undefined.
...@@ -3542,8 +3309,7 @@ pub const Value = struct {...@@ -3542,8 +3309,7 @@ pub const Value = struct {
3542 if (ty.zigTypeTag(mod) == .Vector) {3309 if (ty.zigTypeTag(mod) == .Vector) {
3543 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3310 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3544 for (result_data, 0..) |*scalar, i| {3311 for (result_data, 0..) |*scalar, i| {
3545 var buf: Value.ElemValueBuffer = undefined;3312 const elem_val = try val.elemValue(mod, i);
3546 const elem_val = val.elemValueBuffer(mod, i, &buf);
3547 scalar.* = try bitwiseNotScalar(elem_val, ty.scalarType(mod), arena, mod);3313 scalar.* = try bitwiseNotScalar(elem_val, ty.scalarType(mod), arena, mod);
3548 }3314 }
3549 return Value.Tag.aggregate.create(arena, result_data);3315 return Value.Tag.aggregate.create(arena, result_data);
...@@ -3572,7 +3338,7 @@ pub const Value = struct {...@@ -3572,7 +3338,7 @@ pub const Value = struct {
35723338
3573 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3339 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
3574 result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits);3340 result_bigint.bitNotWrap(val_bigint, info.signedness, info.bits);
3575 return fromBigInt(arena, result_bigint.toConst());3341 return mod.intValue_big(ty, result_bigint.toConst());
3576 }3342 }
35773343
3578 /// operands must be (vectors of) integers; handles undefined scalars.3344 /// operands must be (vectors of) integers; handles undefined scalars.
...@@ -3580,19 +3346,17 @@ pub const Value = struct {...@@ -3580,19 +3346,17 @@ pub const Value = struct {
3580 if (ty.zigTypeTag(mod) == .Vector) {3346 if (ty.zigTypeTag(mod) == .Vector) {
3581 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3347 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3582 for (result_data, 0..) |*scalar, i| {3348 for (result_data, 0..) |*scalar, i| {
3583 var lhs_buf: Value.ElemValueBuffer = undefined;3349 const lhs_elem = try lhs.elemValue(mod, i);
3584 var rhs_buf: Value.ElemValueBuffer = undefined;3350 const rhs_elem = try rhs.elemValue(mod, i);
3585 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3351 scalar.* = try bitwiseAndScalar(lhs_elem, rhs_elem, ty.scalarType(mod), allocator, mod);
3586 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3587 scalar.* = try bitwiseAndScalar(lhs_elem, rhs_elem, allocator, mod);
3588 }3352 }
3589 return Value.Tag.aggregate.create(allocator, result_data);3353 return Value.Tag.aggregate.create(allocator, result_data);
3590 }3354 }
3591 return bitwiseAndScalar(lhs, rhs, allocator, mod);3355 return bitwiseAndScalar(lhs, rhs, ty, allocator, mod);
3592 }3356 }
35933357
3594 /// operands must be integers; handles undefined.3358 /// operands must be integers; handles undefined.
3595 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, mod: *Module) !Value {3359 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3596 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;3360 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
35973361
3598 // TODO is this a performance issue? maybe we should try the operation without3362 // TODO is this a performance issue? maybe we should try the operation without
...@@ -3608,7 +3372,7 @@ pub const Value = struct {...@@ -3608,7 +3372,7 @@ pub const Value = struct {
3608 );3372 );
3609 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3373 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
3610 result_bigint.bitAnd(lhs_bigint, rhs_bigint);3374 result_bigint.bitAnd(lhs_bigint, rhs_bigint);
3611 return fromBigInt(arena, result_bigint.toConst());3375 return mod.intValue_big(ty, result_bigint.toConst());
3612 }3376 }
36133377
3614 /// operands must be (vectors of) integers; handles undefined scalars.3378 /// operands must be (vectors of) integers; handles undefined scalars.
...@@ -3616,10 +3380,8 @@ pub const Value = struct {...@@ -3616,10 +3380,8 @@ pub const Value = struct {
3616 if (ty.zigTypeTag(mod) == .Vector) {3380 if (ty.zigTypeTag(mod) == .Vector) {
3617 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3381 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
3618 for (result_data, 0..) |*scalar, i| {3382 for (result_data, 0..) |*scalar, i| {
3619 var lhs_buf: Value.ElemValueBuffer = undefined;3383 const lhs_elem = try lhs.elemValue(mod, i);
3620 var rhs_buf: Value.ElemValueBuffer = undefined;3384 const rhs_elem = try rhs.elemValue(mod, i);
3621 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3622 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3623 scalar.* = try bitwiseNandScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);3385 scalar.* = try bitwiseNandScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
3624 }3386 }
3625 return Value.Tag.aggregate.create(arena, result_data);3387 return Value.Tag.aggregate.create(arena, result_data);
...@@ -3632,12 +3394,7 @@ pub const Value = struct {...@@ -3632,12 +3394,7 @@ pub const Value = struct {
3632 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;3394 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
36333395
3634 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);3396 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);
36353397 const all_ones = if (ty.isSignedInt(mod)) Value.negative_one else try ty.maxIntScalar(mod);
3636 const all_ones = if (ty.isSignedInt(mod))
3637 try Value.Tag.int_i64.create(arena, -1)
3638 else
3639 try ty.maxInt(arena, mod);
3640
3641 return bitwiseXor(anded, all_ones, ty, arena, mod);3398 return bitwiseXor(anded, all_ones, ty, arena, mod);
3642 }3399 }
36433400
...@@ -3646,19 +3403,17 @@ pub const Value = struct {...@@ -3646,19 +3403,17 @@ pub const Value = struct {
3646 if (ty.zigTypeTag(mod) == .Vector) {3403 if (ty.zigTypeTag(mod) == .Vector) {
3647 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3404 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3648 for (result_data, 0..) |*scalar, i| {3405 for (result_data, 0..) |*scalar, i| {
3649 var lhs_buf: Value.ElemValueBuffer = undefined;3406 const lhs_elem = try lhs.elemValue(mod, i);
3650 var rhs_buf: Value.ElemValueBuffer = undefined;3407 const rhs_elem = try rhs.elemValue(mod, i);
3651 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3408 scalar.* = try bitwiseOrScalar(lhs_elem, rhs_elem, ty.scalarType(mod), allocator, mod);
3652 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3653 scalar.* = try bitwiseOrScalar(lhs_elem, rhs_elem, allocator, mod);
3654 }3409 }
3655 return Value.Tag.aggregate.create(allocator, result_data);3410 return Value.Tag.aggregate.create(allocator, result_data);
3656 }3411 }
3657 return bitwiseOrScalar(lhs, rhs, allocator, mod);3412 return bitwiseOrScalar(lhs, rhs, ty, allocator, mod);
3658 }3413 }
36593414
3660 /// operands must be integers; handles undefined.3415 /// operands must be integers; handles undefined.
3661 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, mod: *Module) !Value {3416 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3662 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;3417 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
36633418
3664 // TODO is this a performance issue? maybe we should try the operation without3419 // TODO is this a performance issue? maybe we should try the operation without
...@@ -3673,27 +3428,26 @@ pub const Value = struct {...@@ -3673,27 +3428,26 @@ pub const Value = struct {
3673 );3428 );
3674 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3429 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
3675 result_bigint.bitOr(lhs_bigint, rhs_bigint);3430 result_bigint.bitOr(lhs_bigint, rhs_bigint);
3676 return fromBigInt(arena, result_bigint.toConst());3431 return mod.intValue_big(ty, result_bigint.toConst());
3677 }3432 }
36783433
3679 /// operands must be (vectors of) integers; handles undefined scalars.3434 /// operands must be (vectors of) integers; handles undefined scalars.
3680 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3435 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3681 if (ty.zigTypeTag(mod) == .Vector) {3436 if (ty.zigTypeTag(mod) == .Vector) {
3682 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3437 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3438 const scalar_ty = ty.scalarType(mod);
3683 for (result_data, 0..) |*scalar, i| {3439 for (result_data, 0..) |*scalar, i| {
3684 var lhs_buf: Value.ElemValueBuffer = undefined;3440 const lhs_elem = try lhs.elemValue(mod, i);
3685 var rhs_buf: Value.ElemValueBuffer = undefined;3441 const rhs_elem = try rhs.elemValue(mod, i);
3686 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3442 scalar.* = try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
3687 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3688 scalar.* = try bitwiseXorScalar(lhs_elem, rhs_elem, allocator, mod);
3689 }3443 }
3690 return Value.Tag.aggregate.create(allocator, result_data);3444 return Value.Tag.aggregate.create(allocator, result_data);
3691 }3445 }
3692 return bitwiseXorScalar(lhs, rhs, allocator, mod);3446 return bitwiseXorScalar(lhs, rhs, ty, allocator, mod);
3693 }3447 }
36943448
3695 /// operands must be integers; handles undefined.3449 /// operands must be integers; handles undefined.
3696 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, mod: *Module) !Value {3450 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3697 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;3451 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
36983452
3699 // TODO is this a performance issue? maybe we should try the operation without3453 // TODO is this a performance issue? maybe we should try the operation without
...@@ -3709,25 +3463,24 @@ pub const Value = struct {...@@ -3709,25 +3463,24 @@ pub const Value = struct {
3709 );3463 );
3710 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3464 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
3711 result_bigint.bitXor(lhs_bigint, rhs_bigint);3465 result_bigint.bitXor(lhs_bigint, rhs_bigint);
3712 return fromBigInt(arena, result_bigint.toConst());3466 return mod.intValue_big(ty, result_bigint.toConst());
3713 }3467 }
37143468
3715 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3469 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3716 if (ty.zigTypeTag(mod) == .Vector) {3470 if (ty.zigTypeTag(mod) == .Vector) {
3717 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3471 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3472 const scalar_ty = ty.scalarType(mod);
3718 for (result_data, 0..) |*scalar, i| {3473 for (result_data, 0..) |*scalar, i| {
3719 var lhs_buf: Value.ElemValueBuffer = undefined;3474 const lhs_elem = try lhs.elemValue(mod, i);
3720 var rhs_buf: Value.ElemValueBuffer = undefined;3475 const rhs_elem = try rhs.elemValue(mod, i);
3721 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3476 scalar.* = try intDivScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
3722 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3723 scalar.* = try intDivScalar(lhs_elem, rhs_elem, allocator, mod);
3724 }3477 }
3725 return Value.Tag.aggregate.create(allocator, result_data);3478 return Value.Tag.aggregate.create(allocator, result_data);
3726 }3479 }
3727 return intDivScalar(lhs, rhs, allocator, mod);3480 return intDivScalar(lhs, rhs, ty, allocator, mod);
3728 }3481 }
37293482
3730 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {3483 pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3731 // TODO is this a performance issue? maybe we should try the operation without3484 // TODO is this a performance issue? maybe we should try the operation without
3732 // resorting to BigInt first.3485 // resorting to BigInt first.
3733 var lhs_space: Value.BigIntSpace = undefined;3486 var lhs_space: Value.BigIntSpace = undefined;
...@@ -3749,25 +3502,24 @@ pub const Value = struct {...@@ -3749,25 +3502,24 @@ pub const Value = struct {
3749 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };3502 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
3750 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };3503 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
3751 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);3504 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
3752 return fromBigInt(allocator, result_q.toConst());3505 return mod.intValue_big(ty, result_q.toConst());
3753 }3506 }
37543507
3755 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3508 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3756 if (ty.zigTypeTag(mod) == .Vector) {3509 if (ty.zigTypeTag(mod) == .Vector) {
3757 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3510 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3511 const scalar_ty = ty.scalarType(mod);
3758 for (result_data, 0..) |*scalar, i| {3512 for (result_data, 0..) |*scalar, i| {
3759 var lhs_buf: Value.ElemValueBuffer = undefined;3513 const lhs_elem = try lhs.elemValue(mod, i);
3760 var rhs_buf: Value.ElemValueBuffer = undefined;3514 const rhs_elem = try rhs.elemValue(mod, i);
3761 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3515 scalar.* = try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
3762 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3763 scalar.* = try intDivFloorScalar(lhs_elem, rhs_elem, allocator, mod);
3764 }3516 }
3765 return Value.Tag.aggregate.create(allocator, result_data);3517 return Value.Tag.aggregate.create(allocator, result_data);
3766 }3518 }
3767 return intDivFloorScalar(lhs, rhs, allocator, mod);3519 return intDivFloorScalar(lhs, rhs, ty, allocator, mod);
3768 }3520 }
37693521
3770 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {3522 pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3771 // TODO is this a performance issue? maybe we should try the operation without3523 // TODO is this a performance issue? maybe we should try the operation without
3772 // resorting to BigInt first.3524 // resorting to BigInt first.
3773 var lhs_space: Value.BigIntSpace = undefined;3525 var lhs_space: Value.BigIntSpace = undefined;
...@@ -3789,25 +3541,24 @@ pub const Value = struct {...@@ -3789,25 +3541,24 @@ pub const Value = struct {
3789 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };3541 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
3790 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };3542 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
3791 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);3543 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
3792 return fromBigInt(allocator, result_q.toConst());3544 return mod.intValue_big(ty, result_q.toConst());
3793 }3545 }
37943546
3795 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3547 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3796 if (ty.zigTypeTag(mod) == .Vector) {3548 if (ty.zigTypeTag(mod) == .Vector) {
3797 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3549 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3550 const scalar_ty = ty.scalarType(mod);
3798 for (result_data, 0..) |*scalar, i| {3551 for (result_data, 0..) |*scalar, i| {
3799 var lhs_buf: Value.ElemValueBuffer = undefined;3552 const lhs_elem = try lhs.elemValue(mod, i);
3800 var rhs_buf: Value.ElemValueBuffer = undefined;3553 const rhs_elem = try rhs.elemValue(mod, i);
3801 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3554 scalar.* = try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
3802 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3803 scalar.* = try intModScalar(lhs_elem, rhs_elem, allocator, mod);
3804 }3555 }
3805 return Value.Tag.aggregate.create(allocator, result_data);3556 return Value.Tag.aggregate.create(allocator, result_data);
3806 }3557 }
3807 return intModScalar(lhs, rhs, allocator, mod);3558 return intModScalar(lhs, rhs, ty, allocator, mod);
3808 }3559 }
38093560
3810 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {3561 pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3811 // TODO is this a performance issue? maybe we should try the operation without3562 // TODO is this a performance issue? maybe we should try the operation without
3812 // resorting to BigInt first.3563 // resorting to BigInt first.
3813 var lhs_space: Value.BigIntSpace = undefined;3564 var lhs_space: Value.BigIntSpace = undefined;
...@@ -3829,7 +3580,7 @@ pub const Value = struct {...@@ -3829,7 +3580,7 @@ pub const Value = struct {
3829 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };3580 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
3830 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };3581 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
3831 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);3582 result_q.divFloor(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
3832 return fromBigInt(allocator, result_r.toConst());3583 return mod.intValue_big(ty, result_r.toConst());
3833 }3584 }
38343585
3835 /// Returns true if the value is a floating point type and is NaN. Returns false otherwise.3586 /// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
...@@ -3877,46 +3628,44 @@ pub const Value = struct {...@@ -3877,46 +3628,44 @@ pub const Value = struct {
3877 }3628 }
38783629
3879 pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3630 pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
3880 const target = mod.getTarget();
3881 if (float_type.zigTypeTag(mod) == .Vector) {3631 if (float_type.zigTypeTag(mod) == .Vector) {
3882 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));3632 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
3883 for (result_data, 0..) |*scalar, i| {3633 for (result_data, 0..) |*scalar, i| {
3884 var lhs_buf: Value.ElemValueBuffer = undefined;3634 const lhs_elem = try lhs.elemValue(mod, i);
3885 var rhs_buf: Value.ElemValueBuffer = undefined;3635 const rhs_elem = try rhs.elemValue(mod, i);
3886 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3636 scalar.* = try floatRemScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);
3887 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3888 scalar.* = try floatRemScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
3889 }3637 }
3890 return Value.Tag.aggregate.create(arena, result_data);3638 return Value.Tag.aggregate.create(arena, result_data);
3891 }3639 }
3892 return floatRemScalar(lhs, rhs, float_type, arena, target);3640 return floatRemScalar(lhs, rhs, float_type, arena, mod);
3893 }3641 }
38943642
3895 pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value {3643 pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *const Module) !Value {
3644 const target = mod.getTarget();
3896 switch (float_type.floatBits(target)) {3645 switch (float_type.floatBits(target)) {
3897 16 => {3646 16 => {
3898 const lhs_val = lhs.toFloat(f16);3647 const lhs_val = lhs.toFloat(f16, mod);
3899 const rhs_val = rhs.toFloat(f16);3648 const rhs_val = rhs.toFloat(f16, mod);
3900 return Value.Tag.float_16.create(arena, @rem(lhs_val, rhs_val));3649 return Value.Tag.float_16.create(arena, @rem(lhs_val, rhs_val));
3901 },3650 },
3902 32 => {3651 32 => {
3903 const lhs_val = lhs.toFloat(f32);3652 const lhs_val = lhs.toFloat(f32, mod);
3904 const rhs_val = rhs.toFloat(f32);3653 const rhs_val = rhs.toFloat(f32, mod);
3905 return Value.Tag.float_32.create(arena, @rem(lhs_val, rhs_val));3654 return Value.Tag.float_32.create(arena, @rem(lhs_val, rhs_val));
3906 },3655 },
3907 64 => {3656 64 => {
3908 const lhs_val = lhs.toFloat(f64);3657 const lhs_val = lhs.toFloat(f64, mod);
3909 const rhs_val = rhs.toFloat(f64);3658 const rhs_val = rhs.toFloat(f64, mod);
3910 return Value.Tag.float_64.create(arena, @rem(lhs_val, rhs_val));3659 return Value.Tag.float_64.create(arena, @rem(lhs_val, rhs_val));
3911 },3660 },
3912 80 => {3661 80 => {
3913 const lhs_val = lhs.toFloat(f80);3662 const lhs_val = lhs.toFloat(f80, mod);
3914 const rhs_val = rhs.toFloat(f80);3663 const rhs_val = rhs.toFloat(f80, mod);
3915 return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val));3664 return Value.Tag.float_80.create(arena, @rem(lhs_val, rhs_val));
3916 },3665 },
3917 128 => {3666 128 => {
3918 const lhs_val = lhs.toFloat(f128);3667 const lhs_val = lhs.toFloat(f128, mod);
3919 const rhs_val = rhs.toFloat(f128);3668 const rhs_val = rhs.toFloat(f128, mod);
3920 return Value.Tag.float_128.create(arena, @rem(lhs_val, rhs_val));3669 return Value.Tag.float_128.create(arena, @rem(lhs_val, rhs_val));
3921 },3670 },
3922 else => unreachable,3671 else => unreachable,
...@@ -3924,46 +3673,44 @@ pub const Value = struct {...@@ -3924,46 +3673,44 @@ pub const Value = struct {
3924 }3673 }
39253674
3926 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {3675 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
3927 const target = mod.getTarget();
3928 if (float_type.zigTypeTag(mod) == .Vector) {3676 if (float_type.zigTypeTag(mod) == .Vector) {
3929 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));3677 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
3930 for (result_data, 0..) |*scalar, i| {3678 for (result_data, 0..) |*scalar, i| {
3931 var lhs_buf: Value.ElemValueBuffer = undefined;3679 const lhs_elem = try lhs.elemValue(mod, i);
3932 var rhs_buf: Value.ElemValueBuffer = undefined;3680 const rhs_elem = try rhs.elemValue(mod, i);
3933 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3681 scalar.* = try floatModScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);
3934 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3935 scalar.* = try floatModScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
3936 }3682 }
3937 return Value.Tag.aggregate.create(arena, result_data);3683 return Value.Tag.aggregate.create(arena, result_data);
3938 }3684 }
3939 return floatModScalar(lhs, rhs, float_type, arena, target);3685 return floatModScalar(lhs, rhs, float_type, arena, mod);
3940 }3686 }
39413687
3942 pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, target: Target) !Value {3688 pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *const Module) !Value {
3689 const target = mod.getTarget();
3943 switch (float_type.floatBits(target)) {3690 switch (float_type.floatBits(target)) {
3944 16 => {3691 16 => {
3945 const lhs_val = lhs.toFloat(f16);3692 const lhs_val = lhs.toFloat(f16, mod);
3946 const rhs_val = rhs.toFloat(f16);3693 const rhs_val = rhs.toFloat(f16, mod);
3947 return Value.Tag.float_16.create(arena, @mod(lhs_val, rhs_val));3694 return Value.Tag.float_16.create(arena, @mod(lhs_val, rhs_val));
3948 },3695 },
3949 32 => {3696 32 => {
3950 const lhs_val = lhs.toFloat(f32);3697 const lhs_val = lhs.toFloat(f32, mod);
3951 const rhs_val = rhs.toFloat(f32);3698 const rhs_val = rhs.toFloat(f32, mod);
3952 return Value.Tag.float_32.create(arena, @mod(lhs_val, rhs_val));3699 return Value.Tag.float_32.create(arena, @mod(lhs_val, rhs_val));
3953 },3700 },
3954 64 => {3701 64 => {
3955 const lhs_val = lhs.toFloat(f64);3702 const lhs_val = lhs.toFloat(f64, mod);
3956 const rhs_val = rhs.toFloat(f64);3703 const rhs_val = rhs.toFloat(f64, mod);
3957 return Value.Tag.float_64.create(arena, @mod(lhs_val, rhs_val));3704 return Value.Tag.float_64.create(arena, @mod(lhs_val, rhs_val));
3958 },3705 },
3959 80 => {3706 80 => {
3960 const lhs_val = lhs.toFloat(f80);3707 const lhs_val = lhs.toFloat(f80, mod);
3961 const rhs_val = rhs.toFloat(f80);3708 const rhs_val = rhs.toFloat(f80, mod);
3962 return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val));3709 return Value.Tag.float_80.create(arena, @mod(lhs_val, rhs_val));
3963 },3710 },
3964 128 => {3711 128 => {
3965 const lhs_val = lhs.toFloat(f128);3712 const lhs_val = lhs.toFloat(f128, mod);
3966 const rhs_val = rhs.toFloat(f128);3713 const rhs_val = rhs.toFloat(f128, mod);
3967 return Value.Tag.float_128.create(arena, @mod(lhs_val, rhs_val));3714 return Value.Tag.float_128.create(arena, @mod(lhs_val, rhs_val));
3968 },3715 },
3969 else => unreachable,3716 else => unreachable,
...@@ -3973,19 +3720,18 @@ pub const Value = struct {...@@ -3973,19 +3720,18 @@ pub const Value = struct {
3973 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3720 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3974 if (ty.zigTypeTag(mod) == .Vector) {3721 if (ty.zigTypeTag(mod) == .Vector) {
3975 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3722 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3723 const scalar_ty = ty.scalarType(mod);
3976 for (result_data, 0..) |*scalar, i| {3724 for (result_data, 0..) |*scalar, i| {
3977 var lhs_buf: Value.ElemValueBuffer = undefined;3725 const lhs_elem = try lhs.elemValue(mod, i);
3978 var rhs_buf: Value.ElemValueBuffer = undefined;3726 const rhs_elem = try rhs.elemValue(mod, i);
3979 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3727 scalar.* = try intMulScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
3980 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3981 scalar.* = try intMulScalar(lhs_elem, rhs_elem, allocator, mod);
3982 }3728 }
3983 return Value.Tag.aggregate.create(allocator, result_data);3729 return Value.Tag.aggregate.create(allocator, result_data);
3984 }3730 }
3985 return intMulScalar(lhs, rhs, allocator, mod);3731 return intMulScalar(lhs, rhs, ty, allocator, mod);
3986 }3732 }
39873733
3988 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {3734 pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3989 // TODO is this a performance issue? maybe we should try the operation without3735 // TODO is this a performance issue? maybe we should try the operation without
3990 // resorting to BigInt first.3736 // resorting to BigInt first.
3991 var lhs_space: Value.BigIntSpace = undefined;3737 var lhs_space: Value.BigIntSpace = undefined;
...@@ -4003,20 +3749,20 @@ pub const Value = struct {...@@ -4003,20 +3749,20 @@ pub const Value = struct {
4003 );3749 );
4004 defer allocator.free(limbs_buffer);3750 defer allocator.free(limbs_buffer);
4005 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator);3751 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, allocator);
4006 return fromBigInt(allocator, result_bigint.toConst());3752 return mod.intValue_big(ty, result_bigint.toConst());
4007 }3753 }
40083754
4009 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {3755 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {
4010 if (ty.zigTypeTag(mod) == .Vector) {3756 if (ty.zigTypeTag(mod) == .Vector) {
4011 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3757 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3758 const scalar_ty = ty.scalarType(mod);
4012 for (result_data, 0..) |*scalar, i| {3759 for (result_data, 0..) |*scalar, i| {
4013 var buf: Value.ElemValueBuffer = undefined;3760 const elem_val = try val.elemValue(mod, i);
4014 const elem_val = val.elemValueBuffer(mod, i, &buf);3761 scalar.* = try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod);
4015 scalar.* = try intTruncScalar(elem_val, allocator, signedness, bits, mod);
4016 }3762 }
4017 return Value.Tag.aggregate.create(allocator, result_data);3763 return Value.Tag.aggregate.create(allocator, result_data);
4018 }3764 }
4019 return intTruncScalar(val, allocator, signedness, bits, mod);3765 return intTruncScalar(val, ty, allocator, signedness, bits, mod);
4020 }3766 }
40213767
4022 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.3768 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
...@@ -4030,19 +3776,25 @@ pub const Value = struct {...@@ -4030,19 +3776,25 @@ pub const Value = struct {
4030 ) !Value {3776 ) !Value {
4031 if (ty.zigTypeTag(mod) == .Vector) {3777 if (ty.zigTypeTag(mod) == .Vector) {
4032 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3778 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3779 const scalar_ty = ty.scalarType(mod);
4033 for (result_data, 0..) |*scalar, i| {3780 for (result_data, 0..) |*scalar, i| {
4034 var buf: Value.ElemValueBuffer = undefined;3781 const elem_val = try val.elemValue(mod, i);
4035 const elem_val = val.elemValueBuffer(mod, i, &buf);3782 const bits_elem = try bits.elemValue(mod, i);
4036 var bits_buf: Value.ElemValueBuffer = undefined;3783 scalar.* = try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(u16, bits_elem.toUnsignedInt(mod)), mod);
4037 const bits_elem = bits.elemValueBuffer(mod, i, &bits_buf);
4038 scalar.* = try intTruncScalar(elem_val, allocator, signedness, @intCast(u16, bits_elem.toUnsignedInt(mod)), mod);
4039 }3784 }
4040 return Value.Tag.aggregate.create(allocator, result_data);3785 return Value.Tag.aggregate.create(allocator, result_data);
4041 }3786 }
4042 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(mod)), mod);3787 return intTruncScalar(val, ty, allocator, signedness, @intCast(u16, bits.toUnsignedInt(mod)), mod);
4043 }3788 }
40443789
4045 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {3790 pub fn intTruncScalar(
3791 val: Value,
3792 ty: Type,
3793 allocator: Allocator,
3794 signedness: std.builtin.Signedness,
3795 bits: u16,
3796 mod: *Module,
3797 ) !Value {
4046 if (bits == 0) return Value.zero;3798 if (bits == 0) return Value.zero;
40473799
4048 var val_space: Value.BigIntSpace = undefined;3800 var val_space: Value.BigIntSpace = undefined;
...@@ -4055,25 +3807,24 @@ pub const Value = struct {...@@ -4055,25 +3807,24 @@ pub const Value = struct {
4055 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };3807 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
40563808
4057 result_bigint.truncate(val_bigint, signedness, bits);3809 result_bigint.truncate(val_bigint, signedness, bits);
4058 return fromBigInt(allocator, result_bigint.toConst());3810 return mod.intValue_big(ty, result_bigint.toConst());
4059 }3811 }
40603812
4061 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3813 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4062 if (ty.zigTypeTag(mod) == .Vector) {3814 if (ty.zigTypeTag(mod) == .Vector) {
4063 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3815 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3816 const scalar_ty = ty.scalarType(mod);
4064 for (result_data, 0..) |*scalar, i| {3817 for (result_data, 0..) |*scalar, i| {
4065 var lhs_buf: Value.ElemValueBuffer = undefined;3818 const lhs_elem = try lhs.elemValue(mod, i);
4066 var rhs_buf: Value.ElemValueBuffer = undefined;3819 const rhs_elem = try rhs.elemValue(mod, i);
4067 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3820 scalar.* = try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
4068 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4069 scalar.* = try shlScalar(lhs_elem, rhs_elem, allocator, mod);
4070 }3821 }
4071 return Value.Tag.aggregate.create(allocator, result_data);3822 return Value.Tag.aggregate.create(allocator, result_data);
4072 }3823 }
4073 return shlScalar(lhs, rhs, allocator, mod);3824 return shlScalar(lhs, rhs, ty, allocator, mod);
4074 }3825 }
40753826
4076 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {3827 pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4077 // TODO is this a performance issue? maybe we should try the operation without3828 // TODO is this a performance issue? maybe we should try the operation without
4078 // resorting to BigInt first.3829 // resorting to BigInt first.
4079 var lhs_space: Value.BigIntSpace = undefined;3830 var lhs_space: Value.BigIntSpace = undefined;
...@@ -4089,7 +3840,7 @@ pub const Value = struct {...@@ -4089,7 +3840,7 @@ pub const Value = struct {
4089 .len = undefined,3840 .len = undefined,
4090 };3841 };
4091 result_bigint.shiftLeft(lhs_bigint, shift);3842 result_bigint.shiftLeft(lhs_bigint, shift);
4092 return fromBigInt(allocator, result_bigint.toConst());3843 return mod.intValue_big(ty, result_bigint.toConst());
4093 }3844 }
40943845
4095 pub fn shlWithOverflow(3846 pub fn shlWithOverflow(
...@@ -4103,10 +3854,8 @@ pub const Value = struct {...@@ -4103,10 +3854,8 @@ pub const Value = struct {
4103 const overflowed_data = try allocator.alloc(Value, ty.vectorLen(mod));3854 const overflowed_data = try allocator.alloc(Value, ty.vectorLen(mod));
4104 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3855 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
4105 for (result_data, 0..) |*scalar, i| {3856 for (result_data, 0..) |*scalar, i| {
4106 var lhs_buf: Value.ElemValueBuffer = undefined;3857 const lhs_elem = try lhs.elemValue(mod, i);
4107 var rhs_buf: Value.ElemValueBuffer = undefined;3858 const rhs_elem = try rhs.elemValue(mod, i);
4108 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4109 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4110 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod), allocator, mod);3859 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod), allocator, mod);
4111 overflowed_data[i] = of_math_result.overflow_bit;3860 overflowed_data[i] = of_math_result.overflow_bit;
4112 scalar.* = of_math_result.wrapped_result;3861 scalar.* = of_math_result.wrapped_result;
...@@ -4146,7 +3895,7 @@ pub const Value = struct {...@@ -4146,7 +3895,7 @@ pub const Value = struct {
4146 }3895 }
4147 return OverflowArithmeticResult{3896 return OverflowArithmeticResult{
4148 .overflow_bit = boolToInt(overflowed),3897 .overflow_bit = boolToInt(overflowed),
4149 .wrapped_result = try fromBigInt(allocator, result_bigint.toConst()),3898 .wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()),
4150 };3899 };
4151 }3900 }
41523901
...@@ -4160,10 +3909,8 @@ pub const Value = struct {...@@ -4160,10 +3909,8 @@ pub const Value = struct {
4160 if (ty.zigTypeTag(mod) == .Vector) {3909 if (ty.zigTypeTag(mod) == .Vector) {
4161 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3910 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
4162 for (result_data, 0..) |*scalar, i| {3911 for (result_data, 0..) |*scalar, i| {
4163 var lhs_buf: Value.ElemValueBuffer = undefined;3912 const lhs_elem = try lhs.elemValue(mod, i);
4164 var rhs_buf: Value.ElemValueBuffer = undefined;3913 const rhs_elem = try rhs.elemValue(mod, i);
4165 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4166 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4167 scalar.* = try shlSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);3914 scalar.* = try shlSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
4168 }3915 }
4169 return Value.Tag.aggregate.create(arena, result_data);3916 return Value.Tag.aggregate.create(arena, result_data);
...@@ -4195,7 +3942,7 @@ pub const Value = struct {...@@ -4195,7 +3942,7 @@ pub const Value = struct {
4195 .len = undefined,3942 .len = undefined,
4196 };3943 };
4197 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);3944 result_bigint.shiftLeftSat(lhs_bigint, shift, info.signedness, info.bits);
4198 return fromBigInt(arena, result_bigint.toConst());3945 return mod.intValue_big(ty, result_bigint.toConst());
4199 }3946 }
42003947
4201 pub fn shlTrunc(3948 pub fn shlTrunc(
...@@ -4208,10 +3955,8 @@ pub const Value = struct {...@@ -4208,10 +3955,8 @@ pub const Value = struct {
4208 if (ty.zigTypeTag(mod) == .Vector) {3955 if (ty.zigTypeTag(mod) == .Vector) {
4209 const result_data = try arena.alloc(Value, ty.vectorLen(mod));3956 const result_data = try arena.alloc(Value, ty.vectorLen(mod));
4210 for (result_data, 0..) |*scalar, i| {3957 for (result_data, 0..) |*scalar, i| {
4211 var lhs_buf: Value.ElemValueBuffer = undefined;3958 const lhs_elem = try lhs.elemValue(mod, i);
4212 var rhs_buf: Value.ElemValueBuffer = undefined;3959 const rhs_elem = try rhs.elemValue(mod, i);
4213 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4214 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4215 scalar.* = try shlTruncScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);3960 scalar.* = try shlTruncScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
4216 }3961 }
4217 return Value.Tag.aggregate.create(arena, result_data);3962 return Value.Tag.aggregate.create(arena, result_data);
...@@ -4235,19 +3980,18 @@ pub const Value = struct {...@@ -4235,19 +3980,18 @@ pub const Value = struct {
4235 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {3980 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4236 if (ty.zigTypeTag(mod) == .Vector) {3981 if (ty.zigTypeTag(mod) == .Vector) {
4237 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));3982 const result_data = try allocator.alloc(Value, ty.vectorLen(mod));
3983 const scalar_ty = ty.scalarType(mod);
4238 for (result_data, 0..) |*scalar, i| {3984 for (result_data, 0..) |*scalar, i| {
4239 var lhs_buf: Value.ElemValueBuffer = undefined;3985 const lhs_elem = try lhs.elemValue(mod, i);
4240 var rhs_buf: Value.ElemValueBuffer = undefined;3986 const rhs_elem = try rhs.elemValue(mod, i);
4241 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3987 scalar.* = try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod);
4242 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4243 scalar.* = try shrScalar(lhs_elem, rhs_elem, allocator, mod);
4244 }3988 }
4245 return Value.Tag.aggregate.create(allocator, result_data);3989 return Value.Tag.aggregate.create(allocator, result_data);
4246 }3990 }
4247 return shrScalar(lhs, rhs, allocator, mod);3991 return shrScalar(lhs, rhs, ty, allocator, mod);
4248 }3992 }
42493993
4250 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {3994 pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4251 // TODO is this a performance issue? maybe we should try the operation without3995 // TODO is this a performance issue? maybe we should try the operation without
4252 // resorting to BigInt first.3996 // resorting to BigInt first.
4253 var lhs_space: Value.BigIntSpace = undefined;3997 var lhs_space: Value.BigIntSpace = undefined;
...@@ -4275,7 +4019,7 @@ pub const Value = struct {...@@ -4275,7 +4019,7 @@ pub const Value = struct {
4275 .len = undefined,4019 .len = undefined,
4276 };4020 };
4277 result_bigint.shiftRight(lhs_bigint, shift);4021 result_bigint.shiftRight(lhs_bigint, shift);
4278 return fromBigInt(allocator, result_bigint.toConst());4022 return mod.intValue_big(ty, result_bigint.toConst());
4279 }4023 }
42804024
4281 pub fn floatNeg(4025 pub fn floatNeg(
...@@ -4284,31 +4028,30 @@ pub const Value = struct {...@@ -4284,31 +4028,30 @@ pub const Value = struct {
4284 arena: Allocator,4028 arena: Allocator,
4285 mod: *Module,4029 mod: *Module,
4286 ) !Value {4030 ) !Value {
4287 const target = mod.getTarget();
4288 if (float_type.zigTypeTag(mod) == .Vector) {4031 if (float_type.zigTypeTag(mod) == .Vector) {
4289 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4032 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4290 for (result_data, 0..) |*scalar, i| {4033 for (result_data, 0..) |*scalar, i| {
4291 var buf: Value.ElemValueBuffer = undefined;4034 const elem_val = try val.elemValue(mod, i);
4292 const elem_val = val.elemValueBuffer(mod, i, &buf);4035 scalar.* = try floatNegScalar(elem_val, float_type.scalarType(mod), arena, mod);
4293 scalar.* = try floatNegScalar(elem_val, float_type.scalarType(mod), arena, target);
4294 }4036 }
4295 return Value.Tag.aggregate.create(arena, result_data);4037 return Value.Tag.aggregate.create(arena, result_data);
4296 }4038 }
4297 return floatNegScalar(val, float_type, arena, target);4039 return floatNegScalar(val, float_type, arena, mod);
4298 }4040 }
42994041
4300 pub fn floatNegScalar(4042 pub fn floatNegScalar(
4301 val: Value,4043 val: Value,
4302 float_type: Type,4044 float_type: Type,
4303 arena: Allocator,4045 arena: Allocator,
4304 target: Target,4046 mod: *const Module,
4305 ) !Value {4047 ) !Value {
4048 const target = mod.getTarget();
4306 switch (float_type.floatBits(target)) {4049 switch (float_type.floatBits(target)) {
4307 16 => return Value.Tag.float_16.create(arena, -val.toFloat(f16)),4050 16 => return Value.Tag.float_16.create(arena, -val.toFloat(f16, mod)),
4308 32 => return Value.Tag.float_32.create(arena, -val.toFloat(f32)),4051 32 => return Value.Tag.float_32.create(arena, -val.toFloat(f32, mod)),
4309 64 => return Value.Tag.float_64.create(arena, -val.toFloat(f64)),4052 64 => return Value.Tag.float_64.create(arena, -val.toFloat(f64, mod)),
4310 80 => return Value.Tag.float_80.create(arena, -val.toFloat(f80)),4053 80 => return Value.Tag.float_80.create(arena, -val.toFloat(f80, mod)),
4311 128 => return Value.Tag.float_128.create(arena, -val.toFloat(f128)),4054 128 => return Value.Tag.float_128.create(arena, -val.toFloat(f128, mod)),
4312 else => unreachable,4055 else => unreachable,
4313 }4056 }
4314 }4057 }
...@@ -4320,19 +4063,16 @@ pub const Value = struct {...@@ -4320,19 +4063,16 @@ pub const Value = struct {
4320 arena: Allocator,4063 arena: Allocator,
4321 mod: *Module,4064 mod: *Module,
4322 ) !Value {4065 ) !Value {
4323 const target = mod.getTarget();
4324 if (float_type.zigTypeTag(mod) == .Vector) {4066 if (float_type.zigTypeTag(mod) == .Vector) {
4325 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4067 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4326 for (result_data, 0..) |*scalar, i| {4068 for (result_data, 0..) |*scalar, i| {
4327 var lhs_buf: Value.ElemValueBuffer = undefined;4069 const lhs_elem = try lhs.elemValue(mod, i);
4328 var rhs_buf: Value.ElemValueBuffer = undefined;4070 const rhs_elem = try rhs.elemValue(mod, i);
4329 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4071 scalar.* = try floatDivScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);
4330 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4331 scalar.* = try floatDivScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
4332 }4072 }
4333 return Value.Tag.aggregate.create(arena, result_data);4073 return Value.Tag.aggregate.create(arena, result_data);
4334 }4074 }
4335 return floatDivScalar(lhs, rhs, float_type, arena, target);4075 return floatDivScalar(lhs, rhs, float_type, arena, mod);
4336 }4076 }
43374077
4338 pub fn floatDivScalar(4078 pub fn floatDivScalar(
...@@ -4340,32 +4080,33 @@ pub const Value = struct {...@@ -4340,32 +4080,33 @@ pub const Value = struct {
4340 rhs: Value,4080 rhs: Value,
4341 float_type: Type,4081 float_type: Type,
4342 arena: Allocator,4082 arena: Allocator,
4343 target: Target,4083 mod: *const Module,
4344 ) !Value {4084 ) !Value {
4085 const target = mod.getTarget();
4345 switch (float_type.floatBits(target)) {4086 switch (float_type.floatBits(target)) {
4346 16 => {4087 16 => {
4347 const lhs_val = lhs.toFloat(f16);4088 const lhs_val = lhs.toFloat(f16, mod);
4348 const rhs_val = rhs.toFloat(f16);4089 const rhs_val = rhs.toFloat(f16, mod);
4349 return Value.Tag.float_16.create(arena, lhs_val / rhs_val);4090 return Value.Tag.float_16.create(arena, lhs_val / rhs_val);
4350 },4091 },
4351 32 => {4092 32 => {
4352 const lhs_val = lhs.toFloat(f32);4093 const lhs_val = lhs.toFloat(f32, mod);
4353 const rhs_val = rhs.toFloat(f32);4094 const rhs_val = rhs.toFloat(f32, mod);
4354 return Value.Tag.float_32.create(arena, lhs_val / rhs_val);4095 return Value.Tag.float_32.create(arena, lhs_val / rhs_val);
4355 },4096 },
4356 64 => {4097 64 => {
4357 const lhs_val = lhs.toFloat(f64);4098 const lhs_val = lhs.toFloat(f64, mod);
4358 const rhs_val = rhs.toFloat(f64);4099 const rhs_val = rhs.toFloat(f64, mod);
4359 return Value.Tag.float_64.create(arena, lhs_val / rhs_val);4100 return Value.Tag.float_64.create(arena, lhs_val / rhs_val);
4360 },4101 },
4361 80 => {4102 80 => {
4362 const lhs_val = lhs.toFloat(f80);4103 const lhs_val = lhs.toFloat(f80, mod);
4363 const rhs_val = rhs.toFloat(f80);4104 const rhs_val = rhs.toFloat(f80, mod);
4364 return Value.Tag.float_80.create(arena, lhs_val / rhs_val);4105 return Value.Tag.float_80.create(arena, lhs_val / rhs_val);
4365 },4106 },
4366 128 => {4107 128 => {
4367 const lhs_val = lhs.toFloat(f128);4108 const lhs_val = lhs.toFloat(f128, mod);
4368 const rhs_val = rhs.toFloat(f128);4109 const rhs_val = rhs.toFloat(f128, mod);
4369 return Value.Tag.float_128.create(arena, lhs_val / rhs_val);4110 return Value.Tag.float_128.create(arena, lhs_val / rhs_val);
4370 },4111 },
4371 else => unreachable,4112 else => unreachable,
...@@ -4379,19 +4120,16 @@ pub const Value = struct {...@@ -4379,19 +4120,16 @@ pub const Value = struct {
4379 arena: Allocator,4120 arena: Allocator,
4380 mod: *Module,4121 mod: *Module,
4381 ) !Value {4122 ) !Value {
4382 const target = mod.getTarget();
4383 if (float_type.zigTypeTag(mod) == .Vector) {4123 if (float_type.zigTypeTag(mod) == .Vector) {
4384 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4124 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4385 for (result_data, 0..) |*scalar, i| {4125 for (result_data, 0..) |*scalar, i| {
4386 var lhs_buf: Value.ElemValueBuffer = undefined;4126 const lhs_elem = try lhs.elemValue(mod, i);
4387 var rhs_buf: Value.ElemValueBuffer = undefined;4127 const rhs_elem = try rhs.elemValue(mod, i);
4388 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4128 scalar.* = try floatDivFloorScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);
4389 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4390 scalar.* = try floatDivFloorScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
4391 }4129 }
4392 return Value.Tag.aggregate.create(arena, result_data);4130 return Value.Tag.aggregate.create(arena, result_data);
4393 }4131 }
4394 return floatDivFloorScalar(lhs, rhs, float_type, arena, target);4132 return floatDivFloorScalar(lhs, rhs, float_type, arena, mod);
4395 }4133 }
43964134
4397 pub fn floatDivFloorScalar(4135 pub fn floatDivFloorScalar(
...@@ -4399,32 +4137,33 @@ pub const Value = struct {...@@ -4399,32 +4137,33 @@ pub const Value = struct {
4399 rhs: Value,4137 rhs: Value,
4400 float_type: Type,4138 float_type: Type,
4401 arena: Allocator,4139 arena: Allocator,
4402 target: Target,4140 mod: *const Module,
4403 ) !Value {4141 ) !Value {
4142 const target = mod.getTarget();
4404 switch (float_type.floatBits(target)) {4143 switch (float_type.floatBits(target)) {
4405 16 => {4144 16 => {
4406 const lhs_val = lhs.toFloat(f16);4145 const lhs_val = lhs.toFloat(f16, mod);
4407 const rhs_val = rhs.toFloat(f16);4146 const rhs_val = rhs.toFloat(f16, mod);
4408 return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val));4147 return Value.Tag.float_16.create(arena, @divFloor(lhs_val, rhs_val));
4409 },4148 },
4410 32 => {4149 32 => {
4411 const lhs_val = lhs.toFloat(f32);4150 const lhs_val = lhs.toFloat(f32, mod);
4412 const rhs_val = rhs.toFloat(f32);4151 const rhs_val = rhs.toFloat(f32, mod);
4413 return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val));4152 return Value.Tag.float_32.create(arena, @divFloor(lhs_val, rhs_val));
4414 },4153 },
4415 64 => {4154 64 => {
4416 const lhs_val = lhs.toFloat(f64);4155 const lhs_val = lhs.toFloat(f64, mod);
4417 const rhs_val = rhs.toFloat(f64);4156 const rhs_val = rhs.toFloat(f64, mod);
4418 return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val));4157 return Value.Tag.float_64.create(arena, @divFloor(lhs_val, rhs_val));
4419 },4158 },
4420 80 => {4159 80 => {
4421 const lhs_val = lhs.toFloat(f80);4160 const lhs_val = lhs.toFloat(f80, mod);
4422 const rhs_val = rhs.toFloat(f80);4161 const rhs_val = rhs.toFloat(f80, mod);
4423 return Value.Tag.float_80.create(arena, @divFloor(lhs_val, rhs_val));4162 return Value.Tag.float_80.create(arena, @divFloor(lhs_val, rhs_val));
4424 },4163 },
4425 128 => {4164 128 => {
4426 const lhs_val = lhs.toFloat(f128);4165 const lhs_val = lhs.toFloat(f128, mod);
4427 const rhs_val = rhs.toFloat(f128);4166 const rhs_val = rhs.toFloat(f128, mod);
4428 return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val));4167 return Value.Tag.float_128.create(arena, @divFloor(lhs_val, rhs_val));
4429 },4168 },
4430 else => unreachable,4169 else => unreachable,
...@@ -4438,19 +4177,16 @@ pub const Value = struct {...@@ -4438,19 +4177,16 @@ pub const Value = struct {
4438 arena: Allocator,4177 arena: Allocator,
4439 mod: *Module,4178 mod: *Module,
4440 ) !Value {4179 ) !Value {
4441 const target = mod.getTarget();
4442 if (float_type.zigTypeTag(mod) == .Vector) {4180 if (float_type.zigTypeTag(mod) == .Vector) {
4443 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4181 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4444 for (result_data, 0..) |*scalar, i| {4182 for (result_data, 0..) |*scalar, i| {
4445 var lhs_buf: Value.ElemValueBuffer = undefined;4183 const lhs_elem = try lhs.elemValue(mod, i);
4446 var rhs_buf: Value.ElemValueBuffer = undefined;4184 const rhs_elem = try rhs.elemValue(mod, i);
4447 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4185 scalar.* = try floatDivTruncScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);
4448 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4449 scalar.* = try floatDivTruncScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
4450 }4186 }
4451 return Value.Tag.aggregate.create(arena, result_data);4187 return Value.Tag.aggregate.create(arena, result_data);
4452 }4188 }
4453 return floatDivTruncScalar(lhs, rhs, float_type, arena, target);4189 return floatDivTruncScalar(lhs, rhs, float_type, arena, mod);
4454 }4190 }
44554191
4456 pub fn floatDivTruncScalar(4192 pub fn floatDivTruncScalar(
...@@ -4458,32 +4194,33 @@ pub const Value = struct {...@@ -4458,32 +4194,33 @@ pub const Value = struct {
4458 rhs: Value,4194 rhs: Value,
4459 float_type: Type,4195 float_type: Type,
4460 arena: Allocator,4196 arena: Allocator,
4461 target: Target,4197 mod: *const Module,
4462 ) !Value {4198 ) !Value {
4199 const target = mod.getTarget();
4463 switch (float_type.floatBits(target)) {4200 switch (float_type.floatBits(target)) {
4464 16 => {4201 16 => {
4465 const lhs_val = lhs.toFloat(f16);4202 const lhs_val = lhs.toFloat(f16, mod);
4466 const rhs_val = rhs.toFloat(f16);4203 const rhs_val = rhs.toFloat(f16, mod);
4467 return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val));4204 return Value.Tag.float_16.create(arena, @divTrunc(lhs_val, rhs_val));
4468 },4205 },
4469 32 => {4206 32 => {
4470 const lhs_val = lhs.toFloat(f32);4207 const lhs_val = lhs.toFloat(f32, mod);
4471 const rhs_val = rhs.toFloat(f32);4208 const rhs_val = rhs.toFloat(f32, mod);
4472 return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val));4209 return Value.Tag.float_32.create(arena, @divTrunc(lhs_val, rhs_val));
4473 },4210 },
4474 64 => {4211 64 => {
4475 const lhs_val = lhs.toFloat(f64);4212 const lhs_val = lhs.toFloat(f64, mod);
4476 const rhs_val = rhs.toFloat(f64);4213 const rhs_val = rhs.toFloat(f64, mod);
4477 return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val));4214 return Value.Tag.float_64.create(arena, @divTrunc(lhs_val, rhs_val));
4478 },4215 },
4479 80 => {4216 80 => {
4480 const lhs_val = lhs.toFloat(f80);4217 const lhs_val = lhs.toFloat(f80, mod);
4481 const rhs_val = rhs.toFloat(f80);4218 const rhs_val = rhs.toFloat(f80, mod);
4482 return Value.Tag.float_80.create(arena, @divTrunc(lhs_val, rhs_val));4219 return Value.Tag.float_80.create(arena, @divTrunc(lhs_val, rhs_val));
4483 },4220 },
4484 128 => {4221 128 => {
4485 const lhs_val = lhs.toFloat(f128);4222 const lhs_val = lhs.toFloat(f128, mod);
4486 const rhs_val = rhs.toFloat(f128);4223 const rhs_val = rhs.toFloat(f128, mod);
4487 return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val));4224 return Value.Tag.float_128.create(arena, @divTrunc(lhs_val, rhs_val));
4488 },4225 },
4489 else => unreachable,4226 else => unreachable,
...@@ -4497,19 +4234,16 @@ pub const Value = struct {...@@ -4497,19 +4234,16 @@ pub const Value = struct {
4497 arena: Allocator,4234 arena: Allocator,
4498 mod: *Module,4235 mod: *Module,
4499 ) !Value {4236 ) !Value {
4500 const target = mod.getTarget();
4501 if (float_type.zigTypeTag(mod) == .Vector) {4237 if (float_type.zigTypeTag(mod) == .Vector) {
4502 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4238 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4503 for (result_data, 0..) |*scalar, i| {4239 for (result_data, 0..) |*scalar, i| {
4504 var lhs_buf: Value.ElemValueBuffer = undefined;4240 const lhs_elem = try lhs.elemValue(mod, i);
4505 var rhs_buf: Value.ElemValueBuffer = undefined;4241 const rhs_elem = try rhs.elemValue(mod, i);
4506 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4242 scalar.* = try floatMulScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, mod);
4507 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4508 scalar.* = try floatMulScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
4509 }4243 }
4510 return Value.Tag.aggregate.create(arena, result_data);4244 return Value.Tag.aggregate.create(arena, result_data);
4511 }4245 }
4512 return floatMulScalar(lhs, rhs, float_type, arena, target);4246 return floatMulScalar(lhs, rhs, float_type, arena, mod);
4513 }4247 }
45144248
4515 pub fn floatMulScalar(4249 pub fn floatMulScalar(
...@@ -4517,32 +4251,33 @@ pub const Value = struct {...@@ -4517,32 +4251,33 @@ pub const Value = struct {
4517 rhs: Value,4251 rhs: Value,
4518 float_type: Type,4252 float_type: Type,
4519 arena: Allocator,4253 arena: Allocator,
4520 target: Target,4254 mod: *const Module,
4521 ) !Value {4255 ) !Value {
4256 const target = mod.getTarget();
4522 switch (float_type.floatBits(target)) {4257 switch (float_type.floatBits(target)) {
4523 16 => {4258 16 => {
4524 const lhs_val = lhs.toFloat(f16);4259 const lhs_val = lhs.toFloat(f16, mod);
4525 const rhs_val = rhs.toFloat(f16);4260 const rhs_val = rhs.toFloat(f16, mod);
4526 return Value.Tag.float_16.create(arena, lhs_val * rhs_val);4261 return Value.Tag.float_16.create(arena, lhs_val * rhs_val);
4527 },4262 },
4528 32 => {4263 32 => {
4529 const lhs_val = lhs.toFloat(f32);4264 const lhs_val = lhs.toFloat(f32, mod);
4530 const rhs_val = rhs.toFloat(f32);4265 const rhs_val = rhs.toFloat(f32, mod);
4531 return Value.Tag.float_32.create(arena, lhs_val * rhs_val);4266 return Value.Tag.float_32.create(arena, lhs_val * rhs_val);
4532 },4267 },
4533 64 => {4268 64 => {
4534 const lhs_val = lhs.toFloat(f64);4269 const lhs_val = lhs.toFloat(f64, mod);
4535 const rhs_val = rhs.toFloat(f64);4270 const rhs_val = rhs.toFloat(f64, mod);
4536 return Value.Tag.float_64.create(arena, lhs_val * rhs_val);4271 return Value.Tag.float_64.create(arena, lhs_val * rhs_val);
4537 },4272 },
4538 80 => {4273 80 => {
4539 const lhs_val = lhs.toFloat(f80);4274 const lhs_val = lhs.toFloat(f80, mod);
4540 const rhs_val = rhs.toFloat(f80);4275 const rhs_val = rhs.toFloat(f80, mod);
4541 return Value.Tag.float_80.create(arena, lhs_val * rhs_val);4276 return Value.Tag.float_80.create(arena, lhs_val * rhs_val);
4542 },4277 },
4543 128 => {4278 128 => {
4544 const lhs_val = lhs.toFloat(f128);4279 const lhs_val = lhs.toFloat(f128, mod);
4545 const rhs_val = rhs.toFloat(f128);4280 const rhs_val = rhs.toFloat(f128, mod);
4546 return Value.Tag.float_128.create(arena, lhs_val * rhs_val);4281 return Value.Tag.float_128.create(arena, lhs_val * rhs_val);
4547 },4282 },
4548 else => unreachable,4283 else => unreachable,
...@@ -4550,39 +4285,38 @@ pub const Value = struct {...@@ -4550,39 +4285,38 @@ pub const Value = struct {
4550 }4285 }
45514286
4552 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4287 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4553 const target = mod.getTarget();
4554 if (float_type.zigTypeTag(mod) == .Vector) {4288 if (float_type.zigTypeTag(mod) == .Vector) {
4555 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4289 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4556 for (result_data, 0..) |*scalar, i| {4290 for (result_data, 0..) |*scalar, i| {
4557 var buf: Value.ElemValueBuffer = undefined;4291 const elem_val = try val.elemValue(mod, i);
4558 const elem_val = val.elemValueBuffer(mod, i, &buf);4292 scalar.* = try sqrtScalar(elem_val, float_type.scalarType(mod), arena, mod);
4559 scalar.* = try sqrtScalar(elem_val, float_type.scalarType(mod), arena, target);
4560 }4293 }
4561 return Value.Tag.aggregate.create(arena, result_data);4294 return Value.Tag.aggregate.create(arena, result_data);
4562 }4295 }
4563 return sqrtScalar(val, float_type, arena, target);4296 return sqrtScalar(val, float_type, arena, mod);
4564 }4297 }
45654298
4566 pub fn sqrtScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4299 pub fn sqrtScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4300 const target = mod.getTarget();
4567 switch (float_type.floatBits(target)) {4301 switch (float_type.floatBits(target)) {
4568 16 => {4302 16 => {
4569 const f = val.toFloat(f16);4303 const f = val.toFloat(f16, mod);
4570 return Value.Tag.float_16.create(arena, @sqrt(f));4304 return Value.Tag.float_16.create(arena, @sqrt(f));
4571 },4305 },
4572 32 => {4306 32 => {
4573 const f = val.toFloat(f32);4307 const f = val.toFloat(f32, mod);
4574 return Value.Tag.float_32.create(arena, @sqrt(f));4308 return Value.Tag.float_32.create(arena, @sqrt(f));
4575 },4309 },
4576 64 => {4310 64 => {
4577 const f = val.toFloat(f64);4311 const f = val.toFloat(f64, mod);
4578 return Value.Tag.float_64.create(arena, @sqrt(f));4312 return Value.Tag.float_64.create(arena, @sqrt(f));
4579 },4313 },
4580 80 => {4314 80 => {
4581 const f = val.toFloat(f80);4315 const f = val.toFloat(f80, mod);
4582 return Value.Tag.float_80.create(arena, @sqrt(f));4316 return Value.Tag.float_80.create(arena, @sqrt(f));
4583 },4317 },
4584 128 => {4318 128 => {
4585 const f = val.toFloat(f128);4319 const f = val.toFloat(f128, mod);
4586 return Value.Tag.float_128.create(arena, @sqrt(f));4320 return Value.Tag.float_128.create(arena, @sqrt(f));
4587 },4321 },
4588 else => unreachable,4322 else => unreachable,
...@@ -4590,39 +4324,38 @@ pub const Value = struct {...@@ -4590,39 +4324,38 @@ pub const Value = struct {
4590 }4324 }
45914325
4592 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4326 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4593 const target = mod.getTarget();
4594 if (float_type.zigTypeTag(mod) == .Vector) {4327 if (float_type.zigTypeTag(mod) == .Vector) {
4595 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4328 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4596 for (result_data, 0..) |*scalar, i| {4329 for (result_data, 0..) |*scalar, i| {
4597 var buf: Value.ElemValueBuffer = undefined;4330 const elem_val = try val.elemValue(mod, i);
4598 const elem_val = val.elemValueBuffer(mod, i, &buf);4331 scalar.* = try sinScalar(elem_val, float_type.scalarType(mod), arena, mod);
4599 scalar.* = try sinScalar(elem_val, float_type.scalarType(mod), arena, target);
4600 }4332 }
4601 return Value.Tag.aggregate.create(arena, result_data);4333 return Value.Tag.aggregate.create(arena, result_data);
4602 }4334 }
4603 return sinScalar(val, float_type, arena, target);4335 return sinScalar(val, float_type, arena, mod);
4604 }4336 }
46054337
4606 pub fn sinScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4338 pub fn sinScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4339 const target = mod.getTarget();
4607 switch (float_type.floatBits(target)) {4340 switch (float_type.floatBits(target)) {
4608 16 => {4341 16 => {
4609 const f = val.toFloat(f16);4342 const f = val.toFloat(f16, mod);
4610 return Value.Tag.float_16.create(arena, @sin(f));4343 return Value.Tag.float_16.create(arena, @sin(f));
4611 },4344 },
4612 32 => {4345 32 => {
4613 const f = val.toFloat(f32);4346 const f = val.toFloat(f32, mod);
4614 return Value.Tag.float_32.create(arena, @sin(f));4347 return Value.Tag.float_32.create(arena, @sin(f));
4615 },4348 },
4616 64 => {4349 64 => {
4617 const f = val.toFloat(f64);4350 const f = val.toFloat(f64, mod);
4618 return Value.Tag.float_64.create(arena, @sin(f));4351 return Value.Tag.float_64.create(arena, @sin(f));
4619 },4352 },
4620 80 => {4353 80 => {
4621 const f = val.toFloat(f80);4354 const f = val.toFloat(f80, mod);
4622 return Value.Tag.float_80.create(arena, @sin(f));4355 return Value.Tag.float_80.create(arena, @sin(f));
4623 },4356 },
4624 128 => {4357 128 => {
4625 const f = val.toFloat(f128);4358 const f = val.toFloat(f128, mod);
4626 return Value.Tag.float_128.create(arena, @sin(f));4359 return Value.Tag.float_128.create(arena, @sin(f));
4627 },4360 },
4628 else => unreachable,4361 else => unreachable,
...@@ -4630,39 +4363,38 @@ pub const Value = struct {...@@ -4630,39 +4363,38 @@ pub const Value = struct {
4630 }4363 }
46314364
4632 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4365 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4633 const target = mod.getTarget();
4634 if (float_type.zigTypeTag(mod) == .Vector) {4366 if (float_type.zigTypeTag(mod) == .Vector) {
4635 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4367 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4636 for (result_data, 0..) |*scalar, i| {4368 for (result_data, 0..) |*scalar, i| {
4637 var buf: Value.ElemValueBuffer = undefined;4369 const elem_val = try val.elemValue(mod, i);
4638 const elem_val = val.elemValueBuffer(mod, i, &buf);4370 scalar.* = try cosScalar(elem_val, float_type.scalarType(mod), arena, mod);
4639 scalar.* = try cosScalar(elem_val, float_type.scalarType(mod), arena, target);
4640 }4371 }
4641 return Value.Tag.aggregate.create(arena, result_data);4372 return Value.Tag.aggregate.create(arena, result_data);
4642 }4373 }
4643 return cosScalar(val, float_type, arena, target);4374 return cosScalar(val, float_type, arena, mod);
4644 }4375 }
46454376
4646 pub fn cosScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4377 pub fn cosScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4378 const target = mod.getTarget();
4647 switch (float_type.floatBits(target)) {4379 switch (float_type.floatBits(target)) {
4648 16 => {4380 16 => {
4649 const f = val.toFloat(f16);4381 const f = val.toFloat(f16, mod);
4650 return Value.Tag.float_16.create(arena, @cos(f));4382 return Value.Tag.float_16.create(arena, @cos(f));
4651 },4383 },
4652 32 => {4384 32 => {
4653 const f = val.toFloat(f32);4385 const f = val.toFloat(f32, mod);
4654 return Value.Tag.float_32.create(arena, @cos(f));4386 return Value.Tag.float_32.create(arena, @cos(f));
4655 },4387 },
4656 64 => {4388 64 => {
4657 const f = val.toFloat(f64);4389 const f = val.toFloat(f64, mod);
4658 return Value.Tag.float_64.create(arena, @cos(f));4390 return Value.Tag.float_64.create(arena, @cos(f));
4659 },4391 },
4660 80 => {4392 80 => {
4661 const f = val.toFloat(f80);4393 const f = val.toFloat(f80, mod);
4662 return Value.Tag.float_80.create(arena, @cos(f));4394 return Value.Tag.float_80.create(arena, @cos(f));
4663 },4395 },
4664 128 => {4396 128 => {
4665 const f = val.toFloat(f128);4397 const f = val.toFloat(f128, mod);
4666 return Value.Tag.float_128.create(arena, @cos(f));4398 return Value.Tag.float_128.create(arena, @cos(f));
4667 },4399 },
4668 else => unreachable,4400 else => unreachable,
...@@ -4670,39 +4402,38 @@ pub const Value = struct {...@@ -4670,39 +4402,38 @@ pub const Value = struct {
4670 }4402 }
46714403
4672 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4404 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4673 const target = mod.getTarget();
4674 if (float_type.zigTypeTag(mod) == .Vector) {4405 if (float_type.zigTypeTag(mod) == .Vector) {
4675 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4406 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4676 for (result_data, 0..) |*scalar, i| {4407 for (result_data, 0..) |*scalar, i| {
4677 var buf: Value.ElemValueBuffer = undefined;4408 const elem_val = try val.elemValue(mod, i);
4678 const elem_val = val.elemValueBuffer(mod, i, &buf);4409 scalar.* = try tanScalar(elem_val, float_type.scalarType(mod), arena, mod);
4679 scalar.* = try tanScalar(elem_val, float_type.scalarType(mod), arena, target);
4680 }4410 }
4681 return Value.Tag.aggregate.create(arena, result_data);4411 return Value.Tag.aggregate.create(arena, result_data);
4682 }4412 }
4683 return tanScalar(val, float_type, arena, target);4413 return tanScalar(val, float_type, arena, mod);
4684 }4414 }
46854415
4686 pub fn tanScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4416 pub fn tanScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4417 const target = mod.getTarget();
4687 switch (float_type.floatBits(target)) {4418 switch (float_type.floatBits(target)) {
4688 16 => {4419 16 => {
4689 const f = val.toFloat(f16);4420 const f = val.toFloat(f16, mod);
4690 return Value.Tag.float_16.create(arena, @tan(f));4421 return Value.Tag.float_16.create(arena, @tan(f));
4691 },4422 },
4692 32 => {4423 32 => {
4693 const f = val.toFloat(f32);4424 const f = val.toFloat(f32, mod);
4694 return Value.Tag.float_32.create(arena, @tan(f));4425 return Value.Tag.float_32.create(arena, @tan(f));
4695 },4426 },
4696 64 => {4427 64 => {
4697 const f = val.toFloat(f64);4428 const f = val.toFloat(f64, mod);
4698 return Value.Tag.float_64.create(arena, @tan(f));4429 return Value.Tag.float_64.create(arena, @tan(f));
4699 },4430 },
4700 80 => {4431 80 => {
4701 const f = val.toFloat(f80);4432 const f = val.toFloat(f80, mod);
4702 return Value.Tag.float_80.create(arena, @tan(f));4433 return Value.Tag.float_80.create(arena, @tan(f));
4703 },4434 },
4704 128 => {4435 128 => {
4705 const f = val.toFloat(f128);4436 const f = val.toFloat(f128, mod);
4706 return Value.Tag.float_128.create(arena, @tan(f));4437 return Value.Tag.float_128.create(arena, @tan(f));
4707 },4438 },
4708 else => unreachable,4439 else => unreachable,
...@@ -4710,39 +4441,38 @@ pub const Value = struct {...@@ -4710,39 +4441,38 @@ pub const Value = struct {
4710 }4441 }
47114442
4712 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4443 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4713 const target = mod.getTarget();
4714 if (float_type.zigTypeTag(mod) == .Vector) {4444 if (float_type.zigTypeTag(mod) == .Vector) {
4715 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4445 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4716 for (result_data, 0..) |*scalar, i| {4446 for (result_data, 0..) |*scalar, i| {
4717 var buf: Value.ElemValueBuffer = undefined;4447 const elem_val = try val.elemValue(mod, i);
4718 const elem_val = val.elemValueBuffer(mod, i, &buf);4448 scalar.* = try expScalar(elem_val, float_type.scalarType(mod), arena, mod);
4719 scalar.* = try expScalar(elem_val, float_type.scalarType(mod), arena, target);
4720 }4449 }
4721 return Value.Tag.aggregate.create(arena, result_data);4450 return Value.Tag.aggregate.create(arena, result_data);
4722 }4451 }
4723 return expScalar(val, float_type, arena, target);4452 return expScalar(val, float_type, arena, mod);
4724 }4453 }
47254454
4726 pub fn expScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4455 pub fn expScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4456 const target = mod.getTarget();
4727 switch (float_type.floatBits(target)) {4457 switch (float_type.floatBits(target)) {
4728 16 => {4458 16 => {
4729 const f = val.toFloat(f16);4459 const f = val.toFloat(f16, mod);
4730 return Value.Tag.float_16.create(arena, @exp(f));4460 return Value.Tag.float_16.create(arena, @exp(f));
4731 },4461 },
4732 32 => {4462 32 => {
4733 const f = val.toFloat(f32);4463 const f = val.toFloat(f32, mod);
4734 return Value.Tag.float_32.create(arena, @exp(f));4464 return Value.Tag.float_32.create(arena, @exp(f));
4735 },4465 },
4736 64 => {4466 64 => {
4737 const f = val.toFloat(f64);4467 const f = val.toFloat(f64, mod);
4738 return Value.Tag.float_64.create(arena, @exp(f));4468 return Value.Tag.float_64.create(arena, @exp(f));
4739 },4469 },
4740 80 => {4470 80 => {
4741 const f = val.toFloat(f80);4471 const f = val.toFloat(f80, mod);
4742 return Value.Tag.float_80.create(arena, @exp(f));4472 return Value.Tag.float_80.create(arena, @exp(f));
4743 },4473 },
4744 128 => {4474 128 => {
4745 const f = val.toFloat(f128);4475 const f = val.toFloat(f128, mod);
4746 return Value.Tag.float_128.create(arena, @exp(f));4476 return Value.Tag.float_128.create(arena, @exp(f));
4747 },4477 },
4748 else => unreachable,4478 else => unreachable,
...@@ -4750,39 +4480,38 @@ pub const Value = struct {...@@ -4750,39 +4480,38 @@ pub const Value = struct {
4750 }4480 }
47514481
4752 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4482 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4753 const target = mod.getTarget();
4754 if (float_type.zigTypeTag(mod) == .Vector) {4483 if (float_type.zigTypeTag(mod) == .Vector) {
4755 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4484 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4756 for (result_data, 0..) |*scalar, i| {4485 for (result_data, 0..) |*scalar, i| {
4757 var buf: Value.ElemValueBuffer = undefined;4486 const elem_val = try val.elemValue(mod, i);
4758 const elem_val = val.elemValueBuffer(mod, i, &buf);4487 scalar.* = try exp2Scalar(elem_val, float_type.scalarType(mod), arena, mod);
4759 scalar.* = try exp2Scalar(elem_val, float_type.scalarType(mod), arena, target);
4760 }4488 }
4761 return Value.Tag.aggregate.create(arena, result_data);4489 return Value.Tag.aggregate.create(arena, result_data);
4762 }4490 }
4763 return exp2Scalar(val, float_type, arena, target);4491 return exp2Scalar(val, float_type, arena, mod);
4764 }4492 }
47654493
4766 pub fn exp2Scalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4494 pub fn exp2Scalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4495 const target = mod.getTarget();
4767 switch (float_type.floatBits(target)) {4496 switch (float_type.floatBits(target)) {
4768 16 => {4497 16 => {
4769 const f = val.toFloat(f16);4498 const f = val.toFloat(f16, mod);
4770 return Value.Tag.float_16.create(arena, @exp2(f));4499 return Value.Tag.float_16.create(arena, @exp2(f));
4771 },4500 },
4772 32 => {4501 32 => {
4773 const f = val.toFloat(f32);4502 const f = val.toFloat(f32, mod);
4774 return Value.Tag.float_32.create(arena, @exp2(f));4503 return Value.Tag.float_32.create(arena, @exp2(f));
4775 },4504 },
4776 64 => {4505 64 => {
4777 const f = val.toFloat(f64);4506 const f = val.toFloat(f64, mod);
4778 return Value.Tag.float_64.create(arena, @exp2(f));4507 return Value.Tag.float_64.create(arena, @exp2(f));
4779 },4508 },
4780 80 => {4509 80 => {
4781 const f = val.toFloat(f80);4510 const f = val.toFloat(f80, mod);
4782 return Value.Tag.float_80.create(arena, @exp2(f));4511 return Value.Tag.float_80.create(arena, @exp2(f));
4783 },4512 },
4784 128 => {4513 128 => {
4785 const f = val.toFloat(f128);4514 const f = val.toFloat(f128, mod);
4786 return Value.Tag.float_128.create(arena, @exp2(f));4515 return Value.Tag.float_128.create(arena, @exp2(f));
4787 },4516 },
4788 else => unreachable,4517 else => unreachable,
...@@ -4790,39 +4519,38 @@ pub const Value = struct {...@@ -4790,39 +4519,38 @@ pub const Value = struct {
4790 }4519 }
47914520
4792 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4521 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4793 const target = mod.getTarget();
4794 if (float_type.zigTypeTag(mod) == .Vector) {4522 if (float_type.zigTypeTag(mod) == .Vector) {
4795 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4523 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4796 for (result_data, 0..) |*scalar, i| {4524 for (result_data, 0..) |*scalar, i| {
4797 var buf: Value.ElemValueBuffer = undefined;4525 const elem_val = try val.elemValue(mod, i);
4798 const elem_val = val.elemValueBuffer(mod, i, &buf);4526 scalar.* = try logScalar(elem_val, float_type.scalarType(mod), arena, mod);
4799 scalar.* = try logScalar(elem_val, float_type.scalarType(mod), arena, target);
4800 }4527 }
4801 return Value.Tag.aggregate.create(arena, result_data);4528 return Value.Tag.aggregate.create(arena, result_data);
4802 }4529 }
4803 return logScalar(val, float_type, arena, target);4530 return logScalar(val, float_type, arena, mod);
4804 }4531 }
48054532
4806 pub fn logScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4533 pub fn logScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4534 const target = mod.getTarget();
4807 switch (float_type.floatBits(target)) {4535 switch (float_type.floatBits(target)) {
4808 16 => {4536 16 => {
4809 const f = val.toFloat(f16);4537 const f = val.toFloat(f16, mod);
4810 return Value.Tag.float_16.create(arena, @log(f));4538 return Value.Tag.float_16.create(arena, @log(f));
4811 },4539 },
4812 32 => {4540 32 => {
4813 const f = val.toFloat(f32);4541 const f = val.toFloat(f32, mod);
4814 return Value.Tag.float_32.create(arena, @log(f));4542 return Value.Tag.float_32.create(arena, @log(f));
4815 },4543 },
4816 64 => {4544 64 => {
4817 const f = val.toFloat(f64);4545 const f = val.toFloat(f64, mod);
4818 return Value.Tag.float_64.create(arena, @log(f));4546 return Value.Tag.float_64.create(arena, @log(f));
4819 },4547 },
4820 80 => {4548 80 => {
4821 const f = val.toFloat(f80);4549 const f = val.toFloat(f80, mod);
4822 return Value.Tag.float_80.create(arena, @log(f));4550 return Value.Tag.float_80.create(arena, @log(f));
4823 },4551 },
4824 128 => {4552 128 => {
4825 const f = val.toFloat(f128);4553 const f = val.toFloat(f128, mod);
4826 return Value.Tag.float_128.create(arena, @log(f));4554 return Value.Tag.float_128.create(arena, @log(f));
4827 },4555 },
4828 else => unreachable,4556 else => unreachable,
...@@ -4830,39 +4558,38 @@ pub const Value = struct {...@@ -4830,39 +4558,38 @@ pub const Value = struct {
4830 }4558 }
48314559
4832 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4560 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4833 const target = mod.getTarget();
4834 if (float_type.zigTypeTag(mod) == .Vector) {4561 if (float_type.zigTypeTag(mod) == .Vector) {
4835 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4562 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4836 for (result_data, 0..) |*scalar, i| {4563 for (result_data, 0..) |*scalar, i| {
4837 var buf: Value.ElemValueBuffer = undefined;4564 const elem_val = try val.elemValue(mod, i);
4838 const elem_val = val.elemValueBuffer(mod, i, &buf);4565 scalar.* = try log2Scalar(elem_val, float_type.scalarType(mod), arena, mod);
4839 scalar.* = try log2Scalar(elem_val, float_type.scalarType(mod), arena, target);
4840 }4566 }
4841 return Value.Tag.aggregate.create(arena, result_data);4567 return Value.Tag.aggregate.create(arena, result_data);
4842 }4568 }
4843 return log2Scalar(val, float_type, arena, target);4569 return log2Scalar(val, float_type, arena, mod);
4844 }4570 }
48454571
4846 pub fn log2Scalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4572 pub fn log2Scalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4573 const target = mod.getTarget();
4847 switch (float_type.floatBits(target)) {4574 switch (float_type.floatBits(target)) {
4848 16 => {4575 16 => {
4849 const f = val.toFloat(f16);4576 const f = val.toFloat(f16, mod);
4850 return Value.Tag.float_16.create(arena, @log2(f));4577 return Value.Tag.float_16.create(arena, @log2(f));
4851 },4578 },
4852 32 => {4579 32 => {
4853 const f = val.toFloat(f32);4580 const f = val.toFloat(f32, mod);
4854 return Value.Tag.float_32.create(arena, @log2(f));4581 return Value.Tag.float_32.create(arena, @log2(f));
4855 },4582 },
4856 64 => {4583 64 => {
4857 const f = val.toFloat(f64);4584 const f = val.toFloat(f64, mod);
4858 return Value.Tag.float_64.create(arena, @log2(f));4585 return Value.Tag.float_64.create(arena, @log2(f));
4859 },4586 },
4860 80 => {4587 80 => {
4861 const f = val.toFloat(f80);4588 const f = val.toFloat(f80, mod);
4862 return Value.Tag.float_80.create(arena, @log2(f));4589 return Value.Tag.float_80.create(arena, @log2(f));
4863 },4590 },
4864 128 => {4591 128 => {
4865 const f = val.toFloat(f128);4592 const f = val.toFloat(f128, mod);
4866 return Value.Tag.float_128.create(arena, @log2(f));4593 return Value.Tag.float_128.create(arena, @log2(f));
4867 },4594 },
4868 else => unreachable,4595 else => unreachable,
...@@ -4870,39 +4597,38 @@ pub const Value = struct {...@@ -4870,39 +4597,38 @@ pub const Value = struct {
4870 }4597 }
48714598
4872 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4599 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4873 const target = mod.getTarget();
4874 if (float_type.zigTypeTag(mod) == .Vector) {4600 if (float_type.zigTypeTag(mod) == .Vector) {
4875 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4601 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4876 for (result_data, 0..) |*scalar, i| {4602 for (result_data, 0..) |*scalar, i| {
4877 var buf: Value.ElemValueBuffer = undefined;4603 const elem_val = try val.elemValue(mod, i);
4878 const elem_val = val.elemValueBuffer(mod, i, &buf);4604 scalar.* = try log10Scalar(elem_val, float_type.scalarType(mod), arena, mod);
4879 scalar.* = try log10Scalar(elem_val, float_type.scalarType(mod), arena, target);
4880 }4605 }
4881 return Value.Tag.aggregate.create(arena, result_data);4606 return Value.Tag.aggregate.create(arena, result_data);
4882 }4607 }
4883 return log10Scalar(val, float_type, arena, target);4608 return log10Scalar(val, float_type, arena, mod);
4884 }4609 }
48854610
4886 pub fn log10Scalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4611 pub fn log10Scalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4612 const target = mod.getTarget();
4887 switch (float_type.floatBits(target)) {4613 switch (float_type.floatBits(target)) {
4888 16 => {4614 16 => {
4889 const f = val.toFloat(f16);4615 const f = val.toFloat(f16, mod);
4890 return Value.Tag.float_16.create(arena, @log10(f));4616 return Value.Tag.float_16.create(arena, @log10(f));
4891 },4617 },
4892 32 => {4618 32 => {
4893 const f = val.toFloat(f32);4619 const f = val.toFloat(f32, mod);
4894 return Value.Tag.float_32.create(arena, @log10(f));4620 return Value.Tag.float_32.create(arena, @log10(f));
4895 },4621 },
4896 64 => {4622 64 => {
4897 const f = val.toFloat(f64);4623 const f = val.toFloat(f64, mod);
4898 return Value.Tag.float_64.create(arena, @log10(f));4624 return Value.Tag.float_64.create(arena, @log10(f));
4899 },4625 },
4900 80 => {4626 80 => {
4901 const f = val.toFloat(f80);4627 const f = val.toFloat(f80, mod);
4902 return Value.Tag.float_80.create(arena, @log10(f));4628 return Value.Tag.float_80.create(arena, @log10(f));
4903 },4629 },
4904 128 => {4630 128 => {
4905 const f = val.toFloat(f128);4631 const f = val.toFloat(f128, mod);
4906 return Value.Tag.float_128.create(arena, @log10(f));4632 return Value.Tag.float_128.create(arena, @log10(f));
4907 },4633 },
4908 else => unreachable,4634 else => unreachable,
...@@ -4910,39 +4636,38 @@ pub const Value = struct {...@@ -4910,39 +4636,38 @@ pub const Value = struct {
4910 }4636 }
49114637
4912 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4638 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4913 const target = mod.getTarget();
4914 if (float_type.zigTypeTag(mod) == .Vector) {4639 if (float_type.zigTypeTag(mod) == .Vector) {
4915 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4640 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4916 for (result_data, 0..) |*scalar, i| {4641 for (result_data, 0..) |*scalar, i| {
4917 var buf: Value.ElemValueBuffer = undefined;4642 const elem_val = try val.elemValue(mod, i);
4918 const elem_val = val.elemValueBuffer(mod, i, &buf);4643 scalar.* = try fabsScalar(elem_val, float_type.scalarType(mod), arena, mod);
4919 scalar.* = try fabsScalar(elem_val, float_type.scalarType(mod), arena, target);
4920 }4644 }
4921 return Value.Tag.aggregate.create(arena, result_data);4645 return Value.Tag.aggregate.create(arena, result_data);
4922 }4646 }
4923 return fabsScalar(val, float_type, arena, target);4647 return fabsScalar(val, float_type, arena, mod);
4924 }4648 }
49254649
4926 pub fn fabsScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4650 pub fn fabsScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4651 const target = mod.getTarget();
4927 switch (float_type.floatBits(target)) {4652 switch (float_type.floatBits(target)) {
4928 16 => {4653 16 => {
4929 const f = val.toFloat(f16);4654 const f = val.toFloat(f16, mod);
4930 return Value.Tag.float_16.create(arena, @fabs(f));4655 return Value.Tag.float_16.create(arena, @fabs(f));
4931 },4656 },
4932 32 => {4657 32 => {
4933 const f = val.toFloat(f32);4658 const f = val.toFloat(f32, mod);
4934 return Value.Tag.float_32.create(arena, @fabs(f));4659 return Value.Tag.float_32.create(arena, @fabs(f));
4935 },4660 },
4936 64 => {4661 64 => {
4937 const f = val.toFloat(f64);4662 const f = val.toFloat(f64, mod);
4938 return Value.Tag.float_64.create(arena, @fabs(f));4663 return Value.Tag.float_64.create(arena, @fabs(f));
4939 },4664 },
4940 80 => {4665 80 => {
4941 const f = val.toFloat(f80);4666 const f = val.toFloat(f80, mod);
4942 return Value.Tag.float_80.create(arena, @fabs(f));4667 return Value.Tag.float_80.create(arena, @fabs(f));
4943 },4668 },
4944 128 => {4669 128 => {
4945 const f = val.toFloat(f128);4670 const f = val.toFloat(f128, mod);
4946 return Value.Tag.float_128.create(arena, @fabs(f));4671 return Value.Tag.float_128.create(arena, @fabs(f));
4947 },4672 },
4948 else => unreachable,4673 else => unreachable,
...@@ -4950,39 +4675,38 @@ pub const Value = struct {...@@ -4950,39 +4675,38 @@ pub const Value = struct {
4950 }4675 }
49514676
4952 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4677 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4953 const target = mod.getTarget();
4954 if (float_type.zigTypeTag(mod) == .Vector) {4678 if (float_type.zigTypeTag(mod) == .Vector) {
4955 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4679 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4956 for (result_data, 0..) |*scalar, i| {4680 for (result_data, 0..) |*scalar, i| {
4957 var buf: Value.ElemValueBuffer = undefined;4681 const elem_val = try val.elemValue(mod, i);
4958 const elem_val = val.elemValueBuffer(mod, i, &buf);4682 scalar.* = try floorScalar(elem_val, float_type.scalarType(mod), arena, mod);
4959 scalar.* = try floorScalar(elem_val, float_type.scalarType(mod), arena, target);
4960 }4683 }
4961 return Value.Tag.aggregate.create(arena, result_data);4684 return Value.Tag.aggregate.create(arena, result_data);
4962 }4685 }
4963 return floorScalar(val, float_type, arena, target);4686 return floorScalar(val, float_type, arena, mod);
4964 }4687 }
49654688
4966 pub fn floorScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4689 pub fn floorScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4690 const target = mod.getTarget();
4967 switch (float_type.floatBits(target)) {4691 switch (float_type.floatBits(target)) {
4968 16 => {4692 16 => {
4969 const f = val.toFloat(f16);4693 const f = val.toFloat(f16, mod);
4970 return Value.Tag.float_16.create(arena, @floor(f));4694 return Value.Tag.float_16.create(arena, @floor(f));
4971 },4695 },
4972 32 => {4696 32 => {
4973 const f = val.toFloat(f32);4697 const f = val.toFloat(f32, mod);
4974 return Value.Tag.float_32.create(arena, @floor(f));4698 return Value.Tag.float_32.create(arena, @floor(f));
4975 },4699 },
4976 64 => {4700 64 => {
4977 const f = val.toFloat(f64);4701 const f = val.toFloat(f64, mod);
4978 return Value.Tag.float_64.create(arena, @floor(f));4702 return Value.Tag.float_64.create(arena, @floor(f));
4979 },4703 },
4980 80 => {4704 80 => {
4981 const f = val.toFloat(f80);4705 const f = val.toFloat(f80, mod);
4982 return Value.Tag.float_80.create(arena, @floor(f));4706 return Value.Tag.float_80.create(arena, @floor(f));
4983 },4707 },
4984 128 => {4708 128 => {
4985 const f = val.toFloat(f128);4709 const f = val.toFloat(f128, mod);
4986 return Value.Tag.float_128.create(arena, @floor(f));4710 return Value.Tag.float_128.create(arena, @floor(f));
4987 },4711 },
4988 else => unreachable,4712 else => unreachable,
...@@ -4990,39 +4714,38 @@ pub const Value = struct {...@@ -4990,39 +4714,38 @@ pub const Value = struct {
4990 }4714 }
49914715
4992 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4716 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
4993 const target = mod.getTarget();
4994 if (float_type.zigTypeTag(mod) == .Vector) {4717 if (float_type.zigTypeTag(mod) == .Vector) {
4995 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4718 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
4996 for (result_data, 0..) |*scalar, i| {4719 for (result_data, 0..) |*scalar, i| {
4997 var buf: Value.ElemValueBuffer = undefined;4720 const elem_val = try val.elemValue(mod, i);
4998 const elem_val = val.elemValueBuffer(mod, i, &buf);4721 scalar.* = try ceilScalar(elem_val, float_type.scalarType(mod), arena, mod);
4999 scalar.* = try ceilScalar(elem_val, float_type.scalarType(mod), arena, target);
5000 }4722 }
5001 return Value.Tag.aggregate.create(arena, result_data);4723 return Value.Tag.aggregate.create(arena, result_data);
5002 }4724 }
5003 return ceilScalar(val, float_type, arena, target);4725 return ceilScalar(val, float_type, arena, mod);
5004 }4726 }
50054727
5006 pub fn ceilScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4728 pub fn ceilScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4729 const target = mod.getTarget();
5007 switch (float_type.floatBits(target)) {4730 switch (float_type.floatBits(target)) {
5008 16 => {4731 16 => {
5009 const f = val.toFloat(f16);4732 const f = val.toFloat(f16, mod);
5010 return Value.Tag.float_16.create(arena, @ceil(f));4733 return Value.Tag.float_16.create(arena, @ceil(f));
5011 },4734 },
5012 32 => {4735 32 => {
5013 const f = val.toFloat(f32);4736 const f = val.toFloat(f32, mod);
5014 return Value.Tag.float_32.create(arena, @ceil(f));4737 return Value.Tag.float_32.create(arena, @ceil(f));
5015 },4738 },
5016 64 => {4739 64 => {
5017 const f = val.toFloat(f64);4740 const f = val.toFloat(f64, mod);
5018 return Value.Tag.float_64.create(arena, @ceil(f));4741 return Value.Tag.float_64.create(arena, @ceil(f));
5019 },4742 },
5020 80 => {4743 80 => {
5021 const f = val.toFloat(f80);4744 const f = val.toFloat(f80, mod);
5022 return Value.Tag.float_80.create(arena, @ceil(f));4745 return Value.Tag.float_80.create(arena, @ceil(f));
5023 },4746 },
5024 128 => {4747 128 => {
5025 const f = val.toFloat(f128);4748 const f = val.toFloat(f128, mod);
5026 return Value.Tag.float_128.create(arena, @ceil(f));4749 return Value.Tag.float_128.create(arena, @ceil(f));
5027 },4750 },
5028 else => unreachable,4751 else => unreachable,
...@@ -5030,39 +4753,38 @@ pub const Value = struct {...@@ -5030,39 +4753,38 @@ pub const Value = struct {
5030 }4753 }
50314754
5032 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4755 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5033 const target = mod.getTarget();
5034 if (float_type.zigTypeTag(mod) == .Vector) {4756 if (float_type.zigTypeTag(mod) == .Vector) {
5035 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4757 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
5036 for (result_data, 0..) |*scalar, i| {4758 for (result_data, 0..) |*scalar, i| {
5037 var buf: Value.ElemValueBuffer = undefined;4759 const elem_val = try val.elemValue(mod, i);
5038 const elem_val = val.elemValueBuffer(mod, i, &buf);4760 scalar.* = try roundScalar(elem_val, float_type.scalarType(mod), arena, mod);
5039 scalar.* = try roundScalar(elem_val, float_type.scalarType(mod), arena, target);
5040 }4761 }
5041 return Value.Tag.aggregate.create(arena, result_data);4762 return Value.Tag.aggregate.create(arena, result_data);
5042 }4763 }
5043 return roundScalar(val, float_type, arena, target);4764 return roundScalar(val, float_type, arena, mod);
5044 }4765 }
50454766
5046 pub fn roundScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4767 pub fn roundScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4768 const target = mod.getTarget();
5047 switch (float_type.floatBits(target)) {4769 switch (float_type.floatBits(target)) {
5048 16 => {4770 16 => {
5049 const f = val.toFloat(f16);4771 const f = val.toFloat(f16, mod);
5050 return Value.Tag.float_16.create(arena, @round(f));4772 return Value.Tag.float_16.create(arena, @round(f));
5051 },4773 },
5052 32 => {4774 32 => {
5053 const f = val.toFloat(f32);4775 const f = val.toFloat(f32, mod);
5054 return Value.Tag.float_32.create(arena, @round(f));4776 return Value.Tag.float_32.create(arena, @round(f));
5055 },4777 },
5056 64 => {4778 64 => {
5057 const f = val.toFloat(f64);4779 const f = val.toFloat(f64, mod);
5058 return Value.Tag.float_64.create(arena, @round(f));4780 return Value.Tag.float_64.create(arena, @round(f));
5059 },4781 },
5060 80 => {4782 80 => {
5061 const f = val.toFloat(f80);4783 const f = val.toFloat(f80, mod);
5062 return Value.Tag.float_80.create(arena, @round(f));4784 return Value.Tag.float_80.create(arena, @round(f));
5063 },4785 },
5064 128 => {4786 128 => {
5065 const f = val.toFloat(f128);4787 const f = val.toFloat(f128, mod);
5066 return Value.Tag.float_128.create(arena, @round(f));4788 return Value.Tag.float_128.create(arena, @round(f));
5067 },4789 },
5068 else => unreachable,4790 else => unreachable,
...@@ -5070,39 +4792,38 @@ pub const Value = struct {...@@ -5070,39 +4792,38 @@ pub const Value = struct {
5070 }4792 }
50714793
5072 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {4794 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
5073 const target = mod.getTarget();
5074 if (float_type.zigTypeTag(mod) == .Vector) {4795 if (float_type.zigTypeTag(mod) == .Vector) {
5075 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4796 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
5076 for (result_data, 0..) |*scalar, i| {4797 for (result_data, 0..) |*scalar, i| {
5077 var buf: Value.ElemValueBuffer = undefined;4798 const elem_val = try val.elemValue(mod, i);
5078 const elem_val = val.elemValueBuffer(mod, i, &buf);4799 scalar.* = try truncScalar(elem_val, float_type.scalarType(mod), arena, mod);
5079 scalar.* = try truncScalar(elem_val, float_type.scalarType(mod), arena, target);
5080 }4800 }
5081 return Value.Tag.aggregate.create(arena, result_data);4801 return Value.Tag.aggregate.create(arena, result_data);
5082 }4802 }
5083 return truncScalar(val, float_type, arena, target);4803 return truncScalar(val, float_type, arena, mod);
5084 }4804 }
50854805
5086 pub fn truncScalar(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {4806 pub fn truncScalar(val: Value, float_type: Type, arena: Allocator, mod: *const Module) Allocator.Error!Value {
4807 const target = mod.getTarget();
5087 switch (float_type.floatBits(target)) {4808 switch (float_type.floatBits(target)) {
5088 16 => {4809 16 => {
5089 const f = val.toFloat(f16);4810 const f = val.toFloat(f16, mod);
5090 return Value.Tag.float_16.create(arena, @trunc(f));4811 return Value.Tag.float_16.create(arena, @trunc(f));
5091 },4812 },
5092 32 => {4813 32 => {
5093 const f = val.toFloat(f32);4814 const f = val.toFloat(f32, mod);
5094 return Value.Tag.float_32.create(arena, @trunc(f));4815 return Value.Tag.float_32.create(arena, @trunc(f));
5095 },4816 },
5096 64 => {4817 64 => {
5097 const f = val.toFloat(f64);4818 const f = val.toFloat(f64, mod);
5098 return Value.Tag.float_64.create(arena, @trunc(f));4819 return Value.Tag.float_64.create(arena, @trunc(f));
5099 },4820 },
5100 80 => {4821 80 => {
5101 const f = val.toFloat(f80);4822 const f = val.toFloat(f80, mod);
5102 return Value.Tag.float_80.create(arena, @trunc(f));4823 return Value.Tag.float_80.create(arena, @trunc(f));
5103 },4824 },
5104 128 => {4825 128 => {
5105 const f = val.toFloat(f128);4826 const f = val.toFloat(f128, mod);
5106 return Value.Tag.float_128.create(arena, @trunc(f));4827 return Value.Tag.float_128.create(arena, @trunc(f));
5107 },4828 },
5108 else => unreachable,4829 else => unreachable,
...@@ -5117,28 +4838,24 @@ pub const Value = struct {...@@ -5117,28 +4838,24 @@ pub const Value = struct {
5117 arena: Allocator,4838 arena: Allocator,
5118 mod: *Module,4839 mod: *Module,
5119 ) !Value {4840 ) !Value {
5120 const target = mod.getTarget();
5121 if (float_type.zigTypeTag(mod) == .Vector) {4841 if (float_type.zigTypeTag(mod) == .Vector) {
5122 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));4842 const result_data = try arena.alloc(Value, float_type.vectorLen(mod));
5123 for (result_data, 0..) |*scalar, i| {4843 for (result_data, 0..) |*scalar, i| {
5124 var mulend1_buf: Value.ElemValueBuffer = undefined;4844 const mulend1_elem = try mulend1.elemValue(mod, i);
5125 const mulend1_elem = mulend1.elemValueBuffer(mod, i, &mulend1_buf);4845 const mulend2_elem = try mulend2.elemValue(mod, i);
5126 var mulend2_buf: Value.ElemValueBuffer = undefined;4846 const addend_elem = try addend.elemValue(mod, i);
5127 const mulend2_elem = mulend2.elemValueBuffer(mod, i, &mulend2_buf);
5128 var addend_buf: Value.ElemValueBuffer = undefined;
5129 const addend_elem = addend.elemValueBuffer(mod, i, &addend_buf);
5130 scalar.* = try mulAddScalar(4847 scalar.* = try mulAddScalar(
5131 float_type.scalarType(mod),4848 float_type.scalarType(mod),
5132 mulend1_elem,4849 mulend1_elem,
5133 mulend2_elem,4850 mulend2_elem,
5134 addend_elem,4851 addend_elem,
5135 arena,4852 arena,
5136 target,4853 mod,
5137 );4854 );
5138 }4855 }
5139 return Value.Tag.aggregate.create(arena, result_data);4856 return Value.Tag.aggregate.create(arena, result_data);
5140 }4857 }
5141 return mulAddScalar(float_type, mulend1, mulend2, addend, arena, target);4858 return mulAddScalar(float_type, mulend1, mulend2, addend, arena, mod);
5142 }4859 }
51434860
5144 pub fn mulAddScalar(4861 pub fn mulAddScalar(
...@@ -5147,37 +4864,38 @@ pub const Value = struct {...@@ -5147,37 +4864,38 @@ pub const Value = struct {
5147 mulend2: Value,4864 mulend2: Value,
5148 addend: Value,4865 addend: Value,
5149 arena: Allocator,4866 arena: Allocator,
5150 target: Target,4867 mod: *const Module,
5151 ) Allocator.Error!Value {4868 ) Allocator.Error!Value {
4869 const target = mod.getTarget();
5152 switch (float_type.floatBits(target)) {4870 switch (float_type.floatBits(target)) {
5153 16 => {4871 16 => {
5154 const m1 = mulend1.toFloat(f16);4872 const m1 = mulend1.toFloat(f16, mod);
5155 const m2 = mulend2.toFloat(f16);4873 const m2 = mulend2.toFloat(f16, mod);
5156 const a = addend.toFloat(f16);4874 const a = addend.toFloat(f16, mod);
5157 return Value.Tag.float_16.create(arena, @mulAdd(f16, m1, m2, a));4875 return Value.Tag.float_16.create(arena, @mulAdd(f16, m1, m2, a));
5158 },4876 },
5159 32 => {4877 32 => {
5160 const m1 = mulend1.toFloat(f32);4878 const m1 = mulend1.toFloat(f32, mod);
5161 const m2 = mulend2.toFloat(f32);4879 const m2 = mulend2.toFloat(f32, mod);
5162 const a = addend.toFloat(f32);4880 const a = addend.toFloat(f32, mod);
5163 return Value.Tag.float_32.create(arena, @mulAdd(f32, m1, m2, a));4881 return Value.Tag.float_32.create(arena, @mulAdd(f32, m1, m2, a));
5164 },4882 },
5165 64 => {4883 64 => {
5166 const m1 = mulend1.toFloat(f64);4884 const m1 = mulend1.toFloat(f64, mod);
5167 const m2 = mulend2.toFloat(f64);4885 const m2 = mulend2.toFloat(f64, mod);
5168 const a = addend.toFloat(f64);4886 const a = addend.toFloat(f64, mod);
5169 return Value.Tag.float_64.create(arena, @mulAdd(f64, m1, m2, a));4887 return Value.Tag.float_64.create(arena, @mulAdd(f64, m1, m2, a));
5170 },4888 },
5171 80 => {4889 80 => {
5172 const m1 = mulend1.toFloat(f80);4890 const m1 = mulend1.toFloat(f80, mod);
5173 const m2 = mulend2.toFloat(f80);4891 const m2 = mulend2.toFloat(f80, mod);
5174 const a = addend.toFloat(f80);4892 const a = addend.toFloat(f80, mod);
5175 return Value.Tag.float_80.create(arena, @mulAdd(f80, m1, m2, a));4893 return Value.Tag.float_80.create(arena, @mulAdd(f80, m1, m2, a));
5176 },4894 },
5177 128 => {4895 128 => {
5178 const m1 = mulend1.toFloat(f128);4896 const m1 = mulend1.toFloat(f128, mod);
5179 const m2 = mulend2.toFloat(f128);4897 const m2 = mulend2.toFloat(f128, mod);
5180 const a = addend.toFloat(f128);4898 const a = addend.toFloat(f128, mod);
5181 return Value.Tag.float_128.create(arena, @mulAdd(f128, m1, m2, a));4899 return Value.Tag.float_128.create(arena, @mulAdd(f128, m1, m2, a));
5182 },4900 },
5183 else => unreachable,4901 else => unreachable,
...@@ -5186,13 +4904,14 @@ pub const Value = struct {...@@ -5186,13 +4904,14 @@ pub const Value = struct {
51864904
5187 /// If the value is represented in-memory as a series of bytes that all4905 /// If the value is represented in-memory as a series of bytes that all
5188 /// have the same value, return that byte value, otherwise null.4906 /// have the same value, return that byte value, otherwise null.
5189 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module, value_buffer: *Payload.U64) !?Value {4907 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module) !?Value {
5190 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;4908 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;
5191 assert(abi_size >= 1);4909 assert(abi_size >= 1);
5192 const byte_buffer = try mod.gpa.alloc(u8, abi_size);4910 const byte_buffer = try mod.gpa.alloc(u8, abi_size);
5193 defer mod.gpa.free(byte_buffer);4911 defer mod.gpa.free(byte_buffer);
51944912
5195 writeToMemory(val, ty, mod, byte_buffer) catch |err| switch (err) {4913 writeToMemory(val, ty, mod, byte_buffer) catch |err| switch (err) {
4914 error.OutOfMemory => return error.OutOfMemory,
5196 error.ReinterpretDeclRef => return null,4915 error.ReinterpretDeclRef => return null,
5197 // TODO: The writeToMemory function was originally created for the purpose4916 // TODO: The writeToMemory function was originally created for the purpose
5198 // of comptime pointer casting. However, it is now additionally being used4917 // of comptime pointer casting. However, it is now additionally being used
...@@ -5206,11 +4925,7 @@ pub const Value = struct {...@@ -5206,11 +4925,7 @@ pub const Value = struct {
5206 for (byte_buffer[1..]) |byte| {4925 for (byte_buffer[1..]) |byte| {
5207 if (byte != first_byte) return null;4926 if (byte != first_byte) return null;
5208 }4927 }
5209 value_buffer.* = .{4928 return try mod.intValue(Type.u8, first_byte);
5210 .base = .{ .tag = .int_u64 },
5211 .data = first_byte,
5212 };
5213 return initPayload(&value_buffer.base);
5214 }4929 }
52154930
5216 pub fn isGenericPoison(val: Value) bool {4931 pub fn isGenericPoison(val: Value) bool {
...@@ -5226,30 +4941,6 @@ pub const Value = struct {...@@ -5226,30 +4941,6 @@ pub const Value = struct {
5226 data: u32,4941 data: u32,
5227 };4942 };
52284943
5229 pub const U64 = struct {
5230 base: Payload,
5231 data: u64,
5232 };
5233
5234 pub const I64 = struct {
5235 base: Payload,
5236 data: i64,
5237 };
5238
5239 pub const BigInt = struct {
5240 base: Payload,
5241 data: []const std.math.big.Limb,
5242
5243 pub fn asBigInt(self: BigInt) BigIntConst {
5244 const positive = switch (self.base.tag) {
5245 .int_big_positive => true,
5246 .int_big_negative => false,
5247 else => unreachable,
5248 };
5249 return BigIntConst{ .limbs = self.data, .positive = positive };
5250 }
5251 };
5252
5253 pub const Function = struct {4944 pub const Function = struct {
5254 base: Payload,4945 base: Payload,
5255 data: *Module.Fn,4946 data: *Module.Fn,
...@@ -5452,12 +5143,9 @@ pub const Value = struct {...@@ -5452,12 +5143,9 @@ pub const Value = struct {
54525143
5453 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;5144 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;
54545145
5455 pub const zero = initTag(.zero);5146 pub const zero: Value = .{ .ip_index = .zero, .legacy = undefined };
5456 pub const one = initTag(.one);5147 pub const one: Value = .{ .ip_index = .one, .legacy = undefined };
5457 pub const negative_one: Value = .{5148 pub const negative_one: Value = .{ .ip_index = .negative_one, .legacy = undefined };
5458 .ip_index = .none,
5459 .legacy = .{ .ptr_otherwise = &negative_one_payload.base },
5460 };
5461 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };5149 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };
5462 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };5150 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };
5463 pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };5151 pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined };
...@@ -5515,8 +5203,3 @@ pub const Value = struct {...@@ -5515,8 +5203,3 @@ pub const Value = struct {
5515 }5203 }
5516 }5204 }
5517};5205};
5518
5519var negative_one_payload: Value.Payload.I64 = .{
5520 .base = .{ .tag = .int_i64 },
5521 .data = -1,
5522};