| author | |
| committer | |
| log | 75900ec1b5a250935a6abe050a006738fba99e66 |
| tree | 9d3dd571b59648a585c3ce5bcdb2dbb50a574d58 |
| parent | 73720b6975e2650ece48cc5f38495c091360c6c9 |
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 | } }, |
| 626 | 628 | ||
| 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 { |
| 1137 | 1144 | ||
| 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 | }), // name | 6601 | }), // name |
| 6602 | try Value.Tag.decl_ref.create(arena, test_decl_index), // func | 6602 | try Value.Tag.decl_ref.create(arena, test_decl_index), // func |
| 6603 | Value.null, // async_frame_size | 6603 | 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); |
| 6634 | 6634 | ||
| ... | @@ -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 | } |
| 6877 | 6877 | ||
| 6878 | pub 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 | |||
| 6886 | pub 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 | |||
| 6894 | pub 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 | |||
| 6902 | pub 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 | |||
| 6878 | pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type { | 6910 | pub 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. |
| 6908 | pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 { | 6940 | pub 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 | } |
| 6938 | 6965 |
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) and | 38 | 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 }; |
| 53 | 53 | ||
| 54 | /// Assumes a and b do not overlap | 54 | /// Assumes a and b do not overlap |
| 55 | fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool { | 55 | fn 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 | } |
| 58 | 58 | ||
| 59 | pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool { | 59 | pub 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 | } |
| 3093 | 3088 | ||
| 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(); |
| 5182 | 5177 | ||
| 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); |
| 5189 | 5188 | ||
| 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 | } |
| 5195 | 5197 | ||
| ... | @@ -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(); |
| 8097 | 8099 | ||
| 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 | }, |
| 8117 | 8121 | ||
| 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 | } |
| 8281 | 8285 | ||
| 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 | } |
| 8287 | 8290 | ||
| ... | @@ -9685,7 +9688,7 @@ fn intCast( | ... | @@ -9685,7 +9688,7 @@ fn intCast( |
| 9685 | // range shrinkage | 9688 | // range shrinkage |
| 9686 | // requirement: int value fits into target type | 9689 | // 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 | else | 9694 | 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 | } |
| 9947 | 9950 | ||
| 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; |
| 10476 | 10479 | ||
| ... | @@ -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(); |
| 10828 | 10831 | ||
| 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 | } |
| 10932 | 10935 | ||
| 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(); |
| 10938 | 10941 | ||
| ... | @@ -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 | } |
| 11002 | 11005 | ||
| ... | @@ -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; |
| 11059 | 11062 | ||
| 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; |
| 11085 | 11088 | ||
| 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 and | 11134 | 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 |
| 11182 | 11185 | ||
| 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; |
| 11188 | 11191 | ||
| ... | @@ -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; |
| 11247 | 11250 | ||
| 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; |
| 11253 | 11256 | ||
| ... | @@ -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 |
| 11289 | 11292 | ||
| 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; |
| 11295 | 11298 | ||
| 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 false | 11341 | } else false |
| 11339 | else | 11342 | 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; |
| 11477 | 11480 | ||
| 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; |
| 11482 | 11485 | ||
| ... | @@ -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 | }; |
| 11593 | 11596 | ||
| ... | @@ -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; |
| 11600 | 11603 | ||
| 11601 | if (sema.mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and | 11604 | 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); |
| 11683 | 11686 | ||
| 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); |
| 12313 | 12310 | ||
| 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); |
| 12469 | 12460 | ||
| 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(); |
| 12697 | 12687 | ||
| 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 |
| 12714 | 12705 | ||
| 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 | }; |
| 12723 | 12714 | ||
| 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 | }; |
| 12782 | 12773 | ||
| 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); |
| 12843 | 12833 | ||
| 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(); |
| 13011 | 13001 | ||
| 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 | } |
| 13026 | 13017 | ||
| 13027 | // Analyze the lhs first, to catch the case that someone tried to do exponentiation | 13018 | // 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); |
| 13050 | 13040 | ||
| 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); |
| 13052 | 13042 | ||
| 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, such | 13055 | // 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 | } |
| 13071 | 13061 | ||
| ... | @@ -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); |
| 13091 | 13081 | ||
| 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 | } |
| 13798 | 13788 | ||
| 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 | else | 13793 | 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 | } |
| 13811 | 13801 | ||
| 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 | } |
| 13816 | 13806 | ||
| 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 | } |
| 14052 | 14041 | ||
| 14053 | fn intRemScalar( | 14042 | fn 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 without | 14044 | // 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 | } |
| 14084 | 14069 | ||
| 14085 | fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 14070 | fn 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: u32 | 15813 | // 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); |
| 15832 | 15817 | ||
| 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 | }; |
| 15983 | 15968 | ||
| ... | @@ -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); |
| 16026 | 16011 | ||
| 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)); |
| 16039 | 16024 | ||
| 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 | else | 16037 | else |
| 16053 | try info.pointee_type.lazyAbiAlignment(mod, sema.arena); | 16038 | try info.pointee_type.lazyAbiAlignment(mod, sema.arena); |
| 16054 | 16039 | ||
| ... | @@ -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); |
| 16108 | 16093 | ||
| ... | @@ -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); |
| 16265 | 16250 | ||
| 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()); | ||
| 16268 | 16252 | ||
| 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 | }; |
| 16404 | 16388 | ||
| ... | @@ -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 | }; |
| 16482 | 16466 | ||
| ... | @@ -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 | }; |
| 16524 | 16508 | ||
| ... | @@ -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 | }; |
| 16567 | 16551 | ||
| ... | @@ -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(); |
| 16641 | 16626 | ||
| ... | @@ -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 | } |
| 16682 | 16667 | ||
| ... | @@ -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 | }; |
| 16719 | 16704 | ||
| ... | @@ -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); |
| 18622 | 18607 | ||
| 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 | } |
| 18719 | 18703 | ||
| 18720 | fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 18704 | fn 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); |
| 18850 | 18839 | ||
| 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); |
| 18853 | 18842 | ||
| 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; |
| 18895 | 18884 | ||
| 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 here | 18932 | // 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); |
| 18948 | 18936 | ||
| 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 |
| 19061 | 19049 | ||
| 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 here | 19054 | // TODO use reflection instead of magic numbers here |
| 19067 | // name: []const u8 | 19055 | // 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 | ); |
| 19077 | 19065 | ||
| 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_tagged | 19171 | 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 |
| 19236 | 19224 | ||
| 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 here | 19229 | // TODO use reflection instead of magic numbers here |
| 19242 | // name: []const u8 | 19230 | // 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 | ); |
| 19254 | 19242 | ||
| 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); |
| 19298 | 19286 | ||
| 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); |
| 19301 | 19289 | ||
| 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); |
| 19310 | 19298 | ||
| 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); |
| 19313 | 19301 | ||
| 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 here | 19379 | // 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 here | 19478 | // TODO use reflection instead of magic numbers here |
| 19492 | // name: []const u8 | 19479 | // 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)}); |
| 19894 | 19881 | ||
| 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 | } |
| 19902 | 19884 | ||
| 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 | } |
| 19909 | 19891 | ||
| 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 and | 20278 | 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); |
| 20361 | 20332 | ||
| 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); |
| 20430 | 20400 | ||
| 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); |
| 20479 | 20448 | ||
| 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); |
| 21243 | 21211 | ||
| 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( |
| 21359 | 21326 | ||
| 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( |
| 21398 | 21364 | ||
| 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); |
| 21511 | 21476 | ||
| 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 | } |
| 21523 | 21487 | ||
| ... | @@ -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 floats | 22068 | if (elem_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats |
| 22107 | 22069 | ||
| 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 undef | 22074 | 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 alignment | 24145 | 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 | else | 25880 | 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 already | 27398 | 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 already | 27404 | 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 | } |
| 27594 | 27558 | ||
| 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(); |
| 28115 | 28079 | ||
| 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; |
| 28134 | 28098 | ||
| ... | @@ -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 that | 28114 | // 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 | } |
| 28155 | 28119 | ||
| 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 slice | 28149 | // 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 | }, |
| 28331 | 28295 | ||
| 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( |
| 28342 | 28300 | ||
| 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 | }; |
| 28347 | 28308 | ||
| 28348 | if (deref.pointee) |tv| { | 28309 | if (deref.pointee) |tv| { |
| ... | @@ -28373,9 +28334,9 @@ fn bitCast( | ... | @@ -28373,9 +28334,9 @@ fn bitCast( |
| 28373 | 28334 | ||
| 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 already | 28373 | 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 location | 28748 | const src = inst_src; // TODO better source location |
| 28787 | const elem_src = inst_src; // TODO better source location | 28749 | 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)); |
| 29638 | 29600 | ||
| 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 | else | 29660 | else |
| ... | @@ -29712,13 +29672,10 @@ fn analyzeSlice( | ... | @@ -29712,13 +29672,10 @@ fn analyzeSlice( |
| 29712 | ); | 29672 | ); |
| 29713 | } | 29673 | } |
| 29714 | 29674 | ||
| 29715 | // If the slice has a sentinel, we subtract one so that | 29675 | // If the slice has a sentinel, we consider end_is_len |
| 29716 | // end_is_len is only true if it equals the length WITHOUT | 29676 | // 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 | } |
| 30136 | 30093 | ||
| 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 | } |
| 30195 | 30152 | ||
| 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 | } |
| 32463 | 32421 | ||
| 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 | } |
| 33208 | 33163 | ||
| 33209 | fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { | 33164 | fn 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 | } |
| 33212 | 33168 | ||
| 33213 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { | 33169 | fn 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 | } |
| 33847 | 33806 | ||
| 33848 | fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value { | 33807 | fn 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 without | 33809 | // 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 | } |
| 33864 | 33823 | ||
| 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 | } |
| 33886 | 33845 | ||
| 33887 | fn intSub( | 33846 | fn 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 | } |
| 33907 | 33860 | ||
| 33908 | fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value { | 33861 | fn 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 without | 33863 | // 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 | } |
| 33924 | 33877 | ||
| 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; |
| 34172 | 34120 | ||
| 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(); |
| 34187 | 34135 | ||
| 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); | ||
| 34193 | 34137 | ||
| 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, |
| 34220 | 34164 | ||
| 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 => { |
| 34237 | 34167 | 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 | }, |
| 34319 | 34186 | ||
| 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 | }, |
| 34342 | 34206 | ||
| 34343 | .aggregate => { | 34207 | .aggregate => { |
| ... | @@ -34354,22 +34218,22 @@ fn intFitsInType( | ... | @@ -34354,22 +34218,22 @@ fn intFitsInType( |
| 34354 | else => unreachable, | 34218 | else => unreachable, |
| 34355 | }, | 34219 | }, |
| 34356 | 34220 | ||
| 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 | } |
| 34360 | 34232 | ||
| 34361 | fn intInRange( | 34233 | fn 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 | } |
| 43 | 43 | ||
| 44 | pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value { | 44 | pub 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 | } |
| 47 | 47 | ||
| 48 | const max_aggregate_items = 100; | 48 | const max_aggregate_items = 100; |
| ... | @@ -157,14 +157,8 @@ pub fn print( | ... | @@ -157,14 +157,8 @@ pub fn print( |
| 157 | 157 | ||
| 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( |
| 313 | 307 | ||
| 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 integer | 3162 | 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); |
| 4900 | 4900 | ||
| 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); | ||
| 4904 | 4903 | ||
| 4905 | try func.emitWValue(result); | 4904 | try func.emitWValue(result); |
| 4906 | 4905 | ||
| ... | @@ -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 { |
| 4920 | 4919 | ||
| 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 | else | 4925 | 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 | }); |
| 2759 | 2759 | ||
| 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); | ||
| 2765 | 2762 | ||
| 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(); |
| 4907 | 4904 | ||
| 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); | ||
| 454 | 455 | ||
| 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(); |
| 675 | 676 | ||
| 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 | } |
| 962 | 963 | ||
| 963 | // generate length | 964 | // 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( |
| 1283 | 1280 | ||
| 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); |
| 570 | 570 | ||
| 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); | ||
| 576 | 572 | ||
| 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 | } |
| 598 | 594 | ||
| 599 | // Renders a "parent" pointer by recursing to the root decl/variable | 595 | /// 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_ptr | 598 | /// 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; |
| 605 | 607 | ||
| 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); |
| 663 | 668 | ||
| 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); | ||
| 669 | 670 | ||
| 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); |
| 953 | 954 | ||
| 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 | }; |
| 964 | 965 | ||
| 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 | } |
| 973 | 974 | ||
| 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); | ||
| 981 | 976 | ||
| 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 get | 1027 | // 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 { |
| 1116 | 1098 | ||
| 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(); | ||
| 1176 | 1162 | ||
| 1177 | // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal | 1163 | // 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; |
| 1179 | 1165 | ||
| 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); |
| 1363 | 1349 | ||
| 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); | ||
| 1366 | 1351 | ||
| 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; |
| 1395 | 1380 | ||
| 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(", "); |
| 1411 | 1397 | ||
| 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(')'); |
| 1429 | 1415 | ||
| 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 | } |
| 1437 | 1424 | ||
| 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 | } |
| 1453 | 1440 | ||
| 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 { |
| 1951 | 1938 | ||
| 1952 | if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); | 1939 | if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); |
| 1953 | 1940 | ||
| 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(','); |
| 2497 | 2484 | ||
| 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); | ||
| 2500 | 2486 | ||
| 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); |
| 2550 | 2536 | ||
| 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); | ||
| 2553 | 2538 | ||
| 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); |
| 2562 | 2547 | ||
| 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); | ||
| 2565 | 2549 | ||
| 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); |
| 3397 | 3381 | ||
| 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)); |
| 3399 | 3383 | 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); | ||
| 3405 | 3384 | ||
| 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))); |
| 3407 | 3386 | ||
| ... | @@ -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) orelse | 3554 | 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); | ||
| 3589 | 3557 | ||
| 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); |
| 3706 | 3674 | ||
| 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)); |
| 3708 | 3676 | 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); | ||
| 3714 | 3677 | ||
| 3715 | const src_bits = src_ty.bitSize(mod); | 3678 | const src_bits = src_ty.bitSize(mod); |
| 3716 | 3679 | ||
| ... | @@ -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); |
| 3727 | 3690 | ||
| 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); | ||
| 3733 | 3692 | ||
| 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); |
| 5358 | 5317 | ||
| 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); | ||
| 5364 | 5319 | ||
| 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); |
| 5414 | 5369 | ||
| 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); | ||
| 5420 | 5371 | ||
| 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 { |
| 5466 | 5417 | ||
| 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)); |
| 5468 | 5419 | ||
| 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); | ||
| 5474 | 5422 | ||
| 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).signedness | 5424 | 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("; "); |
| 5856 | 5804 | ||
| 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)}); |
| 5862 | 5808 | ||
| ... | @@ -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 operands | 6579 | 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("] = "); |
| 6644 | 6585 | ||
| 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 | }; | ||
| 6651 | 6588 | ||
| 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 | } |
| 6657 | 6594 | ||
| ... | @@ -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(); |
| 6731 | 6668 | ||
| 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 { |
| 6879 | 6814 | ||
| 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)); |
| 6881 | 6816 | ||
| 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); | ||
| 6884 | 6818 | ||
| 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 | } |
| 6926 | 6860 | ||
| 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(')'); |
| 6932 | 6867 | ||
| 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 | } |
| 6936 | 6871 | ||
| ... | @@ -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); |
| 6978 | 6913 | ||
| 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); | ||
| 6981 | 6915 | ||
| 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 | }; | ||
| 7647 | 7577 | ||
| 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)); |
| 7754 | 7684 | ||
| 7755 | const local = try f.allocLocal(inst, Type.usize); | 7685 | const local = try f.allocLocal(inst, Type.usize); |
| 7756 | 7686 | ||
| ... | @@ -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"); |
| 12 | const Compilation = @import("../Compilation.zig"); | 12 | const Compilation = @import("../Compilation.zig"); |
| 13 | const build_options = @import("build_options"); | 13 | const build_options = @import("build_options"); |
| 14 | const Module = @import("../Module.zig"); | 14 | const Module = @import("../Module.zig"); |
| 15 | const InternPool = @import("../InternPool.zig"); | ||
| 15 | const Package = @import("../Package.zig"); | 16 | const Package = @import("../Package.zig"); |
| 16 | const TypedValue = @import("../TypedValue.zig"); | 17 | const TypedValue = @import("../TypedValue.zig"); |
| 17 | const Air = @import("../Air.zig"); | 18 | const 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); |
| 1536 | 1537 | ||
| 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); | ||
| 1540 | 1540 | ||
| 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); | ||
| 3282 | 3279 | ||
| 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 first | 3339 | // 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 { |
| 3592 | 3588 | ||
| 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 | } |
| 3598 | 3594 | ||
| ... | @@ -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 | } |
| 3976 | 3962 | ||
| 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); |
| 8528 | 8508 | ||
| 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 a | 8516 | // repeating byte pattern, for example, `@as(u64, 0)` has a |
| 8537 | // repeating byte pattern of 0 bytes. In such case, the memset | 8517 | // 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 { |
| 8829 | 8808 | ||
| 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); |
| 9123 | 9096 | ||
| 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 and | 584 | // 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 dependency | 588 | // 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); | ||
| 748 | 747 | ||
| 749 | const int_ty = ty.intTagType(); | 748 | const int_ty = ty.intTagType(); |
| 750 | 749 | ||
| ... | @@ -787,22 +786,24 @@ pub const DeclGen = struct { | ... | @@ -787,22 +786,24 @@ pub const DeclGen = struct { |
| 787 | 786 | ||
| 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; |
| 806 | 807 | ||
| 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, // TODO | 1000 | 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 | } |
| 1532 | 1533 | ||
| 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 { |
| 2087 | 2089 | ||
| 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 constants | 3151 | 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/645 | 423 | // 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 | } |
| 2078 | 2078 | ||
| 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 | } |
| 2086 | 2086 | ||
| ... | @@ -2468,10 +2468,10 @@ pub const Type = struct { | ... | @@ -2468,10 +2468,10 @@ pub const Type = struct { |
| 2468 | } | 2468 | } |
| 2469 | 2469 | ||
| 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 | } |
| 2477 | 2477 | ||
| ... | @@ -4310,8 +4310,8 @@ pub const Type = struct { | ... | @@ -4310,8 +4310,8 @@ pub const Type = struct { |
| 4310 | } | 4310 | } |
| 4311 | 4311 | ||
| 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 | } |
| 4321 | 4321 | ||
| 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); |
| 4326 | 4325 | 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 | } | ||
| 4334 | 4327 | ||
| 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 | } |
| 4339 | 4332 | ||
| 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); |
| 4342 | 4337 | ||
| 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 | } |
| 4350 | 4340 | ||
| 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 | } |
| 4360 | 4350 | ||
| 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); |
| 4365 | 4354 | ||
| 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, |
| 4369 | 4358 | .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 | } |
| 4375 | 4366 | ||
| 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 | }; |
| 4386 | 4377 | ||
| 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); |
| 4389 | 4382 | ||
| 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 | } |
| 4397 | 4385 | ||
| 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.py | 33 | // 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, |
| 40 | 38 | ||
| ... | @@ -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. |
| 44 | 42 | ||
| 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 global | 46 | /// 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 { |
| 129 | 123 | ||
| 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"), |
| 138 | 130 | ||
| 139 | .int_big_positive, | ||
| 140 | .int_big_negative, | ||
| 141 | => Payload.BigInt, | ||
| 142 | |||
| 143 | .extern_fn => Payload.ExternFn, | 131 | .extern_fn => Payload.ExternFn, |
| 144 | 132 | ||
| 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, |
| 171 | 159 | ||
| 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 { |
| 661 | 625 | ||
| 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 | } |
| 697 | 660 | ||
| 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, u0 | 757 | .the_only_possible_value, // i0, u0 |
| 807 | => BigIntMutable.init(&space.limbs, 0).toConst(), | 758 | => BigIntMutable.init(&space.limbs, 0).toConst(), |
| 808 | 759 | ||
| 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, u0 | 816 | .the_only_possible_value, // i0, u0 |
| 874 | => return 0, | 817 | => return 0, |
| 875 | 818 | ||
| 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, u0 | 861 | .the_only_possible_value, // i0, u0 |
| 927 | => return 0, | 862 | => return 0, |
| 928 | 863 | ||
| 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; |
| 1024 | 938 | ||
| 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); | ||
| 1027 | 940 | ||
| 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, since | 1034 | /// 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)); |
| 1149 | 1066 | ||
| 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); | ||
| 1152 | 1068 | ||
| 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 { |
| 1181 | 1096 | ||
| 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 default | 1100 | // 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 <= u64 | 1178 | 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-int | 1189 | } 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 { |
| 1277 | 1193 | ||
| 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 <= u64 | 1299 | 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-int | 1302 | } 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 { |
| 1390 | 1306 | ||
| 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 | } |
| 1445 | 1361 | ||
| 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), |
| 1454 | 1370 | .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 | } |
| 1475 | 1388 | ||
| ... | @@ -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 | } |
| 1624 | 1488 | ||
| 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()); |
| 1627 | 1491 | ||
| 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); |
| 1639 | 1503 | ||
| 1640 | return fromBigInt(arena, result_bigint.toConst()); | 1504 | return mod.intValue_big(ty, result_bigint.toConst()); |
| 1641 | } | 1505 | } |
| 1642 | 1506 | ||
| 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()); |
| 1645 | 1509 | ||
| 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); |
| 1660 | 1524 | ||
| 1661 | return fromBigInt(arena, result_bigint.toConst()); | 1525 | return mod.intValue_big(ty, result_bigint.toConst()); |
| 1662 | } | 1526 | } |
| 1663 | 1527 | ||
| 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(), | ||
| 1685 | 1537 | ||
| 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 { |
| 1715 | 1567 | ||
| 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 float | 1582 | /// 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, | ||
| 1763 | 1610 | ||
| 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), | ||
| 1784 | 1626 | ||
| 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 | } |
| 1885 | 1727 | ||
| ... | @@ -1929,15 +1771,13 @@ pub const Value = struct { | ... | @@ -1929,15 +1771,13 @@ pub const Value = struct { |
| 1929 | 1771 | ||
| 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); |
| 2296 | 2132 | ||
| 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 | }, |
| 2663 | 2503 | ||
| 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 { |
| 2720 | 2554 | ||
| 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 { |
| 2751 | 2569 | ||
| 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 | }, |
| 2778 | 2580 | ||
| 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, |
| 2781 | 2583 | ||
| 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), |
| 2784 | 2586 | ||
| 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 | }, |
| 2801 | 2603 | ||
| ... | @@ -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, |
| 2805 | 2607 | ||
| 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), |
| 2808 | 2610 | ||
| 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), |
| 2811 | 2613 | ||
| 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 element | 2806 | /// 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 marked | 2807 | /// 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); |
| 3014 | 2816 | ||
| 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 | }, |
| 3022 | 2822 | ||
| 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 { |
| 3036 | 2836 | ||
| 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, |
| 3046 | 2852 | ||
| 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. |
| 3049 | 2855 | ||
| 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), | ||
| 3061 | 2857 | ||
| 3062 | .inferred_alloc => unreachable, | 2858 | .inferred_alloc => unreachable, |
| 3063 | .inferred_alloc_comptime => unreachable, | 2859 | .inferred_alloc_comptime => unreachable, |
| 3064 | 2860 | ||
| 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 | } |
| 3070 | 2872 | ||
| ... | @@ -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, |
| 3088 | 2887 | else => unreachable, | |
| 3089 | else => null, | ||
| 3090 | }, | 2888 | }, |
| 3091 | else => null, | 2889 | else => unreachable, |
| 3092 | }; | 2890 | }; |
| 3093 | } | 2891 | } |
| 3094 | 2892 | ||
| ... | @@ -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 | } |
| 3204 | 2994 | ||
| ... | @@ -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 | }; |
| 3240 | 3030 | ||
| 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 | } |
| 3304 | 3077 | ||
| 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 | } |
| 3352 | 3124 | ||
| 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 { |
| 3408 | 3179 | ||
| 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 | } |
| 3414 | 3185 | ||
| ... | @@ -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 | } |
| 3515 | 3282 | ||
| 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 { |
| 3572 | 3338 | ||
| 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 | } |
| 3577 | 3343 | ||
| 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 | } |
| 3593 | 3357 | ||
| 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; |
| 3597 | 3361 | ||
| 3598 | // TODO is this a performance issue? maybe we should try the operation without | 3362 | // 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 | } |
| 3613 | 3377 | ||
| 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; |
| 3633 | 3395 | ||
| 3634 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); | 3396 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); |
| 3635 | 3397 | 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 | } |
| 3643 | 3400 | ||
| ... | @@ -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 | } |
| 3659 | 3414 | ||
| 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; |
| 3663 | 3418 | ||
| 3664 | // TODO is this a performance issue? maybe we should try the operation without | 3419 | // 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 | } |
| 3678 | 3433 | ||
| 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 | } |
| 3694 | 3448 | ||
| 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; |
| 3698 | 3452 | ||
| 3699 | // TODO is this a performance issue? maybe we should try the operation without | 3453 | // 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 | } |
| 3714 | 3468 | ||
| 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 | } |
| 3729 | 3482 | ||
| 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 without | 3484 | // 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 | } |
| 3754 | 3507 | ||
| 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 | } |
| 3769 | 3521 | ||
| 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 without | 3523 | // 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 | } |
| 3794 | 3546 | ||
| 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 | } |
| 3809 | 3560 | ||
| 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 without | 3562 | // 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 | } |
| 3834 | 3585 | ||
| 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 | } |
| 3878 | 3629 | ||
| 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 | } |
| 3894 | 3642 | ||
| 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 | } |
| 3925 | 3674 | ||
| 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 | } |
| 3941 | 3687 | ||
| 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 | } |
| 3987 | 3733 | ||
| 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 without | 3735 | // 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 | } |
| 4008 | 3754 | ||
| 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 | } |
| 4021 | 3767 | ||
| 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 | } |
| 4044 | 3789 | ||
| 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; |
| 4047 | 3799 | ||
| 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 }; |
| 4056 | 3808 | ||
| 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 | } |
| 4060 | 3812 | ||
| 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 | } |
| 4075 | 3826 | ||
| 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 without | 3828 | // 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 | } |
| 4094 | 3845 | ||
| 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 | } |
| 4152 | 3901 | ||
| ... | @@ -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 | } |
| 4200 | 3947 | ||
| 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 | } |
| 4249 | 3993 | ||
| 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 without | 3995 | // 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 | } |
| 4280 | 4024 | ||
| 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 | } |
| 4299 | 4041 | ||
| 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 | } |
| 4337 | 4077 | ||
| 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 | } |
| 4396 | 4134 | ||
| 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 | } |
| 4455 | 4191 | ||
| 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 | } |
| 4514 | 4248 | ||
| 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 | } |
| 4551 | 4286 | ||
| 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 | } |
| 4565 | 4298 | ||
| 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 | } |
| 4591 | 4325 | ||
| 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 | } |
| 4605 | 4337 | ||
| 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 | } |
| 4631 | 4364 | ||
| 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 | } |
| 4645 | 4376 | ||
| 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 | } |
| 4671 | 4403 | ||
| 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 | } |
| 4685 | 4415 | ||
| 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 | } |
| 4711 | 4442 | ||
| 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 | } |
| 4725 | 4454 | ||
| 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 | } |
| 4751 | 4481 | ||
| 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 | } |
| 4765 | 4493 | ||
| 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 | } |
| 4791 | 4520 | ||
| 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 | } |
| 4805 | 4532 | ||
| 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 | } |
| 4831 | 4559 | ||
| 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 | } |
| 4845 | 4571 | ||
| 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 | } |
| 4871 | 4598 | ||
| 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 | } |
| 4885 | 4610 | ||
| 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 | } |
| 4911 | 4637 | ||
| 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 | } |
| 4925 | 4649 | ||
| 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 | } |
| 4951 | 4676 | ||
| 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 | } |
| 4965 | 4688 | ||
| 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 | } |
| 4991 | 4715 | ||
| 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 | } |
| 5005 | 4727 | ||
| 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 | } |
| 5031 | 4754 | ||
| 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 | } |
| 5045 | 4766 | ||
| 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 | } |
| 5071 | 4793 | ||
| 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 | } |
| 5085 | 4805 | ||
| 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 | } |
| 5143 | 4860 | ||
| 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 { |
| 5186 | 4904 | ||
| 5187 | /// If the value is represented in-memory as a series of bytes that all | 4905 | /// 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); |
| 5194 | 4912 | ||
| 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 purpose | 4916 | // TODO: The writeToMemory function was originally created for the purpose |
| 5198 | // of comptime pointer casting. However, it is now additionally being used | 4917 | // 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 | } |
| 5215 | 4930 | ||
| 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 | }; |
| 5228 | 4943 | ||
| 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 { |
| 5452 | 5143 | ||
| 5453 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; | 5144 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; |
| 5454 | 5145 | ||
| 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 | |||
| 5519 | var negative_one_payload: Value.Payload.I64 = .{ | ||
| 5520 | .base = .{ .tag = .int_i64 }, | ||
| 5521 | .data = -1, | ||
| 5522 | }; |