| author | |
| committer | |
| log | b4bb64ce78bf2dee9437f366a362ef4d8c77b204 |
| tree | 218658e59522e59a432b6e9adea9f1993c0fb51d |
| parent | 849c31a6cc3d1e554f97c2ccf7aaa886070cfadd |
| signature |
32 files changed, 7330 insertions(+), 7120 deletions(-)
src/InternPool.zig+2-2| ... | ... | @@ -3483,7 +3483,7 @@ pub const LoadedStructType = struct { |
| 3483 | 3483 | return s.field_aligns.get(ip)[i]; |
| 3484 | 3484 | } |
| 3485 | 3485 | |
| 3486 | pub fn fieldInit(s: LoadedStructType, ip: *InternPool, i: usize) Index { | |
| 3486 | pub fn fieldInit(s: LoadedStructType, ip: *const InternPool, i: usize) Index { | |
| 3487 | 3487 | if (s.field_inits.len == 0) return .none; |
| 3488 | 3488 | assert(s.haveFieldInits(ip)); |
| 3489 | 3489 | return s.field_inits.get(ip)[i]; |
| ... | ... | @@ -11066,7 +11066,7 @@ pub fn destroyNamespace( |
| 11066 | 11066 | local.mutate.namespaces.free_list = @intFromEnum(namespace_index); |
| 11067 | 11067 | } |
| 11068 | 11068 | |
| 11069 | pub fn filePtr(ip: *InternPool, file_index: FileIndex) *Zcu.File { | |
| 11069 | pub fn filePtr(ip: *const InternPool, file_index: FileIndex) *Zcu.File { | |
| 11070 | 11070 | const file_index_unwrapped = file_index.unwrap(ip); |
| 11071 | 11071 | const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire(); |
| 11072 | 11072 | return files.view().items(.file)[file_index_unwrapped.index]; |
src/RangeSet.zig+15-15| ... | ... | @@ -9,7 +9,7 @@ const Zcu = @import("Zcu.zig"); |
| 9 | 9 | const RangeSet = @This(); |
| 10 | 10 | const LazySrcLoc = Zcu.LazySrcLoc; |
| 11 | 11 | |
| 12 | pt: Zcu.PerThread, | |
| 12 | zcu: *Zcu, | |
| 13 | 13 | ranges: std.ArrayList(Range), |
| 14 | 14 | |
| 15 | 15 | pub const Range = struct { |
| ... | ... | @@ -18,9 +18,9 @@ pub const Range = struct { |
| 18 | 18 | src: LazySrcLoc, |
| 19 | 19 | }; |
| 20 | 20 | |
| 21 | pub fn init(allocator: std.mem.Allocator, pt: Zcu.PerThread) RangeSet { | |
| 21 | pub fn init(allocator: std.mem.Allocator, zcu: *Zcu) RangeSet { | |
| 22 | 22 | return .{ |
| 23 | .pt = pt, | |
| 23 | .zcu = zcu, | |
| 24 | 24 | .ranges = std.ArrayList(Range).init(allocator), |
| 25 | 25 | }; |
| 26 | 26 | } |
| ... | ... | @@ -35,8 +35,8 @@ pub fn add( |
| 35 | 35 | last: InternPool.Index, |
| 36 | 36 | src: LazySrcLoc, |
| 37 | 37 | ) !?LazySrcLoc { |
| 38 | const pt = self.pt; | |
| 39 | const ip = &pt.zcu.intern_pool; | |
| 38 | const zcu = self.zcu; | |
| 39 | const ip = &zcu.intern_pool; | |
| 40 | 40 | |
| 41 | 41 | const ty = ip.typeOf(first); |
| 42 | 42 | assert(ty == ip.typeOf(last)); |
| ... | ... | @@ -45,8 +45,8 @@ pub fn add( |
| 45 | 45 | assert(ty == ip.typeOf(range.first)); |
| 46 | 46 | assert(ty == ip.typeOf(range.last)); |
| 47 | 47 | |
| 48 | if (Value.fromInterned(last).compareScalar(.gte, Value.fromInterned(range.first), Type.fromInterned(ty), pt) and | |
| 49 | Value.fromInterned(first).compareScalar(.lte, Value.fromInterned(range.last), Type.fromInterned(ty), pt)) | |
| 48 | if (Value.fromInterned(last).compareScalar(.gte, Value.fromInterned(range.first), Type.fromInterned(ty), zcu) and | |
| 49 | Value.fromInterned(first).compareScalar(.lte, Value.fromInterned(range.last), Type.fromInterned(ty), zcu)) | |
| 50 | 50 | { |
| 51 | 51 | return range.src; // They overlap. |
| 52 | 52 | } |
| ... | ... | @@ -61,20 +61,20 @@ pub fn add( |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | /// Assumes a and b do not overlap |
| 64 | fn lessThan(pt: Zcu.PerThread, a: Range, b: Range) bool { | |
| 65 | const ty = Type.fromInterned(pt.zcu.intern_pool.typeOf(a.first)); | |
| 66 | return Value.fromInterned(a.first).compareScalar(.lt, Value.fromInterned(b.first), ty, pt); | |
| 64 | fn lessThan(zcu: *Zcu, a: Range, b: Range) bool { | |
| 65 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(a.first)); | |
| 66 | return Value.fromInterned(a.first).compareScalar(.lt, Value.fromInterned(b.first), ty, zcu); | |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) !bool { |
| 70 | const pt = self.pt; | |
| 71 | const ip = &pt.zcu.intern_pool; | |
| 70 | const zcu = self.zcu; | |
| 71 | const ip = &zcu.intern_pool; | |
| 72 | 72 | assert(ip.typeOf(first) == ip.typeOf(last)); |
| 73 | 73 | |
| 74 | 74 | if (self.ranges.items.len == 0) |
| 75 | 75 | return false; |
| 76 | 76 | |
| 77 | std.mem.sort(Range, self.ranges.items, pt, lessThan); | |
| 77 | std.mem.sort(Range, self.ranges.items, zcu, lessThan); | |
| 78 | 78 | |
| 79 | 79 | if (self.ranges.items[0].first != first or |
| 80 | 80 | self.ranges.items[self.ranges.items.len - 1].last != last) |
| ... | ... | @@ -93,10 +93,10 @@ pub fn spans(self: *RangeSet, first: InternPool.Index, last: InternPool.Index) ! |
| 93 | 93 | const prev = self.ranges.items[i]; |
| 94 | 94 | |
| 95 | 95 | // prev.last + 1 == cur.first |
| 96 | try counter.copy(Value.fromInterned(prev.last).toBigInt(&space, pt)); | |
| 96 | try counter.copy(Value.fromInterned(prev.last).toBigInt(&space, zcu)); | |
| 97 | 97 | try counter.addScalar(&counter, 1); |
| 98 | 98 | |
| 99 | const cur_start_int = Value.fromInterned(cur.first).toBigInt(&space, pt); | |
| 99 | const cur_start_int = Value.fromInterned(cur.first).toBigInt(&space, zcu); | |
| 100 | 100 | if (!cur_start_int.eql(counter.toConst())) { |
| 101 | 101 | return false; |
| 102 | 102 | } |
src/Sema.zig+2143-2144| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | //! This is the the heart of the Zig compiler. |
| 7 | 7 | |
| 8 | 8 | pt: Zcu.PerThread, |
| 9 | /// Alias to `mod.gpa`. | |
| 9 | /// Alias to `zcu.gpa`. | |
| 10 | 10 | gpa: Allocator, |
| 11 | 11 | /// Points to the temporary arena allocator of the Sema. |
| 12 | 12 | /// This arena will be cleared when the sema is destroyed. |
| ... | ... | @@ -67,7 +67,7 @@ generic_call_src: LazySrcLoc = LazySrcLoc.unneeded, |
| 67 | 67 | /// breaking from a block. |
| 68 | 68 | post_hoc_blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, *LabeledBlock) = .{}, |
| 69 | 69 | /// Populated with the last compile error created. |
| 70 | err: ?*Module.ErrorMsg = null, | |
| 70 | err: ?*Zcu.ErrorMsg = null, | |
| 71 | 71 | /// Set to true when analyzing a func type instruction so that nested generic |
| 72 | 72 | /// function types will emit generic poison instead of a partial type. |
| 73 | 73 | no_partial_func_ty: bool = false, |
| ... | ... | @@ -172,11 +172,10 @@ const Type = @import("Type.zig"); |
| 172 | 172 | const Air = @import("Air.zig"); |
| 173 | 173 | const Zir = std.zig.Zir; |
| 174 | 174 | const Zcu = @import("Zcu.zig"); |
| 175 | const Module = Zcu; | |
| 176 | 175 | const trace = @import("tracy.zig").trace; |
| 177 | const Namespace = Module.Namespace; | |
| 178 | const CompileError = Module.CompileError; | |
| 179 | const SemaError = Module.SemaError; | |
| 176 | const Namespace = Zcu.Namespace; | |
| 177 | const CompileError = Zcu.CompileError; | |
| 178 | const SemaError = Zcu.SemaError; | |
| 180 | 179 | const LazySrcLoc = Zcu.LazySrcLoc; |
| 181 | 180 | const RangeSet = @import("RangeSet.zig"); |
| 182 | 181 | const target_util = @import("target.zig"); |
| ... | ... | @@ -431,7 +430,7 @@ pub const Block = struct { |
| 431 | 430 | return_ty: Type, |
| 432 | 431 | }, |
| 433 | 432 | |
| 434 | fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Module.ErrorMsg) !void { | |
| 433 | fn explain(cr: ComptimeReason, sema: *Sema, msg: ?*Zcu.ErrorMsg) !void { | |
| 435 | 434 | const parent = msg orelse return; |
| 436 | 435 | const pt = sema.pt; |
| 437 | 436 | const prefix = "expression is evaluated at comptime because "; |
| ... | ... | @@ -733,12 +732,12 @@ pub const Block = struct { |
| 733 | 732 | fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref { |
| 734 | 733 | const sema = block.sema; |
| 735 | 734 | const pt = sema.pt; |
| 736 | const mod = pt.zcu; | |
| 735 | const zcu = pt.zcu; | |
| 737 | 736 | return block.addInst(.{ |
| 738 | 737 | .tag = if (block.float_mode == .optimized) .cmp_vector_optimized else .cmp_vector, |
| 739 | 738 | .data = .{ .ty_pl = .{ |
| 740 | 739 | .ty = Air.internedToRef((try pt.vectorType(.{ |
| 741 | .len = sema.typeOf(lhs).vectorLen(mod), | |
| 740 | .len = sema.typeOf(lhs).vectorLen(zcu), | |
| 742 | 741 | .child = .bool_type, |
| 743 | 742 | })).toIntern()), |
| 744 | 743 | .payload = try sema.addExtra(Air.VectorCmp{ |
| ... | ... | @@ -852,7 +851,7 @@ const LabeledBlock = struct { |
| 852 | 851 | /// The value stored in the inferred allocation. This will go into |
| 853 | 852 | /// peer type resolution. This is stored in a separate list so that |
| 854 | 853 | /// the items are contiguous in memory and thus can be passed to |
| 855 | /// `Module.resolvePeerTypes`. | |
| 854 | /// `Zcu.resolvePeerTypes`. | |
| 856 | 855 | const InferredAlloc = struct { |
| 857 | 856 | /// The placeholder `store` instructions used before the result pointer type |
| 858 | 857 | /// is known. These should be rewritten to perform any required coercions |
| ... | ... | @@ -1950,7 +1949,7 @@ fn resolveDestType( |
| 1950 | 1949 | builtin_name: []const u8, |
| 1951 | 1950 | ) !Type { |
| 1952 | 1951 | const pt = sema.pt; |
| 1953 | const mod = pt.zcu; | |
| 1952 | const zcu = pt.zcu; | |
| 1954 | 1953 | const remove_eu = switch (strat) { |
| 1955 | 1954 | .remove_eu_opt, .remove_eu => true, |
| 1956 | 1955 | .remove_opt => false, |
| ... | ... | @@ -1980,15 +1979,15 @@ fn resolveDestType( |
| 1980 | 1979 | else => |e| return e, |
| 1981 | 1980 | }; |
| 1982 | 1981 | |
| 1983 | if (remove_eu and raw_ty.zigTypeTag(mod) == .ErrorUnion) { | |
| 1984 | const eu_child = raw_ty.errorUnionPayload(mod); | |
| 1985 | if (remove_opt and eu_child.zigTypeTag(mod) == .Optional) { | |
| 1986 | return eu_child.childType(mod); | |
| 1982 | if (remove_eu and raw_ty.zigTypeTag(zcu) == .ErrorUnion) { | |
| 1983 | const eu_child = raw_ty.errorUnionPayload(zcu); | |
| 1984 | if (remove_opt and eu_child.zigTypeTag(zcu) == .Optional) { | |
| 1985 | return eu_child.childType(zcu); | |
| 1987 | 1986 | } |
| 1988 | 1987 | return eu_child; |
| 1989 | 1988 | } |
| 1990 | if (remove_opt and raw_ty.zigTypeTag(mod) == .Optional) { | |
| 1991 | return raw_ty.childType(mod); | |
| 1989 | if (remove_opt and raw_ty.zigTypeTag(zcu) == .Optional) { | |
| 1990 | return raw_ty.childType(zcu); | |
| 1992 | 1991 | } |
| 1993 | 1992 | return raw_ty; |
| 1994 | 1993 | } |
| ... | ... | @@ -2068,10 +2067,10 @@ fn analyzeAsType( |
| 2068 | 2067 | |
| 2069 | 2068 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { |
| 2070 | 2069 | const pt = sema.pt; |
| 2071 | const mod = pt.zcu; | |
| 2072 | const comp = mod.comp; | |
| 2070 | const zcu = pt.zcu; | |
| 2071 | const comp = zcu.comp; | |
| 2073 | 2072 | const gpa = sema.gpa; |
| 2074 | const ip = &mod.intern_pool; | |
| 2073 | const ip = &zcu.intern_pool; | |
| 2075 | 2074 | if (!comp.config.any_error_tracing) return; |
| 2076 | 2075 | |
| 2077 | 2076 | assert(!block.is_comptime); |
| ... | ... | @@ -2140,9 +2139,9 @@ fn resolveDefinedValue( |
| 2140 | 2139 | air_ref: Air.Inst.Ref, |
| 2141 | 2140 | ) CompileError!?Value { |
| 2142 | 2141 | const pt = sema.pt; |
| 2143 | const mod = pt.zcu; | |
| 2142 | const zcu = pt.zcu; | |
| 2144 | 2143 | const val = try sema.resolveValue(air_ref) orelse return null; |
| 2145 | if (val.isUndef(mod)) { | |
| 2144 | if (val.isUndef(zcu)) { | |
| 2146 | 2145 | return sema.failWithUseOfUndef(block, src); |
| 2147 | 2146 | } |
| 2148 | 2147 | return val; |
| ... | ... | @@ -2340,12 +2339,12 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: |
| 2340 | 2339 | |
| 2341 | 2340 | fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazySrcLoc, container_ty: Type, field_index: usize) CompileError { |
| 2342 | 2341 | const pt = sema.pt; |
| 2343 | const mod = pt.zcu; | |
| 2342 | const zcu = pt.zcu; | |
| 2344 | 2343 | const msg = msg: { |
| 2345 | 2344 | const msg = try sema.errMsg(init_src, "value stored in comptime field does not match the default value of the field", .{}); |
| 2346 | 2345 | errdefer msg.destroy(sema.gpa); |
| 2347 | 2346 | |
| 2348 | const struct_type = mod.typeToStruct(container_ty) orelse break :msg msg; | |
| 2347 | const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg; | |
| 2349 | 2348 | try sema.errNote(.{ |
| 2350 | 2349 | .base_node_inst = struct_type.zir_index.unwrap().?, |
| 2351 | 2350 | .offset = .{ .container_field_value = @intCast(field_index) }, |
| ... | ... | @@ -2372,12 +2371,12 @@ fn failWithInvalidFieldAccess( |
| 2372 | 2371 | field_name: InternPool.NullTerminatedString, |
| 2373 | 2372 | ) CompileError { |
| 2374 | 2373 | const pt = sema.pt; |
| 2375 | const mod = pt.zcu; | |
| 2376 | const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty; | |
| 2374 | const zcu = pt.zcu; | |
| 2375 | const inner_ty = if (object_ty.isSinglePointer(zcu)) object_ty.childType(zcu) else object_ty; | |
| 2377 | 2376 | |
| 2378 | if (inner_ty.zigTypeTag(mod) == .Optional) opt: { | |
| 2379 | const child_ty = inner_ty.optionalChild(mod); | |
| 2380 | if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt; | |
| 2377 | if (inner_ty.zigTypeTag(zcu) == .Optional) opt: { | |
| 2378 | const child_ty = inner_ty.optionalChild(zcu); | |
| 2379 | if (!typeSupportsFieldAccess(zcu, child_ty, field_name)) break :opt; | |
| 2381 | 2380 | const msg = msg: { |
| 2382 | 2381 | const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(pt)}); |
| 2383 | 2382 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -2385,9 +2384,9 @@ fn failWithInvalidFieldAccess( |
| 2385 | 2384 | break :msg msg; |
| 2386 | 2385 | }; |
| 2387 | 2386 | return sema.failWithOwnedErrorMsg(block, msg); |
| 2388 | } else if (inner_ty.zigTypeTag(mod) == .ErrorUnion) err: { | |
| 2389 | const child_ty = inner_ty.errorUnionPayload(mod); | |
| 2390 | if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err; | |
| 2387 | } else if (inner_ty.zigTypeTag(zcu) == .ErrorUnion) err: { | |
| 2388 | const child_ty = inner_ty.errorUnionPayload(zcu); | |
| 2389 | if (!typeSupportsFieldAccess(zcu, child_ty, field_name)) break :err; | |
| 2391 | 2390 | const msg = msg: { |
| 2392 | 2391 | const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(pt)}); |
| 2393 | 2392 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -2399,15 +2398,15 @@ fn failWithInvalidFieldAccess( |
| 2399 | 2398 | return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(pt)}); |
| 2400 | 2399 | } |
| 2401 | 2400 | |
| 2402 | fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool { | |
| 2403 | const ip = &mod.intern_pool; | |
| 2404 | switch (ty.zigTypeTag(mod)) { | |
| 2401 | fn typeSupportsFieldAccess(zcu: *const Zcu, ty: Type, field_name: InternPool.NullTerminatedString) bool { | |
| 2402 | const ip = &zcu.intern_pool; | |
| 2403 | switch (ty.zigTypeTag(zcu)) { | |
| 2405 | 2404 | .Array => return field_name.eqlSlice("len", ip), |
| 2406 | 2405 | .Pointer => { |
| 2407 | const ptr_info = ty.ptrInfo(mod); | |
| 2406 | const ptr_info = ty.ptrInfo(zcu); | |
| 2408 | 2407 | if (ptr_info.flags.size == .Slice) { |
| 2409 | 2408 | return field_name.eqlSlice("ptr", ip) or field_name.eqlSlice("len", ip); |
| 2410 | } else if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Array) { | |
| 2409 | } else if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .Array) { | |
| 2411 | 2410 | return field_name.eqlSlice("len", ip); |
| 2412 | 2411 | } else return false; |
| 2413 | 2412 | }, |
| ... | ... | @@ -2423,9 +2422,9 @@ fn failWithComptimeErrorRetTrace( |
| 2423 | 2422 | name: InternPool.NullTerminatedString, |
| 2424 | 2423 | ) CompileError { |
| 2425 | 2424 | const pt = sema.pt; |
| 2426 | const mod = pt.zcu; | |
| 2425 | const zcu = pt.zcu; | |
| 2427 | 2426 | const msg = msg: { |
| 2428 | const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)}); | |
| 2427 | const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&zcu.intern_pool)}); | |
| 2429 | 2428 | errdefer msg.destroy(sema.gpa); |
| 2430 | 2429 | |
| 2431 | 2430 | for (sema.comptime_err_ret_trace.items) |src_loc| { |
| ... | ... | @@ -2451,7 +2450,7 @@ fn failWithInvalidPtrArithmetic(sema: *Sema, block: *Block, src: LazySrcLoc, ari |
| 2451 | 2450 | pub fn errNote( |
| 2452 | 2451 | sema: *Sema, |
| 2453 | 2452 | src: LazySrcLoc, |
| 2454 | parent: *Module.ErrorMsg, | |
| 2453 | parent: *Zcu.ErrorMsg, | |
| 2455 | 2454 | comptime format: []const u8, |
| 2456 | 2455 | args: anytype, |
| 2457 | 2456 | ) error{OutOfMemory}!void { |
| ... | ... | @@ -2462,7 +2461,7 @@ fn addFieldErrNote( |
| 2462 | 2461 | sema: *Sema, |
| 2463 | 2462 | container_ty: Type, |
| 2464 | 2463 | field_index: usize, |
| 2465 | parent: *Module.ErrorMsg, | |
| 2464 | parent: *Zcu.ErrorMsg, | |
| 2466 | 2465 | comptime format: []const u8, |
| 2467 | 2466 | args: anytype, |
| 2468 | 2467 | ) !void { |
| ... | ... | @@ -2480,9 +2479,9 @@ pub fn errMsg( |
| 2480 | 2479 | src: LazySrcLoc, |
| 2481 | 2480 | comptime format: []const u8, |
| 2482 | 2481 | args: anytype, |
| 2483 | ) Allocator.Error!*Module.ErrorMsg { | |
| 2482 | ) Allocator.Error!*Zcu.ErrorMsg { | |
| 2484 | 2483 | assert(src.offset != .unneeded); |
| 2485 | return Module.ErrorMsg.create(sema.gpa, src, format, args); | |
| 2484 | return Zcu.ErrorMsg.create(sema.gpa, src, format, args); | |
| 2486 | 2485 | } |
| 2487 | 2486 | |
| 2488 | 2487 | pub fn fail( |
| ... | ... | @@ -2501,16 +2500,16 @@ pub fn fail( |
| 2501 | 2500 | return sema.failWithOwnedErrorMsg(block, err_msg); |
| 2502 | 2501 | } |
| 2503 | 2502 | |
| 2504 | pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) error{ AnalysisFail, OutOfMemory } { | |
| 2503 | pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg) error{ AnalysisFail, OutOfMemory } { | |
| 2505 | 2504 | @setCold(true); |
| 2506 | 2505 | const gpa = sema.gpa; |
| 2507 | const mod = sema.pt.zcu; | |
| 2506 | const zcu = sema.pt.zcu; | |
| 2508 | 2507 | |
| 2509 | if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) { | |
| 2508 | if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) { | |
| 2510 | 2509 | var all_references: ?std.AutoHashMapUnmanaged(AnalUnit, ?Zcu.ResolvedReference) = null; |
| 2511 | 2510 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 2512 | 2511 | wip_errors.init(gpa) catch @panic("out of memory"); |
| 2513 | Compilation.addModuleErrorMsg(mod, &wip_errors, err_msg.*, &all_references) catch @panic("out of memory"); | |
| 2512 | Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, &all_references) catch @panic("out of memory"); | |
| 2514 | 2513 | std.debug.print("compile error during Sema:\n", .{}); |
| 2515 | 2514 | var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory"); |
| 2516 | 2515 | error_bundle.renderToStdErr(.{ .ttyconf = .no_color }); |
| ... | ... | @@ -2530,12 +2529,12 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error |
| 2530 | 2529 | } |
| 2531 | 2530 | } |
| 2532 | 2531 | |
| 2533 | const use_ref_trace = if (mod.comp.reference_trace) |n| n > 0 else mod.failed_analysis.count() == 0; | |
| 2532 | const use_ref_trace = if (zcu.comp.reference_trace) |n| n > 0 else zcu.failed_analysis.count() == 0; | |
| 2534 | 2533 | if (use_ref_trace) { |
| 2535 | 2534 | err_msg.reference_trace_root = sema.owner.toOptional(); |
| 2536 | 2535 | } |
| 2537 | 2536 | |
| 2538 | const gop = try mod.failed_analysis.getOrPut(gpa, sema.owner); | |
| 2537 | const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner); | |
| 2539 | 2538 | if (gop.found_existing) { |
| 2540 | 2539 | // If there are multiple errors for the same Decl, prefer the first one added. |
| 2541 | 2540 | sema.err = null; |
| ... | ... | @@ -2554,7 +2553,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error |
| 2554 | 2553 | fn reparentOwnedErrorMsg( |
| 2555 | 2554 | sema: *Sema, |
| 2556 | 2555 | src: LazySrcLoc, |
| 2557 | msg: *Module.ErrorMsg, | |
| 2556 | msg: *Zcu.ErrorMsg, | |
| 2558 | 2557 | comptime format: []const u8, |
| 2559 | 2558 | args: anytype, |
| 2560 | 2559 | ) !void { |
| ... | ... | @@ -2562,7 +2561,7 @@ fn reparentOwnedErrorMsg( |
| 2562 | 2561 | |
| 2563 | 2562 | const orig_notes = msg.notes.len; |
| 2564 | 2563 | msg.notes = try sema.gpa.realloc(msg.notes, orig_notes + 1); |
| 2565 | std.mem.copyBackwards(Module.ErrorMsg, msg.notes[1..], msg.notes[0..orig_notes]); | |
| 2564 | std.mem.copyBackwards(Zcu.ErrorMsg, msg.notes[1..], msg.notes[0..orig_notes]); | |
| 2566 | 2565 | msg.notes[0] = .{ |
| 2567 | 2566 | .src_loc = msg.src_loc, |
| 2568 | 2567 | .msg = msg.msg, |
| ... | ... | @@ -2644,7 +2643,7 @@ fn analyzeAsInt( |
| 2644 | 2643 | ) !u64 { |
| 2645 | 2644 | const coerced = try sema.coerce(block, dest_ty, air_ref, src); |
| 2646 | 2645 | const val = try sema.resolveConstDefinedValue(block, src, coerced, reason); |
| 2647 | return (try val.getUnsignedIntAdvanced(sema.pt, .sema)).?; | |
| 2646 | return try val.toUnsignedIntSema(sema.pt); | |
| 2648 | 2647 | } |
| 2649 | 2648 | |
| 2650 | 2649 | /// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`, |
| ... | ... | @@ -2722,9 +2721,9 @@ fn zirStructDecl( |
| 2722 | 2721 | inst: Zir.Inst.Index, |
| 2723 | 2722 | ) CompileError!Air.Inst.Ref { |
| 2724 | 2723 | const pt = sema.pt; |
| 2725 | const mod = pt.zcu; | |
| 2724 | const zcu = pt.zcu; | |
| 2726 | 2725 | const gpa = sema.gpa; |
| 2727 | const ip = &mod.intern_pool; | |
| 2726 | const ip = &zcu.intern_pool; | |
| 2728 | 2727 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); |
| 2729 | 2728 | const extra = sema.code.extraData(Zir.Inst.StructDecl, extended.operand); |
| 2730 | 2729 | |
| ... | ... | @@ -2786,7 +2785,7 @@ fn zirStructDecl( |
| 2786 | 2785 | |
| 2787 | 2786 | // Make sure we update the namespace if the declaration is re-analyzed, to pick |
| 2788 | 2787 | // up on e.g. changed comptime decls. |
| 2789 | try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(mod)); | |
| 2788 | try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu)); | |
| 2790 | 2789 | |
| 2791 | 2790 | try sema.declareDependency(.{ .interned = new_ty }); |
| 2792 | 2791 | try sema.addTypeReferenceEntry(src, new_ty); |
| ... | ... | @@ -2807,8 +2806,8 @@ fn zirStructDecl( |
| 2807 | 2806 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 2808 | 2807 | .parent = block.namespace.toOptional(), |
| 2809 | 2808 | .owner_type = wip_ty.index, |
| 2810 | .file_scope = block.getFileScopeIndex(mod), | |
| 2811 | .generation = mod.generation, | |
| 2809 | .file_scope = block.getFileScopeIndex(zcu), | |
| 2810 | .generation = zcu.generation, | |
| 2812 | 2811 | }); |
| 2813 | 2812 | errdefer pt.destroyNamespace(new_namespace_index); |
| 2814 | 2813 | |
| ... | ... | @@ -2825,11 +2824,11 @@ fn zirStructDecl( |
| 2825 | 2824 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| 2826 | 2825 | try pt.scanNamespace(new_namespace_index, decls); |
| 2827 | 2826 | |
| 2828 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 2827 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 2829 | 2828 | codegen_type: { |
| 2830 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 2829 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 2831 | 2830 | if (block.ownerModule().strip) break :codegen_type; |
| 2832 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 2831 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 2833 | 2832 | } |
| 2834 | 2833 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 2835 | 2834 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -2938,9 +2937,9 @@ fn zirEnumDecl( |
| 2938 | 2937 | defer tracy.end(); |
| 2939 | 2938 | |
| 2940 | 2939 | const pt = sema.pt; |
| 2941 | const mod = pt.zcu; | |
| 2940 | const zcu = pt.zcu; | |
| 2942 | 2941 | const gpa = sema.gpa; |
| 2943 | const ip = &mod.intern_pool; | |
| 2942 | const ip = &zcu.intern_pool; | |
| 2944 | 2943 | const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small); |
| 2945 | 2944 | const extra = sema.code.extraData(Zir.Inst.EnumDecl, extended.operand); |
| 2946 | 2945 | var extra_index: usize = extra.end; |
| ... | ... | @@ -3015,7 +3014,7 @@ fn zirEnumDecl( |
| 3015 | 3014 | |
| 3016 | 3015 | // Make sure we update the namespace if the declaration is re-analyzed, to pick |
| 3017 | 3016 | // up on e.g. changed comptime decls. |
| 3018 | try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(mod)); | |
| 3017 | try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu)); | |
| 3019 | 3018 | |
| 3020 | 3019 | try sema.declareDependency(.{ .interned = new_ty }); |
| 3021 | 3020 | try sema.addTypeReferenceEntry(src, new_ty); |
| ... | ... | @@ -3042,8 +3041,8 @@ fn zirEnumDecl( |
| 3042 | 3041 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 3043 | 3042 | .parent = block.namespace.toOptional(), |
| 3044 | 3043 | .owner_type = wip_ty.index, |
| 3045 | .file_scope = block.getFileScopeIndex(mod), | |
| 3046 | .generation = mod.generation, | |
| 3044 | .file_scope = block.getFileScopeIndex(zcu), | |
| 3045 | .generation = zcu.generation, | |
| 3047 | 3046 | }); |
| 3048 | 3047 | errdefer if (!done) pt.destroyNamespace(new_namespace_index); |
| 3049 | 3048 | |
| ... | ... | @@ -3077,9 +3076,9 @@ fn zirEnumDecl( |
| 3077 | 3076 | ); |
| 3078 | 3077 | |
| 3079 | 3078 | codegen_type: { |
| 3080 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 3079 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 3081 | 3080 | if (block.ownerModule().strip) break :codegen_type; |
| 3082 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3081 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3083 | 3082 | } |
| 3084 | 3083 | return Air.internedToRef(wip_ty.index); |
| 3085 | 3084 | } |
| ... | ... | @@ -3094,9 +3093,9 @@ fn zirUnionDecl( |
| 3094 | 3093 | defer tracy.end(); |
| 3095 | 3094 | |
| 3096 | 3095 | const pt = sema.pt; |
| 3097 | const mod = pt.zcu; | |
| 3096 | const zcu = pt.zcu; | |
| 3098 | 3097 | const gpa = sema.gpa; |
| 3099 | const ip = &mod.intern_pool; | |
| 3098 | const ip = &zcu.intern_pool; | |
| 3100 | 3099 | const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); |
| 3101 | 3100 | const extra = sema.code.extraData(Zir.Inst.UnionDecl, extended.operand); |
| 3102 | 3101 | var extra_index: usize = extra.end; |
| ... | ... | @@ -3159,7 +3158,7 @@ fn zirUnionDecl( |
| 3159 | 3158 | |
| 3160 | 3159 | // Make sure we update the namespace if the declaration is re-analyzed, to pick |
| 3161 | 3160 | // up on e.g. changed comptime decls. |
| 3162 | try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(mod)); | |
| 3161 | try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu)); | |
| 3163 | 3162 | |
| 3164 | 3163 | try sema.declareDependency(.{ .interned = new_ty }); |
| 3165 | 3164 | try sema.addTypeReferenceEntry(src, new_ty); |
| ... | ... | @@ -3180,15 +3179,15 @@ fn zirUnionDecl( |
| 3180 | 3179 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 3181 | 3180 | .parent = block.namespace.toOptional(), |
| 3182 | 3181 | .owner_type = wip_ty.index, |
| 3183 | .file_scope = block.getFileScopeIndex(mod), | |
| 3184 | .generation = mod.generation, | |
| 3182 | .file_scope = block.getFileScopeIndex(zcu), | |
| 3183 | .generation = zcu.generation, | |
| 3185 | 3184 | }); |
| 3186 | 3185 | errdefer pt.destroyNamespace(new_namespace_index); |
| 3187 | 3186 | |
| 3188 | 3187 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); |
| 3189 | 3188 | |
| 3190 | 3189 | if (pt.zcu.comp.incremental) { |
| 3191 | try mod.intern_pool.addDependency( | |
| 3190 | try zcu.intern_pool.addDependency( | |
| 3192 | 3191 | gpa, |
| 3193 | 3192 | AnalUnit.wrap(.{ .cau = new_cau_index }), |
| 3194 | 3193 | .{ .src_hash = tracked_inst }, |
| ... | ... | @@ -3198,11 +3197,11 @@ fn zirUnionDecl( |
| 3198 | 3197 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| 3199 | 3198 | try pt.scanNamespace(new_namespace_index, decls); |
| 3200 | 3199 | |
| 3201 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 3200 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 3202 | 3201 | codegen_type: { |
| 3203 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 3202 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 3204 | 3203 | if (block.ownerModule().strip) break :codegen_type; |
| 3205 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3204 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3206 | 3205 | } |
| 3207 | 3206 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 3208 | 3207 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -3219,9 +3218,9 @@ fn zirOpaqueDecl( |
| 3219 | 3218 | defer tracy.end(); |
| 3220 | 3219 | |
| 3221 | 3220 | const pt = sema.pt; |
| 3222 | const mod = pt.zcu; | |
| 3221 | const zcu = pt.zcu; | |
| 3223 | 3222 | const gpa = sema.gpa; |
| 3224 | const ip = &mod.intern_pool; | |
| 3223 | const ip = &zcu.intern_pool; | |
| 3225 | 3224 | |
| 3226 | 3225 | const small: Zir.Inst.OpaqueDecl.Small = @bitCast(extended.small); |
| 3227 | 3226 | const extra = sema.code.extraData(Zir.Inst.OpaqueDecl, extended.operand); |
| ... | ... | @@ -3255,7 +3254,7 @@ fn zirOpaqueDecl( |
| 3255 | 3254 | .existing => |ty| { |
| 3256 | 3255 | // Make sure we update the namespace if the declaration is re-analyzed, to pick |
| 3257 | 3256 | // up on e.g. changed comptime decls. |
| 3258 | try pt.ensureNamespaceUpToDate(Type.fromInterned(ty).getNamespaceIndex(mod)); | |
| 3257 | try pt.ensureNamespaceUpToDate(Type.fromInterned(ty).getNamespaceIndex(zcu)); | |
| 3259 | 3258 | |
| 3260 | 3259 | try sema.declareDependency(.{ .interned = ty }); |
| 3261 | 3260 | try sema.addTypeReferenceEntry(src, ty); |
| ... | ... | @@ -3276,8 +3275,8 @@ fn zirOpaqueDecl( |
| 3276 | 3275 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 3277 | 3276 | .parent = block.namespace.toOptional(), |
| 3278 | 3277 | .owner_type = wip_ty.index, |
| 3279 | .file_scope = block.getFileScopeIndex(mod), | |
| 3280 | .generation = mod.generation, | |
| 3278 | .file_scope = block.getFileScopeIndex(zcu), | |
| 3279 | .generation = zcu.generation, | |
| 3281 | 3280 | }); |
| 3282 | 3281 | errdefer pt.destroyNamespace(new_namespace_index); |
| 3283 | 3282 | |
| ... | ... | @@ -3285,9 +3284,9 @@ fn zirOpaqueDecl( |
| 3285 | 3284 | try pt.scanNamespace(new_namespace_index, decls); |
| 3286 | 3285 | |
| 3287 | 3286 | codegen_type: { |
| 3288 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 3287 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 3289 | 3288 | if (block.ownerModule().strip) break :codegen_type; |
| 3290 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3289 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 3291 | 3290 | } |
| 3292 | 3291 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| 3293 | 3292 | return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index)); |
| ... | ... | @@ -3301,7 +3300,7 @@ fn zirErrorSetDecl( |
| 3301 | 3300 | defer tracy.end(); |
| 3302 | 3301 | |
| 3303 | 3302 | const pt = sema.pt; |
| 3304 | const mod = pt.zcu; | |
| 3303 | const zcu = pt.zcu; | |
| 3305 | 3304 | const gpa = sema.gpa; |
| 3306 | 3305 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 3307 | 3306 | const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index); |
| ... | ... | @@ -3314,7 +3313,7 @@ fn zirErrorSetDecl( |
| 3314 | 3313 | while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string |
| 3315 | 3314 | const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]); |
| 3316 | 3315 | const name = sema.code.nullTerminatedString(name_index); |
| 3317 | const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls); | |
| 3316 | const name_ip = try zcu.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls); | |
| 3318 | 3317 | _ = try pt.getErrorValue(name_ip); |
| 3319 | 3318 | const result = names.getOrPutAssumeCapacity(name_ip); |
| 3320 | 3319 | assert(!result.found_existing); // verified in AstGen |
| ... | ... | @@ -3329,7 +3328,7 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 3329 | 3328 | |
| 3330 | 3329 | const pt = sema.pt; |
| 3331 | 3330 | |
| 3332 | if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) { | |
| 3331 | if (block.is_comptime or try sema.fn_ret_ty.comptimeOnlySema(pt)) { | |
| 3333 | 3332 | try sema.fn_ret_ty.resolveFields(pt); |
| 3334 | 3333 | return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none); |
| 3335 | 3334 | } |
| ... | ... | @@ -3377,8 +3376,8 @@ fn ensureResultUsed( |
| 3377 | 3376 | src: LazySrcLoc, |
| 3378 | 3377 | ) CompileError!void { |
| 3379 | 3378 | const pt = sema.pt; |
| 3380 | const mod = pt.zcu; | |
| 3381 | switch (ty.zigTypeTag(mod)) { | |
| 3379 | const zcu = pt.zcu; | |
| 3380 | switch (ty.zigTypeTag(zcu)) { | |
| 3382 | 3381 | .Void, .NoReturn => return, |
| 3383 | 3382 | .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}), |
| 3384 | 3383 | .ErrorUnion => { |
| ... | ... | @@ -3408,12 +3407,12 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3408 | 3407 | defer tracy.end(); |
| 3409 | 3408 | |
| 3410 | 3409 | const pt = sema.pt; |
| 3411 | const mod = pt.zcu; | |
| 3410 | const zcu = pt.zcu; | |
| 3412 | 3411 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 3413 | 3412 | const operand = try sema.resolveInst(inst_data.operand); |
| 3414 | 3413 | const src = block.nodeOffset(inst_data.src_node); |
| 3415 | 3414 | const operand_ty = sema.typeOf(operand); |
| 3416 | switch (operand_ty.zigTypeTag(mod)) { | |
| 3415 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 3417 | 3416 | .ErrorSet => return sema.fail(block, src, "error set is discarded", .{}), |
| 3418 | 3417 | .ErrorUnion => { |
| 3419 | 3418 | const msg = msg: { |
| ... | ... | @@ -3433,17 +3432,17 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index |
| 3433 | 3432 | defer tracy.end(); |
| 3434 | 3433 | |
| 3435 | 3434 | const pt = sema.pt; |
| 3436 | const mod = pt.zcu; | |
| 3435 | const zcu = pt.zcu; | |
| 3437 | 3436 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 3438 | 3437 | const src = block.nodeOffset(inst_data.src_node); |
| 3439 | 3438 | const operand = try sema.resolveInst(inst_data.operand); |
| 3440 | 3439 | const operand_ty = sema.typeOf(operand); |
| 3441 | const err_union_ty = if (operand_ty.zigTypeTag(mod) == .Pointer) | |
| 3442 | operand_ty.childType(mod) | |
| 3440 | const err_union_ty = if (operand_ty.zigTypeTag(zcu) == .Pointer) | |
| 3441 | operand_ty.childType(zcu) | |
| 3443 | 3442 | else |
| 3444 | 3443 | operand_ty; |
| 3445 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return; | |
| 3446 | const payload_ty = err_union_ty.errorUnionPayload(mod).zigTypeTag(mod); | |
| 3444 | if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) return; | |
| 3445 | const payload_ty = err_union_ty.errorUnionPayload(zcu).zigTypeTag(zcu); | |
| 3447 | 3446 | if (payload_ty != .Void and payload_ty != .NoReturn) { |
| 3448 | 3447 | const msg = msg: { |
| 3449 | 3448 | const msg = try sema.errMsg(src, "error union payload is ignored", .{}); |
| ... | ... | @@ -3473,12 +3472,12 @@ fn indexablePtrLen( |
| 3473 | 3472 | object: Air.Inst.Ref, |
| 3474 | 3473 | ) CompileError!Air.Inst.Ref { |
| 3475 | 3474 | const pt = sema.pt; |
| 3476 | const mod = pt.zcu; | |
| 3475 | const zcu = pt.zcu; | |
| 3477 | 3476 | const object_ty = sema.typeOf(object); |
| 3478 | const is_pointer_to = object_ty.isSinglePointer(mod); | |
| 3479 | const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty; | |
| 3477 | const is_pointer_to = object_ty.isSinglePointer(zcu); | |
| 3478 | const indexable_ty = if (is_pointer_to) object_ty.childType(zcu) else object_ty; | |
| 3480 | 3479 | try checkIndexable(sema, block, src, indexable_ty); |
| 3481 | const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls); | |
| 3480 | const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls); | |
| 3482 | 3481 | return sema.fieldVal(block, src, object, field_name, src); |
| 3483 | 3482 | } |
| 3484 | 3483 | |
| ... | ... | @@ -3489,11 +3488,11 @@ fn indexablePtrLenOrNone( |
| 3489 | 3488 | operand: Air.Inst.Ref, |
| 3490 | 3489 | ) CompileError!Air.Inst.Ref { |
| 3491 | 3490 | const pt = sema.pt; |
| 3492 | const mod = pt.zcu; | |
| 3491 | const zcu = pt.zcu; | |
| 3493 | 3492 | const operand_ty = sema.typeOf(operand); |
| 3494 | 3493 | try checkMemOperand(sema, block, src, operand_ty); |
| 3495 | if (operand_ty.ptrSize(mod) == .Many) return .none; | |
| 3496 | const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls); | |
| 3494 | if (operand_ty.ptrSize(zcu) == .Many) return .none; | |
| 3495 | const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls); | |
| 3497 | 3496 | return sema.fieldVal(block, src, operand, field_name, src); |
| 3498 | 3497 | } |
| 3499 | 3498 | |
| ... | ... | @@ -3592,11 +3591,11 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 3592 | 3591 | |
| 3593 | 3592 | fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 3594 | 3593 | const pt = sema.pt; |
| 3595 | const mod = pt.zcu; | |
| 3594 | const zcu = pt.zcu; | |
| 3596 | 3595 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 3597 | 3596 | const alloc = try sema.resolveInst(inst_data.operand); |
| 3598 | 3597 | const alloc_ty = sema.typeOf(alloc); |
| 3599 | const ptr_info = alloc_ty.ptrInfo(mod); | |
| 3598 | const ptr_info = alloc_ty.ptrInfo(zcu); | |
| 3600 | 3599 | const elem_ty = Type.fromInterned(ptr_info.child); |
| 3601 | 3600 | |
| 3602 | 3601 | // If the alloc was created in a comptime scope, we already created a comptime alloc for it. |
| ... | ... | @@ -3607,7 +3606,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3607 | 3606 | |
| 3608 | 3607 | // If this was a comptime inferred alloc, then `storeToInferredAllocComptime` |
| 3609 | 3608 | // might have already done our job and created an anon decl ref. |
| 3610 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { | |
| 3609 | switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) { | |
| 3611 | 3610 | .ptr => |ptr| switch (ptr.base_addr) { |
| 3612 | 3611 | .uav => { |
| 3613 | 3612 | // The comptime-ification was already done for us. |
| ... | ... | @@ -3620,12 +3619,12 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3620 | 3619 | } |
| 3621 | 3620 | |
| 3622 | 3621 | if (!sema.isComptimeMutablePtr(ptr_val)) break :already_ct; |
| 3623 | const ptr = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | |
| 3622 | const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | |
| 3624 | 3623 | assert(ptr.byte_offset == 0); |
| 3625 | 3624 | const alloc_index = ptr.base_addr.comptime_alloc; |
| 3626 | 3625 | const ct_alloc = sema.getComptimeAlloc(alloc_index); |
| 3627 | 3626 | const interned = try ct_alloc.val.intern(pt, sema.arena); |
| 3628 | if (interned.canMutateComptimeVarState(mod)) { | |
| 3627 | if (interned.canMutateComptimeVarState(zcu)) { | |
| 3629 | 3628 | // Preserve the comptime alloc, just make the pointer const. |
| 3630 | 3629 | ct_alloc.val = .{ .interned = interned.toIntern() }; |
| 3631 | 3630 | ct_alloc.is_const = true; |
| ... | ... | @@ -3649,7 +3648,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3649 | 3648 | return sema.makePtrConst(block, Air.internedToRef(ptr_val)); |
| 3650 | 3649 | } |
| 3651 | 3650 | |
| 3652 | if (try sema.typeRequiresComptime(elem_ty)) { | |
| 3651 | if (try elem_ty.comptimeOnlySema(pt)) { | |
| 3653 | 3652 | // The value was initialized through RLS, so we didn't detect the runtime condition earlier. |
| 3654 | 3653 | // TODO: source location of runtime control flow |
| 3655 | 3654 | const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); |
| ... | ... | @@ -3918,7 +3917,7 @@ fn finishResolveComptimeKnownAllocPtr( |
| 3918 | 3917 | |
| 3919 | 3918 | if (Value.fromInterned(result_val).canMutateComptimeVarState(zcu)) { |
| 3920 | 3919 | const alloc_index = existing_comptime_alloc orelse a: { |
| 3921 | const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(pt)); | |
| 3920 | const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu)); | |
| 3922 | 3921 | const alloc = sema.getComptimeAlloc(idx); |
| 3923 | 3922 | alloc.val = .{ .interned = result_val }; |
| 3924 | 3923 | break :a idx; |
| ... | ... | @@ -4072,14 +4071,14 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4072 | 4071 | defer tracy.end(); |
| 4073 | 4072 | |
| 4074 | 4073 | const pt = sema.pt; |
| 4075 | const mod = pt.zcu; | |
| 4074 | const zcu = pt.zcu; | |
| 4076 | 4075 | const gpa = sema.gpa; |
| 4077 | 4076 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 4078 | 4077 | const src = block.nodeOffset(inst_data.src_node); |
| 4079 | 4078 | const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node }); |
| 4080 | 4079 | const ptr = try sema.resolveInst(inst_data.operand); |
| 4081 | 4080 | const ptr_inst = ptr.toIndex().?; |
| 4082 | const target = mod.getTarget(); | |
| 4081 | const target = zcu.getTarget(); | |
| 4083 | 4082 | |
| 4084 | 4083 | switch (sema.air_instructions.items(.tag)[@intFromEnum(ptr_inst)]) { |
| 4085 | 4084 | .inferred_alloc_comptime => { |
| ... | ... | @@ -4093,7 +4092,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4093 | 4092 | sema.air_instructions.set(@intFromEnum(ptr_inst), .{ .tag = undefined, .data = undefined }); |
| 4094 | 4093 | } |
| 4095 | 4094 | |
| 4096 | const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) { | |
| 4095 | const val = switch (zcu.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) { | |
| 4097 | 4096 | .uav => |a| a.val, |
| 4098 | 4097 | .comptime_alloc => |i| val: { |
| 4099 | 4098 | const alloc = sema.getComptimeAlloc(i); |
| ... | ... | @@ -4101,11 +4100,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4101 | 4100 | }, |
| 4102 | 4101 | else => unreachable, |
| 4103 | 4102 | }; |
| 4104 | if (mod.intern_pool.isFuncBody(val)) { | |
| 4105 | const ty = Type.fromInterned(mod.intern_pool.typeOf(val)); | |
| 4106 | if (try sema.fnHasRuntimeBits(ty)) { | |
| 4103 | if (zcu.intern_pool.isFuncBody(val)) { | |
| 4104 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(val)); | |
| 4105 | if (try ty.fnHasRuntimeBitsSema(pt)) { | |
| 4107 | 4106 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = val })); |
| 4108 | try mod.ensureFuncBodyAnalysisQueued(val); | |
| 4107 | try zcu.ensureFuncBodyAnalysisQueued(val); | |
| 4109 | 4108 | } |
| 4110 | 4109 | } |
| 4111 | 4110 | |
| ... | ... | @@ -4148,7 +4147,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4148 | 4147 | return; |
| 4149 | 4148 | } |
| 4150 | 4149 | |
| 4151 | if (try sema.typeRequiresComptime(final_elem_ty)) { | |
| 4150 | if (try final_elem_ty.comptimeOnlySema(pt)) { | |
| 4152 | 4151 | // The alloc wasn't comptime-known per the above logic, so the |
| 4153 | 4152 | // type cannot be comptime-only. |
| 4154 | 4153 | // TODO: source location of runtime control flow |
| ... | ... | @@ -4213,9 +4212,9 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4213 | 4212 | |
| 4214 | 4213 | fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 4215 | 4214 | const pt = sema.pt; |
| 4216 | const mod = pt.zcu; | |
| 4215 | const zcu = pt.zcu; | |
| 4217 | 4216 | const gpa = sema.gpa; |
| 4218 | const ip = &mod.intern_pool; | |
| 4217 | const ip = &zcu.intern_pool; | |
| 4219 | 4218 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4220 | 4219 | const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| 4221 | 4220 | const args = sema.code.refSlice(extra.end, extra.data.operands_len); |
| ... | ... | @@ -4238,7 +4237,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4238 | 4237 | const object_ty = sema.typeOf(object); |
| 4239 | 4238 | // Each arg could be an indexable, or a range, in which case the length |
| 4240 | 4239 | // is passed directly as an integer. |
| 4241 | const is_int = switch (object_ty.zigTypeTag(mod)) { | |
| 4240 | const is_int = switch (object_ty.zigTypeTag(zcu)) { | |
| 4242 | 4241 | .Int, .ComptimeInt => true, |
| 4243 | 4242 | else => false, |
| 4244 | 4243 | }; |
| ... | ... | @@ -4247,14 +4246,14 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4247 | 4246 | .input_index = i, |
| 4248 | 4247 | } }); |
| 4249 | 4248 | const arg_len_uncoerced = if (is_int) object else l: { |
| 4250 | if (!object_ty.isIndexable(mod)) { | |
| 4249 | if (!object_ty.isIndexable(zcu)) { | |
| 4251 | 4250 | // Instead of using checkIndexable we customize this error. |
| 4252 | 4251 | const msg = msg: { |
| 4253 | 4252 | const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(pt)}); |
| 4254 | 4253 | errdefer msg.destroy(sema.gpa); |
| 4255 | 4254 | try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{}); |
| 4256 | 4255 | |
| 4257 | if (object_ty.zigTypeTag(mod) == .ErrorUnion) { | |
| 4256 | if (object_ty.zigTypeTag(zcu) == .ErrorUnion) { | |
| 4258 | 4257 | try sema.errNote(arg_src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 4259 | 4258 | } |
| 4260 | 4259 | |
| ... | ... | @@ -4262,7 +4261,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4262 | 4261 | }; |
| 4263 | 4262 | return sema.failWithOwnedErrorMsg(block, msg); |
| 4264 | 4263 | } |
| 4265 | if (!object_ty.indexableHasLen(mod)) continue; | |
| 4264 | if (!object_ty.indexableHasLen(zcu)) continue; | |
| 4266 | 4265 | |
| 4267 | 4266 | break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), arg_src); |
| 4268 | 4267 | }; |
| ... | ... | @@ -4313,7 +4312,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4313 | 4312 | const object_ty = sema.typeOf(object); |
| 4314 | 4313 | // Each arg could be an indexable, or a range, in which case the length |
| 4315 | 4314 | // is passed directly as an integer. |
| 4316 | switch (object_ty.zigTypeTag(mod)) { | |
| 4315 | switch (object_ty.zigTypeTag(zcu)) { | |
| 4317 | 4316 | .Int, .ComptimeInt => continue, |
| 4318 | 4317 | else => {}, |
| 4319 | 4318 | } |
| ... | ... | @@ -4349,9 +4348,9 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4349 | 4348 | /// May invalidate already-stored payload data. |
| 4350 | 4349 | fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref { |
| 4351 | 4350 | const pt = sema.pt; |
| 4352 | const mod = pt.zcu; | |
| 4351 | const zcu = pt.zcu; | |
| 4353 | 4352 | var base_ptr = ptr; |
| 4354 | while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) { | |
| 4353 | while (true) switch (sema.typeOf(base_ptr).childType(zcu).zigTypeTag(zcu)) { | |
| 4355 | 4354 | .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true), |
| 4356 | 4355 | .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true), |
| 4357 | 4356 | else => break, |
| ... | ... | @@ -4368,7 +4367,7 @@ fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile |
| 4368 | 4367 | |
| 4369 | 4368 | fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 4370 | 4369 | const pt = sema.pt; |
| 4371 | const mod = pt.zcu; | |
| 4370 | const zcu = pt.zcu; | |
| 4372 | 4371 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4373 | 4372 | const src = block.nodeOffset(pl_node.src_node); |
| 4374 | 4373 | const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data; |
| ... | ... | @@ -4377,13 +4376,13 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4377 | 4376 | error.GenericPoison => return uncoerced_val, |
| 4378 | 4377 | else => |e| return e, |
| 4379 | 4378 | }; |
| 4380 | const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(mod); | |
| 4381 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); // validated by a previous instruction | |
| 4382 | const elem_ty = ptr_ty.childType(mod); | |
| 4383 | switch (ptr_ty.ptrSize(mod)) { | |
| 4379 | const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(zcu); | |
| 4380 | assert(ptr_ty.zigTypeTag(zcu) == .Pointer); // validated by a previous instruction | |
| 4381 | const elem_ty = ptr_ty.childType(zcu); | |
| 4382 | switch (ptr_ty.ptrSize(zcu)) { | |
| 4384 | 4383 | .One => { |
| 4385 | 4384 | const uncoerced_ty = sema.typeOf(uncoerced_val); |
| 4386 | if (elem_ty.zigTypeTag(mod) == .Array and elem_ty.childType(mod).toIntern() == uncoerced_ty.toIntern()) { | |
| 4385 | if (elem_ty.zigTypeTag(zcu) == .Array and elem_ty.childType(zcu).toIntern() == uncoerced_ty.toIntern()) { | |
| 4387 | 4386 | // We're trying to initialize a *[1]T with a reference to a T - don't perform any coercion. |
| 4388 | 4387 | return uncoerced_val; |
| 4389 | 4388 | } |
| ... | ... | @@ -4397,16 +4396,16 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4397 | 4396 | .Slice, .Many => { |
| 4398 | 4397 | // Our goal is to coerce `uncoerced_val` to an array of `elem_ty`. |
| 4399 | 4398 | const val_ty = sema.typeOf(uncoerced_val); |
| 4400 | switch (val_ty.zigTypeTag(mod)) { | |
| 4399 | switch (val_ty.zigTypeTag(zcu)) { | |
| 4401 | 4400 | .Array, .Vector => {}, |
| 4402 | else => if (!val_ty.isTuple(mod)) { | |
| 4401 | else => if (!val_ty.isTuple(zcu)) { | |
| 4403 | 4402 | return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(pt), val_ty.fmt(pt) }); |
| 4404 | 4403 | }, |
| 4405 | 4404 | } |
| 4406 | 4405 | const want_ty = try pt.arrayType(.{ |
| 4407 | .len = val_ty.arrayLen(mod), | |
| 4406 | .len = val_ty.arrayLen(zcu), | |
| 4408 | 4407 | .child = elem_ty.toIntern(), |
| 4409 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 4408 | .sentinel = if (ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 4410 | 4409 | }); |
| 4411 | 4410 | return sema.coerce(block, want_ty, uncoerced_val, src); |
| 4412 | 4411 | }, |
| ... | ... | @@ -4420,7 +4419,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4420 | 4419 | |
| 4421 | 4420 | fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 4422 | 4421 | const pt = sema.pt; |
| 4423 | const mod = pt.zcu; | |
| 4422 | const zcu = pt.zcu; | |
| 4424 | 4423 | const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; |
| 4425 | 4424 | const src = block.tokenOffset(un_tok.src_tok); |
| 4426 | 4425 | // In case of GenericPoison, we don't actually have a type, so this will be |
| ... | ... | @@ -4434,7 +4433,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4434 | 4433 | else => |e| return e, |
| 4435 | 4434 | }; |
| 4436 | 4435 | if (ty_operand.isGenericPoison()) return; |
| 4437 | if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) { | |
| 4436 | if (ty_operand.optEuBaseType(zcu).zigTypeTag(zcu) != .Pointer) { | |
| 4438 | 4437 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 4439 | 4438 | const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(pt)}); |
| 4440 | 4439 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -4450,7 +4449,7 @@ fn zirValidateArrayInitRefTy( |
| 4450 | 4449 | inst: Zir.Inst.Index, |
| 4451 | 4450 | ) CompileError!Air.Inst.Ref { |
| 4452 | 4451 | const pt = sema.pt; |
| 4453 | const mod = pt.zcu; | |
| 4452 | const zcu = pt.zcu; | |
| 4454 | 4453 | const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4455 | 4454 | const src = block.nodeOffset(pl_node.src_node); |
| 4456 | 4455 | const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data; |
| ... | ... | @@ -4458,16 +4457,16 @@ fn zirValidateArrayInitRefTy( |
| 4458 | 4457 | error.GenericPoison => return .generic_poison_type, |
| 4459 | 4458 | else => |e| return e, |
| 4460 | 4459 | }; |
| 4461 | const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(mod); | |
| 4462 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); // validated by a previous instruction | |
| 4463 | switch (mod.intern_pool.indexToKey(ptr_ty.toIntern())) { | |
| 4460 | const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(zcu); | |
| 4461 | assert(ptr_ty.zigTypeTag(zcu) == .Pointer); // validated by a previous instruction | |
| 4462 | switch (zcu.intern_pool.indexToKey(ptr_ty.toIntern())) { | |
| 4464 | 4463 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 4465 | 4464 | .Slice, .Many => { |
| 4466 | 4465 | // Use array of correct length |
| 4467 | 4466 | const arr_ty = try pt.arrayType(.{ |
| 4468 | 4467 | .len = extra.elem_count, |
| 4469 | .child = ptr_ty.childType(mod).toIntern(), | |
| 4470 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 4468 | .child = ptr_ty.childType(zcu).toIntern(), | |
| 4469 | .sentinel = if (ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 4471 | 4470 | }); |
| 4472 | 4471 | return Air.internedToRef(arr_ty.toIntern()); |
| 4473 | 4472 | }, |
| ... | ... | @@ -4476,12 +4475,12 @@ fn zirValidateArrayInitRefTy( |
| 4476 | 4475 | else => {}, |
| 4477 | 4476 | } |
| 4478 | 4477 | // Otherwise, we just want the pointer child type |
| 4479 | const ret_ty = ptr_ty.childType(mod); | |
| 4478 | const ret_ty = ptr_ty.childType(zcu); | |
| 4480 | 4479 | if (ret_ty.toIntern() == .anyopaque_type) { |
| 4481 | 4480 | // The actual array type is unknown, which we represent with a generic poison. |
| 4482 | 4481 | return .generic_poison_type; |
| 4483 | 4482 | } |
| 4484 | const arr_ty = ret_ty.optEuBaseType(mod); | |
| 4483 | const arr_ty = ret_ty.optEuBaseType(zcu); | |
| 4485 | 4484 | try sema.validateArrayInitTy(block, src, src, extra.elem_count, arr_ty); |
| 4486 | 4485 | return Air.internedToRef(ret_ty.toIntern()); |
| 4487 | 4486 | } |
| ... | ... | @@ -4493,7 +4492,7 @@ fn zirValidateArrayInitTy( |
| 4493 | 4492 | is_result_ty: bool, |
| 4494 | 4493 | ) CompileError!void { |
| 4495 | 4494 | const pt = sema.pt; |
| 4496 | const mod = pt.zcu; | |
| 4495 | const zcu = pt.zcu; | |
| 4497 | 4496 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4498 | 4497 | const src = block.nodeOffset(inst_data.src_node); |
| 4499 | 4498 | const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node }); |
| ... | ... | @@ -4503,7 +4502,7 @@ fn zirValidateArrayInitTy( |
| 4503 | 4502 | error.GenericPoison => return, |
| 4504 | 4503 | else => |e| return e, |
| 4505 | 4504 | }; |
| 4506 | const arr_ty = if (is_result_ty) ty.optEuBaseType(mod) else ty; | |
| 4505 | const arr_ty = if (is_result_ty) ty.optEuBaseType(zcu) else ty; | |
| 4507 | 4506 | return sema.validateArrayInitTy(block, src, ty_src, extra.init_count, arr_ty); |
| 4508 | 4507 | } |
| 4509 | 4508 | |
| ... | ... | @@ -4516,10 +4515,10 @@ fn validateArrayInitTy( |
| 4516 | 4515 | ty: Type, |
| 4517 | 4516 | ) CompileError!void { |
| 4518 | 4517 | const pt = sema.pt; |
| 4519 | const mod = pt.zcu; | |
| 4520 | switch (ty.zigTypeTag(mod)) { | |
| 4518 | const zcu = pt.zcu; | |
| 4519 | switch (ty.zigTypeTag(zcu)) { | |
| 4521 | 4520 | .Array => { |
| 4522 | const array_len = ty.arrayLen(mod); | |
| 4521 | const array_len = ty.arrayLen(zcu); | |
| 4523 | 4522 | if (init_count != array_len) { |
| 4524 | 4523 | return sema.fail(block, src, "expected {d} array elements; found {d}", .{ |
| 4525 | 4524 | array_len, init_count, |
| ... | ... | @@ -4528,7 +4527,7 @@ fn validateArrayInitTy( |
| 4528 | 4527 | return; |
| 4529 | 4528 | }, |
| 4530 | 4529 | .Vector => { |
| 4531 | const array_len = ty.arrayLen(mod); | |
| 4530 | const array_len = ty.arrayLen(zcu); | |
| 4532 | 4531 | if (init_count != array_len) { |
| 4533 | 4532 | return sema.fail(block, src, "expected {d} vector elements; found {d}", .{ |
| 4534 | 4533 | array_len, init_count, |
| ... | ... | @@ -4536,9 +4535,9 @@ fn validateArrayInitTy( |
| 4536 | 4535 | } |
| 4537 | 4536 | return; |
| 4538 | 4537 | }, |
| 4539 | .Struct => if (ty.isTuple(mod)) { | |
| 4538 | .Struct => if (ty.isTuple(zcu)) { | |
| 4540 | 4539 | try ty.resolveFields(pt); |
| 4541 | const array_len = ty.arrayLen(mod); | |
| 4540 | const array_len = ty.arrayLen(zcu); | |
| 4542 | 4541 | if (init_count > array_len) { |
| 4543 | 4542 | return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{ |
| 4544 | 4543 | array_len, init_count, |
| ... | ... | @@ -4558,7 +4557,7 @@ fn zirValidateStructInitTy( |
| 4558 | 4557 | is_result_ty: bool, |
| 4559 | 4558 | ) CompileError!void { |
| 4560 | 4559 | const pt = sema.pt; |
| 4561 | const mod = pt.zcu; | |
| 4560 | const zcu = pt.zcu; | |
| 4562 | 4561 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 4563 | 4562 | const src = block.nodeOffset(inst_data.src_node); |
| 4564 | 4563 | const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { |
| ... | ... | @@ -4566,9 +4565,9 @@ fn zirValidateStructInitTy( |
| 4566 | 4565 | error.GenericPoison => return, |
| 4567 | 4566 | else => |e| return e, |
| 4568 | 4567 | }; |
| 4569 | const struct_ty = if (is_result_ty) ty.optEuBaseType(mod) else ty; | |
| 4568 | const struct_ty = if (is_result_ty) ty.optEuBaseType(zcu) else ty; | |
| 4570 | 4569 | |
| 4571 | switch (struct_ty.zigTypeTag(mod)) { | |
| 4570 | switch (struct_ty.zigTypeTag(zcu)) { | |
| 4572 | 4571 | .Struct, .Union => return, |
| 4573 | 4572 | else => {}, |
| 4574 | 4573 | } |
| ... | ... | @@ -4584,7 +4583,7 @@ fn zirValidatePtrStructInit( |
| 4584 | 4583 | defer tracy.end(); |
| 4585 | 4584 | |
| 4586 | 4585 | const pt = sema.pt; |
| 4587 | const mod = pt.zcu; | |
| 4586 | const zcu = pt.zcu; | |
| 4588 | 4587 | const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 4589 | 4588 | const init_src = block.nodeOffset(validate_inst.src_node); |
| 4590 | 4589 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); |
| ... | ... | @@ -4592,8 +4591,8 @@ fn zirValidatePtrStructInit( |
| 4592 | 4591 | const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node; |
| 4593 | 4592 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 4594 | 4593 | const object_ptr = try sema.resolveInst(field_ptr_extra.lhs); |
| 4595 | const agg_ty = sema.typeOf(object_ptr).childType(mod).optEuBaseType(mod); | |
| 4596 | switch (agg_ty.zigTypeTag(mod)) { | |
| 4594 | const agg_ty = sema.typeOf(object_ptr).childType(zcu).optEuBaseType(zcu); | |
| 4595 | switch (agg_ty.zigTypeTag(zcu)) { | |
| 4597 | 4596 | .Struct => return sema.validateStructInit( |
| 4598 | 4597 | block, |
| 4599 | 4598 | agg_ty, |
| ... | ... | @@ -4620,7 +4619,7 @@ fn validateUnionInit( |
| 4620 | 4619 | union_ptr: Air.Inst.Ref, |
| 4621 | 4620 | ) CompileError!void { |
| 4622 | 4621 | const pt = sema.pt; |
| 4623 | const mod = pt.zcu; | |
| 4622 | const zcu = pt.zcu; | |
| 4624 | 4623 | const gpa = sema.gpa; |
| 4625 | 4624 | |
| 4626 | 4625 | if (instrs.len != 1) { |
| ... | ... | @@ -4654,7 +4653,7 @@ fn validateUnionInit( |
| 4654 | 4653 | const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(field_ptr)].pl_node; |
| 4655 | 4654 | const field_src = block.src(.{ .node_offset_initializer = field_ptr_data.src_node }); |
| 4656 | 4655 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 4657 | const field_name = try mod.intern_pool.getOrPutString( | |
| 4656 | const field_name = try zcu.intern_pool.getOrPutString( | |
| 4658 | 4657 | gpa, |
| 4659 | 4658 | pt.tid, |
| 4660 | 4659 | sema.code.nullTerminatedString(field_ptr_extra.field_name_start), |
| ... | ... | @@ -4718,9 +4717,9 @@ fn validateUnionInit( |
| 4718 | 4717 | break; |
| 4719 | 4718 | } |
| 4720 | 4719 | |
| 4721 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | |
| 4720 | const tag_ty = union_ty.unionTagTypeHypothetical(zcu); | |
| 4722 | 4721 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 4723 | const field_type = union_ty.unionFieldType(tag_val, mod).?; | |
| 4722 | const field_type = union_ty.unionFieldType(tag_val, zcu).?; | |
| 4724 | 4723 | |
| 4725 | 4724 | if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| { |
| 4726 | 4725 | init_val = field_only_value; |
| ... | ... | @@ -4761,7 +4760,7 @@ fn validateUnionInit( |
| 4761 | 4760 | const union_init = Air.internedToRef(union_val); |
| 4762 | 4761 | try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store); |
| 4763 | 4762 | return; |
| 4764 | } else if (try sema.typeRequiresComptime(union_ty)) { | |
| 4763 | } else if (try union_ty.comptimeOnlySema(pt)) { | |
| 4765 | 4764 | return sema.failWithNeededComptime(block, block.nodeOffset(field_ptr_data.src_node), .{ |
| 4766 | 4765 | .needed_comptime_reason = "initializer of comptime only union must be comptime-known", |
| 4767 | 4766 | }); |
| ... | ... | @@ -4781,15 +4780,15 @@ fn validateStructInit( |
| 4781 | 4780 | instrs: []const Zir.Inst.Index, |
| 4782 | 4781 | ) CompileError!void { |
| 4783 | 4782 | const pt = sema.pt; |
| 4784 | const mod = pt.zcu; | |
| 4783 | const zcu = pt.zcu; | |
| 4785 | 4784 | const gpa = sema.gpa; |
| 4786 | const ip = &mod.intern_pool; | |
| 4785 | const ip = &zcu.intern_pool; | |
| 4787 | 4786 | |
| 4788 | 4787 | const field_indices = try gpa.alloc(u32, instrs.len); |
| 4789 | 4788 | defer gpa.free(field_indices); |
| 4790 | 4789 | |
| 4791 | 4790 | // Maps field index to field_ptr index of where it was already initialized. |
| 4792 | const found_fields = try gpa.alloc(Zir.Inst.OptionalIndex, struct_ty.structFieldCount(mod)); | |
| 4791 | const found_fields = try gpa.alloc(Zir.Inst.OptionalIndex, struct_ty.structFieldCount(zcu)); | |
| 4793 | 4792 | defer gpa.free(found_fields); |
| 4794 | 4793 | @memset(found_fields, .none); |
| 4795 | 4794 | |
| ... | ... | @@ -4806,7 +4805,7 @@ fn validateStructInit( |
| 4806 | 4805 | sema.code.nullTerminatedString(field_ptr_extra.field_name_start), |
| 4807 | 4806 | .no_embedded_nulls, |
| 4808 | 4807 | ); |
| 4809 | field_index.* = if (struct_ty.isTuple(mod)) | |
| 4808 | field_index.* = if (struct_ty.isTuple(zcu)) | |
| 4810 | 4809 | try sema.tupleFieldIndex(block, struct_ty, field_name, field_src) |
| 4811 | 4810 | else |
| 4812 | 4811 | try sema.structFieldIndex(block, struct_ty, field_name, field_src); |
| ... | ... | @@ -4814,7 +4813,7 @@ fn validateStructInit( |
| 4814 | 4813 | found_fields[field_index.*] = field_ptr.toOptional(); |
| 4815 | 4814 | } |
| 4816 | 4815 | |
| 4817 | var root_msg: ?*Module.ErrorMsg = null; | |
| 4816 | var root_msg: ?*Zcu.ErrorMsg = null; | |
| 4818 | 4817 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 4819 | 4818 | |
| 4820 | 4819 | const struct_ptr = try sema.resolveInst(struct_ptr_zir_ref); |
| ... | ... | @@ -4830,9 +4829,9 @@ fn validateStructInit( |
| 4830 | 4829 | if (field_ptr != .none) continue; |
| 4831 | 4830 | |
| 4832 | 4831 | try struct_ty.resolveStructFieldInits(pt); |
| 4833 | const default_val = struct_ty.structFieldDefaultValue(i, mod); | |
| 4832 | const default_val = struct_ty.structFieldDefaultValue(i, zcu); | |
| 4834 | 4833 | if (default_val.toIntern() == .unreachable_value) { |
| 4835 | const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse { | |
| 4834 | const field_name = struct_ty.structFieldName(i, zcu).unwrap() orelse { | |
| 4836 | 4835 | const template = "missing tuple field with index {d}"; |
| 4837 | 4836 | if (root_msg) |msg| { |
| 4838 | 4837 | try sema.errNote(init_src, msg, template, .{i}); |
| ... | ... | @@ -4852,7 +4851,7 @@ fn validateStructInit( |
| 4852 | 4851 | } |
| 4853 | 4852 | |
| 4854 | 4853 | const field_src = init_src; // TODO better source location |
| 4855 | const default_field_ptr = if (struct_ty.isTuple(mod)) | |
| 4854 | const default_field_ptr = if (struct_ty.isTuple(zcu)) | |
| 4856 | 4855 | try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true) |
| 4857 | 4856 | else |
| 4858 | 4857 | try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), field_src, struct_ty, true); |
| ... | ... | @@ -4874,7 +4873,7 @@ fn validateStructInit( |
| 4874 | 4873 | var struct_is_comptime = true; |
| 4875 | 4874 | var first_block_index = block.instructions.items.len; |
| 4876 | 4875 | |
| 4877 | const require_comptime = try sema.typeRequiresComptime(struct_ty); | |
| 4876 | const require_comptime = try struct_ty.comptimeOnlySema(pt); | |
| 4878 | 4877 | const air_tags = sema.air_instructions.items(.tag); |
| 4879 | 4878 | const air_datas = sema.air_instructions.items(.data); |
| 4880 | 4879 | |
| ... | ... | @@ -4882,13 +4881,13 @@ fn validateStructInit( |
| 4882 | 4881 | |
| 4883 | 4882 | // We collect the comptime field values in case the struct initialization |
| 4884 | 4883 | // ends up being comptime-known. |
| 4885 | const field_values = try sema.arena.alloc(InternPool.Index, struct_ty.structFieldCount(mod)); | |
| 4884 | const field_values = try sema.arena.alloc(InternPool.Index, struct_ty.structFieldCount(zcu)); | |
| 4886 | 4885 | |
| 4887 | 4886 | field: for (found_fields, 0..) |opt_field_ptr, i_usize| { |
| 4888 | 4887 | const i: u32 = @intCast(i_usize); |
| 4889 | 4888 | if (opt_field_ptr.unwrap()) |field_ptr| { |
| 4890 | 4889 | // Determine whether the value stored to this pointer is comptime-known. |
| 4891 | const field_ty = struct_ty.structFieldType(i, mod); | |
| 4890 | const field_ty = struct_ty.structFieldType(i, zcu); | |
| 4892 | 4891 | if (try sema.typeHasOnePossibleValue(field_ty)) |opv| { |
| 4893 | 4892 | field_values[i] = opv.toIntern(); |
| 4894 | 4893 | continue; |
| ... | ... | @@ -4958,9 +4957,9 @@ fn validateStructInit( |
| 4958 | 4957 | continue :field; |
| 4959 | 4958 | } |
| 4960 | 4959 | |
| 4961 | const default_val = struct_ty.structFieldDefaultValue(i, mod); | |
| 4960 | const default_val = struct_ty.structFieldDefaultValue(i, zcu); | |
| 4962 | 4961 | if (default_val.toIntern() == .unreachable_value) { |
| 4963 | const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse { | |
| 4962 | const field_name = struct_ty.structFieldName(i, zcu).unwrap() orelse { | |
| 4964 | 4963 | const template = "missing tuple field with index {d}"; |
| 4965 | 4964 | if (root_msg) |msg| { |
| 4966 | 4965 | try sema.errNote(init_src, msg, template, .{i}); |
| ... | ... | @@ -5000,7 +4999,7 @@ fn validateStructInit( |
| 5000 | 4999 | var block_index = first_block_index; |
| 5001 | 5000 | for (block.instructions.items[first_block_index..]) |cur_inst| { |
| 5002 | 5001 | while (field_ptr_ref == .none and init_index < instrs.len) : (init_index += 1) { |
| 5003 | const field_ty = struct_ty.structFieldType(field_indices[init_index], mod); | |
| 5002 | const field_ty = struct_ty.structFieldType(field_indices[init_index], zcu); | |
| 5004 | 5003 | if (try field_ty.onePossibleValue(pt)) |_| continue; |
| 5005 | 5004 | field_ptr_ref = sema.inst_map.get(instrs[init_index]).?; |
| 5006 | 5005 | } |
| ... | ... | @@ -5044,7 +5043,7 @@ fn validateStructInit( |
| 5044 | 5043 | if (field_ptr != .none) continue; |
| 5045 | 5044 | |
| 5046 | 5045 | const field_src = init_src; // TODO better source location |
| 5047 | const default_field_ptr = if (struct_ty.isTuple(mod)) | |
| 5046 | const default_field_ptr = if (struct_ty.isTuple(zcu)) | |
| 5048 | 5047 | try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true) |
| 5049 | 5048 | else |
| 5050 | 5049 | try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), field_src, struct_ty, true); |
| ... | ... | @@ -5060,7 +5059,7 @@ fn zirValidatePtrArrayInit( |
| 5060 | 5059 | inst: Zir.Inst.Index, |
| 5061 | 5060 | ) CompileError!void { |
| 5062 | 5061 | const pt = sema.pt; |
| 5063 | const mod = pt.zcu; | |
| 5062 | const zcu = pt.zcu; | |
| 5064 | 5063 | const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5065 | 5064 | const init_src = block.nodeOffset(validate_inst.src_node); |
| 5066 | 5065 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); |
| ... | ... | @@ -5068,8 +5067,8 @@ fn zirValidatePtrArrayInit( |
| 5068 | 5067 | const first_elem_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node; |
| 5069 | 5068 | const elem_ptr_extra = sema.code.extraData(Zir.Inst.ElemPtrImm, first_elem_ptr_data.payload_index).data; |
| 5070 | 5069 | const array_ptr = try sema.resolveInst(elem_ptr_extra.ptr); |
| 5071 | const array_ty = sema.typeOf(array_ptr).childType(mod).optEuBaseType(mod); | |
| 5072 | const array_len = array_ty.arrayLen(mod); | |
| 5070 | const array_ty = sema.typeOf(array_ptr).childType(zcu).optEuBaseType(zcu); | |
| 5071 | const array_len = array_ty.arrayLen(zcu); | |
| 5073 | 5072 | |
| 5074 | 5073 | // Collect the comptime element values in case the array literal ends up |
| 5075 | 5074 | // being comptime-known. |
| ... | ... | @@ -5078,15 +5077,15 @@ fn zirValidatePtrArrayInit( |
| 5078 | 5077 | try sema.usizeCast(block, init_src, array_len), |
| 5079 | 5078 | ); |
| 5080 | 5079 | |
| 5081 | if (instrs.len != array_len) switch (array_ty.zigTypeTag(mod)) { | |
| 5080 | if (instrs.len != array_len) switch (array_ty.zigTypeTag(zcu)) { | |
| 5082 | 5081 | .Struct => { |
| 5083 | var root_msg: ?*Module.ErrorMsg = null; | |
| 5082 | var root_msg: ?*Zcu.ErrorMsg = null; | |
| 5084 | 5083 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 5085 | 5084 | |
| 5086 | 5085 | try array_ty.resolveStructFieldInits(pt); |
| 5087 | 5086 | var i = instrs.len; |
| 5088 | 5087 | while (i < array_len) : (i += 1) { |
| 5089 | const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern(); | |
| 5088 | const default_val = array_ty.structFieldDefaultValue(i, zcu).toIntern(); | |
| 5090 | 5089 | if (default_val == .unreachable_value) { |
| 5091 | 5090 | const template = "missing tuple field with index {d}"; |
| 5092 | 5091 | if (root_msg) |msg| { |
| ... | ... | @@ -5125,7 +5124,7 @@ fn zirValidatePtrArrayInit( |
| 5125 | 5124 | // at comptime so we have almost nothing to do here. However, in case of a |
| 5126 | 5125 | // sentinel-terminated array, the sentinel will not have been populated by |
| 5127 | 5126 | // any ZIR instructions at comptime; we need to do that here. |
| 5128 | if (array_ty.sentinel(mod)) |sentinel_val| { | |
| 5127 | if (array_ty.sentinel(zcu)) |sentinel_val| { | |
| 5129 | 5128 | const array_len_ref = try pt.intRef(Type.usize, array_len); |
| 5130 | 5129 | const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true); |
| 5131 | 5130 | const sentinel = Air.internedToRef(sentinel_val.toIntern()); |
| ... | ... | @@ -5150,8 +5149,8 @@ fn zirValidatePtrArrayInit( |
| 5150 | 5149 | outer: for (instrs, 0..) |elem_ptr, i| { |
| 5151 | 5150 | // Determine whether the value stored to this pointer is comptime-known. |
| 5152 | 5151 | |
| 5153 | if (array_ty.isTuple(mod)) { | |
| 5154 | if (array_ty.structFieldIsComptime(i, mod)) | |
| 5152 | if (array_ty.isTuple(zcu)) { | |
| 5153 | if (array_ty.structFieldIsComptime(i, zcu)) | |
| 5155 | 5154 | try array_ty.resolveStructFieldInits(pt); |
| 5156 | 5155 | if (try array_ty.structFieldValueComptime(pt, i)) |opv| { |
| 5157 | 5156 | element_vals[i] = opv.toIntern(); |
| ... | ... | @@ -5216,7 +5215,7 @@ fn zirValidatePtrArrayInit( |
| 5216 | 5215 | |
| 5217 | 5216 | if (array_is_comptime) { |
| 5218 | 5217 | if (try sema.resolveDefinedValue(block, init_src, array_ptr)) |ptr_val| { |
| 5219 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { | |
| 5218 | switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) { | |
| 5220 | 5219 | .ptr => |ptr| switch (ptr.base_addr) { |
| 5221 | 5220 | .comptime_field => return, // This store was validated by the individual elem ptrs. |
| 5222 | 5221 | else => {}, |
| ... | ... | @@ -5232,7 +5231,7 @@ fn zirValidatePtrArrayInit( |
| 5232 | 5231 | var block_index = first_block_index; |
| 5233 | 5232 | for (block.instructions.items[first_block_index..]) |cur_inst| { |
| 5234 | 5233 | while (elem_ptr_ref == .none and elem_index < instrs.len) : (elem_index += 1) { |
| 5235 | if (array_ty.isTuple(mod) and array_ty.structFieldIsComptime(elem_index, mod)) continue; | |
| 5234 | if (array_ty.isTuple(zcu) and array_ty.structFieldIsComptime(elem_index, zcu)) continue; | |
| 5236 | 5235 | elem_ptr_ref = sema.inst_map.get(instrs[elem_index]).?; |
| 5237 | 5236 | } |
| 5238 | 5237 | switch (air_tags[@intFromEnum(cur_inst)]) { |
| ... | ... | @@ -5266,31 +5265,31 @@ fn zirValidatePtrArrayInit( |
| 5266 | 5265 | |
| 5267 | 5266 | fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5268 | 5267 | const pt = sema.pt; |
| 5269 | const mod = pt.zcu; | |
| 5268 | const zcu = pt.zcu; | |
| 5270 | 5269 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 5271 | 5270 | const src = block.nodeOffset(inst_data.src_node); |
| 5272 | 5271 | const operand = try sema.resolveInst(inst_data.operand); |
| 5273 | 5272 | const operand_ty = sema.typeOf(operand); |
| 5274 | 5273 | |
| 5275 | if (operand_ty.zigTypeTag(mod) != .Pointer) { | |
| 5274 | if (operand_ty.zigTypeTag(zcu) != .Pointer) { | |
| 5276 | 5275 | return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(pt)}); |
| 5277 | } else switch (operand_ty.ptrSize(mod)) { | |
| 5276 | } else switch (operand_ty.ptrSize(zcu)) { | |
| 5278 | 5277 | .One, .C => {}, |
| 5279 | 5278 | .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(pt)}), |
| 5280 | 5279 | .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(pt)}), |
| 5281 | 5280 | } |
| 5282 | 5281 | |
| 5283 | if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) { | |
| 5282 | if ((try sema.typeHasOnePossibleValue(operand_ty.childType(zcu))) != null) { | |
| 5284 | 5283 | // No need to validate the actual pointer value, we don't need it! |
| 5285 | 5284 | return; |
| 5286 | 5285 | } |
| 5287 | 5286 | |
| 5288 | const elem_ty = operand_ty.elemType2(mod); | |
| 5287 | const elem_ty = operand_ty.elemType2(zcu); | |
| 5289 | 5288 | if (try sema.resolveValue(operand)) |val| { |
| 5290 | if (val.isUndef(mod)) { | |
| 5289 | if (val.isUndef(zcu)) { | |
| 5291 | 5290 | return sema.fail(block, src, "cannot dereference undefined value", .{}); |
| 5292 | 5291 | } |
| 5293 | } else if (try sema.typeRequiresComptime(elem_ty)) { | |
| 5292 | } else if (try elem_ty.comptimeOnlySema(pt)) { | |
| 5294 | 5293 | const msg = msg: { |
| 5295 | 5294 | const msg = try sema.errMsg( |
| 5296 | 5295 | src, |
| ... | ... | @@ -5308,7 +5307,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 5308 | 5307 | |
| 5309 | 5308 | fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5310 | 5309 | const pt = sema.pt; |
| 5311 | const mod = pt.zcu; | |
| 5310 | const zcu = pt.zcu; | |
| 5312 | 5311 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5313 | 5312 | const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data; |
| 5314 | 5313 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -5316,9 +5315,9 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 5316 | 5315 | const operand = try sema.resolveInst(extra.operand); |
| 5317 | 5316 | const operand_ty = sema.typeOf(operand); |
| 5318 | 5317 | |
| 5319 | const can_destructure = switch (operand_ty.zigTypeTag(mod)) { | |
| 5318 | const can_destructure = switch (operand_ty.zigTypeTag(zcu)) { | |
| 5320 | 5319 | .Array, .Vector => true, |
| 5321 | .Struct => operand_ty.isTuple(mod), | |
| 5320 | .Struct => operand_ty.isTuple(zcu), | |
| 5322 | 5321 | else => false, |
| 5323 | 5322 | }; |
| 5324 | 5323 | |
| ... | ... | @@ -5331,11 +5330,11 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 5331 | 5330 | }); |
| 5332 | 5331 | } |
| 5333 | 5332 | |
| 5334 | if (operand_ty.arrayLen(mod) != extra.expect_len) { | |
| 5333 | if (operand_ty.arrayLen(zcu) != extra.expect_len) { | |
| 5335 | 5334 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 5336 | 5335 | const msg = try sema.errMsg(src, "expected {} elements for destructure, found {}", .{ |
| 5337 | 5336 | extra.expect_len, |
| 5338 | operand_ty.arrayLen(mod), | |
| 5337 | operand_ty.arrayLen(zcu), | |
| 5339 | 5338 | }); |
| 5340 | 5339 | errdefer msg.destroy(sema.gpa); |
| 5341 | 5340 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); |
| ... | ... | @@ -5423,7 +5422,7 @@ fn failWithBadUnionFieldAccess( |
| 5423 | 5422 | return sema.failWithOwnedErrorMsg(block, msg); |
| 5424 | 5423 | } |
| 5425 | 5424 | |
| 5426 | fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void { | |
| 5425 | fn addDeclaredHereNote(sema: *Sema, parent: *Zcu.ErrorMsg, decl_ty: Type) !void { | |
| 5427 | 5426 | const zcu = sema.pt.zcu; |
| 5428 | 5427 | const src_loc = decl_ty.srcLocOrNull(zcu) orelse return; |
| 5429 | 5428 | const category = switch (decl_ty.zigTypeTag(zcu)) { |
| ... | ... | @@ -5537,7 +5536,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v |
| 5537 | 5536 | defer tracy.end(); |
| 5538 | 5537 | |
| 5539 | 5538 | const pt = sema.pt; |
| 5540 | const mod = pt.zcu; | |
| 5539 | const zcu = pt.zcu; | |
| 5541 | 5540 | const zir_tags = sema.code.instructions.items(.tag); |
| 5542 | 5541 | const zir_datas = sema.code.instructions.items(.data); |
| 5543 | 5542 | const inst_data = zir_datas[@intFromEnum(inst)].pl_node; |
| ... | ... | @@ -5556,7 +5555,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v |
| 5556 | 5555 | // %b = store(%a, %c) |
| 5557 | 5556 | // Where %c is an error union or error set. In such case we need to add |
| 5558 | 5557 | // to the current function's inferred error set, if any. |
| 5559 | if (is_ret and sema.fn_ret_ty_ies != null) switch (sema.typeOf(operand).zigTypeTag(mod)) { | |
| 5558 | if (is_ret and sema.fn_ret_ty_ies != null) switch (sema.typeOf(operand).zigTypeTag(zcu)) { | |
| 5560 | 5559 | .ErrorUnion, .ErrorSet => try sema.addToInferredErrorSet(operand), |
| 5561 | 5560 | else => {}, |
| 5562 | 5561 | }; |
| ... | ... | @@ -5688,9 +5687,9 @@ fn zirCompileLog( |
| 5688 | 5687 | extended: Zir.Inst.Extended.InstData, |
| 5689 | 5688 | ) CompileError!Air.Inst.Ref { |
| 5690 | 5689 | const pt = sema.pt; |
| 5691 | const mod = pt.zcu; | |
| 5690 | const zcu = pt.zcu; | |
| 5692 | 5691 | |
| 5693 | var managed = mod.compile_log_text.toManaged(sema.gpa); | |
| 5692 | var managed = zcu.compile_log_text.toManaged(sema.gpa); | |
| 5694 | 5693 | defer pt.zcu.compile_log_text = managed.moveToUnmanaged(); |
| 5695 | 5694 | const writer = managed.writer(); |
| 5696 | 5695 | |
| ... | ... | @@ -5713,7 +5712,7 @@ fn zirCompileLog( |
| 5713 | 5712 | } |
| 5714 | 5713 | try writer.print("\n", .{}); |
| 5715 | 5714 | |
| 5716 | const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.owner); | |
| 5715 | const gop = try zcu.compile_log_sources.getOrPut(sema.gpa, sema.owner); | |
| 5717 | 5716 | if (!gop.found_existing) gop.value_ptr.* = .{ |
| 5718 | 5717 | .base_node_inst = block.src_base_inst, |
| 5719 | 5718 | .node_offset = src_node, |
| ... | ... | @@ -5749,7 +5748,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5749 | 5748 | defer tracy.end(); |
| 5750 | 5749 | |
| 5751 | 5750 | const pt = sema.pt; |
| 5752 | const mod = pt.zcu; | |
| 5751 | const zcu = pt.zcu; | |
| 5753 | 5752 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 5754 | 5753 | const src = parent_block.nodeOffset(inst_data.src_node); |
| 5755 | 5754 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| ... | ... | @@ -5800,7 +5799,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5800 | 5799 | try sema.analyzeBodyInner(&loop_block, body); |
| 5801 | 5800 | |
| 5802 | 5801 | const loop_block_len = loop_block.instructions.items.len; |
| 5803 | if (loop_block_len > 0 and sema.typeOf(loop_block.instructions.items[loop_block_len - 1].toRef()).isNoReturn(mod)) { | |
| 5802 | if (loop_block_len > 0 and sema.typeOf(loop_block.instructions.items[loop_block_len - 1].toRef()).isNoReturn(zcu)) { | |
| 5804 | 5803 | // If the loop ended with a noreturn terminator, then there is no way for it to loop, |
| 5805 | 5804 | // so we can just use the block instead. |
| 5806 | 5805 | try child_block.instructions.appendSlice(gpa, loop_block.instructions.items); |
| ... | ... | @@ -6069,11 +6068,11 @@ fn resolveAnalyzedBlock( |
| 6069 | 6068 | |
| 6070 | 6069 | const gpa = sema.gpa; |
| 6071 | 6070 | const pt = sema.pt; |
| 6072 | const mod = pt.zcu; | |
| 6071 | const zcu = pt.zcu; | |
| 6073 | 6072 | |
| 6074 | 6073 | // Blocks must terminate with noreturn instruction. |
| 6075 | 6074 | assert(child_block.instructions.items.len != 0); |
| 6076 | assert(sema.typeOf(child_block.instructions.items[child_block.instructions.items.len - 1].toRef()).isNoReturn(mod)); | |
| 6075 | assert(sema.typeOf(child_block.instructions.items[child_block.instructions.items.len - 1].toRef()).isNoReturn(zcu)); | |
| 6077 | 6076 | |
| 6078 | 6077 | const block_tag = sema.air_instructions.items(.tag)[@intFromEnum(merges.block_inst)]; |
| 6079 | 6078 | switch (block_tag) { |
| ... | ... | @@ -6178,7 +6177,7 @@ fn resolveAnalyzedBlock( |
| 6178 | 6177 | // TODO add note "missing else causes void value" |
| 6179 | 6178 | |
| 6180 | 6179 | const type_src = src; // TODO: better source location |
| 6181 | if (try sema.typeRequiresComptime(resolved_ty)) { | |
| 6180 | if (try resolved_ty.comptimeOnlySema(pt)) { | |
| 6182 | 6181 | const msg = msg: { |
| 6183 | 6182 | const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(pt)}); |
| 6184 | 6183 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -6227,7 +6226,7 @@ fn resolveAnalyzedBlock( |
| 6227 | 6226 | const br_operand = sema.air_instructions.items(.data)[@intFromEnum(br)].br.operand; |
| 6228 | 6227 | const br_operand_src = src; |
| 6229 | 6228 | const br_operand_ty = sema.typeOf(br_operand); |
| 6230 | if (br_operand_ty.eql(resolved_ty, mod)) { | |
| 6229 | if (br_operand_ty.eql(resolved_ty, zcu)) { | |
| 6231 | 6230 | // No type coercion needed. |
| 6232 | 6231 | continue; |
| 6233 | 6232 | } |
| ... | ... | @@ -6354,7 +6353,7 @@ pub fn analyzeExport( |
| 6354 | 6353 | sema: *Sema, |
| 6355 | 6354 | block: *Block, |
| 6356 | 6355 | src: LazySrcLoc, |
| 6357 | options: Module.Export.Options, | |
| 6356 | options: Zcu.Export.Options, | |
| 6358 | 6357 | exported_nav_index: InternPool.Nav.Index, |
| 6359 | 6358 | ) !void { |
| 6360 | 6359 | const gpa = sema.gpa; |
| ... | ... | @@ -6427,8 +6426,8 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 6427 | 6426 | |
| 6428 | 6427 | fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| 6429 | 6428 | const pt = sema.pt; |
| 6430 | const mod = pt.zcu; | |
| 6431 | const ip = &mod.intern_pool; | |
| 6429 | const zcu = pt.zcu; | |
| 6430 | const ip = &zcu.intern_pool; | |
| 6432 | 6431 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 6433 | 6432 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 6434 | 6433 | const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{ |
| ... | ... | @@ -6446,8 +6445,8 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) |
| 6446 | 6445 | |
| 6447 | 6446 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { |
| 6448 | 6447 | const pt = sema.pt; |
| 6449 | const mod = pt.zcu; | |
| 6450 | const ip = &mod.intern_pool; | |
| 6448 | const zcu = pt.zcu; | |
| 6449 | const ip = &zcu.intern_pool; | |
| 6451 | 6450 | const func = switch (sema.owner.unwrap()) { |
| 6452 | 6451 | .func => |func| func, |
| 6453 | 6452 | .cau => return, // does nothing outside a function |
| ... | ... | @@ -6572,17 +6571,17 @@ fn addDbgVar( |
| 6572 | 6571 | if (block.is_comptime or block.ownerModule().strip) return; |
| 6573 | 6572 | |
| 6574 | 6573 | const pt = sema.pt; |
| 6575 | const mod = pt.zcu; | |
| 6574 | const zcu = pt.zcu; | |
| 6576 | 6575 | const operand_ty = sema.typeOf(operand); |
| 6577 | 6576 | const val_ty = switch (air_tag) { |
| 6578 | .dbg_var_ptr => operand_ty.childType(mod), | |
| 6577 | .dbg_var_ptr => operand_ty.childType(zcu), | |
| 6579 | 6578 | .dbg_var_val, .dbg_arg_inline => operand_ty, |
| 6580 | 6579 | else => unreachable, |
| 6581 | 6580 | }; |
| 6582 | if (try sema.typeRequiresComptime(val_ty)) return; | |
| 6583 | if (!(try sema.typeHasRuntimeBits(val_ty))) return; | |
| 6581 | if (try val_ty.comptimeOnlySema(pt)) return; | |
| 6582 | if (!(try val_ty.hasRuntimeBitsSema(pt))) return; | |
| 6584 | 6583 | if (try sema.resolveValue(operand)) |operand_val| { |
| 6585 | if (operand_val.canMutateComptimeVarState(mod)) return; | |
| 6584 | if (operand_val.canMutateComptimeVarState(zcu)) return; | |
| 6586 | 6585 | } |
| 6587 | 6586 | |
| 6588 | 6587 | // To ensure the lexical scoping is known to backends, this alloc must be |
| ... | ... | @@ -6619,10 +6618,10 @@ pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!Air.NullTer |
| 6619 | 6618 | |
| 6620 | 6619 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 6621 | 6620 | const pt = sema.pt; |
| 6622 | const mod = pt.zcu; | |
| 6621 | const zcu = pt.zcu; | |
| 6623 | 6622 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 6624 | 6623 | const src = block.tokenOffset(inst_data.src_tok); |
| 6625 | const decl_name = try mod.intern_pool.getOrPutString( | |
| 6624 | const decl_name = try zcu.intern_pool.getOrPutString( | |
| 6626 | 6625 | sema.gpa, |
| 6627 | 6626 | pt.tid, |
| 6628 | 6627 | inst_data.get(sema.code), |
| ... | ... | @@ -6634,10 +6633,10 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6634 | 6633 | |
| 6635 | 6634 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 6636 | 6635 | const pt = sema.pt; |
| 6637 | const mod = pt.zcu; | |
| 6636 | const zcu = pt.zcu; | |
| 6638 | 6637 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 6639 | 6638 | const src = block.tokenOffset(inst_data.src_tok); |
| 6640 | const decl_name = try mod.intern_pool.getOrPutString( | |
| 6639 | const decl_name = try zcu.intern_pool.getOrPutString( | |
| 6641 | 6640 | sema.gpa, |
| 6642 | 6641 | pt.tid, |
| 6643 | 6642 | inst_data.get(sema.code), |
| ... | ... | @@ -6649,14 +6648,14 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6649 | 6648 | |
| 6650 | 6649 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.Nav.Index { |
| 6651 | 6650 | const pt = sema.pt; |
| 6652 | const mod = pt.zcu; | |
| 6651 | const zcu = pt.zcu; | |
| 6653 | 6652 | var namespace = block.namespace; |
| 6654 | 6653 | while (true) { |
| 6655 | 6654 | if (try sema.lookupInNamespace(block, src, namespace, name, false)) |lookup| { |
| 6656 | 6655 | assert(lookup.accessible); |
| 6657 | 6656 | return lookup.nav; |
| 6658 | 6657 | } |
| 6659 | namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break; | |
| 6658 | namespace = zcu.namespacePtr(namespace).parent.unwrap() orelse break; | |
| 6660 | 6659 | } |
| 6661 | 6660 | unreachable; // AstGen detects use of undeclared identifiers. |
| 6662 | 6661 | } |
| ... | ... | @@ -6801,7 +6800,7 @@ fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedIns |
| 6801 | 6800 | |
| 6802 | 6801 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { |
| 6803 | 6802 | const pt = sema.pt; |
| 6804 | const mod = pt.zcu; | |
| 6803 | const zcu = pt.zcu; | |
| 6805 | 6804 | const gpa = sema.gpa; |
| 6806 | 6805 | |
| 6807 | 6806 | if (block.is_comptime or block.is_typeof) { |
| ... | ... | @@ -6813,7 +6812,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref |
| 6813 | 6812 | |
| 6814 | 6813 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 6815 | 6814 | try stack_trace_ty.resolveFields(pt); |
| 6816 | const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | |
| 6815 | const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | |
| 6817 | 6816 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { |
| 6818 | 6817 | error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"), |
| 6819 | 6818 | error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, |
| ... | ... | @@ -6839,7 +6838,7 @@ fn popErrorReturnTrace( |
| 6839 | 6838 | saved_error_trace_index: Air.Inst.Ref, |
| 6840 | 6839 | ) CompileError!void { |
| 6841 | 6840 | const pt = sema.pt; |
| 6842 | const mod = pt.zcu; | |
| 6841 | const zcu = pt.zcu; | |
| 6843 | 6842 | const gpa = sema.gpa; |
| 6844 | 6843 | var is_non_error: ?bool = null; |
| 6845 | 6844 | var is_non_error_inst: Air.Inst.Ref = undefined; |
| ... | ... | @@ -6857,7 +6856,7 @@ fn popErrorReturnTrace( |
| 6857 | 6856 | try stack_trace_ty.resolveFields(pt); |
| 6858 | 6857 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 6859 | 6858 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 6860 | const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | |
| 6859 | const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | |
| 6861 | 6860 | const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true); |
| 6862 | 6861 | try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store); |
| 6863 | 6862 | } else if (is_non_error == null) { |
| ... | ... | @@ -6883,7 +6882,7 @@ fn popErrorReturnTrace( |
| 6883 | 6882 | try stack_trace_ty.resolveFields(pt); |
| 6884 | 6883 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 6885 | 6884 | const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 6886 | const field_name = try mod.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | |
| 6885 | const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | |
| 6887 | 6886 | const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true); |
| 6888 | 6887 | try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store); |
| 6889 | 6888 | _ = try then_block.addBr(cond_block_inst, .void_value); |
| ... | ... | @@ -6923,7 +6922,7 @@ fn zirCall( |
| 6923 | 6922 | defer tracy.end(); |
| 6924 | 6923 | |
| 6925 | 6924 | const pt = sema.pt; |
| 6926 | const mod = pt.zcu; | |
| 6925 | const zcu = pt.zcu; | |
| 6927 | 6926 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 6928 | 6927 | const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node }); |
| 6929 | 6928 | const call_src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -6942,7 +6941,7 @@ fn zirCall( |
| 6942 | 6941 | .direct => .{ .direct = try sema.resolveInst(extra.data.callee) }, |
| 6943 | 6942 | .field => blk: { |
| 6944 | 6943 | const object_ptr = try sema.resolveInst(extra.data.obj_ptr); |
| 6945 | const field_name = try mod.intern_pool.getOrPutString( | |
| 6944 | const field_name = try zcu.intern_pool.getOrPutString( | |
| 6946 | 6945 | sema.gpa, |
| 6947 | 6946 | pt.tid, |
| 6948 | 6947 | sema.code.nullTerminatedString(extra.data.field_name_start), |
| ... | ... | @@ -6987,7 +6986,7 @@ fn zirCall( |
| 6987 | 6986 | |
| 6988 | 6987 | switch (sema.owner.unwrap()) { |
| 6989 | 6988 | .cau => input_is_error = false, |
| 6990 | .func => |owner_func| if (!mod.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) { | |
| 6989 | .func => |owner_func| if (!zcu.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) { | |
| 6991 | 6990 | // No errorable fn actually called; we have no error return trace |
| 6992 | 6991 | input_is_error = false; |
| 6993 | 6992 | }, |
| ... | ... | @@ -6997,7 +6996,7 @@ fn zirCall( |
| 6997 | 6996 | !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) |
| 6998 | 6997 | { |
| 6999 | 6998 | const return_ty = sema.typeOf(call_inst); |
| 7000 | if (modifier != .always_tail and return_ty.isNoReturn(mod)) | |
| 6999 | if (modifier != .always_tail and return_ty.isNoReturn(zcu)) | |
| 7001 | 7000 | return call_inst; // call to "fn (...) noreturn", don't pop |
| 7002 | 7001 | |
| 7003 | 7002 | // TODO: we don't fix up the error trace for always_tail correctly, we should be doing it |
| ... | ... | @@ -7008,10 +7007,10 @@ fn zirCall( |
| 7008 | 7007 | |
| 7009 | 7008 | // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only |
| 7010 | 7009 | // need to clean-up our own trace if we were passed to a non-error-handling expression. |
| 7011 | if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) { | |
| 7010 | if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) { | |
| 7012 | 7011 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 7013 | 7012 | try stack_trace_ty.resolveFields(pt); |
| 7014 | const field_name = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls); | |
| 7013 | const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls); | |
| 7015 | 7014 | const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src); |
| 7016 | 7015 | |
| 7017 | 7016 | // Insert a save instruction before the arg resolution + call instructions we just generated |
| ... | ... | @@ -7044,20 +7043,20 @@ fn checkCallArgumentCount( |
| 7044 | 7043 | member_fn: bool, |
| 7045 | 7044 | ) !Type { |
| 7046 | 7045 | const pt = sema.pt; |
| 7047 | const mod = pt.zcu; | |
| 7046 | const zcu = pt.zcu; | |
| 7048 | 7047 | const func_ty = func_ty: { |
| 7049 | switch (callee_ty.zigTypeTag(mod)) { | |
| 7048 | switch (callee_ty.zigTypeTag(zcu)) { | |
| 7050 | 7049 | .Fn => break :func_ty callee_ty, |
| 7051 | 7050 | .Pointer => { |
| 7052 | const ptr_info = callee_ty.ptrInfo(mod); | |
| 7053 | if (ptr_info.flags.size == .One and Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) { | |
| 7051 | const ptr_info = callee_ty.ptrInfo(zcu); | |
| 7052 | if (ptr_info.flags.size == .One and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .Fn) { | |
| 7054 | 7053 | break :func_ty Type.fromInterned(ptr_info.child); |
| 7055 | 7054 | } |
| 7056 | 7055 | }, |
| 7057 | 7056 | .Optional => { |
| 7058 | const opt_child = callee_ty.optionalChild(mod); | |
| 7059 | if (opt_child.zigTypeTag(mod) == .Fn or (opt_child.isSinglePointer(mod) and | |
| 7060 | opt_child.childType(mod).zigTypeTag(mod) == .Fn)) | |
| 7057 | const opt_child = callee_ty.optionalChild(zcu); | |
| 7058 | if (opt_child.zigTypeTag(zcu) == .Fn or (opt_child.isSinglePointer(zcu) and | |
| 7059 | opt_child.childType(zcu).zigTypeTag(zcu) == .Fn)) | |
| 7061 | 7060 | { |
| 7062 | 7061 | const msg = msg: { |
| 7063 | 7062 | const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{ |
| ... | ... | @@ -7075,7 +7074,7 @@ fn checkCallArgumentCount( |
| 7075 | 7074 | return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(pt)}); |
| 7076 | 7075 | }; |
| 7077 | 7076 | |
| 7078 | const func_ty_info = mod.typeToFunc(func_ty).?; | |
| 7077 | const func_ty_info = zcu.typeToFunc(func_ty).?; | |
| 7079 | 7078 | const fn_params_len = func_ty_info.param_types.len; |
| 7080 | 7079 | const args_len = total_args - @intFromBool(member_fn); |
| 7081 | 7080 | if (func_ty_info.is_var_args) { |
| ... | ... | @@ -7122,14 +7121,14 @@ fn callBuiltin( |
| 7122 | 7121 | operation: CallOperation, |
| 7123 | 7122 | ) !void { |
| 7124 | 7123 | const pt = sema.pt; |
| 7125 | const mod = pt.zcu; | |
| 7124 | const zcu = pt.zcu; | |
| 7126 | 7125 | const callee_ty = sema.typeOf(builtin_fn); |
| 7127 | 7126 | const func_ty = func_ty: { |
| 7128 | switch (callee_ty.zigTypeTag(mod)) { | |
| 7127 | switch (callee_ty.zigTypeTag(zcu)) { | |
| 7129 | 7128 | .Fn => break :func_ty callee_ty, |
| 7130 | 7129 | .Pointer => { |
| 7131 | const ptr_info = callee_ty.ptrInfo(mod); | |
| 7132 | if (ptr_info.flags.size == .One and Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) { | |
| 7130 | const ptr_info = callee_ty.ptrInfo(zcu); | |
| 7131 | if (ptr_info.flags.size == .One and Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .Fn) { | |
| 7133 | 7132 | break :func_ty Type.fromInterned(ptr_info.child); |
| 7134 | 7133 | } |
| 7135 | 7134 | }, |
| ... | ... | @@ -7138,7 +7137,7 @@ fn callBuiltin( |
| 7138 | 7137 | std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(pt)}); |
| 7139 | 7138 | }; |
| 7140 | 7139 | |
| 7141 | const func_ty_info = mod.typeToFunc(func_ty).?; | |
| 7140 | const func_ty_info = zcu.typeToFunc(func_ty).?; | |
| 7142 | 7141 | const fn_params_len = func_ty_info.param_types.len; |
| 7143 | 7142 | if (args.len != fn_params_len or (func_ty_info.is_var_args and args.len < fn_params_len)) { |
| 7144 | 7143 | std.debug.panic("parameter count mismatch calling builtin fn, expected {d}, found {d}", .{ fn_params_len, args.len }); |
| ... | ... | @@ -7242,7 +7241,7 @@ const CallArgsInfo = union(enum) { |
| 7242 | 7241 | func_inst: Air.Inst.Ref, |
| 7243 | 7242 | ) CompileError!Air.Inst.Ref { |
| 7244 | 7243 | const pt = sema.pt; |
| 7245 | const mod = pt.zcu; | |
| 7244 | const zcu = pt.zcu; | |
| 7246 | 7245 | const param_count = func_ty_info.param_types.len; |
| 7247 | 7246 | const uncoerced_arg: Air.Inst.Ref = switch (cai) { |
| 7248 | 7247 | inline .resolved, .call_builtin => |resolved| resolved.args[arg_index], |
| ... | ... | @@ -7277,13 +7276,13 @@ const CallArgsInfo = union(enum) { |
| 7277 | 7276 | // Resolve the arg! |
| 7278 | 7277 | const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst); |
| 7279 | 7278 | |
| 7280 | if (sema.typeOf(uncoerced_arg).zigTypeTag(mod) == .NoReturn) { | |
| 7279 | if (sema.typeOf(uncoerced_arg).zigTypeTag(zcu) == .NoReturn) { | |
| 7281 | 7280 | // This terminates resolution of arguments. The caller should |
| 7282 | 7281 | // propagate this. |
| 7283 | 7282 | return uncoerced_arg; |
| 7284 | 7283 | } |
| 7285 | 7284 | |
| 7286 | if (sema.typeOf(uncoerced_arg).isError(mod)) { | |
| 7285 | if (sema.typeOf(uncoerced_arg).isError(zcu)) { | |
| 7287 | 7286 | zir_call.any_arg_is_error.* = true; |
| 7288 | 7287 | } |
| 7289 | 7288 | |
| ... | ... | @@ -7476,7 +7475,7 @@ fn analyzeCall( |
| 7476 | 7475 | var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .Inline; |
| 7477 | 7476 | var comptime_reason: ?*const Block.ComptimeReason = null; |
| 7478 | 7477 | if (!is_inline_call and !is_comptime_call) { |
| 7479 | if (try sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) { | |
| 7478 | if (try Type.fromInterned(func_ty_info.return_type).comptimeOnlySema(pt)) { | |
| 7480 | 7479 | is_comptime_call = true; |
| 7481 | 7480 | is_inline_call = true; |
| 7482 | 7481 | comptime_reason = &.{ .comptime_ret_ty = .{ |
| ... | ... | @@ -7968,8 +7967,8 @@ fn analyzeInlineCallArg( |
| 7968 | 7967 | func_ty_info: InternPool.Key.FuncType, |
| 7969 | 7968 | func_inst: Air.Inst.Ref, |
| 7970 | 7969 | ) !?Air.Inst.Ref { |
| 7971 | const mod = ics.sema.pt.zcu; | |
| 7972 | const ip = &mod.intern_pool; | |
| 7970 | const zcu = ics.sema.pt.zcu; | |
| 7971 | const ip = &zcu.intern_pool; | |
| 7973 | 7972 | const zir_tags = ics.callee().code.instructions.items(.tag); |
| 7974 | 7973 | switch (zir_tags[@intFromEnum(inst)]) { |
| 7975 | 7974 | .param_comptime, .param_anytype_comptime => param_block.inlining.?.has_comptime_args = true, |
| ... | ... | @@ -7992,11 +7991,11 @@ fn analyzeInlineCallArg( |
| 7992 | 7991 | }; |
| 7993 | 7992 | new_param_types[arg_i.*] = param_ty; |
| 7994 | 7993 | const casted_arg = try args_info.analyzeArg(ics.caller(), arg_block, arg_i.*, Type.fromInterned(param_ty), func_ty_info, func_inst); |
| 7995 | if (ics.caller().typeOf(casted_arg).zigTypeTag(mod) == .NoReturn) { | |
| 7994 | if (ics.caller().typeOf(casted_arg).zigTypeTag(zcu) == .NoReturn) { | |
| 7996 | 7995 | return casted_arg; |
| 7997 | 7996 | } |
| 7998 | 7997 | const arg_src = args_info.argSrc(arg_block, arg_i.*); |
| 7999 | if (try ics.callee().typeRequiresComptime(Type.fromInterned(param_ty))) { | |
| 7998 | if (try Type.fromInterned(param_ty).comptimeOnlySema(ics.callee().pt)) { | |
| 8000 | 7999 | _ = try ics.caller().resolveConstValue(arg_block, arg_src, casted_arg, .{ |
| 8001 | 8000 | .needed_comptime_reason = "argument to parameter with comptime-only type must be comptime-known", |
| 8002 | 8001 | .block_comptime_reason = param_block.comptime_reason, |
| ... | ... | @@ -8025,7 +8024,7 @@ fn analyzeInlineCallArg( |
| 8025 | 8024 | // assertion due to type not being resolved |
| 8026 | 8025 | // when the hash function is called. |
| 8027 | 8026 | const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val); |
| 8028 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod); | |
| 8027 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(zcu); | |
| 8029 | 8028 | memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern(); |
| 8030 | 8029 | } else { |
| 8031 | 8030 | ics.callee().inst_map.putAssumeCapacityNoClobber(inst, casted_arg); |
| ... | ... | @@ -8040,7 +8039,7 @@ fn analyzeInlineCallArg( |
| 8040 | 8039 | .param_anytype, .param_anytype_comptime => { |
| 8041 | 8040 | // No coercion needed. |
| 8042 | 8041 | const uncasted_arg = try args_info.analyzeArg(ics.caller(), arg_block, arg_i.*, Type.generic_poison, func_ty_info, func_inst); |
| 8043 | if (ics.caller().typeOf(uncasted_arg).zigTypeTag(mod) == .NoReturn) { | |
| 8042 | if (ics.caller().typeOf(uncasted_arg).zigTypeTag(zcu) == .NoReturn) { | |
| 8044 | 8043 | return uncasted_arg; |
| 8045 | 8044 | } |
| 8046 | 8045 | const arg_src = args_info.argSrc(arg_block, arg_i.*); |
| ... | ... | @@ -8064,7 +8063,7 @@ fn analyzeInlineCallArg( |
| 8064 | 8063 | // assertion due to type not being resolved |
| 8065 | 8064 | // when the hash function is called. |
| 8066 | 8065 | const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val); |
| 8067 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod); | |
| 8066 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(zcu); | |
| 8068 | 8067 | memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern(); |
| 8069 | 8068 | } else { |
| 8070 | 8069 | if (zir_tags[@intFromEnum(inst)] == .param_anytype_comptime) { |
| ... | ... | @@ -8236,7 +8235,7 @@ fn instantiateGenericCall( |
| 8236 | 8235 | |
| 8237 | 8236 | const arg_is_comptime = switch (param_tag) { |
| 8238 | 8237 | .param_comptime, .param_anytype_comptime => true, |
| 8239 | .param, .param_anytype => try sema.typeRequiresComptime(arg_ty), | |
| 8238 | .param, .param_anytype => try arg_ty.comptimeOnlySema(pt), | |
| 8240 | 8239 | else => unreachable, |
| 8241 | 8240 | }; |
| 8242 | 8241 | |
| ... | ... | @@ -8325,7 +8324,7 @@ fn instantiateGenericCall( |
| 8325 | 8324 | |
| 8326 | 8325 | // If the call evaluated to a return type that requires comptime, never mind |
| 8327 | 8326 | // our generic instantiation. Instead we need to perform a comptime call. |
| 8328 | if (try sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) { | |
| 8327 | if (try Type.fromInterned(func_ty_info.return_type).comptimeOnlySema(pt)) { | |
| 8329 | 8328 | return error.ComptimeReturn; |
| 8330 | 8329 | } |
| 8331 | 8330 | // Similarly, if the call evaluated to a generic type we need to instead |
| ... | ... | @@ -8376,8 +8375,8 @@ fn instantiateGenericCall( |
| 8376 | 8375 | |
| 8377 | 8376 | fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { |
| 8378 | 8377 | const pt = sema.pt; |
| 8379 | const mod = pt.zcu; | |
| 8380 | const ip = &mod.intern_pool; | |
| 8378 | const zcu = pt.zcu; | |
| 8379 | const ip = &zcu.intern_pool; | |
| 8381 | 8380 | const tuple = switch (ip.indexToKey(ty.toIntern())) { |
| 8382 | 8381 | .anon_struct_type => |tuple| tuple, |
| 8383 | 8382 | else => return, |
| ... | ... | @@ -8401,13 +8400,13 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 8401 | 8400 | defer tracy.end(); |
| 8402 | 8401 | |
| 8403 | 8402 | const pt = sema.pt; |
| 8404 | const mod = pt.zcu; | |
| 8403 | const zcu = pt.zcu; | |
| 8405 | 8404 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8406 | 8405 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| 8407 | 8406 | const child_type = try sema.resolveType(block, operand_src, inst_data.operand); |
| 8408 | if (child_type.zigTypeTag(mod) == .Opaque) { | |
| 8407 | if (child_type.zigTypeTag(zcu) == .Opaque) { | |
| 8409 | 8408 | return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(pt)}); |
| 8410 | } else if (child_type.zigTypeTag(mod) == .Null) { | |
| 8409 | } else if (child_type.zigTypeTag(zcu) == .Null) { | |
| 8411 | 8410 | return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(pt)}); |
| 8412 | 8411 | } |
| 8413 | 8412 | const opt_type = try pt.optionalType(child_type.toIntern()); |
| ... | ... | @@ -8417,7 +8416,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 8417 | 8416 | |
| 8418 | 8417 | fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8419 | 8418 | const pt = sema.pt; |
| 8420 | const mod = pt.zcu; | |
| 8419 | const zcu = pt.zcu; | |
| 8421 | 8420 | const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin; |
| 8422 | 8421 | const maybe_wrapped_indexable_ty = sema.resolveType(block, LazySrcLoc.unneeded, bin.lhs) catch |err| switch (err) { |
| 8423 | 8422 | // Since this is a ZIR instruction that returns a type, encountering |
| ... | ... | @@ -8427,40 +8426,40 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8427 | 8426 | error.GenericPoison => return .generic_poison_type, |
| 8428 | 8427 | else => |e| return e, |
| 8429 | 8428 | }; |
| 8430 | const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod); | |
| 8429 | const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu); | |
| 8431 | 8430 | try indexable_ty.resolveFields(pt); |
| 8432 | assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction | |
| 8433 | if (indexable_ty.zigTypeTag(mod) == .Struct) { | |
| 8434 | const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod); | |
| 8431 | assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction | |
| 8432 | if (indexable_ty.zigTypeTag(zcu) == .Struct) { | |
| 8433 | const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), zcu); | |
| 8435 | 8434 | return Air.internedToRef(elem_type.toIntern()); |
| 8436 | 8435 | } else { |
| 8437 | const elem_type = indexable_ty.elemType2(mod); | |
| 8436 | const elem_type = indexable_ty.elemType2(zcu); | |
| 8438 | 8437 | return Air.internedToRef(elem_type.toIntern()); |
| 8439 | 8438 | } |
| 8440 | 8439 | } |
| 8441 | 8440 | |
| 8442 | 8441 | fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8443 | 8442 | const pt = sema.pt; |
| 8444 | const mod = pt.zcu; | |
| 8443 | const zcu = pt.zcu; | |
| 8445 | 8444 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8446 | 8445 | const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) { |
| 8447 | 8446 | error.GenericPoison => return .generic_poison_type, |
| 8448 | 8447 | else => |e| return e, |
| 8449 | 8448 | }; |
| 8450 | const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(mod); | |
| 8451 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); // validated by a previous instruction | |
| 8452 | const elem_ty = ptr_ty.childType(mod); | |
| 8449 | const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(zcu); | |
| 8450 | assert(ptr_ty.zigTypeTag(zcu) == .Pointer); // validated by a previous instruction | |
| 8451 | const elem_ty = ptr_ty.childType(zcu); | |
| 8453 | 8452 | if (elem_ty.toIntern() == .anyopaque_type) { |
| 8454 | 8453 | // The pointer's actual child type is effectively unknown, so it makes |
| 8455 | 8454 | // sense to represent it with a generic poison. |
| 8456 | 8455 | return .generic_poison_type; |
| 8457 | 8456 | } |
| 8458 | return Air.internedToRef(ptr_ty.childType(mod).toIntern()); | |
| 8457 | return Air.internedToRef(ptr_ty.childType(zcu).toIntern()); | |
| 8459 | 8458 | } |
| 8460 | 8459 | |
| 8461 | 8460 | fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8462 | 8461 | const pt = sema.pt; |
| 8463 | const mod = pt.zcu; | |
| 8462 | const zcu = pt.zcu; | |
| 8464 | 8463 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8465 | 8464 | const src = block.nodeOffset(un_node.src_node); |
| 8466 | 8465 | const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) { |
| ... | ... | @@ -8468,16 +8467,16 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 8468 | 8467 | else => |e| return e, |
| 8469 | 8468 | }; |
| 8470 | 8469 | try sema.checkMemOperand(block, src, ptr_ty); |
| 8471 | const elem_ty = switch (ptr_ty.ptrSize(mod)) { | |
| 8472 | .Slice, .Many, .C => ptr_ty.childType(mod), | |
| 8473 | .One => ptr_ty.childType(mod).childType(mod), | |
| 8470 | const elem_ty = switch (ptr_ty.ptrSize(zcu)) { | |
| 8471 | .Slice, .Many, .C => ptr_ty.childType(zcu), | |
| 8472 | .One => ptr_ty.childType(zcu).childType(zcu), | |
| 8474 | 8473 | }; |
| 8475 | 8474 | return Air.internedToRef(elem_ty.toIntern()); |
| 8476 | 8475 | } |
| 8477 | 8476 | |
| 8478 | 8477 | fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8479 | 8478 | const pt = sema.pt; |
| 8480 | const mod = pt.zcu; | |
| 8479 | const zcu = pt.zcu; | |
| 8481 | 8480 | const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8482 | 8481 | const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) { |
| 8483 | 8482 | // Since this is a ZIR instruction that returns a type, encountering |
| ... | ... | @@ -8487,10 +8486,10 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8487 | 8486 | error.GenericPoison => return .generic_poison_type, |
| 8488 | 8487 | else => |e| return e, |
| 8489 | 8488 | }; |
| 8490 | if (!vec_ty.isVector(mod)) { | |
| 8489 | if (!vec_ty.isVector(zcu)) { | |
| 8491 | 8490 | return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(pt)}); |
| 8492 | 8491 | } |
| 8493 | return Air.internedToRef(vec_ty.childType(mod).toIntern()); | |
| 8492 | return Air.internedToRef(vec_ty.childType(zcu).toIntern()); | |
| 8494 | 8493 | } |
| 8495 | 8494 | |
| 8496 | 8495 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -8561,10 +8560,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 8561 | 8560 | |
| 8562 | 8561 | fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void { |
| 8563 | 8562 | const pt = sema.pt; |
| 8564 | const mod = pt.zcu; | |
| 8565 | if (elem_type.zigTypeTag(mod) == .Opaque) { | |
| 8563 | const zcu = pt.zcu; | |
| 8564 | if (elem_type.zigTypeTag(zcu) == .Opaque) { | |
| 8566 | 8565 | return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(pt)}); |
| 8567 | } else if (elem_type.zigTypeTag(mod) == .NoReturn) { | |
| 8566 | } else if (elem_type.zigTypeTag(zcu) == .NoReturn) { | |
| 8568 | 8567 | return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{}); |
| 8569 | 8568 | } |
| 8570 | 8569 | } |
| ... | ... | @@ -8577,10 +8576,10 @@ fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 8577 | 8576 | if (true) { |
| 8578 | 8577 | return sema.failWithUseOfAsync(block, block.nodeOffset(inst_data.src_node)); |
| 8579 | 8578 | } |
| 8580 | const mod = sema.mod; | |
| 8579 | const zcu = sema.zcu; | |
| 8581 | 8580 | const operand_src = block.src(.{ .node_offset_anyframe_type = inst_data.src_node }); |
| 8582 | 8581 | const return_type = try sema.resolveType(block, operand_src, inst_data.operand); |
| 8583 | const anyframe_type = try mod.anyframeType(return_type); | |
| 8582 | const anyframe_type = try zcu.anyframeType(return_type); | |
| 8584 | 8583 | |
| 8585 | 8584 | return Air.internedToRef(anyframe_type.toIntern()); |
| 8586 | 8585 | } |
| ... | ... | @@ -8590,7 +8589,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8590 | 8589 | defer tracy.end(); |
| 8591 | 8590 | |
| 8592 | 8591 | const pt = sema.pt; |
| 8593 | const mod = pt.zcu; | |
| 8592 | const zcu = pt.zcu; | |
| 8594 | 8593 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8595 | 8594 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8596 | 8595 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -8598,7 +8597,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8598 | 8597 | const error_set = try sema.resolveType(block, lhs_src, extra.lhs); |
| 8599 | 8598 | const payload = try sema.resolveType(block, rhs_src, extra.rhs); |
| 8600 | 8599 | |
| 8601 | if (error_set.zigTypeTag(mod) != .ErrorSet) { | |
| 8600 | if (error_set.zigTypeTag(zcu) != .ErrorSet) { | |
| 8602 | 8601 | return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{ |
| 8603 | 8602 | error_set.fmt(pt), |
| 8604 | 8603 | }); |
| ... | ... | @@ -8610,12 +8609,12 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8610 | 8609 | |
| 8611 | 8610 | fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void { |
| 8612 | 8611 | const pt = sema.pt; |
| 8613 | const mod = pt.zcu; | |
| 8614 | if (payload_ty.zigTypeTag(mod) == .Opaque) { | |
| 8612 | const zcu = pt.zcu; | |
| 8613 | if (payload_ty.zigTypeTag(zcu) == .Opaque) { | |
| 8615 | 8614 | return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{ |
| 8616 | 8615 | payload_ty.fmt(pt), |
| 8617 | 8616 | }); |
| 8618 | } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) { | |
| 8617 | } else if (payload_ty.zigTypeTag(zcu) == .ErrorSet) { | |
| 8619 | 8618 | return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{ |
| 8620 | 8619 | payload_ty.fmt(pt), |
| 8621 | 8620 | }); |
| ... | ... | @@ -8646,8 +8645,8 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8646 | 8645 | defer tracy.end(); |
| 8647 | 8646 | |
| 8648 | 8647 | const pt = sema.pt; |
| 8649 | const mod = pt.zcu; | |
| 8650 | const ip = &mod.intern_pool; | |
| 8648 | const zcu = pt.zcu; | |
| 8649 | const ip = &zcu.intern_pool; | |
| 8651 | 8650 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8652 | 8651 | const src = block.nodeOffset(extra.node); |
| 8653 | 8652 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| ... | ... | @@ -8656,7 +8655,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8656 | 8655 | const err_int_ty = try pt.errorIntType(); |
| 8657 | 8656 | |
| 8658 | 8657 | if (try sema.resolveValue(operand)) |val| { |
| 8659 | if (val.isUndef(mod)) { | |
| 8658 | if (val.isUndef(zcu)) { | |
| 8660 | 8659 | return pt.undefRef(err_int_ty); |
| 8661 | 8660 | } |
| 8662 | 8661 | const err_name = ip.indexToKey(val.toIntern()).err.name; |
| ... | ... | @@ -8688,8 +8687,8 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8688 | 8687 | defer tracy.end(); |
| 8689 | 8688 | |
| 8690 | 8689 | const pt = sema.pt; |
| 8691 | const mod = pt.zcu; | |
| 8692 | const ip = &mod.intern_pool; | |
| 8690 | const zcu = pt.zcu; | |
| 8691 | const ip = &zcu.intern_pool; | |
| 8693 | 8692 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8694 | 8693 | const src = block.nodeOffset(extra.node); |
| 8695 | 8694 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| ... | ... | @@ -8733,8 +8732,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8733 | 8732 | defer tracy.end(); |
| 8734 | 8733 | |
| 8735 | 8734 | const pt = sema.pt; |
| 8736 | const mod = pt.zcu; | |
| 8737 | const ip = &mod.intern_pool; | |
| 8735 | const zcu = pt.zcu; | |
| 8736 | const ip = &zcu.intern_pool; | |
| 8738 | 8737 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8739 | 8738 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8740 | 8739 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| ... | ... | @@ -8742,7 +8741,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8742 | 8741 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); |
| 8743 | 8742 | const lhs = try sema.resolveInst(extra.lhs); |
| 8744 | 8743 | const rhs = try sema.resolveInst(extra.rhs); |
| 8745 | if (sema.typeOf(lhs).zigTypeTag(mod) == .Bool and sema.typeOf(rhs).zigTypeTag(mod) == .Bool) { | |
| 8744 | if (sema.typeOf(lhs).zigTypeTag(zcu) == .Bool and sema.typeOf(rhs).zigTypeTag(zcu) == .Bool) { | |
| 8746 | 8745 | const msg = msg: { |
| 8747 | 8746 | const msg = try sema.errMsg(lhs_src, "expected error set type, found 'bool'", .{}); |
| 8748 | 8747 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -8753,9 +8752,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8753 | 8752 | } |
| 8754 | 8753 | const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs); |
| 8755 | 8754 | const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs); |
| 8756 | if (lhs_ty.zigTypeTag(mod) != .ErrorSet) | |
| 8755 | if (lhs_ty.zigTypeTag(zcu) != .ErrorSet) | |
| 8757 | 8756 | return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(pt)}); |
| 8758 | if (rhs_ty.zigTypeTag(mod) != .ErrorSet) | |
| 8757 | if (rhs_ty.zigTypeTag(zcu) != .ErrorSet) | |
| 8759 | 8758 | return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(pt)}); |
| 8760 | 8759 | |
| 8761 | 8760 | // Anything merged with anyerror is anyerror. |
| ... | ... | @@ -8790,28 +8789,28 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8790 | 8789 | defer tracy.end(); |
| 8791 | 8790 | |
| 8792 | 8791 | const pt = sema.pt; |
| 8793 | const mod = pt.zcu; | |
| 8792 | const zcu = pt.zcu; | |
| 8794 | 8793 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 8795 | 8794 | const name = inst_data.get(sema.code); |
| 8796 | 8795 | return Air.internedToRef((try pt.intern(.{ |
| 8797 | .enum_literal = try mod.intern_pool.getOrPutString(sema.gpa, pt.tid, name, .no_embedded_nulls), | |
| 8796 | .enum_literal = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, name, .no_embedded_nulls), | |
| 8798 | 8797 | }))); |
| 8799 | 8798 | } |
| 8800 | 8799 | |
| 8801 | 8800 | fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8802 | 8801 | const pt = sema.pt; |
| 8803 | const mod = pt.zcu; | |
| 8802 | const zcu = pt.zcu; | |
| 8804 | 8803 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 8805 | 8804 | const src = block.nodeOffset(inst_data.src_node); |
| 8806 | 8805 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 8807 | 8806 | const operand = try sema.resolveInst(inst_data.operand); |
| 8808 | 8807 | const operand_ty = sema.typeOf(operand); |
| 8809 | 8808 | |
| 8810 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) { | |
| 8809 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(zcu)) { | |
| 8811 | 8810 | .Enum => operand, |
| 8812 | 8811 | .Union => blk: { |
| 8813 | 8812 | try operand_ty.resolveFields(pt); |
| 8814 | const tag_ty = operand_ty.unionTagType(mod) orelse { | |
| 8813 | const tag_ty = operand_ty.unionTagType(zcu) orelse { | |
| 8815 | 8814 | return sema.fail( |
| 8816 | 8815 | block, |
| 8817 | 8816 | operand_src, |
| ... | ... | @@ -8829,11 +8828,11 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8829 | 8828 | }, |
| 8830 | 8829 | }; |
| 8831 | 8830 | const enum_tag_ty = sema.typeOf(enum_tag); |
| 8832 | const int_tag_ty = enum_tag_ty.intTagType(mod); | |
| 8831 | const int_tag_ty = enum_tag_ty.intTagType(zcu); | |
| 8833 | 8832 | |
| 8834 | 8833 | // TODO: use correct solution |
| 8835 | 8834 | // https://github.com/ziglang/zig/issues/15909 |
| 8836 | if (enum_tag_ty.enumFieldCount(mod) == 0 and !enum_tag_ty.isNonexhaustiveEnum(mod)) { | |
| 8835 | if (enum_tag_ty.enumFieldCount(zcu) == 0 and !enum_tag_ty.isNonexhaustiveEnum(zcu)) { | |
| 8837 | 8836 | return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{ |
| 8838 | 8837 | enum_tag_ty.fmt(pt), |
| 8839 | 8838 | }); |
| ... | ... | @@ -8844,7 +8843,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8844 | 8843 | } |
| 8845 | 8844 | |
| 8846 | 8845 | if (try sema.resolveValue(enum_tag)) |enum_tag_val| { |
| 8847 | if (enum_tag_val.isUndef(mod)) { | |
| 8846 | if (enum_tag_val.isUndef(zcu)) { | |
| 8848 | 8847 | return pt.undefRef(int_tag_ty); |
| 8849 | 8848 | } |
| 8850 | 8849 | |
| ... | ... | @@ -8858,7 +8857,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8858 | 8857 | |
| 8859 | 8858 | fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8860 | 8859 | const pt = sema.pt; |
| 8861 | const mod = pt.zcu; | |
| 8860 | const zcu = pt.zcu; | |
| 8862 | 8861 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 8863 | 8862 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8864 | 8863 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -8866,14 +8865,14 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8866 | 8865 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt"); |
| 8867 | 8866 | const operand = try sema.resolveInst(extra.rhs); |
| 8868 | 8867 | |
| 8869 | if (dest_ty.zigTypeTag(mod) != .Enum) { | |
| 8868 | if (dest_ty.zigTypeTag(zcu) != .Enum) { | |
| 8870 | 8869 | return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(pt)}); |
| 8871 | 8870 | } |
| 8872 | 8871 | _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand)); |
| 8873 | 8872 | |
| 8874 | 8873 | if (try sema.resolveValue(operand)) |int_val| { |
| 8875 | if (dest_ty.isNonexhaustiveEnum(mod)) { | |
| 8876 | const int_tag_ty = dest_ty.intTagType(mod); | |
| 8874 | if (dest_ty.isNonexhaustiveEnum(zcu)) { | |
| 8875 | const int_tag_ty = dest_ty.intTagType(zcu); | |
| 8877 | 8876 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { |
| 8878 | 8877 | return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); |
| 8879 | 8878 | } |
| ... | ... | @@ -8881,7 +8880,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8881 | 8880 | int_val.fmtValueSema(pt, sema), dest_ty.fmt(pt), |
| 8882 | 8881 | }); |
| 8883 | 8882 | } |
| 8884 | if (int_val.isUndef(mod)) { | |
| 8883 | if (int_val.isUndef(zcu)) { | |
| 8885 | 8884 | return sema.failWithUseOfUndef(block, operand_src); |
| 8886 | 8885 | } |
| 8887 | 8886 | if (!(try sema.enumHasInt(dest_ty, int_val))) { |
| ... | ... | @@ -8892,7 +8891,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8892 | 8891 | return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); |
| 8893 | 8892 | } |
| 8894 | 8893 | |
| 8895 | if (dest_ty.intTagType(mod).zigTypeTag(mod) == .ComptimeInt) { | |
| 8894 | if (dest_ty.intTagType(zcu).zigTypeTag(zcu) == .ComptimeInt) { | |
| 8896 | 8895 | return sema.failWithNeededComptime(block, operand_src, .{ |
| 8897 | 8896 | .needed_comptime_reason = "value being casted to enum with 'comptime_int' tag type must be comptime-known", |
| 8898 | 8897 | }); |
| ... | ... | @@ -8909,8 +8908,8 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8909 | 8908 | |
| 8910 | 8909 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 8911 | 8910 | const result = try block.addTyOp(.intcast, dest_ty, operand); |
| 8912 | if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum(mod) and | |
| 8913 | mod.backendSupportsFeature(.is_named_enum_value)) | |
| 8911 | if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum(zcu) and | |
| 8912 | zcu.backendSupportsFeature(.is_named_enum_value)) | |
| 8914 | 8913 | { |
| 8915 | 8914 | const ok = try block.addUnOp(.is_named_enum_value, result); |
| 8916 | 8915 | try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); |
| ... | ... | @@ -9014,20 +9013,20 @@ fn zirOptionalPayload( |
| 9014 | 9013 | defer tracy.end(); |
| 9015 | 9014 | |
| 9016 | 9015 | const pt = sema.pt; |
| 9017 | const mod = pt.zcu; | |
| 9016 | const zcu = pt.zcu; | |
| 9018 | 9017 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 9019 | 9018 | const src = block.nodeOffset(inst_data.src_node); |
| 9020 | 9019 | const operand = try sema.resolveInst(inst_data.operand); |
| 9021 | 9020 | const operand_ty = sema.typeOf(operand); |
| 9022 | const result_ty = switch (operand_ty.zigTypeTag(mod)) { | |
| 9023 | .Optional => operand_ty.optionalChild(mod), | |
| 9021 | const result_ty = switch (operand_ty.zigTypeTag(zcu)) { | |
| 9022 | .Optional => operand_ty.optionalChild(zcu), | |
| 9024 | 9023 | .Pointer => t: { |
| 9025 | if (operand_ty.ptrSize(mod) != .C) { | |
| 9024 | if (operand_ty.ptrSize(zcu) != .C) { | |
| 9026 | 9025 | return sema.failWithExpectedOptionalType(block, src, operand_ty); |
| 9027 | 9026 | } |
| 9028 | 9027 | // TODO https://github.com/ziglang/zig/issues/6597 |
| 9029 | 9028 | if (true) break :t operand_ty; |
| 9030 | const ptr_info = operand_ty.ptrInfo(mod); | |
| 9029 | const ptr_info = operand_ty.ptrInfo(zcu); | |
| 9031 | 9030 | break :t try pt.ptrTypeSema(.{ |
| 9032 | 9031 | .child = ptr_info.child, |
| 9033 | 9032 | .flags = .{ |
| ... | ... | @@ -9043,7 +9042,7 @@ fn zirOptionalPayload( |
| 9043 | 9042 | }; |
| 9044 | 9043 | |
| 9045 | 9044 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 9046 | return if (val.optionalValue(mod)) |payload| | |
| 9045 | return if (val.optionalValue(zcu)) |payload| | |
| 9047 | 9046 | Air.internedToRef(payload.toIntern()) |
| 9048 | 9047 | else |
| 9049 | 9048 | sema.fail(block, src, "unable to unwrap null", .{}); |
| ... | ... | @@ -9067,13 +9066,13 @@ fn zirErrUnionPayload( |
| 9067 | 9066 | defer tracy.end(); |
| 9068 | 9067 | |
| 9069 | 9068 | const pt = sema.pt; |
| 9070 | const mod = pt.zcu; | |
| 9069 | const zcu = pt.zcu; | |
| 9071 | 9070 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 9072 | 9071 | const src = block.nodeOffset(inst_data.src_node); |
| 9073 | 9072 | const operand = try sema.resolveInst(inst_data.operand); |
| 9074 | 9073 | const operand_src = src; |
| 9075 | 9074 | const err_union_ty = sema.typeOf(operand); |
| 9076 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { | |
| 9075 | if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) { | |
| 9077 | 9076 | return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ |
| 9078 | 9077 | err_union_ty.fmt(pt), |
| 9079 | 9078 | }); |
| ... | ... | @@ -9091,20 +9090,20 @@ fn analyzeErrUnionPayload( |
| 9091 | 9090 | safety_check: bool, |
| 9092 | 9091 | ) CompileError!Air.Inst.Ref { |
| 9093 | 9092 | const pt = sema.pt; |
| 9094 | const mod = pt.zcu; | |
| 9095 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 9093 | const zcu = pt.zcu; | |
| 9094 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 9096 | 9095 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { |
| 9097 | if (val.getErrorName(mod).unwrap()) |name| { | |
| 9096 | if (val.getErrorName(zcu).unwrap()) |name| { | |
| 9098 | 9097 | return sema.failWithComptimeErrorRetTrace(block, src, name); |
| 9099 | 9098 | } |
| 9100 | return Air.internedToRef(mod.intern_pool.indexToKey(val.toIntern()).error_union.val.payload); | |
| 9099 | return Air.internedToRef(zcu.intern_pool.indexToKey(val.toIntern()).error_union.val.payload); | |
| 9101 | 9100 | } |
| 9102 | 9101 | |
| 9103 | 9102 | try sema.requireRuntimeBlock(block, src, null); |
| 9104 | 9103 | |
| 9105 | 9104 | // If the error set has no fields then no safety check is needed. |
| 9106 | 9105 | if (safety_check and block.wantSafety() and |
| 9107 | !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) | |
| 9106 | !err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) | |
| 9108 | 9107 | { |
| 9109 | 9108 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err); |
| 9110 | 9109 | } |
| ... | ... | @@ -9215,20 +9214,20 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 9215 | 9214 | |
| 9216 | 9215 | fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| 9217 | 9216 | const pt = sema.pt; |
| 9218 | const mod = pt.zcu; | |
| 9217 | const zcu = pt.zcu; | |
| 9219 | 9218 | const operand_ty = sema.typeOf(operand); |
| 9220 | if (operand_ty.zigTypeTag(mod) != .ErrorUnion) { | |
| 9219 | if (operand_ty.zigTypeTag(zcu) != .ErrorUnion) { | |
| 9221 | 9220 | return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 9222 | 9221 | operand_ty.fmt(pt), |
| 9223 | 9222 | }); |
| 9224 | 9223 | } |
| 9225 | 9224 | |
| 9226 | const result_ty = operand_ty.errorUnionSet(mod); | |
| 9225 | const result_ty = operand_ty.errorUnionSet(zcu); | |
| 9227 | 9226 | |
| 9228 | 9227 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 9229 | 9228 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 9230 | 9229 | .ty = result_ty.toIntern(), |
| 9231 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, | |
| 9230 | .name = zcu.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, | |
| 9232 | 9231 | } }))); |
| 9233 | 9232 | } |
| 9234 | 9233 | |
| ... | ... | @@ -9249,24 +9248,24 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 9249 | 9248 | |
| 9250 | 9249 | fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| 9251 | 9250 | const pt = sema.pt; |
| 9252 | const mod = pt.zcu; | |
| 9251 | const zcu = pt.zcu; | |
| 9253 | 9252 | const operand_ty = sema.typeOf(operand); |
| 9254 | assert(operand_ty.zigTypeTag(mod) == .Pointer); | |
| 9253 | assert(operand_ty.zigTypeTag(zcu) == .Pointer); | |
| 9255 | 9254 | |
| 9256 | if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { | |
| 9255 | if (operand_ty.childType(zcu).zigTypeTag(zcu) != .ErrorUnion) { | |
| 9257 | 9256 | return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 9258 | operand_ty.childType(mod).fmt(pt), | |
| 9257 | operand_ty.childType(zcu).fmt(pt), | |
| 9259 | 9258 | }); |
| 9260 | 9259 | } |
| 9261 | 9260 | |
| 9262 | const result_ty = operand_ty.childType(mod).errorUnionSet(mod); | |
| 9261 | const result_ty = operand_ty.childType(zcu).errorUnionSet(zcu); | |
| 9263 | 9262 | |
| 9264 | 9263 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 9265 | 9264 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { |
| 9266 | assert(val.getErrorName(mod) != .none); | |
| 9265 | assert(val.getErrorName(zcu) != .none); | |
| 9267 | 9266 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 9268 | 9267 | .ty = result_ty.toIntern(), |
| 9269 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, | |
| 9268 | .name = zcu.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, | |
| 9270 | 9269 | } }))); |
| 9271 | 9270 | } |
| 9272 | 9271 | } |
| ... | ... | @@ -9412,7 +9411,7 @@ fn resolveGenericBody( |
| 9412 | 9411 | /// and puts it there if it doesn't exist. |
| 9413 | 9412 | /// It also dupes the library name which can then be saved as part of the |
| 9414 | 9413 | /// respective `Decl` (either `ExternFn` or `Var`). |
| 9415 | /// The liveness of the duped library name is tied to liveness of `Module`. | |
| 9414 | /// The liveness of the duped library name is tied to liveness of `Zcu`. | |
| 9416 | 9415 | /// To deallocate, call `deinit` on the respective `Decl` (`ExternFn` or `Var`). |
| 9417 | 9416 | fn handleExternLibName( |
| 9418 | 9417 | sema: *Sema, |
| ... | ... | @@ -9422,9 +9421,9 @@ fn handleExternLibName( |
| 9422 | 9421 | ) CompileError!void { |
| 9423 | 9422 | blk: { |
| 9424 | 9423 | const pt = sema.pt; |
| 9425 | const mod = pt.zcu; | |
| 9426 | const comp = mod.comp; | |
| 9427 | const target = mod.getTarget(); | |
| 9424 | const zcu = pt.zcu; | |
| 9425 | const comp = zcu.comp; | |
| 9426 | const target = zcu.getTarget(); | |
| 9428 | 9427 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); |
| 9429 | 9428 | if (target.is_libc_lib_name(lib_name)) { |
| 9430 | 9429 | if (!comp.config.link_libc) { |
| ... | ... | @@ -9575,7 +9574,7 @@ fn funcCommon( |
| 9575 | 9574 | .fn_proto_node_offset = src_node_offset, |
| 9576 | 9575 | .param_index = @intCast(i), |
| 9577 | 9576 | } }); |
| 9578 | const requires_comptime = try sema.typeRequiresComptime(param_ty); | |
| 9577 | const requires_comptime = try param_ty.comptimeOnlySema(pt); | |
| 9579 | 9578 | if (param_is_comptime or requires_comptime) { |
| 9580 | 9579 | comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error |
| 9581 | 9580 | } |
| ... | ... | @@ -9631,7 +9630,7 @@ fn funcCommon( |
| 9631 | 9630 | const err_code_size = target.ptrBitWidth(); |
| 9632 | 9631 | switch (i) { |
| 9633 | 9632 | 0 => if (param_ty.zigTypeTag(zcu) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}), |
| 9634 | 1 => if (param_ty.bitSize(pt) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), | |
| 9633 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), | |
| 9635 | 9634 | else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}), |
| 9636 | 9635 | } |
| 9637 | 9636 | } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}), |
| ... | ... | @@ -9640,7 +9639,7 @@ fn funcCommon( |
| 9640 | 9639 | } |
| 9641 | 9640 | } |
| 9642 | 9641 | |
| 9643 | const ret_ty_requires_comptime = try sema.typeRequiresComptime(bare_return_type); | |
| 9642 | const ret_ty_requires_comptime = try bare_return_type.comptimeOnlySema(pt); | |
| 9644 | 9643 | const ret_poison = bare_return_type.isGenericPoison(); |
| 9645 | 9644 | const final_is_generic = is_generic or comptime_bits != 0 or ret_ty_requires_comptime; |
| 9646 | 9645 | |
| ... | ... | @@ -9881,18 +9880,18 @@ fn finishFunc( |
| 9881 | 9880 | final_is_generic: bool, |
| 9882 | 9881 | ) CompileError!Air.Inst.Ref { |
| 9883 | 9882 | const pt = sema.pt; |
| 9884 | const mod = pt.zcu; | |
| 9885 | const ip = &mod.intern_pool; | |
| 9883 | const zcu = pt.zcu; | |
| 9884 | const ip = &zcu.intern_pool; | |
| 9886 | 9885 | const gpa = sema.gpa; |
| 9887 | const target = mod.getTarget(); | |
| 9886 | const target = zcu.getTarget(); | |
| 9888 | 9887 | |
| 9889 | 9888 | const return_type: Type = if (opt_func_index == .none or ret_poison) |
| 9890 | 9889 | bare_return_type |
| 9891 | 9890 | else |
| 9892 | 9891 | Type.fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index))); |
| 9893 | 9892 | |
| 9894 | if (!return_type.isValidReturnType(mod)) { | |
| 9895 | const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else ""; | |
| 9893 | if (!return_type.isValidReturnType(zcu)) { | |
| 9894 | const opaque_str = if (return_type.zigTypeTag(zcu) == .Opaque) "opaque " else ""; | |
| 9896 | 9895 | return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{ |
| 9897 | 9896 | opaque_str, return_type.fmt(pt), |
| 9898 | 9897 | }); |
| ... | ... | @@ -9954,7 +9953,7 @@ fn finishFunc( |
| 9954 | 9953 | } |
| 9955 | 9954 | |
| 9956 | 9955 | switch (cc_resolved) { |
| 9957 | .Interrupt, .Signal => if (return_type.zigTypeTag(mod) != .Void and return_type.zigTypeTag(mod) != .NoReturn) { | |
| 9956 | .Interrupt, .Signal => if (return_type.zigTypeTag(zcu) != .Void and return_type.zigTypeTag(zcu) != .NoReturn) { | |
| 9958 | 9957 | return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(cc_resolved)}); |
| 9959 | 9958 | }, |
| 9960 | 9959 | .Inline => if (is_noinline) { |
| ... | ... | @@ -10070,7 +10069,7 @@ fn zirParam( |
| 10070 | 10069 | } |
| 10071 | 10070 | }; |
| 10072 | 10071 | |
| 10073 | const is_comptime = try sema.typeRequiresComptime(param_ty) or comptime_syntax; | |
| 10072 | const is_comptime = try param_ty.comptimeOnlySema(sema.pt) or comptime_syntax; | |
| 10074 | 10073 | |
| 10075 | 10074 | try block.params.append(sema.arena, .{ |
| 10076 | 10075 | .ty = param_ty.toIntern(), |
| ... | ... | @@ -10141,7 +10140,7 @@ fn analyzeAs( |
| 10141 | 10140 | no_cast_to_comptime_int: bool, |
| 10142 | 10141 | ) CompileError!Air.Inst.Ref { |
| 10143 | 10142 | const pt = sema.pt; |
| 10144 | const mod = pt.zcu; | |
| 10143 | const zcu = pt.zcu; | |
| 10145 | 10144 | const operand = try sema.resolveInst(zir_operand); |
| 10146 | 10145 | const operand_air_inst = sema.resolveInst(zir_dest_type) catch |err| switch (err) { |
| 10147 | 10146 | error.GenericPoison => return operand, |
| ... | ... | @@ -10151,7 +10150,7 @@ fn analyzeAs( |
| 10151 | 10150 | error.GenericPoison => return operand, |
| 10152 | 10151 | else => |e| return e, |
| 10153 | 10152 | }; |
| 10154 | const dest_ty_tag = dest_ty.zigTypeTagOrPoison(mod) catch |err| switch (err) { | |
| 10153 | const dest_ty_tag = dest_ty.zigTypeTagOrPoison(zcu) catch |err| switch (err) { | |
| 10155 | 10154 | error.GenericPoison => return operand, |
| 10156 | 10155 | }; |
| 10157 | 10156 | |
| ... | ... | @@ -10189,7 +10188,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10189 | 10188 | return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}); |
| 10190 | 10189 | } |
| 10191 | 10190 | const pointee_ty = ptr_ty.childType(zcu); |
| 10192 | if (try sema.typeRequiresComptime(ptr_ty)) { | |
| 10191 | if (try ptr_ty.comptimeOnlySema(pt)) { | |
| 10193 | 10192 | const msg = msg: { |
| 10194 | 10193 | const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(pt)}); |
| 10195 | 10194 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -10205,7 +10204,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10205 | 10204 | } |
| 10206 | 10205 | return Air.internedToRef((try pt.intValue( |
| 10207 | 10206 | Type.usize, |
| 10208 | (try operand_val.getUnsignedIntAdvanced(pt, .sema)).?, | |
| 10207 | (try operand_val.toUnsignedIntSema(pt)), | |
| 10209 | 10208 | )).toIntern()); |
| 10210 | 10209 | } |
| 10211 | 10210 | const len = operand_ty.vectorLen(zcu); |
| ... | ... | @@ -10217,7 +10216,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10217 | 10216 | new_elem.* = (try pt.undefValue(Type.usize)).toIntern(); |
| 10218 | 10217 | continue; |
| 10219 | 10218 | } |
| 10220 | const addr = try ptr_val.getUnsignedIntAdvanced(pt, .sema) orelse { | |
| 10219 | const addr = try ptr_val.getUnsignedIntSema(pt) orelse { | |
| 10221 | 10220 | // A vector element wasn't an integer pointer. This is a runtime operation. |
| 10222 | 10221 | break :ct; |
| 10223 | 10222 | }; |
| ... | ... | @@ -10252,12 +10251,12 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10252 | 10251 | defer tracy.end(); |
| 10253 | 10252 | |
| 10254 | 10253 | const pt = sema.pt; |
| 10255 | const mod = pt.zcu; | |
| 10254 | const zcu = pt.zcu; | |
| 10256 | 10255 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10257 | 10256 | const src = block.nodeOffset(inst_data.src_node); |
| 10258 | 10257 | const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node }); |
| 10259 | 10258 | const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 10260 | const field_name = try mod.intern_pool.getOrPutString( | |
| 10259 | const field_name = try zcu.intern_pool.getOrPutString( | |
| 10261 | 10260 | sema.gpa, |
| 10262 | 10261 | pt.tid, |
| 10263 | 10262 | sema.code.nullTerminatedString(extra.field_name_start), |
| ... | ... | @@ -10272,12 +10271,12 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10272 | 10271 | defer tracy.end(); |
| 10273 | 10272 | |
| 10274 | 10273 | const pt = sema.pt; |
| 10275 | const mod = pt.zcu; | |
| 10274 | const zcu = pt.zcu; | |
| 10276 | 10275 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10277 | 10276 | const src = block.nodeOffset(inst_data.src_node); |
| 10278 | 10277 | const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node }); |
| 10279 | 10278 | const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 10280 | const field_name = try mod.intern_pool.getOrPutString( | |
| 10279 | const field_name = try zcu.intern_pool.getOrPutString( | |
| 10281 | 10280 | sema.gpa, |
| 10282 | 10281 | pt.tid, |
| 10283 | 10282 | sema.code.nullTerminatedString(extra.field_name_start), |
| ... | ... | @@ -10292,20 +10291,20 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi |
| 10292 | 10291 | defer tracy.end(); |
| 10293 | 10292 | |
| 10294 | 10293 | const pt = sema.pt; |
| 10295 | const mod = pt.zcu; | |
| 10294 | const zcu = pt.zcu; | |
| 10296 | 10295 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10297 | 10296 | const src = block.nodeOffset(inst_data.src_node); |
| 10298 | 10297 | const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node }); |
| 10299 | 10298 | const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 10300 | const field_name = try mod.intern_pool.getOrPutString( | |
| 10299 | const field_name = try zcu.intern_pool.getOrPutString( | |
| 10301 | 10300 | sema.gpa, |
| 10302 | 10301 | pt.tid, |
| 10303 | 10302 | sema.code.nullTerminatedString(extra.field_name_start), |
| 10304 | 10303 | .no_embedded_nulls, |
| 10305 | 10304 | ); |
| 10306 | 10305 | const object_ptr = try sema.resolveInst(extra.lhs); |
| 10307 | const struct_ty = sema.typeOf(object_ptr).childType(mod); | |
| 10308 | switch (struct_ty.zigTypeTag(mod)) { | |
| 10306 | const struct_ty = sema.typeOf(object_ptr).childType(zcu); | |
| 10307 | switch (struct_ty.zigTypeTag(zcu)) { | |
| 10309 | 10308 | .Struct, .Union => { |
| 10310 | 10309 | return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, true); |
| 10311 | 10310 | }, |
| ... | ... | @@ -10371,25 +10370,25 @@ fn intCast( |
| 10371 | 10370 | runtime_safety: bool, |
| 10372 | 10371 | ) CompileError!Air.Inst.Ref { |
| 10373 | 10372 | const pt = sema.pt; |
| 10374 | const mod = pt.zcu; | |
| 10373 | const zcu = pt.zcu; | |
| 10375 | 10374 | const operand_ty = sema.typeOf(operand); |
| 10376 | 10375 | const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src); |
| 10377 | 10376 | const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src); |
| 10378 | 10377 | |
| 10379 | 10378 | if (try sema.isComptimeKnown(operand)) { |
| 10380 | 10379 | return sema.coerce(block, dest_ty, operand, operand_src); |
| 10381 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 10380 | } else if (dest_scalar_ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 10382 | 10381 | return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_int'", .{}); |
| 10383 | 10382 | } |
| 10384 | 10383 | |
| 10385 | 10384 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, dest_ty_src, operand_src); |
| 10386 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; | |
| 10385 | const is_vector = dest_ty.zigTypeTag(zcu) == .Vector; | |
| 10387 | 10386 | |
| 10388 | 10387 | if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| { |
| 10389 | 10388 | // requirement: intCast(u0, input) iff input == 0 |
| 10390 | 10389 | if (runtime_safety and block.wantSafety()) { |
| 10391 | 10390 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 10392 | const wanted_info = dest_scalar_ty.intInfo(mod); | |
| 10391 | const wanted_info = dest_scalar_ty.intInfo(zcu); | |
| 10393 | 10392 | const wanted_bits = wanted_info.bits; |
| 10394 | 10393 | |
| 10395 | 10394 | if (wanted_bits == 0) { |
| ... | ... | @@ -10416,8 +10415,8 @@ fn intCast( |
| 10416 | 10415 | |
| 10417 | 10416 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 10418 | 10417 | if (runtime_safety and block.wantSafety()) { |
| 10419 | const actual_info = operand_scalar_ty.intInfo(mod); | |
| 10420 | const wanted_info = dest_scalar_ty.intInfo(mod); | |
| 10418 | const actual_info = operand_scalar_ty.intInfo(zcu); | |
| 10419 | const wanted_info = dest_scalar_ty.intInfo(zcu); | |
| 10421 | 10420 | const actual_bits = actual_info.bits; |
| 10422 | 10421 | const wanted_bits = wanted_info.bits; |
| 10423 | 10422 | const actual_value_bits = actual_bits - @intFromBool(actual_info.signedness == .signed); |
| ... | ... | @@ -10437,7 +10436,7 @@ fn intCast( |
| 10437 | 10436 | // negative differences (`operand` > `dest_max`) appear too big. |
| 10438 | 10437 | const unsigned_scalar_operand_ty = try pt.intType(.unsigned, actual_bits); |
| 10439 | 10438 | const unsigned_operand_ty = if (is_vector) try pt.vectorType(.{ |
| 10440 | .len = dest_ty.vectorLen(mod), | |
| 10439 | .len = dest_ty.vectorLen(zcu), | |
| 10441 | 10440 | .child = unsigned_scalar_operand_ty.toIntern(), |
| 10442 | 10441 | }) else unsigned_scalar_operand_ty; |
| 10443 | 10442 | const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff); |
| ... | ... | @@ -10520,7 +10519,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10520 | 10519 | defer tracy.end(); |
| 10521 | 10520 | |
| 10522 | 10521 | const pt = sema.pt; |
| 10523 | const mod = pt.zcu; | |
| 10522 | const zcu = pt.zcu; | |
| 10524 | 10523 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10525 | 10524 | const src = block.nodeOffset(inst_data.src_node); |
| 10526 | 10525 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | ... | @@ -10529,7 +10528,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10529 | 10528 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast"); |
| 10530 | 10529 | const operand = try sema.resolveInst(extra.rhs); |
| 10531 | 10530 | const operand_ty = sema.typeOf(operand); |
| 10532 | switch (dest_ty.zigTypeTag(mod)) { | |
| 10531 | switch (dest_ty.zigTypeTag(zcu)) { | |
| 10533 | 10532 | .AnyFrame, |
| 10534 | 10533 | .ComptimeFloat, |
| 10535 | 10534 | .ComptimeInt, |
| ... | ... | @@ -10551,7 +10550,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10551 | 10550 | const msg = msg: { |
| 10552 | 10551 | const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}); |
| 10553 | 10552 | errdefer msg.destroy(sema.gpa); |
| 10554 | switch (operand_ty.zigTypeTag(mod)) { | |
| 10553 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 10555 | 10554 | .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(pt)}), |
| 10556 | 10555 | else => {}, |
| 10557 | 10556 | } |
| ... | ... | @@ -10565,7 +10564,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10565 | 10564 | const msg = msg: { |
| 10566 | 10565 | const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}); |
| 10567 | 10566 | errdefer msg.destroy(sema.gpa); |
| 10568 | switch (operand_ty.zigTypeTag(mod)) { | |
| 10567 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 10569 | 10568 | .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(pt)}), |
| 10570 | 10569 | .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(pt)}), |
| 10571 | 10570 | else => {}, |
| ... | ... | @@ -10575,8 +10574,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10575 | 10574 | }; |
| 10576 | 10575 | return sema.failWithOwnedErrorMsg(block, msg); |
| 10577 | 10576 | }, |
| 10578 | .Struct, .Union => if (dest_ty.containerLayout(mod) == .auto) { | |
| 10579 | const container = switch (dest_ty.zigTypeTag(mod)) { | |
| 10577 | .Struct, .Union => if (dest_ty.containerLayout(zcu) == .auto) { | |
| 10578 | const container = switch (dest_ty.zigTypeTag(zcu)) { | |
| 10580 | 10579 | .Struct => "struct", |
| 10581 | 10580 | .Union => "union", |
| 10582 | 10581 | else => unreachable, |
| ... | ... | @@ -10593,7 +10592,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10593 | 10592 | .Vector, |
| 10594 | 10593 | => {}, |
| 10595 | 10594 | } |
| 10596 | switch (operand_ty.zigTypeTag(mod)) { | |
| 10595 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 10597 | 10596 | .AnyFrame, |
| 10598 | 10597 | .ComptimeFloat, |
| 10599 | 10598 | .ComptimeInt, |
| ... | ... | @@ -10615,7 +10614,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10615 | 10614 | const msg = msg: { |
| 10616 | 10615 | const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}); |
| 10617 | 10616 | errdefer msg.destroy(sema.gpa); |
| 10618 | switch (dest_ty.zigTypeTag(mod)) { | |
| 10617 | switch (dest_ty.zigTypeTag(zcu)) { | |
| 10619 | 10618 | .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(pt)}), |
| 10620 | 10619 | else => {}, |
| 10621 | 10620 | } |
| ... | ... | @@ -10628,7 +10627,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10628 | 10627 | const msg = msg: { |
| 10629 | 10628 | const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}); |
| 10630 | 10629 | errdefer msg.destroy(sema.gpa); |
| 10631 | switch (dest_ty.zigTypeTag(mod)) { | |
| 10630 | switch (dest_ty.zigTypeTag(zcu)) { | |
| 10632 | 10631 | .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(pt)}), |
| 10633 | 10632 | .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(pt)}), |
| 10634 | 10633 | else => {}, |
| ... | ... | @@ -10638,8 +10637,8 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10638 | 10637 | }; |
| 10639 | 10638 | return sema.failWithOwnedErrorMsg(block, msg); |
| 10640 | 10639 | }, |
| 10641 | .Struct, .Union => if (operand_ty.containerLayout(mod) == .auto) { | |
| 10642 | const container = switch (operand_ty.zigTypeTag(mod)) { | |
| 10640 | .Struct, .Union => if (operand_ty.containerLayout(zcu) == .auto) { | |
| 10641 | const container = switch (operand_ty.zigTypeTag(zcu)) { | |
| 10643 | 10642 | .Struct => "struct", |
| 10644 | 10643 | .Union => "union", |
| 10645 | 10644 | else => unreachable, |
| ... | ... | @@ -10664,24 +10663,24 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10664 | 10663 | defer tracy.end(); |
| 10665 | 10664 | |
| 10666 | 10665 | const pt = sema.pt; |
| 10667 | const mod = pt.zcu; | |
| 10666 | const zcu = pt.zcu; | |
| 10668 | 10667 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10669 | 10668 | const src = block.nodeOffset(inst_data.src_node); |
| 10670 | 10669 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 10671 | 10670 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 10672 | 10671 | |
| 10673 | 10672 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast"); |
| 10674 | const dest_scalar_ty = dest_ty.scalarType(mod); | |
| 10673 | const dest_scalar_ty = dest_ty.scalarType(zcu); | |
| 10675 | 10674 | |
| 10676 | 10675 | const operand = try sema.resolveInst(extra.rhs); |
| 10677 | 10676 | const operand_ty = sema.typeOf(operand); |
| 10678 | const operand_scalar_ty = operand_ty.scalarType(mod); | |
| 10677 | const operand_scalar_ty = operand_ty.scalarType(zcu); | |
| 10679 | 10678 | |
| 10680 | 10679 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src); |
| 10681 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; | |
| 10680 | const is_vector = dest_ty.zigTypeTag(zcu) == .Vector; | |
| 10682 | 10681 | |
| 10683 | const target = mod.getTarget(); | |
| 10684 | const dest_is_comptime_float = switch (dest_scalar_ty.zigTypeTag(mod)) { | |
| 10682 | const target = zcu.getTarget(); | |
| 10683 | const dest_is_comptime_float = switch (dest_scalar_ty.zigTypeTag(zcu)) { | |
| 10685 | 10684 | .ComptimeFloat => true, |
| 10686 | 10685 | .Float => false, |
| 10687 | 10686 | else => return sema.fail( |
| ... | ... | @@ -10692,7 +10691,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10692 | 10691 | ), |
| 10693 | 10692 | }; |
| 10694 | 10693 | |
| 10695 | switch (operand_scalar_ty.zigTypeTag(mod)) { | |
| 10694 | switch (operand_scalar_ty.zigTypeTag(zcu)) { | |
| 10696 | 10695 | .ComptimeFloat, .Float, .ComptimeInt => {}, |
| 10697 | 10696 | else => return sema.fail( |
| 10698 | 10697 | block, |
| ... | ... | @@ -10706,7 +10705,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10706 | 10705 | if (!is_vector) { |
| 10707 | 10706 | return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern()); |
| 10708 | 10707 | } |
| 10709 | const vec_len = operand_ty.vectorLen(mod); | |
| 10708 | const vec_len = operand_ty.vectorLen(zcu); | |
| 10710 | 10709 | const new_elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 10711 | 10710 | for (new_elems, 0..) |*new_elem, i| { |
| 10712 | 10711 | const old_elem = try operand_val.elemValue(pt, i); |
| ... | ... | @@ -10730,7 +10729,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10730 | 10729 | if (!is_vector) { |
| 10731 | 10730 | return block.addTyOp(.fptrunc, dest_ty, operand); |
| 10732 | 10731 | } |
| 10733 | const vec_len = operand_ty.vectorLen(mod); | |
| 10732 | const vec_len = operand_ty.vectorLen(zcu); | |
| 10734 | 10733 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, vec_len); |
| 10735 | 10734 | for (new_elems, 0..) |*new_elem, i| { |
| 10736 | 10735 | const idx_ref = try pt.intRef(Type.usize, i); |
| ... | ... | @@ -10781,21 +10780,21 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10781 | 10780 | defer tracy.end(); |
| 10782 | 10781 | |
| 10783 | 10782 | const pt = sema.pt; |
| 10784 | const mod = pt.zcu; | |
| 10783 | const zcu = pt.zcu; | |
| 10785 | 10784 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10786 | 10785 | const src = block.nodeOffset(inst_data.src_node); |
| 10787 | 10786 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 10788 | 10787 | const array_ptr = try sema.resolveInst(extra.lhs); |
| 10789 | 10788 | const elem_index = try sema.resolveInst(extra.rhs); |
| 10790 | 10789 | const indexable_ty = sema.typeOf(array_ptr); |
| 10791 | if (indexable_ty.zigTypeTag(mod) != .Pointer) { | |
| 10790 | if (indexable_ty.zigTypeTag(zcu) != .Pointer) { | |
| 10792 | 10791 | const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node }); |
| 10793 | 10792 | const msg = msg: { |
| 10794 | 10793 | const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{ |
| 10795 | 10794 | indexable_ty.fmt(pt), |
| 10796 | 10795 | }); |
| 10797 | 10796 | errdefer msg.destroy(sema.gpa); |
| 10798 | if (indexable_ty.isIndexable(mod)) { | |
| 10797 | if (indexable_ty.isIndexable(zcu)) { | |
| 10799 | 10798 | try sema.errNote(src, msg, "consider using '&' here", .{}); |
| 10800 | 10799 | } |
| 10801 | 10800 | break :msg msg; |
| ... | ... | @@ -10824,16 +10823,16 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile |
| 10824 | 10823 | defer tracy.end(); |
| 10825 | 10824 | |
| 10826 | 10825 | const pt = sema.pt; |
| 10827 | const mod = pt.zcu; | |
| 10826 | const zcu = pt.zcu; | |
| 10828 | 10827 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 10829 | 10828 | const src = block.nodeOffset(inst_data.src_node); |
| 10830 | 10829 | const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; |
| 10831 | 10830 | const array_ptr = try sema.resolveInst(extra.ptr); |
| 10832 | 10831 | const elem_index = try pt.intRef(Type.usize, extra.index); |
| 10833 | const array_ty = sema.typeOf(array_ptr).childType(mod); | |
| 10834 | switch (array_ty.zigTypeTag(mod)) { | |
| 10832 | const array_ty = sema.typeOf(array_ptr).childType(zcu); | |
| 10833 | switch (array_ty.zigTypeTag(zcu)) { | |
| 10835 | 10834 | .Array, .Vector => {}, |
| 10836 | else => if (!array_ty.isTuple(mod)) { | |
| 10835 | else => if (!array_ty.isTuple(zcu)) { | |
| 10837 | 10836 | return sema.failWithArrayInitNotSupported(block, src, array_ty); |
| 10838 | 10837 | }, |
| 10839 | 10838 | } |
| ... | ... | @@ -11059,9 +11058,9 @@ const SwitchProngAnalysis = struct { |
| 11059 | 11058 | ) CompileError!Air.Inst.Ref { |
| 11060 | 11059 | const sema = spa.sema; |
| 11061 | 11060 | const pt = sema.pt; |
| 11062 | const mod = pt.zcu; | |
| 11061 | const zcu = pt.zcu; | |
| 11063 | 11062 | const operand_ty = sema.typeOf(spa.operand); |
| 11064 | if (operand_ty.zigTypeTag(mod) != .Union) { | |
| 11063 | if (operand_ty.zigTypeTag(zcu) != .Union) { | |
| 11065 | 11064 | const tag_capture_src: LazySrcLoc = .{ |
| 11066 | 11065 | .base_node_inst = capture_src.base_node_inst, |
| 11067 | 11066 | .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture }, |
| ... | ... | @@ -11429,9 +11428,9 @@ fn switchCond( |
| 11429 | 11428 | operand: Air.Inst.Ref, |
| 11430 | 11429 | ) CompileError!Air.Inst.Ref { |
| 11431 | 11430 | const pt = sema.pt; |
| 11432 | const mod = pt.zcu; | |
| 11431 | const zcu = pt.zcu; | |
| 11433 | 11432 | const operand_ty = sema.typeOf(operand); |
| 11434 | switch (operand_ty.zigTypeTag(mod)) { | |
| 11433 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 11435 | 11434 | .Type, |
| 11436 | 11435 | .Void, |
| 11437 | 11436 | .Bool, |
| ... | ... | @@ -11445,7 +11444,7 @@ fn switchCond( |
| 11445 | 11444 | .ErrorSet, |
| 11446 | 11445 | .Enum, |
| 11447 | 11446 | => { |
| 11448 | if (operand_ty.isSlice(mod)) { | |
| 11447 | if (operand_ty.isSlice(zcu)) { | |
| 11449 | 11448 | return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)}); |
| 11450 | 11449 | } |
| 11451 | 11450 | if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| { |
| ... | ... | @@ -11456,11 +11455,11 @@ fn switchCond( |
| 11456 | 11455 | |
| 11457 | 11456 | .Union => { |
| 11458 | 11457 | try operand_ty.resolveFields(pt); |
| 11459 | const enum_ty = operand_ty.unionTagType(mod) orelse { | |
| 11458 | const enum_ty = operand_ty.unionTagType(zcu) orelse { | |
| 11460 | 11459 | const msg = msg: { |
| 11461 | 11460 | const msg = try sema.errMsg(src, "switch on union with no attached enum", .{}); |
| 11462 | 11461 | errdefer msg.destroy(sema.gpa); |
| 11463 | if (operand_ty.srcLocOrNull(mod)) |union_src| { | |
| 11462 | if (operand_ty.srcLocOrNull(zcu)) |union_src| { | |
| 11464 | 11463 | try sema.errNote(union_src, msg, "consider 'union(enum)' here", .{}); |
| 11465 | 11464 | } |
| 11466 | 11465 | break :msg msg; |
| ... | ... | @@ -11492,7 +11491,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11492 | 11491 | defer tracy.end(); |
| 11493 | 11492 | |
| 11494 | 11493 | const pt = sema.pt; |
| 11495 | const mod = pt.zcu; | |
| 11494 | const zcu = pt.zcu; | |
| 11496 | 11495 | const gpa = sema.gpa; |
| 11497 | 11496 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 11498 | 11497 | const switch_src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -11577,17 +11576,17 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11577 | 11576 | |
| 11578 | 11577 | const operand_ty = sema.typeOf(raw_operand_val); |
| 11579 | 11578 | const operand_err_set = if (extra.data.bits.payload_is_ref) |
| 11580 | operand_ty.childType(mod) | |
| 11579 | operand_ty.childType(zcu) | |
| 11581 | 11580 | else |
| 11582 | 11581 | operand_ty; |
| 11583 | 11582 | |
| 11584 | if (operand_err_set.zigTypeTag(mod) != .ErrorUnion) { | |
| 11583 | if (operand_err_set.zigTypeTag(zcu) != .ErrorUnion) { | |
| 11585 | 11584 | return sema.fail(block, switch_src, "expected error union type, found '{}'", .{ |
| 11586 | 11585 | operand_ty.fmt(pt), |
| 11587 | 11586 | }); |
| 11588 | 11587 | } |
| 11589 | 11588 | |
| 11590 | const operand_err_set_ty = operand_err_set.errorUnionSet(mod); | |
| 11589 | const operand_err_set_ty = operand_err_set.errorUnionSet(zcu); | |
| 11591 | 11590 | |
| 11592 | 11591 | const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); |
| 11593 | 11592 | try sema.air_instructions.append(gpa, .{ |
| ... | ... | @@ -11628,7 +11627,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11628 | 11627 | defer merges.deinit(gpa); |
| 11629 | 11628 | |
| 11630 | 11629 | const resolved_err_set = try sema.resolveInferredErrorSetTy(block, main_src, operand_err_set_ty.toIntern()); |
| 11631 | if (Type.fromInterned(resolved_err_set).errorSetIsEmpty(mod)) { | |
| 11630 | if (Type.fromInterned(resolved_err_set).errorSetIsEmpty(zcu)) { | |
| 11632 | 11631 | return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges); |
| 11633 | 11632 | } |
| 11634 | 11633 | |
| ... | ... | @@ -11662,13 +11661,13 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11662 | 11661 | else |
| 11663 | 11662 | ov; |
| 11664 | 11663 | |
| 11665 | if (operand_val.errorUnionIsPayload(mod)) { | |
| 11664 | if (operand_val.errorUnionIsPayload(zcu)) { | |
| 11666 | 11665 | return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges); |
| 11667 | 11666 | } else { |
| 11668 | 11667 | const err_val = Value.fromInterned(try pt.intern(.{ |
| 11669 | 11668 | .err = .{ |
| 11670 | 11669 | .ty = operand_err_set_ty.toIntern(), |
| 11671 | .name = operand_val.getErrorName(mod).unwrap().?, | |
| 11670 | .name = operand_val.getErrorName(zcu).unwrap().?, | |
| 11672 | 11671 | }, |
| 11673 | 11672 | })); |
| 11674 | 11673 | spa.operand = if (extra.data.bits.payload_is_ref) |
| ... | ... | @@ -11706,7 +11705,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11706 | 11705 | } |
| 11707 | 11706 | |
| 11708 | 11707 | if (scalar_cases_len + multi_cases_len == 0) { |
| 11709 | if (else_error_ty) |ty| if (ty.errorSetIsEmpty(mod)) { | |
| 11708 | if (else_error_ty) |ty| if (ty.errorSetIsEmpty(zcu)) { | |
| 11710 | 11709 | return sema.resolveBlockBody(block, main_operand_src, &child_block, non_error_case.body, inst, merges); |
| 11711 | 11710 | }; |
| 11712 | 11711 | } |
| ... | ... | @@ -11720,7 +11719,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11720 | 11719 | } |
| 11721 | 11720 | |
| 11722 | 11721 | const cond = if (extra.data.bits.payload_is_ref) blk: { |
| 11723 | try sema.checkErrorType(block, main_src, sema.typeOf(raw_operand_val).elemType2(mod)); | |
| 11722 | try sema.checkErrorType(block, main_src, sema.typeOf(raw_operand_val).elemType2(zcu)); | |
| 11724 | 11723 | const loaded = try sema.analyzeLoad(block, main_src, raw_operand_val, main_src); |
| 11725 | 11724 | break :blk try sema.analyzeIsNonErr(block, main_src, loaded); |
| 11726 | 11725 | } else blk: { |
| ... | ... | @@ -11803,7 +11802,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11803 | 11802 | defer tracy.end(); |
| 11804 | 11803 | |
| 11805 | 11804 | const pt = sema.pt; |
| 11806 | const mod = pt.zcu; | |
| 11805 | const zcu = pt.zcu; | |
| 11807 | 11806 | const gpa = sema.gpa; |
| 11808 | 11807 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 11809 | 11808 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -11873,12 +11872,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11873 | 11872 | }; |
| 11874 | 11873 | |
| 11875 | 11874 | const maybe_union_ty = sema.typeOf(raw_operand_val); |
| 11876 | const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; | |
| 11875 | const union_originally = maybe_union_ty.zigTypeTag(zcu) == .Union; | |
| 11877 | 11876 | |
| 11878 | 11877 | // Duplicate checking variables later also used for `inline else`. |
| 11879 | 11878 | var seen_enum_fields: []?LazySrcLoc = &.{}; |
| 11880 | 11879 | var seen_errors = SwitchErrorSet.init(gpa); |
| 11881 | var range_set = RangeSet.init(gpa, pt); | |
| 11880 | var range_set = RangeSet.init(gpa, zcu); | |
| 11882 | 11881 | var true_count: u8 = 0; |
| 11883 | 11882 | var false_count: u8 = 0; |
| 11884 | 11883 | |
| ... | ... | @@ -11891,12 +11890,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11891 | 11890 | var empty_enum = false; |
| 11892 | 11891 | |
| 11893 | 11892 | const operand_ty = sema.typeOf(operand); |
| 11894 | const err_set = operand_ty.zigTypeTag(mod) == .ErrorSet; | |
| 11893 | const err_set = operand_ty.zigTypeTag(zcu) == .ErrorSet; | |
| 11895 | 11894 | |
| 11896 | 11895 | var else_error_ty: ?Type = null; |
| 11897 | 11896 | |
| 11898 | 11897 | // Validate usage of '_' prongs. |
| 11899 | if (special_prong == .under and (!operand_ty.isNonexhaustiveEnum(mod) or union_originally)) { | |
| 11898 | if (special_prong == .under and (!operand_ty.isNonexhaustiveEnum(zcu) or union_originally)) { | |
| 11900 | 11899 | const msg = msg: { |
| 11901 | 11900 | const msg = try sema.errMsg( |
| 11902 | 11901 | src, |
| ... | ... | @@ -11922,11 +11921,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11922 | 11921 | } |
| 11923 | 11922 | |
| 11924 | 11923 | // Validate for duplicate items, missing else prong, and invalid range. |
| 11925 | switch (operand_ty.zigTypeTag(mod)) { | |
| 11924 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 11926 | 11925 | .Union => unreachable, // handled in `switchCond` |
| 11927 | 11926 | .Enum => { |
| 11928 | seen_enum_fields = try gpa.alloc(?LazySrcLoc, operand_ty.enumFieldCount(mod)); | |
| 11929 | empty_enum = seen_enum_fields.len == 0 and !operand_ty.isNonexhaustiveEnum(mod); | |
| 11927 | seen_enum_fields = try gpa.alloc(?LazySrcLoc, operand_ty.enumFieldCount(zcu)); | |
| 11928 | empty_enum = seen_enum_fields.len == 0 and !operand_ty.isNonexhaustiveEnum(zcu); | |
| 11930 | 11929 | @memset(seen_enum_fields, null); |
| 11931 | 11930 | // `range_set` is used for non-exhaustive enum values that do not correspond to any tags. |
| 11932 | 11931 | |
| ... | ... | @@ -11989,7 +11988,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11989 | 11988 | } else true; |
| 11990 | 11989 | |
| 11991 | 11990 | if (special_prong == .@"else") { |
| 11992 | if (all_tags_handled and !operand_ty.isNonexhaustiveEnum(mod)) return sema.fail( | |
| 11991 | if (all_tags_handled and !operand_ty.isNonexhaustiveEnum(zcu)) return sema.fail( | |
| 11993 | 11992 | block, |
| 11994 | 11993 | special_prong_src, |
| 11995 | 11994 | "unreachable else prong; all cases already handled", |
| ... | ... | @@ -12006,17 +12005,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12006 | 12005 | for (seen_enum_fields, 0..) |seen_src, i| { |
| 12007 | 12006 | if (seen_src != null) continue; |
| 12008 | 12007 | |
| 12009 | const field_name = operand_ty.enumFieldName(i, mod); | |
| 12008 | const field_name = operand_ty.enumFieldName(i, zcu); | |
| 12010 | 12009 | try sema.addFieldErrNote( |
| 12011 | 12010 | operand_ty, |
| 12012 | 12011 | i, |
| 12013 | 12012 | msg, |
| 12014 | 12013 | "unhandled enumeration value: '{}'", |
| 12015 | .{field_name.fmt(&mod.intern_pool)}, | |
| 12014 | .{field_name.fmt(&zcu.intern_pool)}, | |
| 12016 | 12015 | ); |
| 12017 | 12016 | } |
| 12018 | 12017 | try sema.errNote( |
| 12019 | operand_ty.srcLoc(mod), | |
| 12018 | operand_ty.srcLoc(zcu), | |
| 12020 | 12019 | msg, |
| 12021 | 12020 | "enum '{}' declared here", |
| 12022 | 12021 | .{operand_ty.fmt(pt)}, |
| ... | ... | @@ -12024,7 +12023,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12024 | 12023 | break :msg msg; |
| 12025 | 12024 | }; |
| 12026 | 12025 | return sema.failWithOwnedErrorMsg(block, msg); |
| 12027 | } else if (special_prong == .none and operand_ty.isNonexhaustiveEnum(mod) and !union_originally) { | |
| 12026 | } else if (special_prong == .none and operand_ty.isNonexhaustiveEnum(zcu) and !union_originally) { | |
| 12028 | 12027 | return sema.fail( |
| 12029 | 12028 | block, |
| 12030 | 12029 | src, |
| ... | ... | @@ -12124,7 +12123,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12124 | 12123 | } |
| 12125 | 12124 | |
| 12126 | 12125 | check_range: { |
| 12127 | if (operand_ty.zigTypeTag(mod) == .Int) { | |
| 12126 | if (operand_ty.zigTypeTag(zcu) == .Int) { | |
| 12128 | 12127 | const min_int = try operand_ty.minInt(pt, operand_ty); |
| 12129 | 12128 | const max_int = try operand_ty.maxInt(pt, operand_ty); |
| 12130 | 12129 | if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) { |
| ... | ... | @@ -12388,8 +12387,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12388 | 12387 | if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand, operand_src, false)) { |
| 12389 | 12388 | return .unreachable_value; |
| 12390 | 12389 | } |
| 12391 | if (mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and | |
| 12392 | (!operand_ty.isNonexhaustiveEnum(mod) or union_originally)) | |
| 12390 | if (zcu.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(zcu) == .Enum and | |
| 12391 | (!operand_ty.isNonexhaustiveEnum(zcu) or union_originally)) | |
| 12393 | 12392 | { |
| 12394 | 12393 | try sema.zirDbgStmt(block, cond_dbg_node_index); |
| 12395 | 12394 | const ok = try block.addUnOp(.is_named_enum_value, operand); |
| ... | ... | @@ -12482,9 +12481,9 @@ fn analyzeSwitchRuntimeBlock( |
| 12482 | 12481 | allow_err_code_unwrap: bool, |
| 12483 | 12482 | ) CompileError!Air.Inst.Ref { |
| 12484 | 12483 | const pt = sema.pt; |
| 12485 | const mod = pt.zcu; | |
| 12484 | const zcu = pt.zcu; | |
| 12486 | 12485 | const gpa = sema.gpa; |
| 12487 | const ip = &mod.intern_pool; | |
| 12486 | const ip = &zcu.intern_pool; | |
| 12488 | 12487 | |
| 12489 | 12488 | const block = child_block.parent.?; |
| 12490 | 12489 | |
| ... | ... | @@ -12519,8 +12518,8 @@ fn analyzeSwitchRuntimeBlock( |
| 12519 | 12518 | const analyze_body = if (union_originally) blk: { |
| 12520 | 12519 | const unresolved_item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable; |
| 12521 | 12520 | const item_val = sema.resolveLazyValue(unresolved_item_val) catch unreachable; |
| 12522 | const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?; | |
| 12523 | break :blk field_ty.zigTypeTag(mod) != .NoReturn; | |
| 12521 | const field_ty = maybe_union_ty.unionFieldType(item_val, zcu).?; | |
| 12522 | break :blk field_ty.zigTypeTag(zcu) != .NoReturn; | |
| 12524 | 12523 | } else true; |
| 12525 | 12524 | |
| 12526 | 12525 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand, operand_src, allow_err_code_unwrap)) { |
| ... | ... | @@ -12592,7 +12591,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12592 | 12591 | var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable; |
| 12593 | 12592 | const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable; |
| 12594 | 12593 | |
| 12595 | while (item.compareScalar(.lte, item_last, operand_ty, pt)) : ({ | |
| 12594 | while (item.compareScalar(.lte, item_last, operand_ty, zcu)) : ({ | |
| 12596 | 12595 | // Previous validation has resolved any possible lazy values. |
| 12597 | 12596 | item = sema.intAddScalar(item, try pt.intValue(operand_ty, 1), operand_ty) catch |err| switch (err) { |
| 12598 | 12597 | error.Overflow => unreachable, |
| ... | ... | @@ -12633,7 +12632,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12633 | 12632 | cases_extra.appendAssumeCapacity(@intFromEnum(item_ref)); |
| 12634 | 12633 | cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items)); |
| 12635 | 12634 | |
| 12636 | if (item.compareScalar(.eq, item_last, operand_ty, pt)) break; | |
| 12635 | if (item.compareScalar(.eq, item_last, operand_ty, zcu)) break; | |
| 12637 | 12636 | } |
| 12638 | 12637 | } |
| 12639 | 12638 | |
| ... | ... | @@ -12645,8 +12644,8 @@ fn analyzeSwitchRuntimeBlock( |
| 12645 | 12644 | |
| 12646 | 12645 | const analyze_body = if (union_originally) blk: { |
| 12647 | 12646 | const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable; |
| 12648 | const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?; | |
| 12649 | break :blk field_ty.zigTypeTag(mod) != .NoReturn; | |
| 12647 | const field_ty = maybe_union_ty.unionFieldType(item_val, zcu).?; | |
| 12648 | break :blk field_ty.zigTypeTag(zcu) != .NoReturn; | |
| 12650 | 12649 | } else true; |
| 12651 | 12650 | |
| 12652 | 12651 | if (emit_bb) try sema.emitBackwardBranch(block, block.src(.{ .switch_case_item = .{ |
| ... | ... | @@ -12696,8 +12695,8 @@ fn analyzeSwitchRuntimeBlock( |
| 12696 | 12695 | const analyze_body = if (union_originally) |
| 12697 | 12696 | for (items) |item| { |
| 12698 | 12697 | const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable; |
| 12699 | const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?; | |
| 12700 | if (field_ty.zigTypeTag(mod) != .NoReturn) break true; | |
| 12698 | const field_ty = maybe_union_ty.unionFieldType(item_val, zcu).?; | |
| 12699 | if (field_ty.zigTypeTag(zcu) != .NoReturn) break true; | |
| 12701 | 12700 | } else false |
| 12702 | 12701 | else |
| 12703 | 12702 | true; |
| ... | ... | @@ -12836,9 +12835,9 @@ fn analyzeSwitchRuntimeBlock( |
| 12836 | 12835 | var final_else_body: []const Air.Inst.Index = &.{}; |
| 12837 | 12836 | if (special.body.len != 0 or !is_first or case_block.wantSafety()) { |
| 12838 | 12837 | var emit_bb = false; |
| 12839 | if (special.is_inline) switch (operand_ty.zigTypeTag(mod)) { | |
| 12838 | if (special.is_inline) switch (operand_ty.zigTypeTag(zcu)) { | |
| 12840 | 12839 | .Enum => { |
| 12841 | if (operand_ty.isNonexhaustiveEnum(mod) and !union_originally) { | |
| 12840 | if (operand_ty.isNonexhaustiveEnum(zcu) and !union_originally) { | |
| 12842 | 12841 | return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ |
| 12843 | 12842 | operand_ty.fmt(pt), |
| 12844 | 12843 | }); |
| ... | ... | @@ -12854,8 +12853,8 @@ fn analyzeSwitchRuntimeBlock( |
| 12854 | 12853 | case_block.error_return_trace_index = child_block.error_return_trace_index; |
| 12855 | 12854 | |
| 12856 | 12855 | const analyze_body = if (union_originally) blk: { |
| 12857 | const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?; | |
| 12858 | break :blk field_ty.zigTypeTag(mod) != .NoReturn; | |
| 12856 | const field_ty = maybe_union_ty.unionFieldType(item_val, zcu).?; | |
| 12857 | break :blk field_ty.zigTypeTag(zcu) != .NoReturn; | |
| 12859 | 12858 | } else true; |
| 12860 | 12859 | |
| 12861 | 12860 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); |
| ... | ... | @@ -12887,12 +12886,12 @@ fn analyzeSwitchRuntimeBlock( |
| 12887 | 12886 | } |
| 12888 | 12887 | }, |
| 12889 | 12888 | .ErrorSet => { |
| 12890 | if (operand_ty.isAnyError(mod)) { | |
| 12889 | if (operand_ty.isAnyError(zcu)) { | |
| 12891 | 12890 | return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{ |
| 12892 | 12891 | operand_ty.fmt(pt), |
| 12893 | 12892 | }); |
| 12894 | 12893 | } |
| 12895 | const error_names = operand_ty.errorSetNames(mod); | |
| 12894 | const error_names = operand_ty.errorSetNames(zcu); | |
| 12896 | 12895 | for (0..error_names.len) |name_index| { |
| 12897 | 12896 | const error_name = error_names.get(ip)[name_index]; |
| 12898 | 12897 | if (seen_errors.contains(error_name)) continue; |
| ... | ... | @@ -13033,10 +13032,10 @@ fn analyzeSwitchRuntimeBlock( |
| 13033 | 13032 | case_block.instructions.shrinkRetainingCapacity(0); |
| 13034 | 13033 | case_block.error_return_trace_index = child_block.error_return_trace_index; |
| 13035 | 13034 | |
| 13036 | if (mod.backendSupportsFeature(.is_named_enum_value) and | |
| 13035 | if (zcu.backendSupportsFeature(.is_named_enum_value) and | |
| 13037 | 13036 | special.body.len != 0 and block.wantSafety() and |
| 13038 | operand_ty.zigTypeTag(mod) == .Enum and | |
| 13039 | (!operand_ty.isNonexhaustiveEnum(mod) or union_originally)) | |
| 13037 | operand_ty.zigTypeTag(zcu) == .Enum and | |
| 13038 | (!operand_ty.isNonexhaustiveEnum(zcu) or union_originally)) | |
| 13040 | 13039 | { |
| 13041 | 13040 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); |
| 13042 | 13041 | const ok = try case_block.addUnOp(.is_named_enum_value, operand); |
| ... | ... | @@ -13046,9 +13045,9 @@ fn analyzeSwitchRuntimeBlock( |
| 13046 | 13045 | const analyze_body = if (union_originally and !special.is_inline) |
| 13047 | 13046 | for (seen_enum_fields, 0..) |seen_field, index| { |
| 13048 | 13047 | if (seen_field != null) continue; |
| 13049 | const union_obj = mod.typeToUnion(maybe_union_ty).?; | |
| 13048 | const union_obj = zcu.typeToUnion(maybe_union_ty).?; | |
| 13050 | 13049 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[index]); |
| 13051 | if (field_ty.zigTypeTag(mod) != .NoReturn) break true; | |
| 13050 | if (field_ty.zigTypeTag(zcu) != .NoReturn) break true; | |
| 13052 | 13051 | } else false |
| 13053 | 13052 | else |
| 13054 | 13053 | true; |
| ... | ... | @@ -13371,8 +13370,8 @@ fn validateErrSetSwitch( |
| 13371 | 13370 | ) CompileError!?Type { |
| 13372 | 13371 | const gpa = sema.gpa; |
| 13373 | 13372 | const pt = sema.pt; |
| 13374 | const mod = pt.zcu; | |
| 13375 | const ip = &mod.intern_pool; | |
| 13373 | const zcu = pt.zcu; | |
| 13374 | const ip = &zcu.intern_pool; | |
| 13376 | 13375 | |
| 13377 | 13376 | const src_node_offset = inst_data.src_node; |
| 13378 | 13377 | const src = block.nodeOffset(src_node_offset); |
| ... | ... | @@ -13444,7 +13443,7 @@ fn validateErrSetSwitch( |
| 13444 | 13443 | }, |
| 13445 | 13444 | else => |err_set_ty_index| else_validation: { |
| 13446 | 13445 | const error_names = ip.indexToKey(err_set_ty_index).error_set_type.names; |
| 13447 | var maybe_msg: ?*Module.ErrorMsg = null; | |
| 13446 | var maybe_msg: ?*Zcu.ErrorMsg = null; | |
| 13448 | 13447 | errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa); |
| 13449 | 13448 | |
| 13450 | 13449 | for (error_names.get(ip)) |error_name| { |
| ... | ... | @@ -13711,8 +13710,8 @@ fn maybeErrorUnwrap( |
| 13711 | 13710 | allow_err_code_inst: bool, |
| 13712 | 13711 | ) !bool { |
| 13713 | 13712 | const pt = sema.pt; |
| 13714 | const mod = pt.zcu; | |
| 13715 | if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false; | |
| 13713 | const zcu = pt.zcu; | |
| 13714 | if (!zcu.backendSupportsFeature(.panic_unwrap_error)) return false; | |
| 13716 | 13715 | |
| 13717 | 13716 | const tags = sema.code.instructions.items(.tag); |
| 13718 | 13717 | for (body) |inst| { |
| ... | ... | @@ -13745,7 +13744,7 @@ fn maybeErrorUnwrap( |
| 13745 | 13744 | .as_node => try sema.zirAsNode(block, inst), |
| 13746 | 13745 | .field_val => try sema.zirFieldVal(block, inst), |
| 13747 | 13746 | .@"unreachable" => { |
| 13748 | if (!mod.comp.formatted_panics) { | |
| 13747 | if (!zcu.comp.formatted_panics) { | |
| 13749 | 13748 | try sema.safetyPanic(block, operand_src, .unwrap_error); |
| 13750 | 13749 | return true; |
| 13751 | 13750 | } |
| ... | ... | @@ -13768,7 +13767,7 @@ fn maybeErrorUnwrap( |
| 13768 | 13767 | }, |
| 13769 | 13768 | else => unreachable, |
| 13770 | 13769 | }; |
| 13771 | if (sema.typeOf(air_inst).isNoReturn(mod)) | |
| 13770 | if (sema.typeOf(air_inst).isNoReturn(zcu)) | |
| 13772 | 13771 | return true; |
| 13773 | 13772 | sema.inst_map.putAssumeCapacity(inst, air_inst); |
| 13774 | 13773 | } |
| ... | ... | @@ -13777,20 +13776,20 @@ fn maybeErrorUnwrap( |
| 13777 | 13776 | |
| 13778 | 13777 | fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void { |
| 13779 | 13778 | const pt = sema.pt; |
| 13780 | const mod = pt.zcu; | |
| 13779 | const zcu = pt.zcu; | |
| 13781 | 13780 | const index = cond.toIndex() orelse return; |
| 13782 | 13781 | if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return; |
| 13783 | 13782 | |
| 13784 | 13783 | const err_inst_data = sema.code.instructions.items(.data)[@intFromEnum(index)].un_node; |
| 13785 | 13784 | const err_operand = try sema.resolveInst(err_inst_data.operand); |
| 13786 | 13785 | const operand_ty = sema.typeOf(err_operand); |
| 13787 | if (operand_ty.zigTypeTag(mod) == .ErrorSet) { | |
| 13786 | if (operand_ty.zigTypeTag(zcu) == .ErrorSet) { | |
| 13788 | 13787 | try sema.maybeErrorUnwrapComptime(block, body, err_operand); |
| 13789 | 13788 | return; |
| 13790 | 13789 | } |
| 13791 | 13790 | if (try sema.resolveDefinedValue(block, cond_src, err_operand)) |val| { |
| 13792 | if (!operand_ty.isError(mod)) return; | |
| 13793 | if (val.getErrorName(mod) == .none) return; | |
| 13791 | if (!operand_ty.isError(zcu)) return; | |
| 13792 | if (val.getErrorName(zcu) == .none) return; | |
| 13794 | 13793 | try sema.maybeErrorUnwrapComptime(block, body, err_operand); |
| 13795 | 13794 | } |
| 13796 | 13795 | } |
| ... | ... | @@ -13818,7 +13817,7 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I |
| 13818 | 13817 | |
| 13819 | 13818 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13820 | 13819 | const pt = sema.pt; |
| 13821 | const mod = pt.zcu; | |
| 13820 | const zcu = pt.zcu; | |
| 13822 | 13821 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 13823 | 13822 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 13824 | 13823 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | ... | @@ -13828,7 +13827,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13828 | 13827 | .needed_comptime_reason = "field name must be comptime-known", |
| 13829 | 13828 | }); |
| 13830 | 13829 | try ty.resolveFields(pt); |
| 13831 | const ip = &mod.intern_pool; | |
| 13830 | const ip = &zcu.intern_pool; | |
| 13832 | 13831 | |
| 13833 | 13832 | const has_field = hf: { |
| 13834 | 13833 | switch (ip.indexToKey(ty.toIntern())) { |
| ... | ... | @@ -13845,7 +13844,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13845 | 13844 | break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names.get(ip), field_name) != null; |
| 13846 | 13845 | } else { |
| 13847 | 13846 | const field_index = field_name.toUnsigned(ip) orelse break :hf false; |
| 13848 | break :hf field_index < ty.structFieldCount(mod); | |
| 13847 | break :hf field_index < ty.structFieldCount(zcu); | |
| 13849 | 13848 | } |
| 13850 | 13849 | }, |
| 13851 | 13850 | .struct_type => { |
| ... | ... | @@ -13870,7 +13869,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13870 | 13869 | |
| 13871 | 13870 | fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13872 | 13871 | const pt = sema.pt; |
| 13873 | const mod = pt.zcu; | |
| 13872 | const zcu = pt.zcu; | |
| 13874 | 13873 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 13875 | 13874 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 13876 | 13875 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -13883,7 +13882,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13883 | 13882 | |
| 13884 | 13883 | try sema.checkNamespaceType(block, lhs_src, container_type); |
| 13885 | 13884 | |
| 13886 | const namespace = container_type.getNamespace(mod).unwrap() orelse return .bool_false; | |
| 13885 | const namespace = container_type.getNamespace(zcu).unwrap() orelse return .bool_false; | |
| 13887 | 13886 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| { |
| 13888 | 13887 | if (lookup.accessible) { |
| 13889 | 13888 | return .bool_true; |
| ... | ... | @@ -13958,9 +13957,9 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 13958 | 13957 | |
| 13959 | 13958 | fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13960 | 13959 | const pt = sema.pt; |
| 13961 | const mod = pt.zcu; | |
| 13960 | const zcu = pt.zcu; | |
| 13962 | 13961 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 13963 | const name = try mod.intern_pool.getOrPutString( | |
| 13962 | const name = try zcu.intern_pool.getOrPutString( | |
| 13964 | 13963 | sema.gpa, |
| 13965 | 13964 | pt.tid, |
| 13966 | 13965 | inst_data.get(sema.code), |
| ... | ... | @@ -13984,7 +13983,7 @@ fn zirShl( |
| 13984 | 13983 | defer tracy.end(); |
| 13985 | 13984 | |
| 13986 | 13985 | const pt = sema.pt; |
| 13987 | const mod = pt.zcu; | |
| 13986 | const zcu = pt.zcu; | |
| 13988 | 13987 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 13989 | 13988 | const src = block.nodeOffset(inst_data.src_node); |
| 13990 | 13989 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -13996,8 +13995,8 @@ fn zirShl( |
| 13996 | 13995 | const rhs_ty = sema.typeOf(rhs); |
| 13997 | 13996 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 13998 | 13997 | |
| 13999 | const scalar_ty = lhs_ty.scalarType(mod); | |
| 14000 | const scalar_rhs_ty = rhs_ty.scalarType(mod); | |
| 13998 | const scalar_ty = lhs_ty.scalarType(zcu); | |
| 13999 | const scalar_rhs_ty = rhs_ty.scalarType(zcu); | |
| 14001 | 14000 | |
| 14002 | 14001 | // TODO coerce rhs if air_tag is not shl_sat |
| 14003 | 14002 | const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty); |
| ... | ... | @@ -14006,20 +14005,20 @@ fn zirShl( |
| 14006 | 14005 | const maybe_rhs_val = try sema.resolveValueIntable(rhs); |
| 14007 | 14006 | |
| 14008 | 14007 | if (maybe_rhs_val) |rhs_val| { |
| 14009 | if (rhs_val.isUndef(mod)) { | |
| 14008 | if (rhs_val.isUndef(zcu)) { | |
| 14010 | 14009 | return pt.undefRef(sema.typeOf(lhs)); |
| 14011 | 14010 | } |
| 14012 | 14011 | // If rhs is 0, return lhs without doing any calculations. |
| 14013 | 14012 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 14014 | 14013 | return lhs; |
| 14015 | 14014 | } |
| 14016 | if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) { | |
| 14017 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits); | |
| 14018 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | |
| 14015 | if (scalar_ty.zigTypeTag(zcu) != .ComptimeInt and air_tag != .shl_sat) { | |
| 14016 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(zcu).bits); | |
| 14017 | if (rhs_ty.zigTypeTag(zcu) == .Vector) { | |
| 14019 | 14018 | var i: usize = 0; |
| 14020 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | |
| 14019 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { | |
| 14021 | 14020 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14022 | if (rhs_elem.compareHetero(.gte, bit_value, pt)) { | |
| 14021 | if (rhs_elem.compareHetero(.gte, bit_value, zcu)) { | |
| 14023 | 14022 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ |
| 14024 | 14023 | rhs_elem.fmtValueSema(pt, sema), |
| 14025 | 14024 | i, |
| ... | ... | @@ -14027,25 +14026,25 @@ fn zirShl( |
| 14027 | 14026 | }); |
| 14028 | 14027 | } |
| 14029 | 14028 | } |
| 14030 | } else if (rhs_val.compareHetero(.gte, bit_value, pt)) { | |
| 14029 | } else if (rhs_val.compareHetero(.gte, bit_value, zcu)) { | |
| 14031 | 14030 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ |
| 14032 | 14031 | rhs_val.fmtValueSema(pt, sema), |
| 14033 | 14032 | scalar_ty.fmt(pt), |
| 14034 | 14033 | }); |
| 14035 | 14034 | } |
| 14036 | 14035 | } |
| 14037 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | |
| 14036 | if (rhs_ty.zigTypeTag(zcu) == .Vector) { | |
| 14038 | 14037 | var i: usize = 0; |
| 14039 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | |
| 14038 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { | |
| 14040 | 14039 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14041 | if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), pt)) { | |
| 14040 | if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), zcu)) { | |
| 14042 | 14041 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 14043 | 14042 | rhs_elem.fmtValueSema(pt, sema), |
| 14044 | 14043 | i, |
| 14045 | 14044 | }); |
| 14046 | 14045 | } |
| 14047 | 14046 | } |
| 14048 | } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { | |
| 14047 | } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), zcu)) { | |
| 14049 | 14048 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 14050 | 14049 | rhs_val.fmtValueSema(pt, sema), |
| 14051 | 14050 | }); |
| ... | ... | @@ -14053,19 +14052,19 @@ fn zirShl( |
| 14053 | 14052 | } |
| 14054 | 14053 | |
| 14055 | 14054 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { |
| 14056 | if (lhs_val.isUndef(mod)) return pt.undefRef(lhs_ty); | |
| 14055 | if (lhs_val.isUndef(zcu)) return pt.undefRef(lhs_ty); | |
| 14057 | 14056 | const rhs_val = maybe_rhs_val orelse { |
| 14058 | if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 14057 | if (scalar_ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 14059 | 14058 | return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{}); |
| 14060 | 14059 | } |
| 14061 | 14060 | break :rs rhs_src; |
| 14062 | 14061 | }; |
| 14063 | const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) | |
| 14062 | const val = if (scalar_ty.zigTypeTag(zcu) == .ComptimeInt) | |
| 14064 | 14063 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena, pt) |
| 14065 | 14064 | else switch (air_tag) { |
| 14066 | 14065 | .shl_exact => val: { |
| 14067 | 14066 | const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, pt); |
| 14068 | if (shifted.overflow_bit.compareAllWithZero(.eq, pt)) { | |
| 14067 | if (shifted.overflow_bit.compareAllWithZero(.eq, zcu)) { | |
| 14069 | 14068 | break :val shifted.wrapped_result; |
| 14070 | 14069 | } |
| 14071 | 14070 | return sema.fail(block, src, "operation caused overflow", .{}); |
| ... | ... | @@ -14080,7 +14079,7 @@ fn zirShl( |
| 14080 | 14079 | const new_rhs = if (air_tag == .shl_sat) rhs: { |
| 14081 | 14080 | // Limit the RHS type for saturating shl to be an integer as small as the LHS. |
| 14082 | 14081 | if (rhs_is_comptime_int or |
| 14083 | scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits) | |
| 14082 | scalar_rhs_ty.intInfo(zcu).bits > scalar_ty.intInfo(zcu).bits) | |
| 14084 | 14083 | { |
| 14085 | 14084 | const max_int = Air.internedToRef((try lhs_ty.maxInt(pt, lhs_ty)).toIntern()); |
| 14086 | 14085 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src }); |
| ... | ... | @@ -14092,10 +14091,10 @@ fn zirShl( |
| 14092 | 14091 | |
| 14093 | 14092 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 14094 | 14093 | if (block.wantSafety()) { |
| 14095 | const bit_count = scalar_ty.intInfo(mod).bits; | |
| 14094 | const bit_count = scalar_ty.intInfo(zcu).bits; | |
| 14096 | 14095 | if (!std.math.isPowerOfTwo(bit_count)) { |
| 14097 | 14096 | const bit_count_val = try pt.intValue(scalar_rhs_ty, bit_count); |
| 14098 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { | |
| 14097 | const ok = if (rhs_ty.zigTypeTag(zcu) == .Vector) ok: { | |
| 14099 | 14098 | const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern()); |
| 14100 | 14099 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); |
| 14101 | 14100 | break :ok try block.addInst(.{ |
| ... | ... | @@ -14125,7 +14124,7 @@ fn zirShl( |
| 14125 | 14124 | } }, |
| 14126 | 14125 | }); |
| 14127 | 14126 | const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); |
| 14128 | const any_ov_bit = if (lhs_ty.zigTypeTag(mod) == .Vector) | |
| 14127 | const any_ov_bit = if (lhs_ty.zigTypeTag(zcu) == .Vector) | |
| 14129 | 14128 | try block.addInst(.{ |
| 14130 | 14129 | .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce, |
| 14131 | 14130 | .data = .{ .reduce = .{ |
| ... | ... | @@ -14155,7 +14154,7 @@ fn zirShr( |
| 14155 | 14154 | defer tracy.end(); |
| 14156 | 14155 | |
| 14157 | 14156 | const pt = sema.pt; |
| 14158 | const mod = pt.zcu; | |
| 14157 | const zcu = pt.zcu; | |
| 14159 | 14158 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14160 | 14159 | const src = block.nodeOffset(inst_data.src_node); |
| 14161 | 14160 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -14166,26 +14165,26 @@ fn zirShr( |
| 14166 | 14165 | const lhs_ty = sema.typeOf(lhs); |
| 14167 | 14166 | const rhs_ty = sema.typeOf(rhs); |
| 14168 | 14167 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14169 | const scalar_ty = lhs_ty.scalarType(mod); | |
| 14168 | const scalar_ty = lhs_ty.scalarType(zcu); | |
| 14170 | 14169 | |
| 14171 | 14170 | const maybe_lhs_val = try sema.resolveValueIntable(lhs); |
| 14172 | 14171 | const maybe_rhs_val = try sema.resolveValueIntable(rhs); |
| 14173 | 14172 | |
| 14174 | 14173 | const runtime_src = if (maybe_rhs_val) |rhs_val| rs: { |
| 14175 | if (rhs_val.isUndef(mod)) { | |
| 14174 | if (rhs_val.isUndef(zcu)) { | |
| 14176 | 14175 | return pt.undefRef(lhs_ty); |
| 14177 | 14176 | } |
| 14178 | 14177 | // If rhs is 0, return lhs without doing any calculations. |
| 14179 | 14178 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 14180 | 14179 | return lhs; |
| 14181 | 14180 | } |
| 14182 | if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) { | |
| 14183 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(mod).bits); | |
| 14184 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | |
| 14181 | if (scalar_ty.zigTypeTag(zcu) != .ComptimeInt) { | |
| 14182 | const bit_value = try pt.intValue(Type.comptime_int, scalar_ty.intInfo(zcu).bits); | |
| 14183 | if (rhs_ty.zigTypeTag(zcu) == .Vector) { | |
| 14185 | 14184 | var i: usize = 0; |
| 14186 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | |
| 14185 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { | |
| 14187 | 14186 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14188 | if (rhs_elem.compareHetero(.gte, bit_value, pt)) { | |
| 14187 | if (rhs_elem.compareHetero(.gte, bit_value, zcu)) { | |
| 14189 | 14188 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ |
| 14190 | 14189 | rhs_elem.fmtValueSema(pt, sema), |
| 14191 | 14190 | i, |
| ... | ... | @@ -14193,31 +14192,31 @@ fn zirShr( |
| 14193 | 14192 | }); |
| 14194 | 14193 | } |
| 14195 | 14194 | } |
| 14196 | } else if (rhs_val.compareHetero(.gte, bit_value, pt)) { | |
| 14195 | } else if (rhs_val.compareHetero(.gte, bit_value, zcu)) { | |
| 14197 | 14196 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ |
| 14198 | 14197 | rhs_val.fmtValueSema(pt, sema), |
| 14199 | 14198 | scalar_ty.fmt(pt), |
| 14200 | 14199 | }); |
| 14201 | 14200 | } |
| 14202 | 14201 | } |
| 14203 | if (rhs_ty.zigTypeTag(mod) == .Vector) { | |
| 14202 | if (rhs_ty.zigTypeTag(zcu) == .Vector) { | |
| 14204 | 14203 | var i: usize = 0; |
| 14205 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | |
| 14204 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { | |
| 14206 | 14205 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14207 | if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(mod), 0), pt)) { | |
| 14206 | if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(zcu), 0), zcu)) { | |
| 14208 | 14207 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 14209 | 14208 | rhs_elem.fmtValueSema(pt, sema), |
| 14210 | 14209 | i, |
| 14211 | 14210 | }); |
| 14212 | 14211 | } |
| 14213 | 14212 | } |
| 14214 | } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), pt)) { | |
| 14213 | } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), zcu)) { | |
| 14215 | 14214 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 14216 | 14215 | rhs_val.fmtValueSema(pt, sema), |
| 14217 | 14216 | }); |
| 14218 | 14217 | } |
| 14219 | 14218 | if (maybe_lhs_val) |lhs_val| { |
| 14220 | if (lhs_val.isUndef(mod)) { | |
| 14219 | if (lhs_val.isUndef(zcu)) { | |
| 14221 | 14220 | return pt.undefRef(lhs_ty); |
| 14222 | 14221 | } |
| 14223 | 14222 | if (air_tag == .shr_exact) { |
| ... | ... | @@ -14234,18 +14233,18 @@ fn zirShr( |
| 14234 | 14233 | } |
| 14235 | 14234 | } else rhs_src; |
| 14236 | 14235 | |
| 14237 | if (maybe_rhs_val == null and scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 14236 | if (maybe_rhs_val == null and scalar_ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 14238 | 14237 | return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{}); |
| 14239 | 14238 | } |
| 14240 | 14239 | |
| 14241 | 14240 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 14242 | 14241 | const result = try block.addBinOp(air_tag, lhs, rhs); |
| 14243 | 14242 | if (block.wantSafety()) { |
| 14244 | const bit_count = scalar_ty.intInfo(mod).bits; | |
| 14243 | const bit_count = scalar_ty.intInfo(zcu).bits; | |
| 14245 | 14244 | if (!std.math.isPowerOfTwo(bit_count)) { |
| 14246 | const bit_count_val = try pt.intValue(rhs_ty.scalarType(mod), bit_count); | |
| 14245 | const bit_count_val = try pt.intValue(rhs_ty.scalarType(zcu), bit_count); | |
| 14247 | 14246 | |
| 14248 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { | |
| 14247 | const ok = if (rhs_ty.zigTypeTag(zcu) == .Vector) ok: { | |
| 14249 | 14248 | const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern()); |
| 14250 | 14249 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); |
| 14251 | 14250 | break :ok try block.addInst(.{ |
| ... | ... | @@ -14265,7 +14264,7 @@ fn zirShr( |
| 14265 | 14264 | if (air_tag == .shr_exact) { |
| 14266 | 14265 | const back = try block.addBinOp(.shl, result, rhs); |
| 14267 | 14266 | |
| 14268 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { | |
| 14267 | const ok = if (rhs_ty.zigTypeTag(zcu) == .Vector) ok: { | |
| 14269 | 14268 | const eql = try block.addCmpVector(lhs, back, .eq); |
| 14270 | 14269 | break :ok try block.addInst(.{ |
| 14271 | 14270 | .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce, |
| ... | ... | @@ -14291,7 +14290,7 @@ fn zirBitwise( |
| 14291 | 14290 | defer tracy.end(); |
| 14292 | 14291 | |
| 14293 | 14292 | const pt = sema.pt; |
| 14294 | const mod = pt.zcu; | |
| 14293 | const zcu = pt.zcu; | |
| 14295 | 14294 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14296 | 14295 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 14297 | 14296 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -14305,8 +14304,8 @@ fn zirBitwise( |
| 14305 | 14304 | |
| 14306 | 14305 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 14307 | 14306 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); |
| 14308 | const scalar_type = resolved_type.scalarType(mod); | |
| 14309 | const scalar_tag = scalar_type.zigTypeTag(mod); | |
| 14307 | const scalar_type = resolved_type.scalarType(zcu); | |
| 14308 | const scalar_tag = scalar_type.zigTypeTag(zcu); | |
| 14310 | 14309 | |
| 14311 | 14310 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14312 | 14311 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | ... | @@ -14314,7 +14313,7 @@ fn zirBitwise( |
| 14314 | 14313 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 14315 | 14314 | |
| 14316 | 14315 | if (!is_int) { |
| 14317 | return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag(mod)), @tagName(rhs_ty.zigTypeTag(mod)) }); | |
| 14316 | return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag(zcu)), @tagName(rhs_ty.zigTypeTag(zcu)) }); | |
| 14318 | 14317 | } |
| 14319 | 14318 | |
| 14320 | 14319 | const runtime_src = runtime: { |
| ... | ... | @@ -14346,26 +14345,26 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14346 | 14345 | defer tracy.end(); |
| 14347 | 14346 | |
| 14348 | 14347 | const pt = sema.pt; |
| 14349 | const mod = pt.zcu; | |
| 14348 | const zcu = pt.zcu; | |
| 14350 | 14349 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 14351 | 14350 | const src = block.nodeOffset(inst_data.src_node); |
| 14352 | 14351 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| 14353 | 14352 | |
| 14354 | 14353 | const operand = try sema.resolveInst(inst_data.operand); |
| 14355 | 14354 | const operand_type = sema.typeOf(operand); |
| 14356 | const scalar_type = operand_type.scalarType(mod); | |
| 14355 | const scalar_type = operand_type.scalarType(zcu); | |
| 14357 | 14356 | |
| 14358 | if (scalar_type.zigTypeTag(mod) != .Int) { | |
| 14357 | if (scalar_type.zigTypeTag(zcu) != .Int) { | |
| 14359 | 14358 | return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{ |
| 14360 | 14359 | operand_type.fmt(pt), |
| 14361 | 14360 | }); |
| 14362 | 14361 | } |
| 14363 | 14362 | |
| 14364 | 14363 | if (try sema.resolveValue(operand)) |val| { |
| 14365 | if (val.isUndef(mod)) { | |
| 14364 | if (val.isUndef(zcu)) { | |
| 14366 | 14365 | return pt.undefRef(operand_type); |
| 14367 | } else if (operand_type.zigTypeTag(mod) == .Vector) { | |
| 14368 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod)); | |
| 14366 | } else if (operand_type.zigTypeTag(zcu) == .Vector) { | |
| 14367 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(zcu)); | |
| 14369 | 14368 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 14370 | 14369 | for (elems, 0..) |*elem, i| { |
| 14371 | 14370 | const elem_val = try val.elemValue(pt, i); |
| ... | ... | @@ -14393,13 +14392,13 @@ fn analyzeTupleCat( |
| 14393 | 14392 | rhs: Air.Inst.Ref, |
| 14394 | 14393 | ) CompileError!Air.Inst.Ref { |
| 14395 | 14394 | const pt = sema.pt; |
| 14396 | const mod = pt.zcu; | |
| 14395 | const zcu = pt.zcu; | |
| 14397 | 14396 | const lhs_ty = sema.typeOf(lhs); |
| 14398 | 14397 | const rhs_ty = sema.typeOf(rhs); |
| 14399 | 14398 | const src = block.nodeOffset(src_node); |
| 14400 | 14399 | |
| 14401 | const lhs_len = lhs_ty.structFieldCount(mod); | |
| 14402 | const rhs_len = rhs_ty.structFieldCount(mod); | |
| 14400 | const lhs_len = lhs_ty.structFieldCount(zcu); | |
| 14401 | const rhs_len = rhs_ty.structFieldCount(zcu); | |
| 14403 | 14402 | const dest_fields = lhs_len + rhs_len; |
| 14404 | 14403 | |
| 14405 | 14404 | if (dest_fields == 0) { |
| ... | ... | @@ -14420,8 +14419,8 @@ fn analyzeTupleCat( |
| 14420 | 14419 | var runtime_src: ?LazySrcLoc = null; |
| 14421 | 14420 | var i: u32 = 0; |
| 14422 | 14421 | while (i < lhs_len) : (i += 1) { |
| 14423 | types[i] = lhs_ty.structFieldType(i, mod).toIntern(); | |
| 14424 | const default_val = lhs_ty.structFieldDefaultValue(i, mod); | |
| 14422 | types[i] = lhs_ty.structFieldType(i, zcu).toIntern(); | |
| 14423 | const default_val = lhs_ty.structFieldDefaultValue(i, zcu); | |
| 14425 | 14424 | values[i] = default_val.toIntern(); |
| 14426 | 14425 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14427 | 14426 | .array_cat_offset = src_node, |
| ... | ... | @@ -14434,8 +14433,8 @@ fn analyzeTupleCat( |
| 14434 | 14433 | } |
| 14435 | 14434 | i = 0; |
| 14436 | 14435 | while (i < rhs_len) : (i += 1) { |
| 14437 | types[i + lhs_len] = rhs_ty.structFieldType(i, mod).toIntern(); | |
| 14438 | const default_val = rhs_ty.structFieldDefaultValue(i, mod); | |
| 14436 | types[i + lhs_len] = rhs_ty.structFieldType(i, zcu).toIntern(); | |
| 14437 | const default_val = rhs_ty.structFieldDefaultValue(i, zcu); | |
| 14439 | 14438 | values[i + lhs_len] = default_val.toIntern(); |
| 14440 | 14439 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| 14441 | 14440 | .array_cat_offset = src_node, |
| ... | ... | @@ -14449,7 +14448,7 @@ fn analyzeTupleCat( |
| 14449 | 14448 | break :rs runtime_src; |
| 14450 | 14449 | }; |
| 14451 | 14450 | |
| 14452 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{ | |
| 14451 | const tuple_ty = try zcu.intern_pool.getAnonStructType(zcu.gpa, pt.tid, .{ | |
| 14453 | 14452 | .types = types, |
| 14454 | 14453 | .values = values, |
| 14455 | 14454 | .names = &.{}, |
| ... | ... | @@ -14492,7 +14491,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14492 | 14491 | defer tracy.end(); |
| 14493 | 14492 | |
| 14494 | 14493 | const pt = sema.pt; |
| 14495 | const mod = pt.zcu; | |
| 14494 | const zcu = pt.zcu; | |
| 14496 | 14495 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14497 | 14496 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 14498 | 14497 | const lhs = try sema.resolveInst(extra.lhs); |
| ... | ... | @@ -14501,8 +14500,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14501 | 14500 | const rhs_ty = sema.typeOf(rhs); |
| 14502 | 14501 | const src = block.nodeOffset(inst_data.src_node); |
| 14503 | 14502 | |
| 14504 | const lhs_is_tuple = lhs_ty.isTuple(mod); | |
| 14505 | const rhs_is_tuple = rhs_ty.isTuple(mod); | |
| 14503 | const lhs_is_tuple = lhs_ty.isTuple(zcu); | |
| 14504 | const rhs_is_tuple = rhs_ty.isTuple(zcu); | |
| 14506 | 14505 | if (lhs_is_tuple and rhs_is_tuple) { |
| 14507 | 14506 | return sema.analyzeTupleCat(block, inst_data.src_node, lhs, rhs); |
| 14508 | 14507 | } |
| ... | ... | @@ -14584,31 +14583,31 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14584 | 14583 | .child = resolved_elem_ty.toIntern(), |
| 14585 | 14584 | }); |
| 14586 | 14585 | const ptr_addrspace = p: { |
| 14587 | if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod); | |
| 14588 | if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod); | |
| 14586 | if (lhs_ty.zigTypeTag(zcu) == .Pointer) break :p lhs_ty.ptrAddressSpace(zcu); | |
| 14587 | if (rhs_ty.zigTypeTag(zcu) == .Pointer) break :p rhs_ty.ptrAddressSpace(zcu); | |
| 14589 | 14588 | break :p null; |
| 14590 | 14589 | }; |
| 14591 | 14590 | |
| 14592 | const runtime_src = if (switch (lhs_ty.zigTypeTag(mod)) { | |
| 14591 | const runtime_src = if (switch (lhs_ty.zigTypeTag(zcu)) { | |
| 14593 | 14592 | .Array, .Struct => try sema.resolveValue(lhs), |
| 14594 | 14593 | .Pointer => try sema.resolveDefinedValue(block, lhs_src, lhs), |
| 14595 | 14594 | else => unreachable, |
| 14596 | 14595 | }) |lhs_val| rs: { |
| 14597 | if (switch (rhs_ty.zigTypeTag(mod)) { | |
| 14596 | if (switch (rhs_ty.zigTypeTag(zcu)) { | |
| 14598 | 14597 | .Array, .Struct => try sema.resolveValue(rhs), |
| 14599 | 14598 | .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs), |
| 14600 | 14599 | else => unreachable, |
| 14601 | 14600 | }) |rhs_val| { |
| 14602 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) | |
| 14601 | const lhs_sub_val = if (lhs_ty.isSinglePointer(zcu)) | |
| 14603 | 14602 | try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :rs lhs_src |
| 14604 | else if (lhs_ty.isSlice(mod)) | |
| 14603 | else if (lhs_ty.isSlice(zcu)) | |
| 14605 | 14604 | try sema.maybeDerefSliceAsArray(block, lhs_src, lhs_val) orelse break :rs lhs_src |
| 14606 | 14605 | else |
| 14607 | 14606 | lhs_val; |
| 14608 | 14607 | |
| 14609 | const rhs_sub_val = if (rhs_ty.isSinglePointer(mod)) | |
| 14608 | const rhs_sub_val = if (rhs_ty.isSinglePointer(zcu)) | |
| 14610 | 14609 | try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty) orelse break :rs rhs_src |
| 14611 | else if (rhs_ty.isSlice(mod)) | |
| 14610 | else if (rhs_ty.isSlice(zcu)) | |
| 14612 | 14611 | try sema.maybeDerefSliceAsArray(block, rhs_src, rhs_val) orelse break :rs rhs_src |
| 14613 | 14612 | else |
| 14614 | 14613 | rhs_val; |
| ... | ... | @@ -14617,7 +14616,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14617 | 14616 | var elem_i: u32 = 0; |
| 14618 | 14617 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 14619 | 14618 | const lhs_elem_i = elem_i; |
| 14620 | const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable"; | |
| 14619 | const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, zcu) else Value.@"unreachable"; | |
| 14621 | 14620 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(pt, lhs_elem_i) else elem_default_val; |
| 14622 | 14621 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); |
| 14623 | 14622 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| ... | ... | @@ -14630,7 +14629,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14630 | 14629 | } |
| 14631 | 14630 | while (elem_i < result_len) : (elem_i += 1) { |
| 14632 | 14631 | const rhs_elem_i = elem_i - lhs_len; |
| 14633 | const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable"; | |
| 14632 | const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, zcu) else Value.@"unreachable"; | |
| 14634 | 14633 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(pt, rhs_elem_i) else elem_default_val; |
| 14635 | 14634 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); |
| 14636 | 14635 | const operand_src = block.src(.{ .array_cat_rhs = .{ |
| ... | ... | @@ -14723,12 +14722,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14723 | 14722 | |
| 14724 | 14723 | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo { |
| 14725 | 14724 | const pt = sema.pt; |
| 14726 | const mod = pt.zcu; | |
| 14725 | const zcu = pt.zcu; | |
| 14727 | 14726 | const operand_ty = sema.typeOf(operand); |
| 14728 | switch (operand_ty.zigTypeTag(mod)) { | |
| 14729 | .Array => return operand_ty.arrayInfo(mod), | |
| 14727 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 14728 | .Array => return operand_ty.arrayInfo(zcu), | |
| 14730 | 14729 | .Pointer => { |
| 14731 | const ptr_info = operand_ty.ptrInfo(mod); | |
| 14730 | const ptr_info = operand_ty.ptrInfo(zcu); | |
| 14732 | 14731 | switch (ptr_info.flags.size) { |
| 14733 | 14732 | .Slice => { |
| 14734 | 14733 | const val = try sema.resolveConstDefinedValue(block, src, operand, .{ |
| ... | ... | @@ -14744,20 +14743,20 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 14744 | 14743 | }; |
| 14745 | 14744 | }, |
| 14746 | 14745 | .One => { |
| 14747 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Array) { | |
| 14748 | return Type.fromInterned(ptr_info.child).arrayInfo(mod); | |
| 14746 | if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .Array) { | |
| 14747 | return Type.fromInterned(ptr_info.child).arrayInfo(zcu); | |
| 14749 | 14748 | } |
| 14750 | 14749 | }, |
| 14751 | 14750 | .C, .Many => {}, |
| 14752 | 14751 | } |
| 14753 | 14752 | }, |
| 14754 | 14753 | .Struct => { |
| 14755 | if (operand_ty.isTuple(mod) and peer_ty.isIndexable(mod)) { | |
| 14756 | assert(!peer_ty.isTuple(mod)); | |
| 14754 | if (operand_ty.isTuple(zcu) and peer_ty.isIndexable(zcu)) { | |
| 14755 | assert(!peer_ty.isTuple(zcu)); | |
| 14757 | 14756 | return .{ |
| 14758 | .elem_type = peer_ty.elemType2(mod), | |
| 14757 | .elem_type = peer_ty.elemType2(zcu), | |
| 14759 | 14758 | .sentinel = null, |
| 14760 | .len = operand_ty.arrayLen(mod), | |
| 14759 | .len = operand_ty.arrayLen(zcu), | |
| 14761 | 14760 | }; |
| 14762 | 14761 | } |
| 14763 | 14762 | }, |
| ... | ... | @@ -14774,12 +14773,12 @@ fn analyzeTupleMul( |
| 14774 | 14773 | factor: usize, |
| 14775 | 14774 | ) CompileError!Air.Inst.Ref { |
| 14776 | 14775 | const pt = sema.pt; |
| 14777 | const mod = pt.zcu; | |
| 14776 | const zcu = pt.zcu; | |
| 14778 | 14777 | const operand_ty = sema.typeOf(operand); |
| 14779 | 14778 | const src = block.nodeOffset(src_node); |
| 14780 | 14779 | const len_src = block.src(.{ .node_offset_bin_rhs = src_node }); |
| 14781 | 14780 | |
| 14782 | const tuple_len = operand_ty.structFieldCount(mod); | |
| 14781 | const tuple_len = operand_ty.structFieldCount(zcu); | |
| 14783 | 14782 | const final_len = std.math.mul(usize, tuple_len, factor) catch |
| 14784 | 14783 | return sema.fail(block, len_src, "operation results in overflow", .{}); |
| 14785 | 14784 | |
| ... | ... | @@ -14792,8 +14791,8 @@ fn analyzeTupleMul( |
| 14792 | 14791 | const opt_runtime_src = rs: { |
| 14793 | 14792 | var runtime_src: ?LazySrcLoc = null; |
| 14794 | 14793 | for (0..tuple_len) |i| { |
| 14795 | types[i] = operand_ty.structFieldType(i, mod).toIntern(); | |
| 14796 | values[i] = operand_ty.structFieldDefaultValue(i, mod).toIntern(); | |
| 14794 | types[i] = operand_ty.structFieldType(i, zcu).toIntern(); | |
| 14795 | values[i] = operand_ty.structFieldDefaultValue(i, zcu).toIntern(); | |
| 14797 | 14796 | const operand_src = block.src(.{ .array_cat_lhs = .{ |
| 14798 | 14797 | .array_cat_offset = src_node, |
| 14799 | 14798 | .elem_index = @intCast(i), |
| ... | ... | @@ -14810,7 +14809,7 @@ fn analyzeTupleMul( |
| 14810 | 14809 | break :rs runtime_src; |
| 14811 | 14810 | }; |
| 14812 | 14811 | |
| 14813 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, pt.tid, .{ | |
| 14812 | const tuple_ty = try zcu.intern_pool.getAnonStructType(zcu.gpa, pt.tid, .{ | |
| 14814 | 14813 | .types = types, |
| 14815 | 14814 | .values = values, |
| 14816 | 14815 | .names = &.{}, |
| ... | ... | @@ -14848,7 +14847,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14848 | 14847 | defer tracy.end(); |
| 14849 | 14848 | |
| 14850 | 14849 | const pt = sema.pt; |
| 14851 | const mod = pt.zcu; | |
| 14850 | const zcu = pt.zcu; | |
| 14852 | 14851 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14853 | 14852 | const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data; |
| 14854 | 14853 | const uncoerced_lhs = try sema.resolveInst(extra.lhs); |
| ... | ... | @@ -14867,17 +14866,17 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14867 | 14866 | const res_ty_inst = try sema.resolveInst(extra.res_ty); |
| 14868 | 14867 | const res_ty = try sema.analyzeAsType(block, src, res_ty_inst); |
| 14869 | 14868 | if (res_ty.isGenericPoison()) break :no_coerce; |
| 14870 | if (!uncoerced_lhs_ty.isTuple(mod)) break :no_coerce; | |
| 14871 | const lhs_len = uncoerced_lhs_ty.structFieldCount(mod); | |
| 14872 | const lhs_dest_ty = switch (res_ty.zigTypeTag(mod)) { | |
| 14869 | if (!uncoerced_lhs_ty.isTuple(zcu)) break :no_coerce; | |
| 14870 | const lhs_len = uncoerced_lhs_ty.structFieldCount(zcu); | |
| 14871 | const lhs_dest_ty = switch (res_ty.zigTypeTag(zcu)) { | |
| 14873 | 14872 | else => break :no_coerce, |
| 14874 | 14873 | .Array => try pt.arrayType(.{ |
| 14875 | .child = res_ty.childType(mod).toIntern(), | |
| 14874 | .child = res_ty.childType(zcu).toIntern(), | |
| 14876 | 14875 | .len = lhs_len, |
| 14877 | .sentinel = if (res_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 14876 | .sentinel = if (res_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 14878 | 14877 | }), |
| 14879 | 14878 | .Vector => try pt.vectorType(.{ |
| 14880 | .child = res_ty.childType(mod).toIntern(), | |
| 14879 | .child = res_ty.childType(zcu).toIntern(), | |
| 14881 | 14880 | .len = lhs_len, |
| 14882 | 14881 | }), |
| 14883 | 14882 | }; |
| ... | ... | @@ -14893,7 +14892,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14893 | 14892 | break :coerced_lhs .{ uncoerced_lhs, uncoerced_lhs_ty }; |
| 14894 | 14893 | }; |
| 14895 | 14894 | |
| 14896 | if (lhs_ty.isTuple(mod)) { | |
| 14895 | if (lhs_ty.isTuple(zcu)) { | |
| 14897 | 14896 | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 14898 | 14897 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, .{ |
| 14899 | 14898 | .needed_comptime_reason = "array multiplication factor must be comptime-known", |
| ... | ... | @@ -14907,7 +14906,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14907 | 14906 | const msg = msg: { |
| 14908 | 14907 | const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)}); |
| 14909 | 14908 | errdefer msg.destroy(sema.gpa); |
| 14910 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 14909 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 14911 | 14910 | .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => { |
| 14912 | 14911 | try sema.errNote(operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{}); |
| 14913 | 14912 | }, |
| ... | ... | @@ -14933,13 +14932,13 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14933 | 14932 | .child = lhs_info.elem_type.toIntern(), |
| 14934 | 14933 | }); |
| 14935 | 14934 | |
| 14936 | const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null; | |
| 14935 | const ptr_addrspace = if (lhs_ty.zigTypeTag(zcu) == .Pointer) lhs_ty.ptrAddressSpace(zcu) else null; | |
| 14937 | 14936 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); |
| 14938 | 14937 | |
| 14939 | 14938 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| ct: { |
| 14940 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) | |
| 14939 | const lhs_sub_val = if (lhs_ty.isSinglePointer(zcu)) | |
| 14941 | 14940 | try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :ct |
| 14942 | else if (lhs_ty.isSlice(mod)) | |
| 14941 | else if (lhs_ty.isSlice(zcu)) | |
| 14943 | 14942 | try sema.maybeDerefSliceAsArray(block, lhs_src, lhs_val) orelse break :ct |
| 14944 | 14943 | else |
| 14945 | 14944 | lhs_val; |
| ... | ... | @@ -15022,7 +15021,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15022 | 15021 | |
| 15023 | 15022 | fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15024 | 15023 | const pt = sema.pt; |
| 15025 | const mod = pt.zcu; | |
| 15024 | const zcu = pt.zcu; | |
| 15026 | 15025 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 15027 | 15026 | const src = block.nodeOffset(inst_data.src_node); |
| 15028 | 15027 | const lhs_src = src; |
| ... | ... | @@ -15030,9 +15029,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15030 | 15029 | |
| 15031 | 15030 | const rhs = try sema.resolveInst(inst_data.operand); |
| 15032 | 15031 | const rhs_ty = sema.typeOf(rhs); |
| 15033 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | |
| 15032 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | |
| 15034 | 15033 | |
| 15035 | if (rhs_scalar_ty.isUnsignedInt(mod) or switch (rhs_scalar_ty.zigTypeTag(mod)) { | |
| 15034 | if (rhs_scalar_ty.isUnsignedInt(zcu) or switch (rhs_scalar_ty.zigTypeTag(zcu)) { | |
| 15036 | 15035 | .Int, .ComptimeInt, .Float, .ComptimeFloat => false, |
| 15037 | 15036 | else => true, |
| 15038 | 15037 | }) { |
| ... | ... | @@ -15042,7 +15041,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15042 | 15041 | if (rhs_scalar_ty.isAnyFloat()) { |
| 15043 | 15042 | // We handle float negation here to ensure negative zero is represented in the bits. |
| 15044 | 15043 | if (try sema.resolveValue(rhs)) |rhs_val| { |
| 15045 | if (rhs_val.isUndef(mod)) return pt.undefRef(rhs_ty); | |
| 15044 | if (rhs_val.isUndef(zcu)) return pt.undefRef(rhs_ty); | |
| 15046 | 15045 | return Air.internedToRef((try rhs_val.floatNeg(rhs_ty, sema.arena, pt)).toIntern()); |
| 15047 | 15046 | } |
| 15048 | 15047 | try sema.requireRuntimeBlock(block, src, null); |
| ... | ... | @@ -15055,7 +15054,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15055 | 15054 | |
| 15056 | 15055 | fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15057 | 15056 | const pt = sema.pt; |
| 15058 | const mod = pt.zcu; | |
| 15057 | const zcu = pt.zcu; | |
| 15059 | 15058 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 15060 | 15059 | const src = block.nodeOffset(inst_data.src_node); |
| 15061 | 15060 | const lhs_src = src; |
| ... | ... | @@ -15063,9 +15062,9 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15063 | 15062 | |
| 15064 | 15063 | const rhs = try sema.resolveInst(inst_data.operand); |
| 15065 | 15064 | const rhs_ty = sema.typeOf(rhs); |
| 15066 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | |
| 15065 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | |
| 15067 | 15066 | |
| 15068 | switch (rhs_scalar_ty.zigTypeTag(mod)) { | |
| 15067 | switch (rhs_scalar_ty.zigTypeTag(zcu)) { | |
| 15069 | 15068 | .Int, .ComptimeInt, .Float, .ComptimeFloat => {}, |
| 15070 | 15069 | else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)}), |
| 15071 | 15070 | } |
| ... | ... | @@ -15097,7 +15096,7 @@ fn zirArithmetic( |
| 15097 | 15096 | |
| 15098 | 15097 | fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15099 | 15098 | const pt = sema.pt; |
| 15100 | const mod = pt.zcu; | |
| 15099 | const zcu = pt.zcu; | |
| 15101 | 15100 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15102 | 15101 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15103 | 15102 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -15107,8 +15106,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15107 | 15106 | const rhs = try sema.resolveInst(extra.rhs); |
| 15108 | 15107 | const lhs_ty = sema.typeOf(lhs); |
| 15109 | 15108 | const rhs_ty = sema.typeOf(rhs); |
| 15110 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 15111 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 15109 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 15110 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 15112 | 15111 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15113 | 15112 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 15114 | 15113 | |
| ... | ... | @@ -15120,9 +15119,9 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15120 | 15119 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15121 | 15120 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 15122 | 15121 | |
| 15123 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 15124 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | |
| 15125 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 15122 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 15123 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | |
| 15124 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 15126 | 15125 | |
| 15127 | 15126 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 15128 | 15127 | |
| ... | ... | @@ -15131,15 +15130,15 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15131 | 15130 | const maybe_lhs_val = try sema.resolveValueIntable(casted_lhs); |
| 15132 | 15131 | const maybe_rhs_val = try sema.resolveValueIntable(casted_rhs); |
| 15133 | 15132 | |
| 15134 | if ((lhs_ty.zigTypeTag(mod) == .ComptimeFloat and rhs_ty.zigTypeTag(mod) == .ComptimeInt) or | |
| 15135 | (lhs_ty.zigTypeTag(mod) == .ComptimeInt and rhs_ty.zigTypeTag(mod) == .ComptimeFloat)) | |
| 15133 | if ((lhs_ty.zigTypeTag(zcu) == .ComptimeFloat and rhs_ty.zigTypeTag(zcu) == .ComptimeInt) or | |
| 15134 | (lhs_ty.zigTypeTag(zcu) == .ComptimeInt and rhs_ty.zigTypeTag(zcu) == .ComptimeFloat)) | |
| 15136 | 15135 | { |
| 15137 | 15136 | // If it makes a difference whether we coerce to ints or floats before doing the division, error. |
| 15138 | 15137 | // If lhs % rhs is 0, it doesn't matter. |
| 15139 | 15138 | const lhs_val = maybe_lhs_val orelse unreachable; |
| 15140 | 15139 | const rhs_val = maybe_rhs_val orelse unreachable; |
| 15141 | 15140 | const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt) catch unreachable; |
| 15142 | if (!rem.compareAllWithZero(.eq, pt)) { | |
| 15141 | if (!rem.compareAllWithZero(.eq, zcu)) { | |
| 15143 | 15142 | return sema.fail( |
| 15144 | 15143 | block, |
| 15145 | 15144 | src, |
| ... | ... | @@ -15179,11 +15178,11 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15179 | 15178 | switch (scalar_tag) { |
| 15180 | 15179 | .Int, .ComptimeInt, .ComptimeFloat => { |
| 15181 | 15180 | if (maybe_lhs_val) |lhs_val| { |
| 15182 | if (!lhs_val.isUndef(mod)) { | |
| 15181 | if (!lhs_val.isUndef(zcu)) { | |
| 15183 | 15182 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15184 | 15183 | const scalar_zero = switch (scalar_tag) { |
| 15185 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), | |
| 15186 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), | |
| 15184 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(zcu), 0.0), | |
| 15185 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(zcu), 0), | |
| 15187 | 15186 | else => unreachable, |
| 15188 | 15187 | }; |
| 15189 | 15188 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | ... | @@ -15192,7 +15191,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15192 | 15191 | } |
| 15193 | 15192 | } |
| 15194 | 15193 | if (maybe_rhs_val) |rhs_val| { |
| 15195 | if (rhs_val.isUndef(mod)) { | |
| 15194 | if (rhs_val.isUndef(zcu)) { | |
| 15196 | 15195 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15197 | 15196 | } |
| 15198 | 15197 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -15206,8 +15205,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15206 | 15205 | |
| 15207 | 15206 | const runtime_src = rs: { |
| 15208 | 15207 | if (maybe_lhs_val) |lhs_val| { |
| 15209 | if (lhs_val.isUndef(mod)) { | |
| 15210 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | |
| 15208 | if (lhs_val.isUndef(zcu)) { | |
| 15209 | if (lhs_scalar_ty.isSignedInt(zcu) and rhs_scalar_ty.isSignedInt(zcu)) { | |
| 15211 | 15210 | if (maybe_rhs_val) |rhs_val| { |
| 15212 | 15211 | if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) { |
| 15213 | 15212 | return pt.undefRef(resolved_type); |
| ... | ... | @@ -15245,7 +15244,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15245 | 15244 | } |
| 15246 | 15245 | |
| 15247 | 15246 | const air_tag = if (is_int) blk: { |
| 15248 | if (lhs_ty.isSignedInt(mod) or rhs_ty.isSignedInt(mod)) { | |
| 15247 | if (lhs_ty.isSignedInt(zcu) or rhs_ty.isSignedInt(zcu)) { | |
| 15249 | 15248 | return sema.fail( |
| 15250 | 15249 | block, |
| 15251 | 15250 | src, |
| ... | ... | @@ -15263,7 +15262,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15263 | 15262 | |
| 15264 | 15263 | fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15265 | 15264 | const pt = sema.pt; |
| 15266 | const mod = pt.zcu; | |
| 15265 | const zcu = pt.zcu; | |
| 15267 | 15266 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15268 | 15267 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15269 | 15268 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -15273,8 +15272,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15273 | 15272 | const rhs = try sema.resolveInst(extra.rhs); |
| 15274 | 15273 | const lhs_ty = sema.typeOf(lhs); |
| 15275 | 15274 | const rhs_ty = sema.typeOf(rhs); |
| 15276 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 15277 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 15275 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 15276 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 15278 | 15277 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15279 | 15278 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 15280 | 15279 | |
| ... | ... | @@ -15286,8 +15285,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15286 | 15285 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15287 | 15286 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 15288 | 15287 | |
| 15289 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 15290 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 15288 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 15289 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 15291 | 15290 | |
| 15292 | 15291 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 15293 | 15292 | |
| ... | ... | @@ -15314,13 +15313,13 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15314 | 15313 | // If the lhs is undefined, compile error because there is a possible |
| 15315 | 15314 | // value for which the division would result in a remainder. |
| 15316 | 15315 | if (maybe_lhs_val) |lhs_val| { |
| 15317 | if (lhs_val.isUndef(mod)) { | |
| 15316 | if (lhs_val.isUndef(zcu)) { | |
| 15318 | 15317 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15319 | 15318 | } else { |
| 15320 | 15319 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15321 | 15320 | const scalar_zero = switch (scalar_tag) { |
| 15322 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), | |
| 15323 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), | |
| 15321 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(zcu), 0.0), | |
| 15322 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(zcu), 0), | |
| 15324 | 15323 | else => unreachable, |
| 15325 | 15324 | }; |
| 15326 | 15325 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | ... | @@ -15329,7 +15328,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15329 | 15328 | } |
| 15330 | 15329 | } |
| 15331 | 15330 | if (maybe_rhs_val) |rhs_val| { |
| 15332 | if (rhs_val.isUndef(mod)) { | |
| 15331 | if (rhs_val.isUndef(zcu)) { | |
| 15333 | 15332 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15334 | 15333 | } |
| 15335 | 15334 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -15341,7 +15340,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15341 | 15340 | if (maybe_rhs_val) |rhs_val| { |
| 15342 | 15341 | if (is_int) { |
| 15343 | 15342 | const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, pt); |
| 15344 | if (!(modulus_val.compareAllWithZero(.eq, pt))) { | |
| 15343 | if (!(modulus_val.compareAllWithZero(.eq, zcu))) { | |
| 15345 | 15344 | return sema.fail(block, src, "exact division produced remainder", .{}); |
| 15346 | 15345 | } |
| 15347 | 15346 | var overflow_idx: ?usize = null; |
| ... | ... | @@ -15352,7 +15351,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15352 | 15351 | return Air.internedToRef(res.toIntern()); |
| 15353 | 15352 | } else { |
| 15354 | 15353 | const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, pt); |
| 15355 | if (!(modulus_val.compareAllWithZero(.eq, pt))) { | |
| 15354 | if (!(modulus_val.compareAllWithZero(.eq, zcu))) { | |
| 15356 | 15355 | return sema.fail(block, src, "exact division produced remainder", .{}); |
| 15357 | 15356 | } |
| 15358 | 15357 | return Air.internedToRef((try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| ... | ... | @@ -15376,7 +15375,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15376 | 15375 | const ok = if (!is_int) ok: { |
| 15377 | 15376 | const floored = try block.addUnOp(.floor, result); |
| 15378 | 15377 | |
| 15379 | if (resolved_type.zigTypeTag(mod) == .Vector) { | |
| 15378 | if (resolved_type.zigTypeTag(zcu) == .Vector) { | |
| 15380 | 15379 | const eql = try block.addCmpVector(result, floored, .eq); |
| 15381 | 15380 | break :ok try block.addInst(.{ |
| 15382 | 15381 | .tag = switch (block.float_mode) { |
| ... | ... | @@ -15399,11 +15398,11 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15399 | 15398 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); |
| 15400 | 15399 | |
| 15401 | 15400 | const scalar_zero = switch (scalar_tag) { |
| 15402 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), | |
| 15403 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), | |
| 15401 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(zcu), 0.0), | |
| 15402 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(zcu), 0), | |
| 15404 | 15403 | else => unreachable, |
| 15405 | 15404 | }; |
| 15406 | if (resolved_type.zigTypeTag(mod) == .Vector) { | |
| 15405 | if (resolved_type.zigTypeTag(zcu) == .Vector) { | |
| 15407 | 15406 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 15408 | 15407 | const zero = Air.internedToRef(zero_val.toIntern()); |
| 15409 | 15408 | const eql = try block.addCmpVector(remainder, zero, .eq); |
| ... | ... | @@ -15429,7 +15428,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15429 | 15428 | |
| 15430 | 15429 | fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15431 | 15430 | const pt = sema.pt; |
| 15432 | const mod = pt.zcu; | |
| 15431 | const zcu = pt.zcu; | |
| 15433 | 15432 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15434 | 15433 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15435 | 15434 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -15439,8 +15438,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15439 | 15438 | const rhs = try sema.resolveInst(extra.rhs); |
| 15440 | 15439 | const lhs_ty = sema.typeOf(lhs); |
| 15441 | 15440 | const rhs_ty = sema.typeOf(rhs); |
| 15442 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 15443 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 15441 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 15442 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 15444 | 15443 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15445 | 15444 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 15446 | 15445 | |
| ... | ... | @@ -15452,9 +15451,9 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15452 | 15451 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15453 | 15452 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 15454 | 15453 | |
| 15455 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 15456 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | |
| 15457 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 15454 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 15455 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | |
| 15456 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 15458 | 15457 | |
| 15459 | 15458 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 15460 | 15459 | |
| ... | ... | @@ -15484,11 +15483,11 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15484 | 15483 | // value (zero) for which the division would be illegal behavior. |
| 15485 | 15484 | // If the lhs is undefined, result is undefined. |
| 15486 | 15485 | if (maybe_lhs_val) |lhs_val| { |
| 15487 | if (!lhs_val.isUndef(mod)) { | |
| 15486 | if (!lhs_val.isUndef(zcu)) { | |
| 15488 | 15487 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15489 | 15488 | const scalar_zero = switch (scalar_tag) { |
| 15490 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), | |
| 15491 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), | |
| 15489 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(zcu), 0.0), | |
| 15490 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(zcu), 0), | |
| 15492 | 15491 | else => unreachable, |
| 15493 | 15492 | }; |
| 15494 | 15493 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | ... | @@ -15497,7 +15496,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15497 | 15496 | } |
| 15498 | 15497 | } |
| 15499 | 15498 | if (maybe_rhs_val) |rhs_val| { |
| 15500 | if (rhs_val.isUndef(mod)) { | |
| 15499 | if (rhs_val.isUndef(zcu)) { | |
| 15501 | 15500 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15502 | 15501 | } |
| 15503 | 15502 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -15506,8 +15505,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15506 | 15505 | // TODO: if the RHS is one, return the LHS directly |
| 15507 | 15506 | } |
| 15508 | 15507 | if (maybe_lhs_val) |lhs_val| { |
| 15509 | if (lhs_val.isUndef(mod)) { | |
| 15510 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | |
| 15508 | if (lhs_val.isUndef(zcu)) { | |
| 15509 | if (lhs_scalar_ty.isSignedInt(zcu) and rhs_scalar_ty.isSignedInt(zcu)) { | |
| 15511 | 15510 | if (maybe_rhs_val) |rhs_val| { |
| 15512 | 15511 | if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) { |
| 15513 | 15512 | return pt.undefRef(resolved_type); |
| ... | ... | @@ -15540,7 +15539,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15540 | 15539 | |
| 15541 | 15540 | fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15542 | 15541 | const pt = sema.pt; |
| 15543 | const mod = pt.zcu; | |
| 15542 | const zcu = pt.zcu; | |
| 15544 | 15543 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15545 | 15544 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15546 | 15545 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -15550,8 +15549,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15550 | 15549 | const rhs = try sema.resolveInst(extra.rhs); |
| 15551 | 15550 | const lhs_ty = sema.typeOf(lhs); |
| 15552 | 15551 | const rhs_ty = sema.typeOf(rhs); |
| 15553 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 15554 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 15552 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 15553 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 15555 | 15554 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15556 | 15555 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 15557 | 15556 | |
| ... | ... | @@ -15563,9 +15562,9 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15563 | 15562 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15564 | 15563 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 15565 | 15564 | |
| 15566 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 15567 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | |
| 15568 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 15565 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 15566 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | |
| 15567 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 15569 | 15568 | |
| 15570 | 15569 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 15571 | 15570 | |
| ... | ... | @@ -15595,11 +15594,11 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15595 | 15594 | // value (zero) for which the division would be illegal behavior. |
| 15596 | 15595 | // If the lhs is undefined, result is undefined. |
| 15597 | 15596 | if (maybe_lhs_val) |lhs_val| { |
| 15598 | if (!lhs_val.isUndef(mod)) { | |
| 15597 | if (!lhs_val.isUndef(zcu)) { | |
| 15599 | 15598 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15600 | 15599 | const scalar_zero = switch (scalar_tag) { |
| 15601 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), | |
| 15602 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), | |
| 15600 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(zcu), 0.0), | |
| 15601 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(zcu), 0), | |
| 15603 | 15602 | else => unreachable, |
| 15604 | 15603 | }; |
| 15605 | 15604 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| ... | ... | @@ -15608,7 +15607,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15608 | 15607 | } |
| 15609 | 15608 | } |
| 15610 | 15609 | if (maybe_rhs_val) |rhs_val| { |
| 15611 | if (rhs_val.isUndef(mod)) { | |
| 15610 | if (rhs_val.isUndef(zcu)) { | |
| 15612 | 15611 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15613 | 15612 | } |
| 15614 | 15613 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -15616,8 +15615,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15616 | 15615 | } |
| 15617 | 15616 | } |
| 15618 | 15617 | if (maybe_lhs_val) |lhs_val| { |
| 15619 | if (lhs_val.isUndef(mod)) { | |
| 15620 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | |
| 15618 | if (lhs_val.isUndef(zcu)) { | |
| 15619 | if (lhs_scalar_ty.isSignedInt(zcu) and rhs_scalar_ty.isSignedInt(zcu)) { | |
| 15621 | 15620 | if (maybe_rhs_val) |rhs_val| { |
| 15622 | 15621 | if (try sema.compareAll(rhs_val, .neq, try pt.intValue(resolved_type, -1), resolved_type)) { |
| 15623 | 15622 | return pt.undefRef(resolved_type); |
| ... | ... | @@ -15666,14 +15665,14 @@ fn addDivIntOverflowSafety( |
| 15666 | 15665 | is_int: bool, |
| 15667 | 15666 | ) CompileError!void { |
| 15668 | 15667 | const pt = sema.pt; |
| 15669 | const mod = pt.zcu; | |
| 15668 | const zcu = pt.zcu; | |
| 15670 | 15669 | if (!is_int) return; |
| 15671 | 15670 | |
| 15672 | 15671 | // If the LHS is unsigned, it cannot cause overflow. |
| 15673 | if (!lhs_scalar_ty.isSignedInt(mod)) return; | |
| 15672 | if (!lhs_scalar_ty.isSignedInt(zcu)) return; | |
| 15674 | 15673 | |
| 15675 | 15674 | // If the LHS is widened to a larger integer type, no overflow is possible. |
| 15676 | if (lhs_scalar_ty.intInfo(mod).bits < resolved_type.intInfo(mod).bits) { | |
| 15675 | if (lhs_scalar_ty.intInfo(zcu).bits < resolved_type.intInfo(zcu).bits) { | |
| 15677 | 15676 | return; |
| 15678 | 15677 | } |
| 15679 | 15678 | |
| ... | ... | @@ -15693,7 +15692,7 @@ fn addDivIntOverflowSafety( |
| 15693 | 15692 | } |
| 15694 | 15693 | |
| 15695 | 15694 | var ok: Air.Inst.Ref = .none; |
| 15696 | if (resolved_type.zigTypeTag(mod) == .Vector) { | |
| 15695 | if (resolved_type.zigTypeTag(zcu) == .Vector) { | |
| 15697 | 15696 | if (maybe_lhs_val == null) { |
| 15698 | 15697 | const min_int_ref = Air.internedToRef(min_int.toIntern()); |
| 15699 | 15698 | ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq); |
| ... | ... | @@ -15751,12 +15750,12 @@ fn addDivByZeroSafety( |
| 15751 | 15750 | if (maybe_rhs_val != null) return; |
| 15752 | 15751 | |
| 15753 | 15752 | const pt = sema.pt; |
| 15754 | const mod = pt.zcu; | |
| 15753 | const zcu = pt.zcu; | |
| 15755 | 15754 | const scalar_zero = if (is_int) |
| 15756 | try pt.intValue(resolved_type.scalarType(mod), 0) | |
| 15755 | try pt.intValue(resolved_type.scalarType(zcu), 0) | |
| 15757 | 15756 | else |
| 15758 | try pt.floatValue(resolved_type.scalarType(mod), 0.0); | |
| 15759 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { | |
| 15757 | try pt.floatValue(resolved_type.scalarType(zcu), 0.0); | |
| 15758 | const ok = if (resolved_type.zigTypeTag(zcu) == .Vector) ok: { | |
| 15760 | 15759 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 15761 | 15760 | const zero = Air.internedToRef(zero_val.toIntern()); |
| 15762 | 15761 | const ok = try block.addCmpVector(casted_rhs, zero, .neq); |
| ... | ... | @@ -15784,7 +15783,7 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst |
| 15784 | 15783 | |
| 15785 | 15784 | fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15786 | 15785 | const pt = sema.pt; |
| 15787 | const mod = pt.zcu; | |
| 15786 | const zcu = pt.zcu; | |
| 15788 | 15787 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15789 | 15788 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15790 | 15789 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -15794,8 +15793,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15794 | 15793 | const rhs = try sema.resolveInst(extra.rhs); |
| 15795 | 15794 | const lhs_ty = sema.typeOf(lhs); |
| 15796 | 15795 | const rhs_ty = sema.typeOf(rhs); |
| 15797 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 15798 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 15796 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 15797 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 15799 | 15798 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15800 | 15799 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 15801 | 15800 | |
| ... | ... | @@ -15804,14 +15803,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15804 | 15803 | .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, |
| 15805 | 15804 | }); |
| 15806 | 15805 | |
| 15807 | const is_vector = resolved_type.zigTypeTag(mod) == .Vector; | |
| 15806 | const is_vector = resolved_type.zigTypeTag(zcu) == .Vector; | |
| 15808 | 15807 | |
| 15809 | 15808 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15810 | 15809 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 15811 | 15810 | |
| 15812 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 15813 | const rhs_scalar_ty = rhs_ty.scalarType(mod); | |
| 15814 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 15811 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 15812 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | |
| 15813 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 15815 | 15814 | |
| 15816 | 15815 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 15817 | 15816 | |
| ... | ... | @@ -15836,13 +15835,13 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15836 | 15835 | // then emit a compile error saying you have to pick one. |
| 15837 | 15836 | if (is_int) { |
| 15838 | 15837 | if (maybe_lhs_val) |lhs_val| { |
| 15839 | if (lhs_val.isUndef(mod)) { | |
| 15838 | if (lhs_val.isUndef(zcu)) { | |
| 15840 | 15839 | return sema.failWithUseOfUndef(block, lhs_src); |
| 15841 | 15840 | } |
| 15842 | 15841 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 15843 | 15842 | const scalar_zero = switch (scalar_tag) { |
| 15844 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(mod), 0.0), | |
| 15845 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(mod), 0), | |
| 15843 | .ComptimeFloat, .Float => try pt.floatValue(resolved_type.scalarType(zcu), 0.0), | |
| 15844 | .ComptimeInt, .Int => try pt.intValue(resolved_type.scalarType(zcu), 0), | |
| 15846 | 15845 | else => unreachable, |
| 15847 | 15846 | }; |
| 15848 | 15847 | const zero_val = if (is_vector) Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| ... | ... | @@ -15851,11 +15850,11 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15851 | 15850 | } })) else scalar_zero; |
| 15852 | 15851 | return Air.internedToRef(zero_val.toIntern()); |
| 15853 | 15852 | } |
| 15854 | } else if (lhs_scalar_ty.isSignedInt(mod)) { | |
| 15853 | } else if (lhs_scalar_ty.isSignedInt(zcu)) { | |
| 15855 | 15854 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 15856 | 15855 | } |
| 15857 | 15856 | if (maybe_rhs_val) |rhs_val| { |
| 15858 | if (rhs_val.isUndef(mod)) { | |
| 15857 | if (rhs_val.isUndef(zcu)) { | |
| 15859 | 15858 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15860 | 15859 | } |
| 15861 | 15860 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -15876,7 +15875,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15876 | 15875 | return Air.internedToRef(rem_result.toIntern()); |
| 15877 | 15876 | } |
| 15878 | 15877 | break :rs lhs_src; |
| 15879 | } else if (rhs_scalar_ty.isSignedInt(mod)) { | |
| 15878 | } else if (rhs_scalar_ty.isSignedInt(zcu)) { | |
| 15880 | 15879 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); |
| 15881 | 15880 | } else { |
| 15882 | 15881 | break :rs rhs_src; |
| ... | ... | @@ -15884,7 +15883,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15884 | 15883 | } |
| 15885 | 15884 | // float operands |
| 15886 | 15885 | if (maybe_rhs_val) |rhs_val| { |
| 15887 | if (rhs_val.isUndef(mod)) { | |
| 15886 | if (rhs_val.isUndef(zcu)) { | |
| 15888 | 15887 | return sema.failWithUseOfUndef(block, rhs_src); |
| 15889 | 15888 | } |
| 15890 | 15889 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -15894,7 +15893,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15894 | 15893 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); |
| 15895 | 15894 | } |
| 15896 | 15895 | if (maybe_lhs_val) |lhs_val| { |
| 15897 | if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, pt))) { | |
| 15896 | if (lhs_val.isUndef(zcu) or !(try lhs_val.compareAllWithZeroSema(.gte, pt))) { | |
| 15898 | 15897 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 15899 | 15898 | } |
| 15900 | 15899 | return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| ... | ... | @@ -15923,10 +15922,10 @@ fn intRem( |
| 15923 | 15922 | rhs: Value, |
| 15924 | 15923 | ) CompileError!Value { |
| 15925 | 15924 | const pt = sema.pt; |
| 15926 | const mod = pt.zcu; | |
| 15927 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 15928 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 15929 | const scalar_ty = ty.scalarType(mod); | |
| 15925 | const zcu = pt.zcu; | |
| 15926 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 15927 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 15928 | const scalar_ty = ty.scalarType(zcu); | |
| 15930 | 15929 | for (result_data, 0..) |*scalar, i| { |
| 15931 | 15930 | const lhs_elem = try lhs.elemValue(pt, i); |
| 15932 | 15931 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -15946,8 +15945,8 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr |
| 15946 | 15945 | // resorting to BigInt first. |
| 15947 | 15946 | var lhs_space: Value.BigIntSpace = undefined; |
| 15948 | 15947 | var rhs_space: Value.BigIntSpace = undefined; |
| 15949 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); | |
| 15950 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); | |
| 15948 | const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt); | |
| 15949 | const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt); | |
| 15951 | 15950 | const limbs_q = try sema.arena.alloc( |
| 15952 | 15951 | math.big.Limb, |
| 15953 | 15952 | lhs_bigint.limbs.len, |
| ... | ... | @@ -15970,7 +15969,7 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr |
| 15970 | 15969 | |
| 15971 | 15970 | fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15972 | 15971 | const pt = sema.pt; |
| 15973 | const mod = pt.zcu; | |
| 15972 | const zcu = pt.zcu; | |
| 15974 | 15973 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15975 | 15974 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15976 | 15975 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -15980,8 +15979,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15980 | 15979 | const rhs = try sema.resolveInst(extra.rhs); |
| 15981 | 15980 | const lhs_ty = sema.typeOf(lhs); |
| 15982 | 15981 | const rhs_ty = sema.typeOf(rhs); |
| 15983 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 15984 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 15982 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 15983 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 15985 | 15984 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15986 | 15985 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 15987 | 15986 | |
| ... | ... | @@ -15993,7 +15992,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15993 | 15992 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 15994 | 15993 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 15995 | 15994 | |
| 15996 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 15995 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 15997 | 15996 | |
| 15998 | 15997 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 15999 | 15998 | |
| ... | ... | @@ -16016,12 +16015,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16016 | 16015 | // If the lhs is undefined, result is undefined. |
| 16017 | 16016 | if (is_int) { |
| 16018 | 16017 | if (maybe_lhs_val) |lhs_val| { |
| 16019 | if (lhs_val.isUndef(mod)) { | |
| 16018 | if (lhs_val.isUndef(zcu)) { | |
| 16020 | 16019 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16021 | 16020 | } |
| 16022 | 16021 | } |
| 16023 | 16022 | if (maybe_rhs_val) |rhs_val| { |
| 16024 | if (rhs_val.isUndef(mod)) { | |
| 16023 | if (rhs_val.isUndef(zcu)) { | |
| 16025 | 16024 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16026 | 16025 | } |
| 16027 | 16026 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -16037,7 +16036,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16037 | 16036 | } |
| 16038 | 16037 | // float operands |
| 16039 | 16038 | if (maybe_rhs_val) |rhs_val| { |
| 16040 | if (rhs_val.isUndef(mod)) { | |
| 16039 | if (rhs_val.isUndef(zcu)) { | |
| 16041 | 16040 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16042 | 16041 | } |
| 16043 | 16042 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -16045,7 +16044,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16045 | 16044 | } |
| 16046 | 16045 | } |
| 16047 | 16046 | if (maybe_lhs_val) |lhs_val| { |
| 16048 | if (lhs_val.isUndef(mod)) { | |
| 16047 | if (lhs_val.isUndef(zcu)) { | |
| 16049 | 16048 | return pt.undefRef(resolved_type); |
| 16050 | 16049 | } |
| 16051 | 16050 | if (maybe_rhs_val) |rhs_val| { |
| ... | ... | @@ -16066,7 +16065,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16066 | 16065 | |
| 16067 | 16066 | fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 16068 | 16067 | const pt = sema.pt; |
| 16069 | const mod = pt.zcu; | |
| 16068 | const zcu = pt.zcu; | |
| 16070 | 16069 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 16071 | 16070 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 16072 | 16071 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); |
| ... | ... | @@ -16076,8 +16075,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16076 | 16075 | const rhs = try sema.resolveInst(extra.rhs); |
| 16077 | 16076 | const lhs_ty = sema.typeOf(lhs); |
| 16078 | 16077 | const rhs_ty = sema.typeOf(rhs); |
| 16079 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 16080 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 16078 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 16079 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 16081 | 16080 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 16082 | 16081 | try sema.checkInvalidPtrIntArithmetic(block, src, lhs_ty); |
| 16083 | 16082 | |
| ... | ... | @@ -16089,7 +16088,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16089 | 16088 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 16090 | 16089 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 16091 | 16090 | |
| 16092 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | |
| 16091 | const scalar_tag = resolved_type.scalarType(zcu).zigTypeTag(zcu); | |
| 16093 | 16092 | |
| 16094 | 16093 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 16095 | 16094 | |
| ... | ... | @@ -16112,12 +16111,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16112 | 16111 | // If the lhs is undefined, result is undefined. |
| 16113 | 16112 | if (is_int) { |
| 16114 | 16113 | if (maybe_lhs_val) |lhs_val| { |
| 16115 | if (lhs_val.isUndef(mod)) { | |
| 16114 | if (lhs_val.isUndef(zcu)) { | |
| 16116 | 16115 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16117 | 16116 | } |
| 16118 | 16117 | } |
| 16119 | 16118 | if (maybe_rhs_val) |rhs_val| { |
| 16120 | if (rhs_val.isUndef(mod)) { | |
| 16119 | if (rhs_val.isUndef(zcu)) { | |
| 16121 | 16120 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16122 | 16121 | } |
| 16123 | 16122 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -16133,7 +16132,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16133 | 16132 | } |
| 16134 | 16133 | // float operands |
| 16135 | 16134 | if (maybe_rhs_val) |rhs_val| { |
| 16136 | if (rhs_val.isUndef(mod)) { | |
| 16135 | if (rhs_val.isUndef(zcu)) { | |
| 16137 | 16136 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16138 | 16137 | } |
| 16139 | 16138 | if (!(try rhs_val.compareAllWithZeroSema(.neq, pt))) { |
| ... | ... | @@ -16141,7 +16140,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16141 | 16140 | } |
| 16142 | 16141 | } |
| 16143 | 16142 | if (maybe_lhs_val) |lhs_val| { |
| 16144 | if (lhs_val.isUndef(mod)) { | |
| 16143 | if (lhs_val.isUndef(zcu)) { | |
| 16145 | 16144 | return pt.undefRef(resolved_type); |
| 16146 | 16145 | } |
| 16147 | 16146 | if (maybe_rhs_val) |rhs_val| { |
| ... | ... | @@ -16181,8 +16180,8 @@ fn zirOverflowArithmetic( |
| 16181 | 16180 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 16182 | 16181 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 16183 | 16182 | const pt = sema.pt; |
| 16184 | const mod = pt.zcu; | |
| 16185 | const ip = &mod.intern_pool; | |
| 16183 | const zcu = pt.zcu; | |
| 16184 | const ip = &zcu.intern_pool; | |
| 16186 | 16185 | |
| 16187 | 16186 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 16188 | 16187 | |
| ... | ... | @@ -16202,7 +16201,7 @@ fn zirOverflowArithmetic( |
| 16202 | 16201 | const lhs = try sema.coerce(block, dest_ty, uncasted_lhs, lhs_src); |
| 16203 | 16202 | const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src); |
| 16204 | 16203 | |
| 16205 | if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) { | |
| 16204 | if (dest_ty.scalarType(zcu).zigTypeTag(zcu) != .Int) { | |
| 16206 | 16205 | return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(pt)}); |
| 16207 | 16206 | } |
| 16208 | 16207 | |
| ... | ... | @@ -16224,18 +16223,18 @@ fn zirOverflowArithmetic( |
| 16224 | 16223 | // to the result, even if it is undefined.. |
| 16225 | 16224 | // Otherwise, if either of the argument is undefined, undefined is returned. |
| 16226 | 16225 | if (maybe_lhs_val) |lhs_val| { |
| 16227 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16226 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16228 | 16227 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; |
| 16229 | 16228 | } |
| 16230 | 16229 | } |
| 16231 | 16230 | if (maybe_rhs_val) |rhs_val| { |
| 16232 | if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16231 | if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16233 | 16232 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16234 | 16233 | } |
| 16235 | 16234 | } |
| 16236 | 16235 | if (maybe_lhs_val) |lhs_val| { |
| 16237 | 16236 | if (maybe_rhs_val) |rhs_val| { |
| 16238 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | |
| 16237 | if (lhs_val.isUndef(zcu) or rhs_val.isUndef(zcu)) { | |
| 16239 | 16238 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16240 | 16239 | } |
| 16241 | 16240 | |
| ... | ... | @@ -16248,12 +16247,12 @@ fn zirOverflowArithmetic( |
| 16248 | 16247 | // If the rhs is zero, then the result is lhs and no overflow occured. |
| 16249 | 16248 | // Otherwise, if either result is undefined, both results are undefined. |
| 16250 | 16249 | if (maybe_rhs_val) |rhs_val| { |
| 16251 | if (rhs_val.isUndef(mod)) { | |
| 16250 | if (rhs_val.isUndef(zcu)) { | |
| 16252 | 16251 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16253 | 16252 | } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16254 | 16253 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16255 | 16254 | } else if (maybe_lhs_val) |lhs_val| { |
| 16256 | if (lhs_val.isUndef(mod)) { | |
| 16255 | if (lhs_val.isUndef(zcu)) { | |
| 16257 | 16256 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16258 | 16257 | } |
| 16259 | 16258 | |
| ... | ... | @@ -16266,9 +16265,9 @@ fn zirOverflowArithmetic( |
| 16266 | 16265 | // If either of the arguments is zero, the result is zero and no overflow occured. |
| 16267 | 16266 | // If either of the arguments is one, the result is the other and no overflow occured. |
| 16268 | 16267 | // Otherwise, if either of the arguments is undefined, both results are undefined. |
| 16269 | const scalar_one = try pt.intValue(dest_ty.scalarType(mod), 1); | |
| 16268 | const scalar_one = try pt.intValue(dest_ty.scalarType(zcu), 1); | |
| 16270 | 16269 | if (maybe_lhs_val) |lhs_val| { |
| 16271 | if (!lhs_val.isUndef(mod)) { | |
| 16270 | if (!lhs_val.isUndef(zcu)) { | |
| 16272 | 16271 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16273 | 16272 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16274 | 16273 | } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { |
| ... | ... | @@ -16278,7 +16277,7 @@ fn zirOverflowArithmetic( |
| 16278 | 16277 | } |
| 16279 | 16278 | |
| 16280 | 16279 | if (maybe_rhs_val) |rhs_val| { |
| 16281 | if (!rhs_val.isUndef(mod)) { | |
| 16280 | if (!rhs_val.isUndef(zcu)) { | |
| 16282 | 16281 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16283 | 16282 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs }; |
| 16284 | 16283 | } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) { |
| ... | ... | @@ -16289,7 +16288,7 @@ fn zirOverflowArithmetic( |
| 16289 | 16288 | |
| 16290 | 16289 | if (maybe_lhs_val) |lhs_val| { |
| 16291 | 16290 | if (maybe_rhs_val) |rhs_val| { |
| 16292 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | |
| 16291 | if (lhs_val.isUndef(zcu) or rhs_val.isUndef(zcu)) { | |
| 16293 | 16292 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16294 | 16293 | } |
| 16295 | 16294 | |
| ... | ... | @@ -16303,18 +16302,18 @@ fn zirOverflowArithmetic( |
| 16303 | 16302 | // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred. |
| 16304 | 16303 | // Oterhwise if either of the arguments is undefined, both results are undefined. |
| 16305 | 16304 | if (maybe_lhs_val) |lhs_val| { |
| 16306 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16305 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16307 | 16306 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16308 | 16307 | } |
| 16309 | 16308 | } |
| 16310 | 16309 | if (maybe_rhs_val) |rhs_val| { |
| 16311 | if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16310 | if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16312 | 16311 | break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs }; |
| 16313 | 16312 | } |
| 16314 | 16313 | } |
| 16315 | 16314 | if (maybe_lhs_val) |lhs_val| { |
| 16316 | 16315 | if (maybe_rhs_val) |rhs_val| { |
| 16317 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | |
| 16316 | if (lhs_val.isUndef(zcu) or rhs_val.isUndef(zcu)) { | |
| 16318 | 16317 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 16319 | 16318 | } |
| 16320 | 16319 | |
| ... | ... | @@ -16374,8 +16373,8 @@ fn zirOverflowArithmetic( |
| 16374 | 16373 | |
| 16375 | 16374 | fn splat(sema: *Sema, ty: Type, val: Value) !Value { |
| 16376 | 16375 | const pt = sema.pt; |
| 16377 | const mod = pt.zcu; | |
| 16378 | if (ty.zigTypeTag(mod) != .Vector) return val; | |
| 16376 | const zcu = pt.zcu; | |
| 16377 | if (ty.zigTypeTag(zcu) != .Vector) return val; | |
| 16379 | 16378 | const repeated = try pt.intern(.{ .aggregate = .{ |
| 16380 | 16379 | .ty = ty.toIntern(), |
| 16381 | 16380 | .storage = .{ .repeated_elem = val.toIntern() }, |
| ... | ... | @@ -16385,16 +16384,16 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { |
| 16385 | 16384 | |
| 16386 | 16385 | fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { |
| 16387 | 16386 | const pt = sema.pt; |
| 16388 | const mod = pt.zcu; | |
| 16389 | const ip = &mod.intern_pool; | |
| 16390 | const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try pt.vectorType(.{ | |
| 16391 | .len = ty.vectorLen(mod), | |
| 16387 | const zcu = pt.zcu; | |
| 16388 | const ip = &zcu.intern_pool; | |
| 16389 | const ov_ty = if (ty.zigTypeTag(zcu) == .Vector) try pt.vectorType(.{ | |
| 16390 | .len = ty.vectorLen(zcu), | |
| 16392 | 16391 | .child = .u1_type, |
| 16393 | 16392 | }) else Type.u1; |
| 16394 | 16393 | |
| 16395 | 16394 | const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() }; |
| 16396 | 16395 | const values = [2]InternPool.Index{ .none, .none }; |
| 16397 | const tuple_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{ | |
| 16396 | const tuple_ty = try ip.getAnonStructType(zcu.gpa, pt.tid, .{ | |
| 16398 | 16397 | .types = &types, |
| 16399 | 16398 | .values = &values, |
| 16400 | 16399 | .names = &.{}, |
| ... | ... | @@ -16415,41 +16414,41 @@ fn analyzeArithmetic( |
| 16415 | 16414 | want_safety: bool, |
| 16416 | 16415 | ) CompileError!Air.Inst.Ref { |
| 16417 | 16416 | const pt = sema.pt; |
| 16418 | const mod = pt.zcu; | |
| 16417 | const zcu = pt.zcu; | |
| 16419 | 16418 | const lhs_ty = sema.typeOf(lhs); |
| 16420 | 16419 | const rhs_ty = sema.typeOf(rhs); |
| 16421 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 16422 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 16420 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 16421 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 16423 | 16422 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 16424 | 16423 | |
| 16425 | 16424 | if (lhs_zig_ty_tag == .Pointer) { |
| 16426 | 16425 | if (rhs_zig_ty_tag == .Pointer) { |
| 16427 | if (lhs_ty.ptrSize(mod) != .Slice and rhs_ty.ptrSize(mod) != .Slice) { | |
| 16426 | if (lhs_ty.ptrSize(zcu) != .Slice and rhs_ty.ptrSize(zcu) != .Slice) { | |
| 16428 | 16427 | if (zir_tag != .sub) { |
| 16429 | 16428 | return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction"); |
| 16430 | 16429 | } |
| 16431 | if (!lhs_ty.elemType2(mod).eql(rhs_ty.elemType2(mod), mod)) { | |
| 16430 | if (!lhs_ty.elemType2(zcu).eql(rhs_ty.elemType2(zcu), zcu)) { | |
| 16432 | 16431 | return sema.fail(block, src, "incompatible pointer arithmetic operands '{}' and '{}'", .{ |
| 16433 | 16432 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), |
| 16434 | 16433 | }); |
| 16435 | 16434 | } |
| 16436 | 16435 | |
| 16437 | const elem_size = lhs_ty.elemType2(mod).abiSize(pt); | |
| 16436 | const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu); | |
| 16438 | 16437 | if (elem_size == 0) { |
| 16439 | 16438 | return sema.fail(block, src, "pointer arithmetic requires element type '{}' to have runtime bits", .{ |
| 16440 | lhs_ty.elemType2(mod).fmt(pt), | |
| 16439 | lhs_ty.elemType2(zcu).fmt(pt), | |
| 16441 | 16440 | }); |
| 16442 | 16441 | } |
| 16443 | 16442 | |
| 16444 | 16443 | const runtime_src = runtime_src: { |
| 16445 | 16444 | if (try sema.resolveValue(lhs)) |lhs_value| { |
| 16446 | 16445 | if (try sema.resolveValue(rhs)) |rhs_value| { |
| 16447 | const lhs_ptr = switch (mod.intern_pool.indexToKey(lhs_value.toIntern())) { | |
| 16446 | const lhs_ptr = switch (zcu.intern_pool.indexToKey(lhs_value.toIntern())) { | |
| 16448 | 16447 | .undef => return sema.failWithUseOfUndef(block, lhs_src), |
| 16449 | 16448 | .ptr => |ptr| ptr, |
| 16450 | 16449 | else => unreachable, |
| 16451 | 16450 | }; |
| 16452 | const rhs_ptr = switch (mod.intern_pool.indexToKey(rhs_value.toIntern())) { | |
| 16451 | const rhs_ptr = switch (zcu.intern_pool.indexToKey(rhs_value.toIntern())) { | |
| 16453 | 16452 | .undef => return sema.failWithUseOfUndef(block, rhs_src), |
| 16454 | 16453 | .ptr => |ptr| ptr, |
| 16455 | 16454 | else => unreachable, |
| ... | ... | @@ -16475,7 +16474,7 @@ fn analyzeArithmetic( |
| 16475 | 16474 | return try block.addBinOp(.div_exact, address, try pt.intRef(Type.usize, elem_size)); |
| 16476 | 16475 | } |
| 16477 | 16476 | } else { |
| 16478 | switch (lhs_ty.ptrSize(mod)) { | |
| 16477 | switch (lhs_ty.ptrSize(zcu)) { | |
| 16479 | 16478 | .One, .Slice => {}, |
| 16480 | 16479 | .Many, .C => { |
| 16481 | 16480 | const air_tag: Air.Inst.Tag = switch (zir_tag) { |
| ... | ... | @@ -16484,9 +16483,9 @@ fn analyzeArithmetic( |
| 16484 | 16483 | else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"), |
| 16485 | 16484 | }; |
| 16486 | 16485 | |
| 16487 | if (!try sema.typeHasRuntimeBits(lhs_ty.elemType2(mod))) { | |
| 16486 | if (!try lhs_ty.elemType2(zcu).hasRuntimeBitsSema(pt)) { | |
| 16488 | 16487 | return sema.fail(block, src, "pointer arithmetic requires element type '{}' to have runtime bits", .{ |
| 16489 | lhs_ty.elemType2(mod).fmt(pt), | |
| 16488 | lhs_ty.elemType2(zcu).fmt(pt), | |
| 16490 | 16489 | }); |
| 16491 | 16490 | } |
| 16492 | 16491 | return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, lhs_src, rhs_src); |
| ... | ... | @@ -16503,8 +16502,8 @@ fn analyzeArithmetic( |
| 16503 | 16502 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 16504 | 16503 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 16505 | 16504 | |
| 16506 | const scalar_type = resolved_type.scalarType(mod); | |
| 16507 | const scalar_tag = scalar_type.zigTypeTag(mod); | |
| 16505 | const scalar_type = resolved_type.scalarType(zcu); | |
| 16506 | const scalar_tag = scalar_type.zigTypeTag(zcu); | |
| 16508 | 16507 | |
| 16509 | 16508 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 16510 | 16509 | |
| ... | ... | @@ -16523,12 +16522,12 @@ fn analyzeArithmetic( |
| 16523 | 16522 | // overflow (max_int), causing illegal behavior. |
| 16524 | 16523 | // For floats: either operand being undef makes the result undef. |
| 16525 | 16524 | if (maybe_lhs_val) |lhs_val| { |
| 16526 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16525 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16527 | 16526 | return casted_rhs; |
| 16528 | 16527 | } |
| 16529 | 16528 | } |
| 16530 | 16529 | if (maybe_rhs_val) |rhs_val| { |
| 16531 | if (rhs_val.isUndef(mod)) { | |
| 16530 | if (rhs_val.isUndef(zcu)) { | |
| 16532 | 16531 | if (is_int) { |
| 16533 | 16532 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16534 | 16533 | } else { |
| ... | ... | @@ -16541,7 +16540,7 @@ fn analyzeArithmetic( |
| 16541 | 16540 | } |
| 16542 | 16541 | const air_tag: Air.Inst.Tag = if (block.float_mode == .optimized) .add_optimized else .add; |
| 16543 | 16542 | if (maybe_lhs_val) |lhs_val| { |
| 16544 | if (lhs_val.isUndef(mod)) { | |
| 16543 | if (lhs_val.isUndef(zcu)) { | |
| 16545 | 16544 | if (is_int) { |
| 16546 | 16545 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16547 | 16546 | } else { |
| ... | ... | @@ -16567,12 +16566,12 @@ fn analyzeArithmetic( |
| 16567 | 16566 | // If either of the operands are zero, the other operand is returned. |
| 16568 | 16567 | // If either of the operands are undefined, the result is undefined. |
| 16569 | 16568 | if (maybe_lhs_val) |lhs_val| { |
| 16570 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16569 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16571 | 16570 | return casted_rhs; |
| 16572 | 16571 | } |
| 16573 | 16572 | } |
| 16574 | 16573 | if (maybe_rhs_val) |rhs_val| { |
| 16575 | if (rhs_val.isUndef(mod)) { | |
| 16574 | if (rhs_val.isUndef(zcu)) { | |
| 16576 | 16575 | return pt.undefRef(resolved_type); |
| 16577 | 16576 | } |
| 16578 | 16577 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| ... | ... | @@ -16588,19 +16587,19 @@ fn analyzeArithmetic( |
| 16588 | 16587 | // If either of the operands are zero, then the other operand is returned. |
| 16589 | 16588 | // If either of the operands are undefined, the result is undefined. |
| 16590 | 16589 | if (maybe_lhs_val) |lhs_val| { |
| 16591 | if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16590 | if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) { | |
| 16592 | 16591 | return casted_rhs; |
| 16593 | 16592 | } |
| 16594 | 16593 | } |
| 16595 | 16594 | if (maybe_rhs_val) |rhs_val| { |
| 16596 | if (rhs_val.isUndef(mod)) { | |
| 16595 | if (rhs_val.isUndef(zcu)) { | |
| 16597 | 16596 | return pt.undefRef(resolved_type); |
| 16598 | 16597 | } |
| 16599 | 16598 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16600 | 16599 | return casted_lhs; |
| 16601 | 16600 | } |
| 16602 | 16601 | if (maybe_lhs_val) |lhs_val| { |
| 16603 | if (lhs_val.isUndef(mod)) { | |
| 16602 | if (lhs_val.isUndef(zcu)) { | |
| 16604 | 16603 | return pt.undefRef(resolved_type); |
| 16605 | 16604 | } |
| 16606 | 16605 | |
| ... | ... | @@ -16630,7 +16629,7 @@ fn analyzeArithmetic( |
| 16630 | 16629 | // overflow, causing illegal behavior. |
| 16631 | 16630 | // For floats: either operand being undef makes the result undef. |
| 16632 | 16631 | if (maybe_rhs_val) |rhs_val| { |
| 16633 | if (rhs_val.isUndef(mod)) { | |
| 16632 | if (rhs_val.isUndef(zcu)) { | |
| 16634 | 16633 | if (is_int) { |
| 16635 | 16634 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16636 | 16635 | } else { |
| ... | ... | @@ -16643,7 +16642,7 @@ fn analyzeArithmetic( |
| 16643 | 16642 | } |
| 16644 | 16643 | const air_tag: Air.Inst.Tag = if (block.float_mode == .optimized) .sub_optimized else .sub; |
| 16645 | 16644 | if (maybe_lhs_val) |lhs_val| { |
| 16646 | if (lhs_val.isUndef(mod)) { | |
| 16645 | if (lhs_val.isUndef(zcu)) { | |
| 16647 | 16646 | if (is_int) { |
| 16648 | 16647 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16649 | 16648 | } else { |
| ... | ... | @@ -16669,7 +16668,7 @@ fn analyzeArithmetic( |
| 16669 | 16668 | // If the RHS is zero, then the LHS is returned, even if it is undefined. |
| 16670 | 16669 | // If either of the operands are undefined, the result is undefined. |
| 16671 | 16670 | if (maybe_rhs_val) |rhs_val| { |
| 16672 | if (rhs_val.isUndef(mod)) { | |
| 16671 | if (rhs_val.isUndef(zcu)) { | |
| 16673 | 16672 | return pt.undefRef(resolved_type); |
| 16674 | 16673 | } |
| 16675 | 16674 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| ... | ... | @@ -16677,7 +16676,7 @@ fn analyzeArithmetic( |
| 16677 | 16676 | } |
| 16678 | 16677 | } |
| 16679 | 16678 | if (maybe_lhs_val) |lhs_val| { |
| 16680 | if (lhs_val.isUndef(mod)) { | |
| 16679 | if (lhs_val.isUndef(zcu)) { | |
| 16681 | 16680 | return pt.undefRef(resolved_type); |
| 16682 | 16681 | } |
| 16683 | 16682 | if (maybe_rhs_val) |rhs_val| { |
| ... | ... | @@ -16690,7 +16689,7 @@ fn analyzeArithmetic( |
| 16690 | 16689 | // If the RHS is zero, then the LHS is returned, even if it is undefined. |
| 16691 | 16690 | // If either of the operands are undefined, the result is undefined. |
| 16692 | 16691 | if (maybe_rhs_val) |rhs_val| { |
| 16693 | if (rhs_val.isUndef(mod)) { | |
| 16692 | if (rhs_val.isUndef(zcu)) { | |
| 16694 | 16693 | return pt.undefRef(resolved_type); |
| 16695 | 16694 | } |
| 16696 | 16695 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| ... | ... | @@ -16698,7 +16697,7 @@ fn analyzeArithmetic( |
| 16698 | 16697 | } |
| 16699 | 16698 | } |
| 16700 | 16699 | if (maybe_lhs_val) |lhs_val| { |
| 16701 | if (lhs_val.isUndef(mod)) { | |
| 16700 | if (lhs_val.isUndef(zcu)) { | |
| 16702 | 16701 | return pt.undefRef(resolved_type); |
| 16703 | 16702 | } |
| 16704 | 16703 | if (maybe_rhs_val) |rhs_val| { |
| ... | ... | @@ -16736,16 +16735,16 @@ fn analyzeArithmetic( |
| 16736 | 16735 | else => unreachable, |
| 16737 | 16736 | }; |
| 16738 | 16737 | if (maybe_lhs_val) |lhs_val| { |
| 16739 | if (!lhs_val.isUndef(mod)) { | |
| 16740 | if (lhs_val.isNan(mod)) { | |
| 16738 | if (!lhs_val.isUndef(zcu)) { | |
| 16739 | if (lhs_val.isNan(zcu)) { | |
| 16741 | 16740 | return Air.internedToRef(lhs_val.toIntern()); |
| 16742 | 16741 | } |
| 16743 | 16742 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) lz: { |
| 16744 | 16743 | if (maybe_rhs_val) |rhs_val| { |
| 16745 | if (rhs_val.isNan(mod)) { | |
| 16744 | if (rhs_val.isNan(zcu)) { | |
| 16746 | 16745 | return Air.internedToRef(rhs_val.toIntern()); |
| 16747 | 16746 | } |
| 16748 | if (rhs_val.isInf(mod)) { | |
| 16747 | if (rhs_val.isInf(zcu)) { | |
| 16749 | 16748 | return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern()); |
| 16750 | 16749 | } |
| 16751 | 16750 | } else if (resolved_type.isAnyFloat()) { |
| ... | ... | @@ -16761,19 +16760,19 @@ fn analyzeArithmetic( |
| 16761 | 16760 | } |
| 16762 | 16761 | const air_tag: Air.Inst.Tag = if (block.float_mode == .optimized) .mul_optimized else .mul; |
| 16763 | 16762 | if (maybe_rhs_val) |rhs_val| { |
| 16764 | if (rhs_val.isUndef(mod)) { | |
| 16763 | if (rhs_val.isUndef(zcu)) { | |
| 16765 | 16764 | if (is_int) { |
| 16766 | 16765 | return sema.failWithUseOfUndef(block, rhs_src); |
| 16767 | 16766 | } else { |
| 16768 | 16767 | return pt.undefRef(resolved_type); |
| 16769 | 16768 | } |
| 16770 | 16769 | } |
| 16771 | if (rhs_val.isNan(mod)) { | |
| 16770 | if (rhs_val.isNan(zcu)) { | |
| 16772 | 16771 | return Air.internedToRef(rhs_val.toIntern()); |
| 16773 | 16772 | } |
| 16774 | 16773 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) rz: { |
| 16775 | 16774 | if (maybe_lhs_val) |lhs_val| { |
| 16776 | if (lhs_val.isInf(mod)) { | |
| 16775 | if (lhs_val.isInf(zcu)) { | |
| 16777 | 16776 | return Air.internedToRef((try pt.floatValue(resolved_type, std.math.nan(f128))).toIntern()); |
| 16778 | 16777 | } |
| 16779 | 16778 | } else if (resolved_type.isAnyFloat()) { |
| ... | ... | @@ -16786,7 +16785,7 @@ fn analyzeArithmetic( |
| 16786 | 16785 | return casted_lhs; |
| 16787 | 16786 | } |
| 16788 | 16787 | if (maybe_lhs_val) |lhs_val| { |
| 16789 | if (lhs_val.isUndef(mod)) { | |
| 16788 | if (lhs_val.isUndef(zcu)) { | |
| 16790 | 16789 | if (is_int) { |
| 16791 | 16790 | return sema.failWithUseOfUndef(block, lhs_src); |
| 16792 | 16791 | } else { |
| ... | ... | @@ -16822,7 +16821,7 @@ fn analyzeArithmetic( |
| 16822 | 16821 | else => unreachable, |
| 16823 | 16822 | }; |
| 16824 | 16823 | if (maybe_lhs_val) |lhs_val| { |
| 16825 | if (!lhs_val.isUndef(mod)) { | |
| 16824 | if (!lhs_val.isUndef(zcu)) { | |
| 16826 | 16825 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16827 | 16826 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 16828 | 16827 | return Air.internedToRef(zero_val.toIntern()); |
| ... | ... | @@ -16833,7 +16832,7 @@ fn analyzeArithmetic( |
| 16833 | 16832 | } |
| 16834 | 16833 | } |
| 16835 | 16834 | if (maybe_rhs_val) |rhs_val| { |
| 16836 | if (rhs_val.isUndef(mod)) { | |
| 16835 | if (rhs_val.isUndef(zcu)) { | |
| 16837 | 16836 | return pt.undefRef(resolved_type); |
| 16838 | 16837 | } |
| 16839 | 16838 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| ... | ... | @@ -16844,7 +16843,7 @@ fn analyzeArithmetic( |
| 16844 | 16843 | return casted_lhs; |
| 16845 | 16844 | } |
| 16846 | 16845 | if (maybe_lhs_val) |lhs_val| { |
| 16847 | if (lhs_val.isUndef(mod)) { | |
| 16846 | if (lhs_val.isUndef(zcu)) { | |
| 16848 | 16847 | return pt.undefRef(resolved_type); |
| 16849 | 16848 | } |
| 16850 | 16849 | return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, pt)).toIntern()); |
| ... | ... | @@ -16867,7 +16866,7 @@ fn analyzeArithmetic( |
| 16867 | 16866 | else => unreachable, |
| 16868 | 16867 | }; |
| 16869 | 16868 | if (maybe_lhs_val) |lhs_val| { |
| 16870 | if (!lhs_val.isUndef(mod)) { | |
| 16869 | if (!lhs_val.isUndef(zcu)) { | |
| 16871 | 16870 | if (try lhs_val.compareAllWithZeroSema(.eq, pt)) { |
| 16872 | 16871 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 16873 | 16872 | return Air.internedToRef(zero_val.toIntern()); |
| ... | ... | @@ -16878,7 +16877,7 @@ fn analyzeArithmetic( |
| 16878 | 16877 | } |
| 16879 | 16878 | } |
| 16880 | 16879 | if (maybe_rhs_val) |rhs_val| { |
| 16881 | if (rhs_val.isUndef(mod)) { | |
| 16880 | if (rhs_val.isUndef(zcu)) { | |
| 16882 | 16881 | return pt.undefRef(resolved_type); |
| 16883 | 16882 | } |
| 16884 | 16883 | if (try rhs_val.compareAllWithZeroSema(.eq, pt)) { |
| ... | ... | @@ -16889,7 +16888,7 @@ fn analyzeArithmetic( |
| 16889 | 16888 | return casted_lhs; |
| 16890 | 16889 | } |
| 16891 | 16890 | if (maybe_lhs_val) |lhs_val| { |
| 16892 | if (lhs_val.isUndef(mod)) { | |
| 16891 | if (lhs_val.isUndef(zcu)) { | |
| 16893 | 16892 | return pt.undefRef(resolved_type); |
| 16894 | 16893 | } |
| 16895 | 16894 | |
| ... | ... | @@ -16909,7 +16908,7 @@ fn analyzeArithmetic( |
| 16909 | 16908 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 16910 | 16909 | |
| 16911 | 16910 | if (block.wantSafety() and want_safety and scalar_tag == .Int) { |
| 16912 | if (mod.backendSupportsFeature(.safety_checked_instructions)) { | |
| 16911 | if (zcu.backendSupportsFeature(.safety_checked_instructions)) { | |
| 16913 | 16912 | if (air_tag != air_tag_safe) { |
| 16914 | 16913 | _ = try sema.preparePanicId(block, src, .integer_overflow); |
| 16915 | 16914 | } |
| ... | ... | @@ -16934,7 +16933,7 @@ fn analyzeArithmetic( |
| 16934 | 16933 | } }, |
| 16935 | 16934 | }); |
| 16936 | 16935 | const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); |
| 16937 | const any_ov_bit = if (resolved_type.zigTypeTag(mod) == .Vector) | |
| 16936 | const any_ov_bit = if (resolved_type.zigTypeTag(zcu) == .Vector) | |
| 16938 | 16937 | try block.addInst(.{ |
| 16939 | 16938 | .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce, |
| 16940 | 16939 | .data = .{ .reduce = .{ |
| ... | ... | @@ -16969,11 +16968,11 @@ fn analyzePtrArithmetic( |
| 16969 | 16968 | // coerce to isize instead of usize. |
| 16970 | 16969 | const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src); |
| 16971 | 16970 | const pt = sema.pt; |
| 16972 | const mod = pt.zcu; | |
| 16971 | const zcu = pt.zcu; | |
| 16973 | 16972 | const opt_ptr_val = try sema.resolveValue(ptr); |
| 16974 | 16973 | const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); |
| 16975 | 16974 | const ptr_ty = sema.typeOf(ptr); |
| 16976 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 16975 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 16977 | 16976 | assert(ptr_info.flags.size == .Many or ptr_info.flags.size == .C); |
| 16978 | 16977 | |
| 16979 | 16978 | const new_ptr_ty = t: { |
| ... | ... | @@ -16985,7 +16984,7 @@ fn analyzePtrArithmetic( |
| 16985 | 16984 | } |
| 16986 | 16985 | // If the addend is not a comptime-known value we can still count on |
| 16987 | 16986 | // it being a multiple of the type size. |
| 16988 | const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child)); | |
| 16987 | const elem_size = try Type.fromInterned(ptr_info.child).abiSizeSema(pt); | |
| 16989 | 16988 | const addend = if (opt_off_val) |off_val| a: { |
| 16990 | 16989 | const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(pt)); |
| 16991 | 16990 | break :a elem_size * off_int; |
| ... | ... | @@ -17017,12 +17016,12 @@ fn analyzePtrArithmetic( |
| 17017 | 17016 | const runtime_src = rs: { |
| 17018 | 17017 | if (opt_ptr_val) |ptr_val| { |
| 17019 | 17018 | if (opt_off_val) |offset_val| { |
| 17020 | if (ptr_val.isUndef(mod)) return pt.undefRef(new_ptr_ty); | |
| 17019 | if (ptr_val.isUndef(zcu)) return pt.undefRef(new_ptr_ty); | |
| 17021 | 17020 | |
| 17022 | 17021 | const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(pt)); |
| 17023 | 17022 | if (offset_int == 0) return ptr; |
| 17024 | 17023 | if (air_tag == .ptr_sub) { |
| 17025 | const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child)); | |
| 17024 | const elem_size = try Type.fromInterned(ptr_info.child).abiSizeSema(pt); | |
| 17026 | 17025 | const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty); |
| 17027 | 17026 | return Air.internedToRef(new_ptr_val.toIntern()); |
| 17028 | 17027 | } else { |
| ... | ... | @@ -17067,7 +17066,7 @@ fn zirAsm( |
| 17067 | 17066 | defer tracy.end(); |
| 17068 | 17067 | |
| 17069 | 17068 | const pt = sema.pt; |
| 17070 | const mod = pt.zcu; | |
| 17069 | const zcu = pt.zcu; | |
| 17071 | 17070 | const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand); |
| 17072 | 17071 | const src = block.nodeOffset(extra.data.src_node); |
| 17073 | 17072 | const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node }); |
| ... | ... | @@ -17099,7 +17098,7 @@ fn zirAsm( |
| 17099 | 17098 | if (is_volatile) { |
| 17100 | 17099 | return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{}); |
| 17101 | 17100 | } |
| 17102 | try mod.addGlobalAssembly(sema.owner.unwrap().cau, asm_source); | |
| 17101 | try zcu.addGlobalAssembly(sema.owner.unwrap().cau, asm_source); | |
| 17103 | 17102 | return .void_value; |
| 17104 | 17103 | } |
| 17105 | 17104 | |
| ... | ... | @@ -17153,7 +17152,7 @@ fn zirAsm( |
| 17153 | 17152 | |
| 17154 | 17153 | const uncasted_arg = try sema.resolveInst(input.data.operand); |
| 17155 | 17154 | const uncasted_arg_ty = sema.typeOf(uncasted_arg); |
| 17156 | switch (uncasted_arg_ty.zigTypeTag(mod)) { | |
| 17155 | switch (uncasted_arg_ty.zigTypeTag(zcu)) { | |
| 17157 | 17156 | .ComptimeInt => arg.* = try sema.coerce(block, Type.usize, uncasted_arg, src), |
| 17158 | 17157 | .ComptimeFloat => arg.* = try sema.coerce(block, Type.f64, uncasted_arg, src), |
| 17159 | 17158 | else => { |
| ... | ... | @@ -17236,7 +17235,7 @@ fn zirCmpEq( |
| 17236 | 17235 | defer tracy.end(); |
| 17237 | 17236 | |
| 17238 | 17237 | const pt = sema.pt; |
| 17239 | const mod = pt.zcu; | |
| 17238 | const zcu = pt.zcu; | |
| 17240 | 17239 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 17241 | 17240 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 17242 | 17241 | const src: LazySrcLoc = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -17247,18 +17246,18 @@ fn zirCmpEq( |
| 17247 | 17246 | |
| 17248 | 17247 | const lhs_ty = sema.typeOf(lhs); |
| 17249 | 17248 | const rhs_ty = sema.typeOf(rhs); |
| 17250 | const lhs_ty_tag = lhs_ty.zigTypeTag(mod); | |
| 17251 | const rhs_ty_tag = rhs_ty.zigTypeTag(mod); | |
| 17249 | const lhs_ty_tag = lhs_ty.zigTypeTag(zcu); | |
| 17250 | const rhs_ty_tag = rhs_ty.zigTypeTag(zcu); | |
| 17252 | 17251 | if (lhs_ty_tag == .Null and rhs_ty_tag == .Null) { |
| 17253 | 17252 | // null == null, null != null |
| 17254 | 17253 | return if (op == .eq) .bool_true else .bool_false; |
| 17255 | 17254 | } |
| 17256 | 17255 | |
| 17257 | 17256 | // comparing null with optionals |
| 17258 | if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr(mod))) { | |
| 17257 | if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr(zcu))) { | |
| 17259 | 17258 | return sema.analyzeIsNull(block, src, rhs, op == .neq); |
| 17260 | 17259 | } |
| 17261 | if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr(mod))) { | |
| 17260 | if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr(zcu))) { | |
| 17262 | 17261 | return sema.analyzeIsNull(block, src, lhs, op == .neq); |
| 17263 | 17262 | } |
| 17264 | 17263 | |
| ... | ... | @@ -17278,11 +17277,11 @@ fn zirCmpEq( |
| 17278 | 17277 | const runtime_src: LazySrcLoc = src: { |
| 17279 | 17278 | if (try sema.resolveValue(lhs)) |lval| { |
| 17280 | 17279 | if (try sema.resolveValue(rhs)) |rval| { |
| 17281 | if (lval.isUndef(mod) or rval.isUndef(mod)) { | |
| 17280 | if (lval.isUndef(zcu) or rval.isUndef(zcu)) { | |
| 17282 | 17281 | return pt.undefRef(Type.bool); |
| 17283 | 17282 | } |
| 17284 | const lkey = mod.intern_pool.indexToKey(lval.toIntern()); | |
| 17285 | const rkey = mod.intern_pool.indexToKey(rval.toIntern()); | |
| 17283 | const lkey = zcu.intern_pool.indexToKey(lval.toIntern()); | |
| 17284 | const rkey = zcu.intern_pool.indexToKey(rval.toIntern()); | |
| 17286 | 17285 | return if ((lkey.err.name == rkey.err.name) == (op == .eq)) |
| 17287 | 17286 | .bool_true |
| 17288 | 17287 | else |
| ... | ... | @@ -17300,7 +17299,7 @@ fn zirCmpEq( |
| 17300 | 17299 | if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) { |
| 17301 | 17300 | const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs); |
| 17302 | 17301 | const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs); |
| 17303 | return if (lhs_as_type.eql(rhs_as_type, mod) == (op == .eq)) .bool_true else .bool_false; | |
| 17302 | return if (lhs_as_type.eql(rhs_as_type, zcu) == (op == .eq)) .bool_true else .bool_false; | |
| 17304 | 17303 | } |
| 17305 | 17304 | return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, true); |
| 17306 | 17305 | } |
| ... | ... | @@ -17316,14 +17315,14 @@ fn analyzeCmpUnionTag( |
| 17316 | 17315 | op: std.math.CompareOperator, |
| 17317 | 17316 | ) CompileError!Air.Inst.Ref { |
| 17318 | 17317 | const pt = sema.pt; |
| 17319 | const mod = pt.zcu; | |
| 17318 | const zcu = pt.zcu; | |
| 17320 | 17319 | const union_ty = sema.typeOf(un); |
| 17321 | 17320 | try union_ty.resolveFields(pt); |
| 17322 | const union_tag_ty = union_ty.unionTagType(mod) orelse { | |
| 17321 | const union_tag_ty = union_ty.unionTagType(zcu) orelse { | |
| 17323 | 17322 | const msg = msg: { |
| 17324 | 17323 | const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); |
| 17325 | 17324 | errdefer msg.destroy(sema.gpa); |
| 17326 | try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(pt)}); | |
| 17325 | try sema.errNote(union_ty.srcLoc(zcu), msg, "union '{}' is not a tagged union", .{union_ty.fmt(pt)}); | |
| 17327 | 17326 | break :msg msg; |
| 17328 | 17327 | }; |
| 17329 | 17328 | return sema.failWithOwnedErrorMsg(block, msg); |
| ... | ... | @@ -17334,9 +17333,9 @@ fn analyzeCmpUnionTag( |
| 17334 | 17333 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); |
| 17335 | 17334 | |
| 17336 | 17335 | if (try sema.resolveValue(coerced_tag)) |enum_val| { |
| 17337 | if (enum_val.isUndef(mod)) return pt.undefRef(Type.bool); | |
| 17338 | const field_ty = union_ty.unionFieldType(enum_val, mod).?; | |
| 17339 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | |
| 17336 | if (enum_val.isUndef(zcu)) return pt.undefRef(Type.bool); | |
| 17337 | const field_ty = union_ty.unionFieldType(enum_val, zcu).?; | |
| 17338 | if (field_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 17340 | 17339 | return .bool_false; |
| 17341 | 17340 | } |
| 17342 | 17341 | } |
| ... | ... | @@ -17376,33 +17375,33 @@ fn analyzeCmp( |
| 17376 | 17375 | is_equality_cmp: bool, |
| 17377 | 17376 | ) CompileError!Air.Inst.Ref { |
| 17378 | 17377 | const pt = sema.pt; |
| 17379 | const mod = pt.zcu; | |
| 17378 | const zcu = pt.zcu; | |
| 17380 | 17379 | const lhs_ty = sema.typeOf(lhs); |
| 17381 | 17380 | const rhs_ty = sema.typeOf(rhs); |
| 17382 | if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) { | |
| 17381 | if (lhs_ty.zigTypeTag(zcu) != .Optional and rhs_ty.zigTypeTag(zcu) != .Optional) { | |
| 17383 | 17382 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 17384 | 17383 | } |
| 17385 | 17384 | |
| 17386 | if (lhs_ty.zigTypeTag(mod) == .Vector and rhs_ty.zigTypeTag(mod) == .Vector) { | |
| 17385 | if (lhs_ty.zigTypeTag(zcu) == .Vector and rhs_ty.zigTypeTag(zcu) == .Vector) { | |
| 17387 | 17386 | return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| 17388 | 17387 | } |
| 17389 | if (lhs_ty.isNumeric(mod) and rhs_ty.isNumeric(mod)) { | |
| 17388 | if (lhs_ty.isNumeric(zcu) and rhs_ty.isNumeric(zcu)) { | |
| 17390 | 17389 | // This operation allows any combination of integer and float types, regardless of the |
| 17391 | 17390 | // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for |
| 17392 | 17391 | // numeric types. |
| 17393 | 17392 | return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| 17394 | 17393 | } |
| 17395 | if (is_equality_cmp and lhs_ty.zigTypeTag(mod) == .ErrorUnion and rhs_ty.zigTypeTag(mod) == .ErrorSet) { | |
| 17394 | if (is_equality_cmp and lhs_ty.zigTypeTag(zcu) == .ErrorUnion and rhs_ty.zigTypeTag(zcu) == .ErrorSet) { | |
| 17396 | 17395 | const casted_lhs = try sema.analyzeErrUnionCode(block, lhs_src, lhs); |
| 17397 | 17396 | return sema.cmpSelf(block, src, casted_lhs, rhs, op, lhs_src, rhs_src); |
| 17398 | 17397 | } |
| 17399 | if (is_equality_cmp and lhs_ty.zigTypeTag(mod) == .ErrorSet and rhs_ty.zigTypeTag(mod) == .ErrorUnion) { | |
| 17398 | if (is_equality_cmp and lhs_ty.zigTypeTag(zcu) == .ErrorSet and rhs_ty.zigTypeTag(zcu) == .ErrorUnion) { | |
| 17400 | 17399 | const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs); |
| 17401 | 17400 | return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src); |
| 17402 | 17401 | } |
| 17403 | 17402 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 17404 | 17403 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); |
| 17405 | if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) { | |
| 17404 | if (!resolved_type.isSelfComparable(zcu, is_equality_cmp)) { | |
| 17406 | 17405 | return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{ |
| 17407 | 17406 | compareOperatorName(op), resolved_type.fmt(pt), |
| 17408 | 17407 | }); |
| ... | ... | @@ -17434,15 +17433,15 @@ fn cmpSelf( |
| 17434 | 17433 | rhs_src: LazySrcLoc, |
| 17435 | 17434 | ) CompileError!Air.Inst.Ref { |
| 17436 | 17435 | const pt = sema.pt; |
| 17437 | const mod = pt.zcu; | |
| 17436 | const zcu = pt.zcu; | |
| 17438 | 17437 | const resolved_type = sema.typeOf(casted_lhs); |
| 17439 | 17438 | const runtime_src: LazySrcLoc = src: { |
| 17440 | 17439 | if (try sema.resolveValue(casted_lhs)) |lhs_val| { |
| 17441 | if (lhs_val.isUndef(mod)) return pt.undefRef(Type.bool); | |
| 17440 | if (lhs_val.isUndef(zcu)) return pt.undefRef(Type.bool); | |
| 17442 | 17441 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { |
| 17443 | if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool); | |
| 17442 | if (rhs_val.isUndef(zcu)) return pt.undefRef(Type.bool); | |
| 17444 | 17443 | |
| 17445 | if (resolved_type.zigTypeTag(mod) == .Vector) { | |
| 17444 | if (resolved_type.zigTypeTag(zcu) == .Vector) { | |
| 17446 | 17445 | const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type); |
| 17447 | 17446 | return Air.internedToRef(cmp_val.toIntern()); |
| 17448 | 17447 | } |
| ... | ... | @@ -17452,7 +17451,7 @@ fn cmpSelf( |
| 17452 | 17451 | else |
| 17453 | 17452 | .bool_false; |
| 17454 | 17453 | } else { |
| 17455 | if (resolved_type.zigTypeTag(mod) == .Bool) { | |
| 17454 | if (resolved_type.zigTypeTag(zcu) == .Bool) { | |
| 17456 | 17455 | // We can lower bool eq/neq more efficiently. |
| 17457 | 17456 | return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src); |
| 17458 | 17457 | } |
| ... | ... | @@ -17461,9 +17460,9 @@ fn cmpSelf( |
| 17461 | 17460 | } else { |
| 17462 | 17461 | // For bools, we still check the other operand, because we can lower |
| 17463 | 17462 | // bool eq/neq more efficiently. |
| 17464 | if (resolved_type.zigTypeTag(mod) == .Bool) { | |
| 17463 | if (resolved_type.zigTypeTag(zcu) == .Bool) { | |
| 17465 | 17464 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { |
| 17466 | if (rhs_val.isUndef(mod)) return pt.undefRef(Type.bool); | |
| 17465 | if (rhs_val.isUndef(zcu)) return pt.undefRef(Type.bool); | |
| 17467 | 17466 | return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src); |
| 17468 | 17467 | } |
| 17469 | 17468 | } |
| ... | ... | @@ -17471,7 +17470,7 @@ fn cmpSelf( |
| 17471 | 17470 | } |
| 17472 | 17471 | }; |
| 17473 | 17472 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17474 | if (resolved_type.zigTypeTag(mod) == .Vector) { | |
| 17473 | if (resolved_type.zigTypeTag(zcu) == .Vector) { | |
| 17475 | 17474 | return block.addCmpVector(casted_lhs, casted_rhs, op); |
| 17476 | 17475 | } |
| 17477 | 17476 | const tag = Air.Inst.Tag.fromCmpOp(op, block.float_mode == .optimized); |
| ... | ... | @@ -17541,11 +17540,11 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 17541 | 17540 | |
| 17542 | 17541 | fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 17543 | 17542 | const pt = sema.pt; |
| 17544 | const mod = pt.zcu; | |
| 17543 | const zcu = pt.zcu; | |
| 17545 | 17544 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 17546 | 17545 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 17547 | 17546 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 17548 | switch (operand_ty.zigTypeTag(mod)) { | |
| 17547 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 17549 | 17548 | .Fn, |
| 17550 | 17549 | .NoReturn, |
| 17551 | 17550 | .Undefined, |
| ... | ... | @@ -17576,7 +17575,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17576 | 17575 | .AnyFrame, |
| 17577 | 17576 | => {}, |
| 17578 | 17577 | } |
| 17579 | const bit_size = try operand_ty.bitSizeAdvanced(pt, .sema); | |
| 17578 | const bit_size = try operand_ty.bitSizeSema(pt); | |
| 17580 | 17579 | return pt.intRef(Type.comptime_int, bit_size); |
| 17581 | 17580 | } |
| 17582 | 17581 | |
| ... | ... | @@ -17599,9 +17598,9 @@ fn zirThis( |
| 17599 | 17598 | |
| 17600 | 17599 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 17601 | 17600 | const pt = sema.pt; |
| 17602 | const mod = pt.zcu; | |
| 17603 | const ip = &mod.intern_pool; | |
| 17604 | const captures = Type.fromInterned(mod.namespacePtr(block.namespace).owner_type).getCaptures(mod); | |
| 17601 | const zcu = pt.zcu; | |
| 17602 | const ip = &zcu.intern_pool; | |
| 17603 | const captures = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type).getCaptures(zcu); | |
| 17605 | 17604 | |
| 17606 | 17605 | const src_node: i32 = @bitCast(extended.operand); |
| 17607 | 17606 | const src = block.nodeOffset(src_node); |
| ... | ... | @@ -17619,7 +17618,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17619 | 17618 | const msg = msg: { |
| 17620 | 17619 | const name = name: { |
| 17621 | 17620 | // TODO: we should probably store this name in the ZIR to avoid this complexity. |
| 17622 | const file, const src_base_node = Module.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod).?; | |
| 17621 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; | |
| 17623 | 17622 | const tree = file.getTree(sema.gpa) catch |err| { |
| 17624 | 17623 | // In this case we emit a warning + a less precise source location. |
| 17625 | 17624 | log.warn("unable to load {s}: {s}", .{ |
| ... | ... | @@ -17647,7 +17646,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17647 | 17646 | if (!block.is_typeof and !block.is_comptime and sema.func_index != .none) { |
| 17648 | 17647 | const msg = msg: { |
| 17649 | 17648 | const name = name: { |
| 17650 | const file, const src_base_node = Module.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod).?; | |
| 17649 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; | |
| 17651 | 17650 | const tree = file.getTree(sema.gpa) catch |err| { |
| 17652 | 17651 | // In this case we emit a warning + a less precise source location. |
| 17653 | 17652 | log.warn("unable to load {s}: {s}", .{ |
| ... | ... | @@ -17816,20 +17815,20 @@ fn zirBuiltinSrc( |
| 17816 | 17815 | |
| 17817 | 17816 | fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 17818 | 17817 | const pt = sema.pt; |
| 17819 | const mod = pt.zcu; | |
| 17818 | const zcu = pt.zcu; | |
| 17820 | 17819 | const gpa = sema.gpa; |
| 17821 | const ip = &mod.intern_pool; | |
| 17820 | const ip = &zcu.intern_pool; | |
| 17822 | 17821 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 17823 | 17822 | const src = block.nodeOffset(inst_data.src_node); |
| 17824 | 17823 | const ty = try sema.resolveType(block, src, inst_data.operand); |
| 17825 | 17824 | const type_info_ty = try pt.getBuiltinType("Type"); |
| 17826 | const type_info_tag_ty = type_info_ty.unionTagType(mod).?; | |
| 17825 | const type_info_tag_ty = type_info_ty.unionTagType(zcu).?; | |
| 17827 | 17826 | |
| 17828 | if (ty.typeDeclInst(mod)) |type_decl_inst| { | |
| 17827 | if (ty.typeDeclInst(zcu)) |type_decl_inst| { | |
| 17829 | 17828 | try sema.declareDependency(.{ .namespace = type_decl_inst }); |
| 17830 | 17829 | } |
| 17831 | 17830 | |
| 17832 | switch (ty.zigTypeTag(mod)) { | |
| 17831 | switch (ty.zigTypeTag(zcu)) { | |
| 17833 | 17832 | .Type, |
| 17834 | 17833 | .Void, |
| 17835 | 17834 | .Bool, |
| ... | ... | @@ -17848,7 +17847,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17848 | 17847 | const fn_info_nav = try sema.namespaceLookup( |
| 17849 | 17848 | block, |
| 17850 | 17849 | src, |
| 17851 | type_info_ty.getNamespaceIndex(mod), | |
| 17850 | type_info_ty.getNamespaceIndex(zcu), | |
| 17852 | 17851 | try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls), |
| 17853 | 17852 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 17854 | 17853 | try sema.ensureNavResolved(src, fn_info_nav); |
| ... | ... | @@ -17857,13 +17856,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17857 | 17856 | const param_info_nav = try sema.namespaceLookup( |
| 17858 | 17857 | block, |
| 17859 | 17858 | src, |
| 17860 | fn_info_ty.getNamespaceIndex(mod), | |
| 17859 | fn_info_ty.getNamespaceIndex(zcu), | |
| 17861 | 17860 | try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls), |
| 17862 | 17861 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 17863 | 17862 | try sema.ensureNavResolved(src, param_info_nav); |
| 17864 | 17863 | const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val); |
| 17865 | 17864 | |
| 17866 | const func_ty_info = mod.typeToFunc(ty).?; | |
| 17865 | const func_ty_info = zcu.typeToFunc(ty).?; | |
| 17867 | 17866 | const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| 17868 | 17867 | for (param_vals, 0..) |*param_val, i| { |
| 17869 | 17868 | const param_ty = func_ty_info.param_types.get(ip)[i]; |
| ... | ... | @@ -17908,7 +17907,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17908 | 17907 | .is_const = true, |
| 17909 | 17908 | }, |
| 17910 | 17909 | })).toIntern(); |
| 17911 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | |
| 17910 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); | |
| 17912 | 17911 | break :v try pt.intern(.{ .slice = .{ |
| 17913 | 17912 | .ty = slice_ty, |
| 17914 | 17913 | .ptr = try pt.intern(.{ .ptr = .{ |
| ... | ... | @@ -17958,14 +17957,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17958 | 17957 | const int_info_nav = try sema.namespaceLookup( |
| 17959 | 17958 | block, |
| 17960 | 17959 | src, |
| 17961 | type_info_ty.getNamespaceIndex(mod), | |
| 17960 | type_info_ty.getNamespaceIndex(zcu), | |
| 17962 | 17961 | try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls), |
| 17963 | 17962 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 17964 | 17963 | try sema.ensureNavResolved(src, int_info_nav); |
| 17965 | 17964 | const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val); |
| 17966 | 17965 | |
| 17967 | 17966 | const signedness_ty = try pt.getBuiltinType("Signedness"); |
| 17968 | const info = ty.intInfo(mod); | |
| 17967 | const info = ty.intInfo(zcu); | |
| 17969 | 17968 | const field_values = .{ |
| 17970 | 17969 | // signedness: Signedness, |
| 17971 | 17970 | (try pt.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), |
| ... | ... | @@ -17985,7 +17984,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17985 | 17984 | const float_info_nav = try sema.namespaceLookup( |
| 17986 | 17985 | block, |
| 17987 | 17986 | src, |
| 17988 | type_info_ty.getNamespaceIndex(mod), | |
| 17987 | type_info_ty.getNamespaceIndex(zcu), | |
| 17989 | 17988 | try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls), |
| 17990 | 17989 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 17991 | 17990 | try sema.ensureNavResolved(src, float_info_nav); |
| ... | ... | @@ -17993,7 +17992,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17993 | 17992 | |
| 17994 | 17993 | const field_vals = .{ |
| 17995 | 17994 | // bits: u16, |
| 17996 | (try pt.intValue(Type.u16, ty.bitSize(pt))).toIntern(), | |
| 17995 | (try pt.intValue(Type.u16, ty.bitSize(zcu))).toIntern(), | |
| 17997 | 17996 | }; |
| 17998 | 17997 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 17999 | 17998 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -18005,7 +18004,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18005 | 18004 | } }))); |
| 18006 | 18005 | }, |
| 18007 | 18006 | .Pointer => { |
| 18008 | const info = ty.ptrInfo(mod); | |
| 18007 | const info = ty.ptrInfo(zcu); | |
| 18009 | 18008 | const alignment = if (info.flags.alignment.toByteUnits()) |alignment| |
| 18010 | 18009 | try pt.intValue(Type.comptime_int, alignment) |
| 18011 | 18010 | else |
| ... | ... | @@ -18016,7 +18015,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18016 | 18015 | const nav = try sema.namespaceLookup( |
| 18017 | 18016 | block, |
| 18018 | 18017 | src, |
| 18019 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), | |
| 18018 | (try pt.getBuiltinType("Type")).getNamespaceIndex(zcu), | |
| 18020 | 18019 | try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls), |
| 18021 | 18020 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18022 | 18021 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18026,7 +18025,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18026 | 18025 | const nav = try sema.namespaceLookup( |
| 18027 | 18026 | block, |
| 18028 | 18027 | src, |
| 18029 | pointer_ty.getNamespaceIndex(mod), | |
| 18028 | pointer_ty.getNamespaceIndex(zcu), | |
| 18030 | 18029 | try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls), |
| 18031 | 18030 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18032 | 18031 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18068,14 +18067,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18068 | 18067 | const nav = try sema.namespaceLookup( |
| 18069 | 18068 | block, |
| 18070 | 18069 | src, |
| 18071 | type_info_ty.getNamespaceIndex(mod), | |
| 18070 | type_info_ty.getNamespaceIndex(zcu), | |
| 18072 | 18071 | try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls), |
| 18073 | 18072 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18074 | 18073 | try sema.ensureNavResolved(src, nav); |
| 18075 | 18074 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18076 | 18075 | }; |
| 18077 | 18076 | |
| 18078 | const info = ty.arrayInfo(mod); | |
| 18077 | const info = ty.arrayInfo(zcu); | |
| 18079 | 18078 | const field_values = .{ |
| 18080 | 18079 | // len: comptime_int, |
| 18081 | 18080 | (try pt.intValue(Type.comptime_int, info.len)).toIntern(), |
| ... | ... | @@ -18098,14 +18097,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18098 | 18097 | const nav = try sema.namespaceLookup( |
| 18099 | 18098 | block, |
| 18100 | 18099 | src, |
| 18101 | type_info_ty.getNamespaceIndex(mod), | |
| 18100 | type_info_ty.getNamespaceIndex(zcu), | |
| 18102 | 18101 | try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls), |
| 18103 | 18102 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18104 | 18103 | try sema.ensureNavResolved(src, nav); |
| 18105 | 18104 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18106 | 18105 | }; |
| 18107 | 18106 | |
| 18108 | const info = ty.arrayInfo(mod); | |
| 18107 | const info = ty.arrayInfo(zcu); | |
| 18109 | 18108 | const field_values = .{ |
| 18110 | 18109 | // len: comptime_int, |
| 18111 | 18110 | (try pt.intValue(Type.comptime_int, info.len)).toIntern(), |
| ... | ... | @@ -18126,7 +18125,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18126 | 18125 | const nav = try sema.namespaceLookup( |
| 18127 | 18126 | block, |
| 18128 | 18127 | src, |
| 18129 | type_info_ty.getNamespaceIndex(mod), | |
| 18128 | type_info_ty.getNamespaceIndex(zcu), | |
| 18130 | 18129 | try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls), |
| 18131 | 18130 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18132 | 18131 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18135,7 +18134,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18135 | 18134 | |
| 18136 | 18135 | const field_values = .{ |
| 18137 | 18136 | // child: type, |
| 18138 | ty.optionalChild(mod).toIntern(), | |
| 18137 | ty.optionalChild(zcu).toIntern(), | |
| 18139 | 18138 | }; |
| 18140 | 18139 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18141 | 18140 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -18152,7 +18151,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18152 | 18151 | const nav = try sema.namespaceLookup( |
| 18153 | 18152 | block, |
| 18154 | 18153 | src, |
| 18155 | type_info_ty.getNamespaceIndex(mod), | |
| 18154 | type_info_ty.getNamespaceIndex(zcu), | |
| 18156 | 18155 | try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls), |
| 18157 | 18156 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18158 | 18157 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18226,7 +18225,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18226 | 18225 | .ty = array_errors_ty.toIntern(), |
| 18227 | 18226 | .storage = .{ .elems = vals }, |
| 18228 | 18227 | } }); |
| 18229 | const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(mod).toIntern(); | |
| 18228 | const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(zcu).toIntern(); | |
| 18230 | 18229 | break :v try pt.intern(.{ .slice = .{ |
| 18231 | 18230 | .ty = slice_errors_ty.toIntern(), |
| 18232 | 18231 | .ptr = try pt.intern(.{ .ptr = .{ |
| ... | ... | @@ -18257,7 +18256,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18257 | 18256 | const nav = try sema.namespaceLookup( |
| 18258 | 18257 | block, |
| 18259 | 18258 | src, |
| 18260 | type_info_ty.getNamespaceIndex(mod), | |
| 18259 | type_info_ty.getNamespaceIndex(zcu), | |
| 18261 | 18260 | try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls), |
| 18262 | 18261 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18263 | 18262 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18266,9 +18265,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18266 | 18265 | |
| 18267 | 18266 | const field_values = .{ |
| 18268 | 18267 | // error_set: type, |
| 18269 | ty.errorUnionSet(mod).toIntern(), | |
| 18268 | ty.errorUnionSet(zcu).toIntern(), | |
| 18270 | 18269 | // payload: type, |
| 18271 | ty.errorUnionPayload(mod).toIntern(), | |
| 18270 | ty.errorUnionPayload(zcu).toIntern(), | |
| 18272 | 18271 | }; |
| 18273 | 18272 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18274 | 18273 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -18286,7 +18285,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18286 | 18285 | const nav = try sema.namespaceLookup( |
| 18287 | 18286 | block, |
| 18288 | 18287 | src, |
| 18289 | type_info_ty.getNamespaceIndex(mod), | |
| 18288 | type_info_ty.getNamespaceIndex(zcu), | |
| 18290 | 18289 | try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls), |
| 18291 | 18290 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18292 | 18291 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18298,7 +18297,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18298 | 18297 | const enum_type = ip.loadEnumType(ty.toIntern()); |
| 18299 | 18298 | const value_val = if (enum_type.values.len > 0) |
| 18300 | 18299 | try ip.getCoercedInts( |
| 18301 | mod.gpa, | |
| 18300 | zcu.gpa, | |
| 18302 | 18301 | pt.tid, |
| 18303 | 18302 | ip.indexToKey(enum_type.values.get(ip)[tag_index]).int, |
| 18304 | 18303 | .comptime_int_type, |
| ... | ... | @@ -18361,7 +18360,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18361 | 18360 | .is_const = true, |
| 18362 | 18361 | }, |
| 18363 | 18362 | })).toIntern(); |
| 18364 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | |
| 18363 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); | |
| 18365 | 18364 | break :v try pt.intern(.{ .slice = .{ |
| 18366 | 18365 | .ty = slice_ty, |
| 18367 | 18366 | .ptr = try pt.intern(.{ .ptr = .{ |
| ... | ... | @@ -18382,7 +18381,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18382 | 18381 | const nav = try sema.namespaceLookup( |
| 18383 | 18382 | block, |
| 18384 | 18383 | src, |
| 18385 | type_info_ty.getNamespaceIndex(mod), | |
| 18384 | type_info_ty.getNamespaceIndex(zcu), | |
| 18386 | 18385 | try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls), |
| 18387 | 18386 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18388 | 18387 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18413,7 +18412,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18413 | 18412 | const nav = try sema.namespaceLookup( |
| 18414 | 18413 | block, |
| 18415 | 18414 | src, |
| 18416 | type_info_ty.getNamespaceIndex(mod), | |
| 18415 | type_info_ty.getNamespaceIndex(zcu), | |
| 18417 | 18416 | try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls), |
| 18418 | 18417 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18419 | 18418 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18424,7 +18423,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18424 | 18423 | const nav = try sema.namespaceLookup( |
| 18425 | 18424 | block, |
| 18426 | 18425 | src, |
| 18427 | type_info_ty.getNamespaceIndex(mod), | |
| 18426 | type_info_ty.getNamespaceIndex(zcu), | |
| 18428 | 18427 | try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls), |
| 18429 | 18428 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18430 | 18429 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18432,7 +18431,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18432 | 18431 | }; |
| 18433 | 18432 | |
| 18434 | 18433 | try ty.resolveLayout(pt); // Getting alignment requires type layout |
| 18435 | const union_obj = mod.typeToUnion(ty).?; | |
| 18434 | const union_obj = zcu.typeToUnion(ty).?; | |
| 18436 | 18435 | const tag_type = union_obj.loadTagType(ip); |
| 18437 | 18436 | const layout = union_obj.flagsUnordered(ip).layout; |
| 18438 | 18437 | |
| ... | ... | @@ -18467,7 +18466,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18467 | 18466 | }; |
| 18468 | 18467 | |
| 18469 | 18468 | const alignment = switch (layout) { |
| 18470 | .auto, .@"extern" => try pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema), | |
| 18469 | .auto, .@"extern" => try Type.unionFieldNormalAlignmentAdvanced( | |
| 18470 | union_obj, | |
| 18471 | @intCast(field_index), | |
| 18472 | .sema, | |
| 18473 | pt.zcu, | |
| 18474 | pt.tid, | |
| 18475 | ), | |
| 18471 | 18476 | .@"packed" => .none, |
| 18472 | 18477 | }; |
| 18473 | 18478 | |
| ... | ... | @@ -18502,7 +18507,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18502 | 18507 | .is_const = true, |
| 18503 | 18508 | }, |
| 18504 | 18509 | })).toIntern(); |
| 18505 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | |
| 18510 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); | |
| 18506 | 18511 | break :v try pt.intern(.{ .slice = .{ |
| 18507 | 18512 | .ty = slice_ty, |
| 18508 | 18513 | .ptr = try pt.intern(.{ .ptr = .{ |
| ... | ... | @@ -18517,18 +18522,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18517 | 18522 | } }); |
| 18518 | 18523 | }; |
| 18519 | 18524 | |
| 18520 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod).toOptional()); | |
| 18525 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(zcu).toOptional()); | |
| 18521 | 18526 | |
| 18522 | 18527 | const enum_tag_ty_val = try pt.intern(.{ .opt = .{ |
| 18523 | 18528 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| 18524 | .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none, | |
| 18529 | .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none, | |
| 18525 | 18530 | } }); |
| 18526 | 18531 | |
| 18527 | 18532 | const container_layout_ty = t: { |
| 18528 | 18533 | const nav = try sema.namespaceLookup( |
| 18529 | 18534 | block, |
| 18530 | 18535 | src, |
| 18531 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), | |
| 18536 | (try pt.getBuiltinType("Type")).getNamespaceIndex(zcu), | |
| 18532 | 18537 | try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls), |
| 18533 | 18538 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18534 | 18539 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18560,7 +18565,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18560 | 18565 | const nav = try sema.namespaceLookup( |
| 18561 | 18566 | block, |
| 18562 | 18567 | src, |
| 18563 | type_info_ty.getNamespaceIndex(mod), | |
| 18568 | type_info_ty.getNamespaceIndex(zcu), | |
| 18564 | 18569 | try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls), |
| 18565 | 18570 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18566 | 18571 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18571,7 +18576,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18571 | 18576 | const nav = try sema.namespaceLookup( |
| 18572 | 18577 | block, |
| 18573 | 18578 | src, |
| 18574 | type_info_ty.getNamespaceIndex(mod), | |
| 18579 | type_info_ty.getNamespaceIndex(zcu), | |
| 18575 | 18580 | try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls), |
| 18576 | 18581 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18577 | 18582 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18633,7 +18638,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18633 | 18638 | // is_comptime: bool, |
| 18634 | 18639 | Value.makeBool(is_comptime).toIntern(), |
| 18635 | 18640 | // alignment: comptime_int, |
| 18636 | (try pt.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(pt).toByteUnits() orelse 0)).toIntern(), | |
| 18641 | (try pt.intValue(Type.comptime_int, Type.fromInterned(field_ty).abiAlignment(zcu).toByteUnits() orelse 0)).toIntern(), | |
| 18637 | 18642 | }; |
| 18638 | 18643 | struct_field_val.* = try pt.intern(.{ .aggregate = .{ |
| 18639 | 18644 | .ty = struct_field_ty.toIntern(), |
| ... | ... | @@ -18686,11 +18691,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18686 | 18691 | const default_val_ptr = try sema.optRefValue(opt_default_val); |
| 18687 | 18692 | const alignment = switch (struct_type.layout) { |
| 18688 | 18693 | .@"packed" => .none, |
| 18689 | else => try pt.structFieldAlignmentAdvanced( | |
| 18694 | else => try field_ty.structFieldAlignmentAdvanced( | |
| 18690 | 18695 | struct_type.fieldAlign(ip, field_index), |
| 18691 | field_ty, | |
| 18692 | 18696 | struct_type.layout, |
| 18693 | 18697 | .sema, |
| 18698 | pt.zcu, | |
| 18699 | pt.tid, | |
| 18694 | 18700 | ), |
| 18695 | 18701 | }; |
| 18696 | 18702 | |
| ... | ... | @@ -18729,7 +18735,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18729 | 18735 | .is_const = true, |
| 18730 | 18736 | }, |
| 18731 | 18737 | })).toIntern(); |
| 18732 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | |
| 18738 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); | |
| 18733 | 18739 | break :v try pt.intern(.{ .slice = .{ |
| 18734 | 18740 | .ty = slice_ty, |
| 18735 | 18741 | .ptr = try pt.intern(.{ .ptr = .{ |
| ... | ... | @@ -18744,12 +18750,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18744 | 18750 | } }); |
| 18745 | 18751 | }; |
| 18746 | 18752 | |
| 18747 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(mod)); | |
| 18753 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu)); | |
| 18748 | 18754 | |
| 18749 | 18755 | const backing_integer_val = try pt.intern(.{ .opt = .{ |
| 18750 | 18756 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| 18751 | .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: { | |
| 18752 | assert(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)).isInt(mod)); | |
| 18757 | .val = if (zcu.typeToPackedStruct(ty)) |packed_struct| val: { | |
| 18758 | assert(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)).isInt(zcu)); | |
| 18753 | 18759 | break :val packed_struct.backingIntTypeUnordered(ip); |
| 18754 | 18760 | } else .none, |
| 18755 | 18761 | } }); |
| ... | ... | @@ -18758,14 +18764,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18758 | 18764 | const nav = try sema.namespaceLookup( |
| 18759 | 18765 | block, |
| 18760 | 18766 | src, |
| 18761 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), | |
| 18767 | (try pt.getBuiltinType("Type")).getNamespaceIndex(zcu), | |
| 18762 | 18768 | try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls), |
| 18763 | 18769 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18764 | 18770 | try sema.ensureNavResolved(src, nav); |
| 18765 | 18771 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18766 | 18772 | }; |
| 18767 | 18773 | |
| 18768 | const layout = ty.containerLayout(mod); | |
| 18774 | const layout = ty.containerLayout(zcu); | |
| 18769 | 18775 | |
| 18770 | 18776 | const field_values = [_]InternPool.Index{ |
| 18771 | 18777 | // layout: ContainerLayout, |
| ... | ... | @@ -18777,7 +18783,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18777 | 18783 | // decls: []const Declaration, |
| 18778 | 18784 | decls_val, |
| 18779 | 18785 | // is_tuple: bool, |
| 18780 | Value.makeBool(ty.isTuple(mod)).toIntern(), | |
| 18786 | Value.makeBool(ty.isTuple(zcu)).toIntern(), | |
| 18781 | 18787 | }; |
| 18782 | 18788 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 18783 | 18789 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -18793,7 +18799,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18793 | 18799 | const nav = try sema.namespaceLookup( |
| 18794 | 18800 | block, |
| 18795 | 18801 | src, |
| 18796 | type_info_ty.getNamespaceIndex(mod), | |
| 18802 | type_info_ty.getNamespaceIndex(zcu), | |
| 18797 | 18803 | try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls), |
| 18798 | 18804 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18799 | 18805 | try sema.ensureNavResolved(src, nav); |
| ... | ... | @@ -18801,7 +18807,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18801 | 18807 | }; |
| 18802 | 18808 | |
| 18803 | 18809 | try ty.resolveFields(pt); |
| 18804 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(mod)); | |
| 18810 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu)); | |
| 18805 | 18811 | |
| 18806 | 18812 | const field_values = .{ |
| 18807 | 18813 | // decls: []const Declaration, |
| ... | ... | @@ -19000,11 +19006,11 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 19000 | 19006 | |
| 19001 | 19007 | fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type { |
| 19002 | 19008 | const pt = sema.pt; |
| 19003 | const mod = pt.zcu; | |
| 19004 | switch (operand.zigTypeTag(mod)) { | |
| 19009 | const zcu = pt.zcu; | |
| 19010 | switch (operand.zigTypeTag(zcu)) { | |
| 19005 | 19011 | .ComptimeInt => return Type.comptime_int, |
| 19006 | 19012 | .Int => { |
| 19007 | const bits = operand.bitSize(pt); | |
| 19013 | const bits = operand.bitSize(zcu); | |
| 19008 | 19014 | const count = if (bits == 0) |
| 19009 | 19015 | 0 |
| 19010 | 19016 | else blk: { |
| ... | ... | @@ -19018,10 +19024,10 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi |
| 19018 | 19024 | return pt.intType(.unsigned, count); |
| 19019 | 19025 | }, |
| 19020 | 19026 | .Vector => { |
| 19021 | const elem_ty = operand.elemType2(mod); | |
| 19027 | const elem_ty = operand.elemType2(zcu); | |
| 19022 | 19028 | const log2_elem_ty = try sema.log2IntType(block, elem_ty, src); |
| 19023 | 19029 | return pt.vectorType(.{ |
| 19024 | .len = operand.vectorLen(mod), | |
| 19030 | .len = operand.vectorLen(zcu), | |
| 19025 | 19031 | .child = log2_elem_ty.toIntern(), |
| 19026 | 19032 | }); |
| 19027 | 19033 | }, |
| ... | ... | @@ -19084,7 +19090,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19084 | 19090 | defer tracy.end(); |
| 19085 | 19091 | |
| 19086 | 19092 | const pt = sema.pt; |
| 19087 | const mod = pt.zcu; | |
| 19093 | const zcu = pt.zcu; | |
| 19088 | 19094 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19089 | 19095 | const src = block.nodeOffset(inst_data.src_node); |
| 19090 | 19096 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| ... | ... | @@ -19092,7 +19098,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19092 | 19098 | |
| 19093 | 19099 | const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src); |
| 19094 | 19100 | if (try sema.resolveValue(operand)) |val| { |
| 19095 | return if (val.isUndef(mod)) | |
| 19101 | return if (val.isUndef(zcu)) | |
| 19096 | 19102 | pt.undefRef(Type.bool) |
| 19097 | 19103 | else if (val.toBool()) .bool_false else .bool_true; |
| 19098 | 19104 | } |
| ... | ... | @@ -19110,7 +19116,7 @@ fn zirBoolBr( |
| 19110 | 19116 | defer tracy.end(); |
| 19111 | 19117 | |
| 19112 | 19118 | const pt = sema.pt; |
| 19113 | const mod = pt.zcu; | |
| 19119 | const zcu = pt.zcu; | |
| 19114 | 19120 | const gpa = sema.gpa; |
| 19115 | 19121 | |
| 19116 | 19122 | const datas = sema.code.instructions.items(.data); |
| ... | ... | @@ -19134,7 +19140,7 @@ fn zirBoolBr( |
| 19134 | 19140 | // is simply the rhs expression. Here we rely on there only being 1 |
| 19135 | 19141 | // break instruction (`break_inline`). |
| 19136 | 19142 | const rhs_result = try sema.resolveInlineBody(parent_block, body, inst); |
| 19137 | if (sema.typeOf(rhs_result).isNoReturn(mod)) { | |
| 19143 | if (sema.typeOf(rhs_result).isNoReturn(zcu)) { | |
| 19138 | 19144 | return rhs_result; |
| 19139 | 19145 | } |
| 19140 | 19146 | return sema.coerce(parent_block, Type.bool, rhs_result, rhs_src); |
| ... | ... | @@ -19168,7 +19174,7 @@ fn zirBoolBr( |
| 19168 | 19174 | _ = try lhs_block.addBr(block_inst, lhs_result); |
| 19169 | 19175 | |
| 19170 | 19176 | const rhs_result = try sema.resolveInlineBody(rhs_block, body, inst); |
| 19171 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod); | |
| 19177 | const rhs_noret = sema.typeOf(rhs_result).isNoReturn(zcu); | |
| 19172 | 19178 | const coerced_rhs_result = if (!rhs_noret) rhs: { |
| 19173 | 19179 | const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src); |
| 19174 | 19180 | _ = try rhs_block.addBr(block_inst, coerced_result); |
| ... | ... | @@ -19227,10 +19233,10 @@ fn finishCondBr( |
| 19227 | 19233 | |
| 19228 | 19234 | fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 19229 | 19235 | const pt = sema.pt; |
| 19230 | const mod = pt.zcu; | |
| 19231 | switch (ty.zigTypeTag(mod)) { | |
| 19236 | const zcu = pt.zcu; | |
| 19237 | switch (ty.zigTypeTag(zcu)) { | |
| 19232 | 19238 | .Optional, .Null, .Undefined => return, |
| 19233 | .Pointer => if (ty.isPtrLikeOptional(mod)) return, | |
| 19239 | .Pointer => if (ty.isPtrLikeOptional(zcu)) return, | |
| 19234 | 19240 | else => {}, |
| 19235 | 19241 | } |
| 19236 | 19242 | return sema.failWithExpectedOptionalType(block, src, ty); |
| ... | ... | @@ -19260,11 +19266,11 @@ fn zirIsNonNullPtr( |
| 19260 | 19266 | defer tracy.end(); |
| 19261 | 19267 | |
| 19262 | 19268 | const pt = sema.pt; |
| 19263 | const mod = pt.zcu; | |
| 19269 | const zcu = pt.zcu; | |
| 19264 | 19270 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19265 | 19271 | const src = block.nodeOffset(inst_data.src_node); |
| 19266 | 19272 | const ptr = try sema.resolveInst(inst_data.operand); |
| 19267 | try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2(mod)); | |
| 19273 | try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2(zcu)); | |
| 19268 | 19274 | if ((try sema.resolveValue(ptr)) == null) { |
| 19269 | 19275 | return block.addUnOp(.is_non_null_ptr, ptr); |
| 19270 | 19276 | } |
| ... | ... | @@ -19274,8 +19280,8 @@ fn zirIsNonNullPtr( |
| 19274 | 19280 | |
| 19275 | 19281 | fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 19276 | 19282 | const pt = sema.pt; |
| 19277 | const mod = pt.zcu; | |
| 19278 | switch (ty.zigTypeTag(mod)) { | |
| 19283 | const zcu = pt.zcu; | |
| 19284 | switch (ty.zigTypeTag(zcu)) { | |
| 19279 | 19285 | .ErrorSet, .ErrorUnion, .Undefined => return, |
| 19280 | 19286 | else => return sema.fail(block, src, "expected error union type, found '{}'", .{ |
| 19281 | 19287 | ty.fmt(pt), |
| ... | ... | @@ -19299,11 +19305,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 19299 | 19305 | defer tracy.end(); |
| 19300 | 19306 | |
| 19301 | 19307 | const pt = sema.pt; |
| 19302 | const mod = pt.zcu; | |
| 19308 | const zcu = pt.zcu; | |
| 19303 | 19309 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 19304 | 19310 | const src = block.nodeOffset(inst_data.src_node); |
| 19305 | 19311 | const ptr = try sema.resolveInst(inst_data.operand); |
| 19306 | try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2(mod)); | |
| 19312 | try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2(zcu)); | |
| 19307 | 19313 | const loaded = try sema.analyzeLoad(block, src, ptr, src); |
| 19308 | 19314 | return sema.analyzeIsNonErr(block, src, loaded); |
| 19309 | 19315 | } |
| ... | ... | @@ -19327,7 +19333,7 @@ fn zirCondbr( |
| 19327 | 19333 | defer tracy.end(); |
| 19328 | 19334 | |
| 19329 | 19335 | const pt = sema.pt; |
| 19330 | const mod = pt.zcu; | |
| 19336 | const zcu = pt.zcu; | |
| 19331 | 19337 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19332 | 19338 | const cond_src = parent_block.src(.{ .node_offset_if_cond = inst_data.src_node }); |
| 19333 | 19339 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| ... | ... | @@ -19368,8 +19374,8 @@ fn zirCondbr( |
| 19368 | 19374 | const err_inst_data = sema.code.instructions.items(.data)[@intFromEnum(index)].un_node; |
| 19369 | 19375 | const err_operand = try sema.resolveInst(err_inst_data.operand); |
| 19370 | 19376 | const operand_ty = sema.typeOf(err_operand); |
| 19371 | assert(operand_ty.zigTypeTag(mod) == .ErrorUnion); | |
| 19372 | const result_ty = operand_ty.errorUnionSet(mod); | |
| 19377 | assert(operand_ty.zigTypeTag(zcu) == .ErrorUnion); | |
| 19378 | const result_ty = operand_ty.errorUnionSet(zcu); | |
| 19373 | 19379 | break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand); |
| 19374 | 19380 | }; |
| 19375 | 19381 | |
| ... | ... | @@ -19403,8 +19409,8 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19403 | 19409 | const err_union = try sema.resolveInst(extra.data.operand); |
| 19404 | 19410 | const err_union_ty = sema.typeOf(err_union); |
| 19405 | 19411 | const pt = sema.pt; |
| 19406 | const mod = pt.zcu; | |
| 19407 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { | |
| 19412 | const zcu = pt.zcu; | |
| 19413 | if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) { | |
| 19408 | 19414 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ |
| 19409 | 19415 | err_union_ty.fmt(pt), |
| 19410 | 19416 | }); |
| ... | ... | @@ -19452,8 +19458,8 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19452 | 19458 | const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src); |
| 19453 | 19459 | const err_union_ty = sema.typeOf(err_union); |
| 19454 | 19460 | const pt = sema.pt; |
| 19455 | const mod = pt.zcu; | |
| 19456 | if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { | |
| 19461 | const zcu = pt.zcu; | |
| 19462 | if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) { | |
| 19457 | 19463 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ |
| 19458 | 19464 | err_union_ty.fmt(pt), |
| 19459 | 19465 | }); |
| ... | ... | @@ -19477,9 +19483,9 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 19477 | 19483 | try sema.analyzeBodyInner(&sub_block, body); |
| 19478 | 19484 | |
| 19479 | 19485 | const operand_ty = sema.typeOf(operand); |
| 19480 | const ptr_info = operand_ty.ptrInfo(mod); | |
| 19486 | const ptr_info = operand_ty.ptrInfo(zcu); | |
| 19481 | 19487 | const res_ty = try pt.ptrTypeSema(.{ |
| 19482 | .child = err_union_ty.errorUnionPayload(mod).toIntern(), | |
| 19488 | .child = err_union_ty.errorUnionPayload(zcu).toIntern(), | |
| 19483 | 19489 | .flags = .{ |
| 19484 | 19490 | .is_const = ptr_info.flags.is_const, |
| 19485 | 19491 | .is_volatile = ptr_info.flags.is_volatile, |
| ... | ... | @@ -19594,10 +19600,10 @@ fn zirRetErrValue( |
| 19594 | 19600 | inst: Zir.Inst.Index, |
| 19595 | 19601 | ) CompileError!void { |
| 19596 | 19602 | const pt = sema.pt; |
| 19597 | const mod = pt.zcu; | |
| 19603 | const zcu = pt.zcu; | |
| 19598 | 19604 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 19599 | 19605 | const src = block.tokenOffset(inst_data.src_tok); |
| 19600 | const err_name = try mod.intern_pool.getOrPutString( | |
| 19606 | const err_name = try zcu.intern_pool.getOrPutString( | |
| 19601 | 19607 | sema.gpa, |
| 19602 | 19608 | pt.tid, |
| 19603 | 19609 | inst_data.get(sema.code), |
| ... | ... | @@ -19622,7 +19628,7 @@ fn zirRetImplicit( |
| 19622 | 19628 | defer tracy.end(); |
| 19623 | 19629 | |
| 19624 | 19630 | const pt = sema.pt; |
| 19625 | const mod = pt.zcu; | |
| 19631 | const zcu = pt.zcu; | |
| 19626 | 19632 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; |
| 19627 | 19633 | const r_brace_src = block.tokenOffset(inst_data.src_tok); |
| 19628 | 19634 | if (block.inlining == null and sema.func_is_naked) { |
| ... | ... | @@ -19638,7 +19644,7 @@ fn zirRetImplicit( |
| 19638 | 19644 | |
| 19639 | 19645 | const operand = try sema.resolveInst(inst_data.operand); |
| 19640 | 19646 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = 0 }); |
| 19641 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod); | |
| 19647 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu); | |
| 19642 | 19648 | if (base_tag == .NoReturn) { |
| 19643 | 19649 | const msg = msg: { |
| 19644 | 19650 | const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{ |
| ... | ... | @@ -19755,13 +19761,13 @@ fn retWithErrTracing( |
| 19755 | 19761 | |
| 19756 | 19762 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| 19757 | 19763 | const pt = sema.pt; |
| 19758 | const mod = pt.zcu; | |
| 19759 | return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing; | |
| 19764 | const zcu = pt.zcu; | |
| 19765 | return fn_ret_ty.isError(zcu) and zcu.comp.config.any_error_tracing; | |
| 19760 | 19766 | } |
| 19761 | 19767 | |
| 19762 | 19768 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 19763 | 19769 | const pt = sema.pt; |
| 19764 | const mod = pt.zcu; | |
| 19770 | const zcu = pt.zcu; | |
| 19765 | 19771 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index; |
| 19766 | 19772 | |
| 19767 | 19773 | if (!block.ownerModule().error_tracing) return; |
| ... | ... | @@ -19772,7 +19778,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 19772 | 19778 | const save_index = inst_data.operand == .none or b: { |
| 19773 | 19779 | const operand = try sema.resolveInst(inst_data.operand); |
| 19774 | 19780 | const operand_ty = sema.typeOf(operand); |
| 19775 | break :b operand_ty.isError(mod); | |
| 19781 | break :b operand_ty.isError(zcu); | |
| 19776 | 19782 | }; |
| 19777 | 19783 | |
| 19778 | 19784 | if (save_index) |
| ... | ... | @@ -19792,7 +19798,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19792 | 19798 | defer tracy.end(); |
| 19793 | 19799 | |
| 19794 | 19800 | const pt = sema.pt; |
| 19795 | const mod = pt.zcu; | |
| 19801 | const zcu = pt.zcu; | |
| 19796 | 19802 | |
| 19797 | 19803 | const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: { |
| 19798 | 19804 | var block = start_block; |
| ... | ... | @@ -19830,13 +19836,13 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19830 | 19836 | if (is_non_error) return; |
| 19831 | 19837 | |
| 19832 | 19838 | const saved_index_val = try sema.resolveDefinedValue(start_block, src, saved_index); |
| 19833 | const saved_index_int = saved_index_val.?.toUnsignedInt(pt); | |
| 19839 | const saved_index_int = saved_index_val.?.toUnsignedInt(zcu); | |
| 19834 | 19840 | assert(saved_index_int <= sema.comptime_err_ret_trace.items.len); |
| 19835 | 19841 | sema.comptime_err_ret_trace.items.len = @intCast(saved_index_int); |
| 19836 | 19842 | return; |
| 19837 | 19843 | } |
| 19838 | 19844 | |
| 19839 | if (!mod.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return; | |
| 19845 | if (!zcu.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return; | |
| 19840 | 19846 | if (!start_block.ownerModule().error_tracing) return; |
| 19841 | 19847 | |
| 19842 | 19848 | assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere |
| ... | ... | @@ -19846,10 +19852,10 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19846 | 19852 | |
| 19847 | 19853 | fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { |
| 19848 | 19854 | const pt = sema.pt; |
| 19849 | const mod = pt.zcu; | |
| 19850 | const ip = &mod.intern_pool; | |
| 19851 | assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion); | |
| 19852 | const err_set_ty = sema.fn_ret_ty.errorUnionSet(mod).toIntern(); | |
| 19855 | const zcu = pt.zcu; | |
| 19856 | const ip = &zcu.intern_pool; | |
| 19857 | assert(sema.fn_ret_ty.zigTypeTag(zcu) == .ErrorUnion); | |
| 19858 | const err_set_ty = sema.fn_ret_ty.errorUnionSet(zcu).toIntern(); | |
| 19853 | 19859 | switch (err_set_ty) { |
| 19854 | 19860 | .adhoc_inferred_error_set_type => { |
| 19855 | 19861 | const ies = sema.fn_ret_ty_ies.?; |
| ... | ... | @@ -19867,11 +19873,11 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { |
| 19867 | 19873 | fn addToInferredErrorSetPtr(sema: *Sema, ies: *InferredErrorSet, op_ty: Type) !void { |
| 19868 | 19874 | const arena = sema.arena; |
| 19869 | 19875 | const pt = sema.pt; |
| 19870 | const mod = pt.zcu; | |
| 19871 | const ip = &mod.intern_pool; | |
| 19872 | switch (op_ty.zigTypeTag(mod)) { | |
| 19876 | const zcu = pt.zcu; | |
| 19877 | const ip = &zcu.intern_pool; | |
| 19878 | switch (op_ty.zigTypeTag(zcu)) { | |
| 19873 | 19879 | .ErrorSet => try ies.addErrorSet(op_ty, ip, arena), |
| 19874 | .ErrorUnion => try ies.addErrorSet(op_ty.errorUnionSet(mod), ip, arena), | |
| 19880 | .ErrorUnion => try ies.addErrorSet(op_ty.errorUnionSet(zcu), ip, arena), | |
| 19875 | 19881 | else => {}, |
| 19876 | 19882 | } |
| 19877 | 19883 | } |
| ... | ... | @@ -19887,8 +19893,8 @@ fn analyzeRet( |
| 19887 | 19893 | // add the error tag to the inferred error set of the in-scope function, so |
| 19888 | 19894 | // that the coercion below works correctly. |
| 19889 | 19895 | const pt = sema.pt; |
| 19890 | const mod = pt.zcu; | |
| 19891 | if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) { | |
| 19896 | const zcu = pt.zcu; | |
| 19897 | if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(zcu) == .ErrorUnion) { | |
| 19892 | 19898 | try sema.addToInferredErrorSet(uncasted_operand); |
| 19893 | 19899 | } |
| 19894 | 19900 | const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, operand_src, .{ .is_ret = true }) catch |err| switch (err) { |
| ... | ... | @@ -19903,7 +19909,7 @@ fn analyzeRet( |
| 19903 | 19909 | }); |
| 19904 | 19910 | inlining.comptime_result = operand; |
| 19905 | 19911 | |
| 19906 | if (sema.fn_ret_ty.isError(mod) and ret_val.getErrorName(mod) != .none) { | |
| 19912 | if (sema.fn_ret_ty.isError(zcu) and ret_val.getErrorName(zcu) != .none) { | |
| 19907 | 19913 | try sema.comptime_err_ret_trace.append(src); |
| 19908 | 19914 | } |
| 19909 | 19915 | return error.ComptimeReturn; |
| ... | ... | @@ -19955,7 +19961,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19955 | 19961 | defer tracy.end(); |
| 19956 | 19962 | |
| 19957 | 19963 | const pt = sema.pt; |
| 19958 | const mod = pt.zcu; | |
| 19964 | const zcu = pt.zcu; | |
| 19959 | 19965 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type; |
| 19960 | 19966 | const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); |
| 19961 | 19967 | const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node }); |
| ... | ... | @@ -19968,7 +19974,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19968 | 19974 | const elem_ty = blk: { |
| 19969 | 19975 | const air_inst = try sema.resolveInst(extra.data.elem_type); |
| 19970 | 19976 | const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| { |
| 19971 | if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(mod)) { | |
| 19977 | if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(zcu)) { | |
| 19972 | 19978 | try sema.errNote(elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{}); |
| 19973 | 19979 | } |
| 19974 | 19980 | return err; |
| ... | ... | @@ -19977,10 +19983,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19977 | 19983 | break :blk ty; |
| 19978 | 19984 | }; |
| 19979 | 19985 | |
| 19980 | if (elem_ty.zigTypeTag(mod) == .NoReturn) | |
| 19986 | if (elem_ty.zigTypeTag(zcu) == .NoReturn) | |
| 19981 | 19987 | return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{}); |
| 19982 | 19988 | |
| 19983 | const target = mod.getTarget(); | |
| 19989 | const target = zcu.getTarget(); | |
| 19984 | 19990 | |
| 19985 | 19991 | var extra_i = extra.end; |
| 19986 | 19992 | |
| ... | ... | @@ -20003,14 +20009,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20003 | 20009 | }); |
| 20004 | 20010 | // Check if this happens to be the lazy alignment of our element type, in |
| 20005 | 20011 | // which case we can make this 0 without resolving it. |
| 20006 | switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 20012 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 20007 | 20013 | .int => |int| switch (int.storage) { |
| 20008 | 20014 | .lazy_align => |lazy_ty| if (lazy_ty == elem_ty.toIntern()) break :blk .none, |
| 20009 | 20015 | else => {}, |
| 20010 | 20016 | }, |
| 20011 | 20017 | else => {}, |
| 20012 | 20018 | } |
| 20013 | const align_bytes = (try val.getUnsignedIntAdvanced(pt, .sema)).?; | |
| 20019 | const align_bytes = (try val.getUnsignedIntSema(pt)).?; | |
| 20014 | 20020 | break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes); |
| 20015 | 20021 | } else .none; |
| 20016 | 20022 | |
| ... | ... | @@ -20018,7 +20024,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20018 | 20024 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 20019 | 20025 | extra_i += 1; |
| 20020 | 20026 | break :blk try sema.resolveAddressSpace(block, addrspace_src, ref, .pointer); |
| 20021 | } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic; | |
| 20027 | } else if (elem_ty.zigTypeTag(zcu) == .Fn and target.cpu.arch == .avr) .flash else .generic; | |
| 20022 | 20028 | |
| 20023 | 20029 | const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 20024 | 20030 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| ... | ... | @@ -20044,7 +20050,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20044 | 20050 | elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size, |
| 20045 | 20051 | }); |
| 20046 | 20052 | } |
| 20047 | const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, .sema); | |
| 20053 | const elem_bit_size = try elem_ty.bitSizeSema(pt); | |
| 20048 | 20054 | if (elem_bit_size > host_size * 8 - bit_offset) { |
| 20049 | 20055 | return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{ |
| 20050 | 20056 | elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size, |
| ... | ... | @@ -20052,11 +20058,11 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20052 | 20058 | } |
| 20053 | 20059 | } |
| 20054 | 20060 | |
| 20055 | if (elem_ty.zigTypeTag(mod) == .Fn) { | |
| 20061 | if (elem_ty.zigTypeTag(zcu) == .Fn) { | |
| 20056 | 20062 | if (inst_data.size != .One) { |
| 20057 | 20063 | return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); |
| 20058 | 20064 | } |
| 20059 | } else if (inst_data.size == .Many and elem_ty.zigTypeTag(mod) == .Opaque) { | |
| 20065 | } else if (inst_data.size == .Many and elem_ty.zigTypeTag(zcu) == .Opaque) { | |
| 20060 | 20066 | return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{}); |
| 20061 | 20067 | } else if (inst_data.size == .C) { |
| 20062 | 20068 | if (!try sema.validateExternType(elem_ty, .other)) { |
| ... | ... | @@ -20071,7 +20077,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20071 | 20077 | }; |
| 20072 | 20078 | return sema.failWithOwnedErrorMsg(block, msg); |
| 20073 | 20079 | } |
| 20074 | if (elem_ty.zigTypeTag(mod) == .Opaque) { | |
| 20080 | if (elem_ty.zigTypeTag(zcu) == .Opaque) { | |
| 20075 | 20081 | return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{}); |
| 20076 | 20082 | } |
| 20077 | 20083 | } |
| ... | ... | @@ -20113,9 +20119,9 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 20113 | 20119 | const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node }); |
| 20114 | 20120 | const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 20115 | 20121 | const pt = sema.pt; |
| 20116 | const mod = pt.zcu; | |
| 20122 | const zcu = pt.zcu; | |
| 20117 | 20123 | |
| 20118 | switch (obj_ty.zigTypeTag(mod)) { | |
| 20124 | switch (obj_ty.zigTypeTag(zcu)) { | |
| 20119 | 20125 | .Struct => return sema.structInitEmpty(block, obj_ty, src, src), |
| 20120 | 20126 | .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty), |
| 20121 | 20127 | .Void => return Air.internedToRef(Value.void.toIntern()), |
| ... | ... | @@ -20129,7 +20135,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is |
| 20129 | 20135 | defer tracy.end(); |
| 20130 | 20136 | |
| 20131 | 20137 | const pt = sema.pt; |
| 20132 | const mod = pt.zcu; | |
| 20138 | const zcu = pt.zcu; | |
| 20133 | 20139 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 20134 | 20140 | const src = block.nodeOffset(inst_data.src_node); |
| 20135 | 20141 | const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { |
| ... | ... | @@ -20138,21 +20144,21 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is |
| 20138 | 20144 | else => |e| return e, |
| 20139 | 20145 | }; |
| 20140 | 20146 | const init_ty = if (is_byref) ty: { |
| 20141 | const ptr_ty = ty_operand.optEuBaseType(mod); | |
| 20142 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); // validated by a previous instruction | |
| 20143 | if (!ptr_ty.isSlice(mod)) { | |
| 20144 | break :ty ptr_ty.childType(mod); | |
| 20147 | const ptr_ty = ty_operand.optEuBaseType(zcu); | |
| 20148 | assert(ptr_ty.zigTypeTag(zcu) == .Pointer); // validated by a previous instruction | |
| 20149 | if (!ptr_ty.isSlice(zcu)) { | |
| 20150 | break :ty ptr_ty.childType(zcu); | |
| 20145 | 20151 | } |
| 20146 | 20152 | // To make `&.{}` a `[:s]T`, the init should be a `[0:s]T`. |
| 20147 | 20153 | break :ty try pt.arrayType(.{ |
| 20148 | 20154 | .len = 0, |
| 20149 | .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 20150 | .child = ptr_ty.childType(mod).toIntern(), | |
| 20155 | .sentinel = if (ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 20156 | .child = ptr_ty.childType(zcu).toIntern(), | |
| 20151 | 20157 | }); |
| 20152 | 20158 | } else ty_operand; |
| 20153 | const obj_ty = init_ty.optEuBaseType(mod); | |
| 20159 | const obj_ty = init_ty.optEuBaseType(zcu); | |
| 20154 | 20160 | |
| 20155 | const empty_ref = switch (obj_ty.zigTypeTag(mod)) { | |
| 20161 | const empty_ref = switch (obj_ty.zigTypeTag(zcu)) { | |
| 20156 | 20162 | .Struct => try sema.structInitEmpty(block, obj_ty, src, src), |
| 20157 | 20163 | .Array, .Vector => try sema.arrayInitEmpty(block, src, obj_ty), |
| 20158 | 20164 | .Union => return sema.fail(block, src, "union initializer must initialize one field", .{}), |
| ... | ... | @@ -20176,13 +20182,13 @@ fn structInitEmpty( |
| 20176 | 20182 | init_src: LazySrcLoc, |
| 20177 | 20183 | ) CompileError!Air.Inst.Ref { |
| 20178 | 20184 | const pt = sema.pt; |
| 20179 | const mod = pt.zcu; | |
| 20185 | const zcu = pt.zcu; | |
| 20180 | 20186 | const gpa = sema.gpa; |
| 20181 | 20187 | // This logic must be synchronized with that in `zirStructInit`. |
| 20182 | 20188 | try struct_ty.resolveFields(pt); |
| 20183 | 20189 | |
| 20184 | 20190 | // The init values to use for the struct instance. |
| 20185 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod)); | |
| 20191 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(zcu)); | |
| 20186 | 20192 | defer gpa.free(field_inits); |
| 20187 | 20193 | @memset(field_inits, .none); |
| 20188 | 20194 | |
| ... | ... | @@ -20191,10 +20197,10 @@ fn structInitEmpty( |
| 20191 | 20197 | |
| 20192 | 20198 | fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref { |
| 20193 | 20199 | const pt = sema.pt; |
| 20194 | const mod = pt.zcu; | |
| 20195 | const arr_len = obj_ty.arrayLen(mod); | |
| 20200 | const zcu = pt.zcu; | |
| 20201 | const arr_len = obj_ty.arrayLen(zcu); | |
| 20196 | 20202 | if (arr_len != 0) { |
| 20197 | if (obj_ty.zigTypeTag(mod) == .Array) { | |
| 20203 | if (obj_ty.zigTypeTag(zcu) == .Array) { | |
| 20198 | 20204 | return sema.fail(block, src, "expected {d} array elements; found 0", .{arr_len}); |
| 20199 | 20205 | } else { |
| 20200 | 20206 | return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len}); |
| ... | ... | @@ -20235,14 +20241,14 @@ fn unionInit( |
| 20235 | 20241 | field_src: LazySrcLoc, |
| 20236 | 20242 | ) CompileError!Air.Inst.Ref { |
| 20237 | 20243 | const pt = sema.pt; |
| 20238 | const mod = pt.zcu; | |
| 20239 | const ip = &mod.intern_pool; | |
| 20244 | const zcu = pt.zcu; | |
| 20245 | const ip = &zcu.intern_pool; | |
| 20240 | 20246 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src); |
| 20241 | const field_ty = Type.fromInterned(mod.typeToUnion(union_ty).?.field_types.get(ip)[field_index]); | |
| 20247 | const field_ty = Type.fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]); | |
| 20242 | 20248 | const init = try sema.coerce(block, field_ty, uncasted_init, init_src); |
| 20243 | 20249 | |
| 20244 | 20250 | if (try sema.resolveValue(init)) |init_val| { |
| 20245 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | |
| 20251 | const tag_ty = union_ty.unionTagTypeHypothetical(zcu); | |
| 20246 | 20252 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 20247 | 20253 | return Air.internedToRef((try pt.intern(.{ .un = .{ |
| 20248 | 20254 | .ty = union_ty.toIntern(), |
| ... | ... | @@ -20269,8 +20275,8 @@ fn zirStructInit( |
| 20269 | 20275 | const src = block.nodeOffset(inst_data.src_node); |
| 20270 | 20276 | |
| 20271 | 20277 | const pt = sema.pt; |
| 20272 | const mod = pt.zcu; | |
| 20273 | const ip = &mod.intern_pool; | |
| 20278 | const zcu = pt.zcu; | |
| 20279 | const ip = &zcu.intern_pool; | |
| 20274 | 20280 | const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data; |
| 20275 | 20281 | const first_field_type_data = zir_datas[@intFromEnum(first_item.field_type)].pl_node; |
| 20276 | 20282 | const first_field_type_extra = sema.code.extraData(Zir.Inst.FieldType, first_field_type_data.payload_index).data; |
| ... | ... | @@ -20281,26 +20287,26 @@ fn zirStructInit( |
| 20281 | 20287 | }, |
| 20282 | 20288 | else => |e| return e, |
| 20283 | 20289 | }; |
| 20284 | const resolved_ty = result_ty.optEuBaseType(mod); | |
| 20290 | const resolved_ty = result_ty.optEuBaseType(zcu); | |
| 20285 | 20291 | try resolved_ty.resolveLayout(pt); |
| 20286 | 20292 | |
| 20287 | if (resolved_ty.zigTypeTag(mod) == .Struct) { | |
| 20293 | if (resolved_ty.zigTypeTag(zcu) == .Struct) { | |
| 20288 | 20294 | // This logic must be synchronized with that in `zirStructInitEmpty`. |
| 20289 | 20295 | |
| 20290 | 20296 | // Maps field index to field_type index of where it was already initialized. |
| 20291 | 20297 | // For making sure all fields are accounted for and no fields are duplicated. |
| 20292 | const found_fields = try gpa.alloc(Zir.Inst.Index, resolved_ty.structFieldCount(mod)); | |
| 20298 | const found_fields = try gpa.alloc(Zir.Inst.Index, resolved_ty.structFieldCount(zcu)); | |
| 20293 | 20299 | defer gpa.free(found_fields); |
| 20294 | 20300 | |
| 20295 | 20301 | // The init values to use for the struct instance. |
| 20296 | const field_inits = try gpa.alloc(Air.Inst.Ref, resolved_ty.structFieldCount(mod)); | |
| 20302 | const field_inits = try gpa.alloc(Air.Inst.Ref, resolved_ty.structFieldCount(zcu)); | |
| 20297 | 20303 | defer gpa.free(field_inits); |
| 20298 | 20304 | @memset(field_inits, .none); |
| 20299 | 20305 | |
| 20300 | 20306 | var field_i: u32 = 0; |
| 20301 | 20307 | var extra_index = extra.end; |
| 20302 | 20308 | |
| 20303 | const is_packed = resolved_ty.containerLayout(mod) == .@"packed"; | |
| 20309 | const is_packed = resolved_ty.containerLayout(zcu) == .@"packed"; | |
| 20304 | 20310 | while (field_i < extra.data.fields_len) : (field_i += 1) { |
| 20305 | 20311 | const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra_index); |
| 20306 | 20312 | extra_index = item.end; |
| ... | ... | @@ -20314,14 +20320,14 @@ fn zirStructInit( |
| 20314 | 20320 | sema.code.nullTerminatedString(field_type_extra.name_start), |
| 20315 | 20321 | .no_embedded_nulls, |
| 20316 | 20322 | ); |
| 20317 | const field_index = if (resolved_ty.isTuple(mod)) | |
| 20323 | const field_index = if (resolved_ty.isTuple(zcu)) | |
| 20318 | 20324 | try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src) |
| 20319 | 20325 | else |
| 20320 | 20326 | try sema.structFieldIndex(block, resolved_ty, field_name, field_src); |
| 20321 | 20327 | assert(field_inits[field_index] == .none); |
| 20322 | 20328 | found_fields[field_index] = item.data.field_type; |
| 20323 | 20329 | const uncoerced_init = try sema.resolveInst(item.data.init); |
| 20324 | const field_ty = resolved_ty.structFieldType(field_index, mod); | |
| 20330 | const field_ty = resolved_ty.structFieldType(field_index, zcu); | |
| 20325 | 20331 | field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src); |
| 20326 | 20332 | if (!is_packed) { |
| 20327 | 20333 | try resolved_ty.resolveStructFieldInits(pt); |
| ... | ... | @@ -20332,7 +20338,7 @@ fn zirStructInit( |
| 20332 | 20338 | }); |
| 20333 | 20339 | }; |
| 20334 | 20340 | |
| 20335 | if (!init_val.eql(default_value, resolved_ty.structFieldType(field_index, mod), mod)) { | |
| 20341 | if (!init_val.eql(default_value, resolved_ty.structFieldType(field_index, zcu), zcu)) { | |
| 20336 | 20342 | return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index); |
| 20337 | 20343 | } |
| 20338 | 20344 | } |
| ... | ... | @@ -20340,7 +20346,7 @@ fn zirStructInit( |
| 20340 | 20346 | } |
| 20341 | 20347 | |
| 20342 | 20348 | return sema.finishStructInit(block, src, src, field_inits, resolved_ty, result_ty, is_ref); |
| 20343 | } else if (resolved_ty.zigTypeTag(mod) == .Union) { | |
| 20349 | } else if (resolved_ty.zigTypeTag(zcu) == .Union) { | |
| 20344 | 20350 | if (extra.data.fields_len != 1) { |
| 20345 | 20351 | return sema.fail(block, src, "union initialization expects exactly one field", .{}); |
| 20346 | 20352 | } |
| ... | ... | @@ -20357,11 +20363,11 @@ fn zirStructInit( |
| 20357 | 20363 | .no_embedded_nulls, |
| 20358 | 20364 | ); |
| 20359 | 20365 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |
| 20360 | const tag_ty = resolved_ty.unionTagTypeHypothetical(mod); | |
| 20366 | const tag_ty = resolved_ty.unionTagTypeHypothetical(zcu); | |
| 20361 | 20367 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 20362 | const field_ty = Type.fromInterned(mod.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); | |
| 20368 | const field_ty = Type.fromInterned(zcu.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); | |
| 20363 | 20369 | |
| 20364 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | |
| 20370 | if (field_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 20365 | 20371 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 20366 | 20372 | const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{}); |
| 20367 | 20373 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -20388,7 +20394,7 @@ fn zirStructInit( |
| 20388 | 20394 | return sema.addConstantMaybeRef(final_val.toIntern(), is_ref); |
| 20389 | 20395 | } |
| 20390 | 20396 | |
| 20391 | if (try sema.typeRequiresComptime(resolved_ty)) { | |
| 20397 | if (try resolved_ty.comptimeOnlySema(pt)) { | |
| 20392 | 20398 | return sema.failWithNeededComptime(block, field_src, .{ |
| 20393 | 20399 | .needed_comptime_reason = "initializer of comptime only union must be comptime-known", |
| 20394 | 20400 | }); |
| ... | ... | @@ -20397,7 +20403,7 @@ fn zirStructInit( |
| 20397 | 20403 | try sema.validateRuntimeValue(block, field_src, init_inst); |
| 20398 | 20404 | |
| 20399 | 20405 | if (is_ref) { |
| 20400 | const target = mod.getTarget(); | |
| 20406 | const target = zcu.getTarget(); | |
| 20401 | 20407 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20402 | 20408 | .child = result_ty.toIntern(), |
| 20403 | 20409 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| ... | ... | @@ -20429,10 +20435,10 @@ fn finishStructInit( |
| 20429 | 20435 | is_ref: bool, |
| 20430 | 20436 | ) CompileError!Air.Inst.Ref { |
| 20431 | 20437 | const pt = sema.pt; |
| 20432 | const mod = pt.zcu; | |
| 20433 | const ip = &mod.intern_pool; | |
| 20438 | const zcu = pt.zcu; | |
| 20439 | const ip = &zcu.intern_pool; | |
| 20434 | 20440 | |
| 20435 | var root_msg: ?*Module.ErrorMsg = null; | |
| 20441 | var root_msg: ?*Zcu.ErrorMsg = null; | |
| 20436 | 20442 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 20437 | 20443 | |
| 20438 | 20444 | switch (ip.indexToKey(struct_ty.toIntern())) { |
| ... | ... | @@ -20545,7 +20551,7 @@ fn finishStructInit( |
| 20545 | 20551 | return sema.addConstantMaybeRef(final_val.toIntern(), is_ref); |
| 20546 | 20552 | }; |
| 20547 | 20553 | |
| 20548 | if (try sema.typeRequiresComptime(struct_ty)) { | |
| 20554 | if (try struct_ty.comptimeOnlySema(pt)) { | |
| 20549 | 20555 | return sema.failWithNeededComptime(block, block.src(.{ .init_elem = .{ |
| 20550 | 20556 | .init_node_offset = init_src.offset.node_offset.x, |
| 20551 | 20557 | .elem_index = @intCast(runtime_index), |
| ... | ... | @@ -20560,7 +20566,7 @@ fn finishStructInit( |
| 20560 | 20566 | |
| 20561 | 20567 | if (is_ref) { |
| 20562 | 20568 | try struct_ty.resolveLayout(pt); |
| 20563 | const target = mod.getTarget(); | |
| 20569 | const target = zcu.getTarget(); | |
| 20564 | 20570 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20565 | 20571 | .child = result_ty.toIntern(), |
| 20566 | 20572 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| ... | ... | @@ -20612,9 +20618,9 @@ fn structInitAnon( |
| 20612 | 20618 | is_ref: bool, |
| 20613 | 20619 | ) CompileError!Air.Inst.Ref { |
| 20614 | 20620 | const pt = sema.pt; |
| 20615 | const mod = pt.zcu; | |
| 20621 | const zcu = pt.zcu; | |
| 20616 | 20622 | const gpa = sema.gpa; |
| 20617 | const ip = &mod.intern_pool; | |
| 20623 | const ip = &zcu.intern_pool; | |
| 20618 | 20624 | const zir_datas = sema.code.instructions.items(.data); |
| 20619 | 20625 | |
| 20620 | 20626 | const types = try sema.arena.alloc(InternPool.Index, extra_data.fields_len); |
| ... | ... | @@ -20642,11 +20648,11 @@ fn structInitAnon( |
| 20642 | 20648 | }, |
| 20643 | 20649 | }; |
| 20644 | 20650 | |
| 20645 | field_name.* = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls); | |
| 20651 | field_name.* = try zcu.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls); | |
| 20646 | 20652 | |
| 20647 | 20653 | const init = try sema.resolveInst(item.data.init); |
| 20648 | 20654 | field_ty.* = sema.typeOf(init).toIntern(); |
| 20649 | if (Type.fromInterned(field_ty.*).zigTypeTag(mod) == .Opaque) { | |
| 20655 | if (Type.fromInterned(field_ty.*).zigTypeTag(zcu) == .Opaque) { | |
| 20650 | 20656 | const msg = msg: { |
| 20651 | 20657 | const field_src = block.src(.{ .init_elem = .{ |
| 20652 | 20658 | .init_node_offset = src.offset.node_offset.x, |
| ... | ... | @@ -20690,7 +20696,7 @@ fn structInitAnon( |
| 20690 | 20696 | } })); |
| 20691 | 20697 | |
| 20692 | 20698 | if (is_ref) { |
| 20693 | const target = mod.getTarget(); | |
| 20699 | const target = zcu.getTarget(); | |
| 20694 | 20700 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20695 | 20701 | .child = tuple_ty, |
| 20696 | 20702 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| ... | ... | @@ -20740,7 +20746,7 @@ fn zirArrayInit( |
| 20740 | 20746 | is_ref: bool, |
| 20741 | 20747 | ) CompileError!Air.Inst.Ref { |
| 20742 | 20748 | const pt = sema.pt; |
| 20743 | const mod = pt.zcu; | |
| 20749 | const zcu = pt.zcu; | |
| 20744 | 20750 | const gpa = sema.gpa; |
| 20745 | 20751 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 20746 | 20752 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -20756,14 +20762,14 @@ fn zirArrayInit( |
| 20756 | 20762 | }, |
| 20757 | 20763 | else => |e| return e, |
| 20758 | 20764 | }; |
| 20759 | const array_ty = result_ty.optEuBaseType(mod); | |
| 20760 | const is_tuple = array_ty.zigTypeTag(mod) == .Struct; | |
| 20761 | const sentinel_val = array_ty.sentinel(mod); | |
| 20765 | const array_ty = result_ty.optEuBaseType(zcu); | |
| 20766 | const is_tuple = array_ty.zigTypeTag(zcu) == .Struct; | |
| 20767 | const sentinel_val = array_ty.sentinel(zcu); | |
| 20762 | 20768 | |
| 20763 | var root_msg: ?*Module.ErrorMsg = null; | |
| 20769 | var root_msg: ?*Zcu.ErrorMsg = null; | |
| 20764 | 20770 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 20765 | 20771 | |
| 20766 | const final_len = try sema.usizeCast(block, src, array_ty.arrayLenIncludingSentinel(mod)); | |
| 20772 | const final_len = try sema.usizeCast(block, src, array_ty.arrayLenIncludingSentinel(zcu)); | |
| 20767 | 20773 | const resolved_args = try gpa.alloc(Air.Inst.Ref, final_len); |
| 20768 | 20774 | defer gpa.free(resolved_args); |
| 20769 | 20775 | for (resolved_args, 0..) |*dest, i| { |
| ... | ... | @@ -20773,7 +20779,7 @@ fn zirArrayInit( |
| 20773 | 20779 | } }); |
| 20774 | 20780 | // Less inits than needed. |
| 20775 | 20781 | if (i + 2 > args.len) if (is_tuple) { |
| 20776 | const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern(); | |
| 20782 | const default_val = array_ty.structFieldDefaultValue(i, zcu).toIntern(); | |
| 20777 | 20783 | if (default_val == .unreachable_value) { |
| 20778 | 20784 | const template = "missing tuple field with index {d}"; |
| 20779 | 20785 | if (root_msg) |msg| { |
| ... | ... | @@ -20793,12 +20799,12 @@ fn zirArrayInit( |
| 20793 | 20799 | const arg = args[i + 1]; |
| 20794 | 20800 | const resolved_arg = try sema.resolveInst(arg); |
| 20795 | 20801 | const elem_ty = if (is_tuple) |
| 20796 | array_ty.structFieldType(i, mod) | |
| 20802 | array_ty.structFieldType(i, zcu) | |
| 20797 | 20803 | else |
| 20798 | array_ty.elemType2(mod); | |
| 20804 | array_ty.elemType2(zcu); | |
| 20799 | 20805 | dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src); |
| 20800 | 20806 | if (is_tuple) { |
| 20801 | if (array_ty.structFieldIsComptime(i, mod)) | |
| 20807 | if (array_ty.structFieldIsComptime(i, zcu)) | |
| 20802 | 20808 | try array_ty.resolveStructFieldInits(pt); |
| 20803 | 20809 | if (try array_ty.structFieldValueComptime(pt, i)) |field_val| { |
| 20804 | 20810 | const init_val = try sema.resolveValue(dest.*) orelse { |
| ... | ... | @@ -20806,7 +20812,7 @@ fn zirArrayInit( |
| 20806 | 20812 | .needed_comptime_reason = "value stored in comptime field must be comptime-known", |
| 20807 | 20813 | }); |
| 20808 | 20814 | }; |
| 20809 | if (!field_val.eql(init_val, elem_ty, mod)) { | |
| 20815 | if (!field_val.eql(init_val, elem_ty, zcu)) { | |
| 20810 | 20816 | return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i); |
| 20811 | 20817 | } |
| 20812 | 20818 | } |
| ... | ... | @@ -20845,7 +20851,7 @@ fn zirArrayInit( |
| 20845 | 20851 | } })); |
| 20846 | 20852 | |
| 20847 | 20853 | if (is_ref) { |
| 20848 | const target = mod.getTarget(); | |
| 20854 | const target = zcu.getTarget(); | |
| 20849 | 20855 | const alloc_ty = try pt.ptrTypeSema(.{ |
| 20850 | 20856 | .child = result_ty.toIntern(), |
| 20851 | 20857 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| ... | ... | @@ -20856,7 +20862,7 @@ fn zirArrayInit( |
| 20856 | 20862 | if (is_tuple) { |
| 20857 | 20863 | for (resolved_args, 0..) |arg, i| { |
| 20858 | 20864 | const elem_ptr_ty = try pt.ptrTypeSema(.{ |
| 20859 | .child = array_ty.structFieldType(i, mod).toIntern(), | |
| 20865 | .child = array_ty.structFieldType(i, zcu).toIntern(), | |
| 20860 | 20866 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20861 | 20867 | }); |
| 20862 | 20868 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); |
| ... | ... | @@ -20869,7 +20875,7 @@ fn zirArrayInit( |
| 20869 | 20875 | } |
| 20870 | 20876 | |
| 20871 | 20877 | const elem_ptr_ty = try pt.ptrTypeSema(.{ |
| 20872 | .child = array_ty.elemType2(mod).toIntern(), | |
| 20878 | .child = array_ty.elemType2(zcu).toIntern(), | |
| 20873 | 20879 | .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) }, |
| 20874 | 20880 | }); |
| 20875 | 20881 | const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern()); |
| ... | ... | @@ -20906,9 +20912,9 @@ fn arrayInitAnon( |
| 20906 | 20912 | is_ref: bool, |
| 20907 | 20913 | ) CompileError!Air.Inst.Ref { |
| 20908 | 20914 | const pt = sema.pt; |
| 20909 | const mod = pt.zcu; | |
| 20915 | const zcu = pt.zcu; | |
| 20910 | 20916 | const gpa = sema.gpa; |
| 20911 | const ip = &mod.intern_pool; | |
| 20917 | const ip = &zcu.intern_pool; | |
| 20912 | 20918 | |
| 20913 | 20919 | const types = try sema.arena.alloc(InternPool.Index, operands.len); |
| 20914 | 20920 | const values = try sema.arena.alloc(InternPool.Index, operands.len); |
| ... | ... | @@ -20919,7 +20925,7 @@ fn arrayInitAnon( |
| 20919 | 20925 | const operand_src = src; // TODO better source location |
| 20920 | 20926 | const elem = try sema.resolveInst(operand); |
| 20921 | 20927 | types[i] = sema.typeOf(elem).toIntern(); |
| 20922 | if (Type.fromInterned(types[i]).zigTypeTag(mod) == .Opaque) { | |
| 20928 | if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .Opaque) { | |
| 20923 | 20929 | const msg = msg: { |
| 20924 | 20930 | const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 20925 | 20931 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -21003,8 +21009,8 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 21003 | 21009 | |
| 21004 | 21010 | fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 21005 | 21011 | const pt = sema.pt; |
| 21006 | const mod = pt.zcu; | |
| 21007 | const ip = &mod.intern_pool; | |
| 21012 | const zcu = pt.zcu; | |
| 21013 | const ip = &zcu.intern_pool; | |
| 21008 | 21014 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 21009 | 21015 | const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; |
| 21010 | 21016 | const ty_src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -21017,7 +21023,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 21017 | 21023 | error.GenericPoison => return .generic_poison_type, |
| 21018 | 21024 | else => |e| return e, |
| 21019 | 21025 | }; |
| 21020 | const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(mod); | |
| 21026 | const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu); | |
| 21021 | 21027 | const zir_field_name = sema.code.nullTerminatedString(extra.name_start); |
| 21022 | 21028 | const field_name = try ip.getOrPutString(sema.gpa, pt.tid, zir_field_name, .no_embedded_nulls); |
| 21023 | 21029 | return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src); |
| ... | ... | @@ -21032,12 +21038,12 @@ fn fieldType( |
| 21032 | 21038 | ty_src: LazySrcLoc, |
| 21033 | 21039 | ) CompileError!Air.Inst.Ref { |
| 21034 | 21040 | const pt = sema.pt; |
| 21035 | const mod = pt.zcu; | |
| 21036 | const ip = &mod.intern_pool; | |
| 21041 | const zcu = pt.zcu; | |
| 21042 | const ip = &zcu.intern_pool; | |
| 21037 | 21043 | var cur_ty = aggregate_ty; |
| 21038 | 21044 | while (true) { |
| 21039 | 21045 | try cur_ty.resolveFields(pt); |
| 21040 | switch (cur_ty.zigTypeTag(mod)) { | |
| 21046 | switch (cur_ty.zigTypeTag(zcu)) { | |
| 21041 | 21047 | .Struct => switch (ip.indexToKey(cur_ty.toIntern())) { |
| 21042 | 21048 | .anon_struct_type => |anon_struct| { |
| 21043 | 21049 | const field_index = if (anon_struct.names.len == 0) |
| ... | ... | @@ -21056,7 +21062,7 @@ fn fieldType( |
| 21056 | 21062 | else => unreachable, |
| 21057 | 21063 | }, |
| 21058 | 21064 | .Union => { |
| 21059 | const union_obj = mod.typeToUnion(cur_ty).?; | |
| 21065 | const union_obj = zcu.typeToUnion(cur_ty).?; | |
| 21060 | 21066 | const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse |
| 21061 | 21067 | return sema.failWithBadUnionFieldAccess(block, cur_ty, union_obj, field_src, field_name); |
| 21062 | 21068 | const field_ty = union_obj.field_types.get(ip)[field_index]; |
| ... | ... | @@ -21069,7 +21075,7 @@ fn fieldType( |
| 21069 | 21075 | continue; |
| 21070 | 21076 | }, |
| 21071 | 21077 | .ErrorUnion => { |
| 21072 | cur_ty = cur_ty.errorUnionPayload(mod); | |
| 21078 | cur_ty = cur_ty.errorUnionPayload(zcu); | |
| 21073 | 21079 | continue; |
| 21074 | 21080 | }, |
| 21075 | 21081 | else => {}, |
| ... | ... | @@ -21086,8 +21092,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 21086 | 21092 | |
| 21087 | 21093 | fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 21088 | 21094 | const pt = sema.pt; |
| 21089 | const mod = pt.zcu; | |
| 21090 | const ip = &mod.intern_pool; | |
| 21095 | const zcu = pt.zcu; | |
| 21096 | const ip = &zcu.intern_pool; | |
| 21091 | 21097 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 21092 | 21098 | try stack_trace_ty.resolveFields(pt); |
| 21093 | 21099 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| ... | ... | @@ -21115,42 +21121,42 @@ fn zirFrame( |
| 21115 | 21121 | } |
| 21116 | 21122 | |
| 21117 | 21123 | fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 21118 | const pt = sema.pt; | |
| 21124 | const zcu = sema.pt.zcu; | |
| 21119 | 21125 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 21120 | 21126 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 21121 | 21127 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 21122 | if (ty.isNoReturn(pt.zcu)) { | |
| 21123 | return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(pt)}); | |
| 21128 | if (ty.isNoReturn(zcu)) { | |
| 21129 | return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.pt)}); | |
| 21124 | 21130 | } |
| 21125 | const val = try ty.lazyAbiAlignment(pt); | |
| 21131 | const val = try ty.lazyAbiAlignment(sema.pt); | |
| 21126 | 21132 | return Air.internedToRef(val.toIntern()); |
| 21127 | 21133 | } |
| 21128 | 21134 | |
| 21129 | 21135 | fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 21130 | 21136 | const pt = sema.pt; |
| 21131 | const mod = pt.zcu; | |
| 21137 | const zcu = pt.zcu; | |
| 21132 | 21138 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 21133 | 21139 | const src = block.nodeOffset(inst_data.src_node); |
| 21134 | 21140 | const operand = try sema.resolveInst(inst_data.operand); |
| 21135 | 21141 | const operand_ty = sema.typeOf(operand); |
| 21136 | const is_vector = operand_ty.zigTypeTag(mod) == .Vector; | |
| 21137 | const operand_scalar_ty = operand_ty.scalarType(mod); | |
| 21142 | const is_vector = operand_ty.zigTypeTag(zcu) == .Vector; | |
| 21143 | const operand_scalar_ty = operand_ty.scalarType(zcu); | |
| 21138 | 21144 | if (operand_scalar_ty.toIntern() != .bool_type) { |
| 21139 | return sema.fail(block, src, "expected 'bool', found '{}'", .{operand_scalar_ty.zigTypeTag(mod)}); | |
| 21145 | return sema.fail(block, src, "expected 'bool', found '{}'", .{operand_scalar_ty.zigTypeTag(zcu)}); | |
| 21140 | 21146 | } |
| 21141 | 21147 | if (try sema.resolveValue(operand)) |val| { |
| 21142 | 21148 | if (!is_vector) { |
| 21143 | if (val.isUndef(mod)) return pt.undefRef(Type.u1); | |
| 21149 | if (val.isUndef(zcu)) return pt.undefRef(Type.u1); | |
| 21144 | 21150 | if (val.toBool()) return Air.internedToRef((try pt.intValue(Type.u1, 1)).toIntern()); |
| 21145 | 21151 | return Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern()); |
| 21146 | 21152 | } |
| 21147 | const len = operand_ty.vectorLen(mod); | |
| 21153 | const len = operand_ty.vectorLen(zcu); | |
| 21148 | 21154 | const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len }); |
| 21149 | if (val.isUndef(mod)) return pt.undefRef(dest_ty); | |
| 21155 | if (val.isUndef(zcu)) return pt.undefRef(dest_ty); | |
| 21150 | 21156 | const new_elems = try sema.arena.alloc(InternPool.Index, len); |
| 21151 | 21157 | for (new_elems, 0..) |*new_elem, i| { |
| 21152 | 21158 | const old_elem = try val.elemValue(pt, i); |
| 21153 | const new_val = if (old_elem.isUndef(mod)) | |
| 21159 | const new_val = if (old_elem.isUndef(zcu)) | |
| 21154 | 21160 | try pt.undefValue(Type.u1) |
| 21155 | 21161 | else if (old_elem.toBool()) |
| 21156 | 21162 | try pt.intValue(Type.u1, 1) |
| ... | ... | @@ -21166,7 +21172,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 21166 | 21172 | if (!is_vector) { |
| 21167 | 21173 | return block.addUnOp(.int_from_bool, operand); |
| 21168 | 21174 | } |
| 21169 | const len = operand_ty.vectorLen(mod); | |
| 21175 | const len = operand_ty.vectorLen(zcu); | |
| 21170 | 21176 | const dest_ty = try pt.vectorType(.{ .child = .u1_type, .len = len }); |
| 21171 | 21177 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 21172 | 21178 | for (new_elems, 0..) |*new_elem, i| { |
| ... | ... | @@ -21199,16 +21205,16 @@ fn zirAbs( |
| 21199 | 21205 | inst: Zir.Inst.Index, |
| 21200 | 21206 | ) CompileError!Air.Inst.Ref { |
| 21201 | 21207 | const pt = sema.pt; |
| 21202 | const mod = pt.zcu; | |
| 21208 | const zcu = pt.zcu; | |
| 21203 | 21209 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 21204 | 21210 | const operand = try sema.resolveInst(inst_data.operand); |
| 21205 | 21211 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 21206 | 21212 | const operand_ty = sema.typeOf(operand); |
| 21207 | const scalar_ty = operand_ty.scalarType(mod); | |
| 21213 | const scalar_ty = operand_ty.scalarType(zcu); | |
| 21208 | 21214 | |
| 21209 | const result_ty = switch (scalar_ty.zigTypeTag(mod)) { | |
| 21215 | const result_ty = switch (scalar_ty.zigTypeTag(zcu)) { | |
| 21210 | 21216 | .ComptimeFloat, .Float, .ComptimeInt => operand_ty, |
| 21211 | .Int => if (scalar_ty.isSignedInt(mod)) try operand_ty.toUnsigned(pt) else return operand, | |
| 21217 | .Int => if (scalar_ty.isSignedInt(zcu)) try operand_ty.toUnsigned(pt) else return operand, | |
| 21212 | 21218 | else => return sema.fail( |
| 21213 | 21219 | block, |
| 21214 | 21220 | operand_src, |
| ... | ... | @@ -21230,12 +21236,12 @@ fn maybeConstantUnaryMath( |
| 21230 | 21236 | comptime eval: fn (Value, Type, Allocator, Zcu.PerThread) Allocator.Error!Value, |
| 21231 | 21237 | ) CompileError!?Air.Inst.Ref { |
| 21232 | 21238 | const pt = sema.pt; |
| 21233 | const mod = pt.zcu; | |
| 21234 | switch (result_ty.zigTypeTag(mod)) { | |
| 21239 | const zcu = pt.zcu; | |
| 21240 | switch (result_ty.zigTypeTag(zcu)) { | |
| 21235 | 21241 | .Vector => if (try sema.resolveValue(operand)) |val| { |
| 21236 | const scalar_ty = result_ty.scalarType(mod); | |
| 21237 | const vec_len = result_ty.vectorLen(mod); | |
| 21238 | if (val.isUndef(mod)) | |
| 21242 | const scalar_ty = result_ty.scalarType(zcu); | |
| 21243 | const vec_len = result_ty.vectorLen(zcu); | |
| 21244 | if (val.isUndef(zcu)) | |
| 21239 | 21245 | return try pt.undefRef(result_ty); |
| 21240 | 21246 | |
| 21241 | 21247 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| ... | ... | @@ -21249,7 +21255,7 @@ fn maybeConstantUnaryMath( |
| 21249 | 21255 | } }))); |
| 21250 | 21256 | }, |
| 21251 | 21257 | else => if (try sema.resolveValue(operand)) |operand_val| { |
| 21252 | if (operand_val.isUndef(mod)) | |
| 21258 | if (operand_val.isUndef(zcu)) | |
| 21253 | 21259 | return try pt.undefRef(result_ty); |
| 21254 | 21260 | const result_val = try eval(operand_val, result_ty, sema.arena, pt); |
| 21255 | 21261 | return Air.internedToRef(result_val.toIntern()); |
| ... | ... | @@ -21269,14 +21275,14 @@ fn zirUnaryMath( |
| 21269 | 21275 | defer tracy.end(); |
| 21270 | 21276 | |
| 21271 | 21277 | const pt = sema.pt; |
| 21272 | const mod = pt.zcu; | |
| 21278 | const zcu = pt.zcu; | |
| 21273 | 21279 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 21274 | 21280 | const operand = try sema.resolveInst(inst_data.operand); |
| 21275 | 21281 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 21276 | 21282 | const operand_ty = sema.typeOf(operand); |
| 21277 | const scalar_ty = operand_ty.scalarType(mod); | |
| 21283 | const scalar_ty = operand_ty.scalarType(zcu); | |
| 21278 | 21284 | |
| 21279 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 21285 | switch (scalar_ty.zigTypeTag(zcu)) { | |
| 21280 | 21286 | .ComptimeFloat, .Float => {}, |
| 21281 | 21287 | else => return sema.fail( |
| 21282 | 21288 | block, |
| ... | ... | @@ -21359,9 +21365,9 @@ fn zirReify( |
| 21359 | 21365 | inst: Zir.Inst.Index, |
| 21360 | 21366 | ) CompileError!Air.Inst.Ref { |
| 21361 | 21367 | const pt = sema.pt; |
| 21362 | const mod = pt.zcu; | |
| 21368 | const zcu = pt.zcu; | |
| 21363 | 21369 | const gpa = sema.gpa; |
| 21364 | const ip = &mod.intern_pool; | |
| 21370 | const ip = &zcu.intern_pool; | |
| 21365 | 21371 | const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); |
| 21366 | 21372 | const extra = sema.code.extraData(Zir.Inst.Reify, extended.operand).data; |
| 21367 | 21373 | const tracked_inst = try block.trackZir(inst); |
| ... | ... | @@ -21388,7 +21394,7 @@ fn zirReify( |
| 21388 | 21394 | if (try sema.anyUndef(block, operand_src, Value.fromInterned(union_val.val))) { |
| 21389 | 21395 | return sema.failWithUseOfUndef(block, operand_src); |
| 21390 | 21396 | } |
| 21391 | const tag_index = type_info_ty.unionTagFieldIndex(Value.fromInterned(union_val.tag), mod).?; | |
| 21397 | const tag_index = type_info_ty.unionTagFieldIndex(Value.fromInterned(union_val.tag), zcu).?; | |
| 21392 | 21398 | switch (@as(std.builtin.TypeId, @enumFromInt(tag_index))) { |
| 21393 | 21399 | .Type => return .type_type, |
| 21394 | 21400 | .Void => return .void_type, |
| ... | ... | @@ -21411,7 +21417,7 @@ fn zirReify( |
| 21411 | 21417 | struct_type.nameIndex(ip, try ip.getOrPutString(gpa, pt.tid, "bits", .no_embedded_nulls)).?, |
| 21412 | 21418 | ); |
| 21413 | 21419 | |
| 21414 | const signedness = mod.toEnum(std.builtin.Signedness, signedness_val); | |
| 21420 | const signedness = zcu.toEnum(std.builtin.Signedness, signedness_val); | |
| 21415 | 21421 | const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(pt)); |
| 21416 | 21422 | const ty = try pt.intType(signedness, bits); |
| 21417 | 21423 | return Air.internedToRef(ty.toIntern()); |
| ... | ... | @@ -21495,7 +21501,7 @@ fn zirReify( |
| 21495 | 21501 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 21496 | 21502 | } |
| 21497 | 21503 | |
| 21498 | const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(pt, .sema)).?; | |
| 21504 | const alignment_val_int = try alignment_val.toUnsignedIntSema(pt); | |
| 21499 | 21505 | if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) { |
| 21500 | 21506 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int}); |
| 21501 | 21507 | } |
| ... | ... | @@ -21506,14 +21512,14 @@ fn zirReify( |
| 21506 | 21512 | try elem_ty.resolveLayout(pt); |
| 21507 | 21513 | } |
| 21508 | 21514 | |
| 21509 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); | |
| 21515 | const ptr_size = zcu.toEnum(std.builtin.Type.Pointer.Size, size_val); | |
| 21510 | 21516 | |
| 21511 | 21517 | const actual_sentinel: InternPool.Index = s: { |
| 21512 | if (!sentinel_val.isNull(mod)) { | |
| 21518 | if (!sentinel_val.isNull(zcu)) { | |
| 21513 | 21519 | if (ptr_size == .One or ptr_size == .C) { |
| 21514 | 21520 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); |
| 21515 | 21521 | } |
| 21516 | const sentinel_ptr_val = sentinel_val.optionalValue(mod).?; | |
| 21522 | const sentinel_ptr_val = sentinel_val.optionalValue(zcu).?; | |
| 21517 | 21523 | const ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 21518 | 21524 | const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; |
| 21519 | 21525 | break :s sent_val.toIntern(); |
| ... | ... | @@ -21521,13 +21527,13 @@ fn zirReify( |
| 21521 | 21527 | break :s .none; |
| 21522 | 21528 | }; |
| 21523 | 21529 | |
| 21524 | if (elem_ty.zigTypeTag(mod) == .NoReturn) { | |
| 21530 | if (elem_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 21525 | 21531 | return sema.fail(block, src, "pointer to noreturn not allowed", .{}); |
| 21526 | } else if (elem_ty.zigTypeTag(mod) == .Fn) { | |
| 21532 | } else if (elem_ty.zigTypeTag(zcu) == .Fn) { | |
| 21527 | 21533 | if (ptr_size != .One) { |
| 21528 | 21534 | return sema.fail(block, src, "function pointers must be single pointers", .{}); |
| 21529 | 21535 | } |
| 21530 | } else if (ptr_size == .Many and elem_ty.zigTypeTag(mod) == .Opaque) { | |
| 21536 | } else if (ptr_size == .Many and elem_ty.zigTypeTag(zcu) == .Opaque) { | |
| 21531 | 21537 | return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{}); |
| 21532 | 21538 | } else if (ptr_size == .C) { |
| 21533 | 21539 | if (!try sema.validateExternType(elem_ty, .other)) { |
| ... | ... | @@ -21542,7 +21548,7 @@ fn zirReify( |
| 21542 | 21548 | }; |
| 21543 | 21549 | return sema.failWithOwnedErrorMsg(block, msg); |
| 21544 | 21550 | } |
| 21545 | if (elem_ty.zigTypeTag(mod) == .Opaque) { | |
| 21551 | if (elem_ty.zigTypeTag(zcu) == .Opaque) { | |
| 21546 | 21552 | return sema.fail(block, src, "C pointers cannot point to opaque types", .{}); |
| 21547 | 21553 | } |
| 21548 | 21554 | } |
| ... | ... | @@ -21555,7 +21561,7 @@ fn zirReify( |
| 21555 | 21561 | .is_const = is_const_val.toBool(), |
| 21556 | 21562 | .is_volatile = is_volatile_val.toBool(), |
| 21557 | 21563 | .alignment = abi_align, |
| 21558 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), | |
| 21564 | .address_space = zcu.toEnum(std.builtin.AddressSpace, address_space_val), | |
| 21559 | 21565 | .is_allowzero = is_allowzero_val.toBool(), |
| 21560 | 21566 | }, |
| 21561 | 21567 | }); |
| ... | ... | @@ -21578,7 +21584,7 @@ fn zirReify( |
| 21578 | 21584 | |
| 21579 | 21585 | const len = try len_val.toUnsignedIntSema(pt); |
| 21580 | 21586 | const child_ty = child_val.toType(); |
| 21581 | const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: { | |
| 21587 | const sentinel = if (sentinel_val.optionalValue(zcu)) |p| blk: { | |
| 21582 | 21588 | const ptr_ty = try pt.singleMutPtrType(child_ty); |
| 21583 | 21589 | break :blk (try sema.pointerDeref(block, src, p, ptr_ty)).?; |
| 21584 | 21590 | } else null; |
| ... | ... | @@ -21616,7 +21622,7 @@ fn zirReify( |
| 21616 | 21622 | const error_set_ty = error_set_val.toType(); |
| 21617 | 21623 | const payload_ty = payload_val.toType(); |
| 21618 | 21624 | |
| 21619 | if (error_set_ty.zigTypeTag(mod) != .ErrorSet) { | |
| 21625 | if (error_set_ty.zigTypeTag(zcu) != .ErrorSet) { | |
| 21620 | 21626 | return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{}); |
| 21621 | 21627 | } |
| 21622 | 21628 | |
| ... | ... | @@ -21624,14 +21630,14 @@ fn zirReify( |
| 21624 | 21630 | return Air.internedToRef(ty.toIntern()); |
| 21625 | 21631 | }, |
| 21626 | 21632 | .ErrorSet => { |
| 21627 | const payload_val = Value.fromInterned(union_val.val).optionalValue(mod) orelse | |
| 21633 | const payload_val = Value.fromInterned(union_val.val).optionalValue(zcu) orelse | |
| 21628 | 21634 | return Air.internedToRef(Type.anyerror.toIntern()); |
| 21629 | 21635 | |
| 21630 | 21636 | const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{ |
| 21631 | 21637 | .needed_comptime_reason = "error set contents must be comptime-known", |
| 21632 | 21638 | }); |
| 21633 | 21639 | |
| 21634 | const len = try sema.usizeCast(block, src, names_val.typeOf(mod).arrayLen(mod)); | |
| 21640 | const len = try sema.usizeCast(block, src, names_val.typeOf(zcu).arrayLen(zcu)); | |
| 21635 | 21641 | var names: InferredErrorSet.NameMap = .{}; |
| 21636 | 21642 | try names.ensureUnusedCapacity(sema.arena, len); |
| 21637 | 21643 | for (0..len) |i| { |
| ... | ... | @@ -21680,14 +21686,14 @@ fn zirReify( |
| 21680 | 21686 | try ip.getOrPutString(gpa, pt.tid, "is_tuple", .no_embedded_nulls), |
| 21681 | 21687 | ).?); |
| 21682 | 21688 | |
| 21683 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); | |
| 21689 | const layout = zcu.toEnum(std.builtin.Type.ContainerLayout, layout_val); | |
| 21684 | 21690 | |
| 21685 | 21691 | // Decls |
| 21686 | 21692 | if (try decls_val.sliceLen(pt) > 0) { |
| 21687 | 21693 | return sema.fail(block, src, "reified structs must have no decls", .{}); |
| 21688 | 21694 | } |
| 21689 | 21695 | |
| 21690 | if (layout != .@"packed" and !backing_integer_val.isNull(mod)) { | |
| 21696 | if (layout != .@"packed" and !backing_integer_val.isNull(zcu)) { | |
| 21691 | 21697 | return sema.fail(block, src, "non-packed struct does not support backing integer type", .{}); |
| 21692 | 21698 | } |
| 21693 | 21699 | |
| ... | ... | @@ -21762,8 +21768,8 @@ fn zirReify( |
| 21762 | 21768 | const new_namespace_index = try pt.createNamespace(.{ |
| 21763 | 21769 | .parent = block.namespace.toOptional(), |
| 21764 | 21770 | .owner_type = wip_ty.index, |
| 21765 | .file_scope = block.getFileScopeIndex(mod), | |
| 21766 | .generation = mod.generation, | |
| 21771 | .file_scope = block.getFileScopeIndex(zcu), | |
| 21772 | .generation = zcu.generation, | |
| 21767 | 21773 | }); |
| 21768 | 21774 | |
| 21769 | 21775 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -21791,7 +21797,7 @@ fn zirReify( |
| 21791 | 21797 | if (try decls_val.sliceLen(pt) > 0) { |
| 21792 | 21798 | return sema.fail(block, src, "reified unions must have no decls", .{}); |
| 21793 | 21799 | } |
| 21794 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); | |
| 21800 | const layout = zcu.toEnum(std.builtin.Type.ContainerLayout, layout_val); | |
| 21795 | 21801 | |
| 21796 | 21802 | const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ |
| 21797 | 21803 | .needed_comptime_reason = "union fields must be comptime-known", |
| ... | ... | @@ -21828,19 +21834,19 @@ fn zirReify( |
| 21828 | 21834 | } |
| 21829 | 21835 | |
| 21830 | 21836 | const is_var_args = is_var_args_val.toBool(); |
| 21831 | const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val); | |
| 21837 | const cc = zcu.toEnum(std.builtin.CallingConvention, calling_convention_val); | |
| 21832 | 21838 | if (is_var_args) { |
| 21833 | 21839 | try sema.checkCallConvSupportsVarArgs(block, src, cc); |
| 21834 | 21840 | } |
| 21835 | 21841 | |
| 21836 | const return_type = return_type_val.optionalValue(mod) orelse | |
| 21842 | const return_type = return_type_val.optionalValue(zcu) orelse | |
| 21837 | 21843 | return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{}); |
| 21838 | 21844 | |
| 21839 | 21845 | const params_val = try sema.derefSliceAsArray(block, operand_src, params_slice_val, .{ |
| 21840 | 21846 | .needed_comptime_reason = "function parameters must be comptime-known", |
| 21841 | 21847 | }); |
| 21842 | 21848 | |
| 21843 | const args_len = try sema.usizeCast(block, src, params_val.typeOf(mod).arrayLen(mod)); | |
| 21849 | const args_len = try sema.usizeCast(block, src, params_val.typeOf(zcu).arrayLen(zcu)); | |
| 21844 | 21850 | const param_types = try sema.arena.alloc(InternPool.Index, args_len); |
| 21845 | 21851 | |
| 21846 | 21852 | var noalias_bits: u32 = 0; |
| ... | ... | @@ -21864,12 +21870,12 @@ fn zirReify( |
| 21864 | 21870 | return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{}); |
| 21865 | 21871 | } |
| 21866 | 21872 | |
| 21867 | const param_type_val = opt_param_type_val.optionalValue(mod) orelse | |
| 21873 | const param_type_val = opt_param_type_val.optionalValue(zcu) orelse | |
| 21868 | 21874 | return sema.fail(block, src, "Type.Fn.Param.type must be non-null for @Type", .{}); |
| 21869 | 21875 | param_type.* = param_type_val.toIntern(); |
| 21870 | 21876 | |
| 21871 | 21877 | if (param_is_noalias_val.toBool()) { |
| 21872 | if (!Type.fromInterned(param_type.*).isPtrAtRuntime(mod)) { | |
| 21878 | if (!Type.fromInterned(param_type.*).isPtrAtRuntime(zcu)) { | |
| 21873 | 21879 | return sema.fail(block, src, "non-pointer parameter declared noalias", .{}); |
| 21874 | 21880 | } |
| 21875 | 21881 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, i) orelse |
| ... | ... | @@ -21901,13 +21907,13 @@ fn reifyEnum( |
| 21901 | 21907 | name_strategy: Zir.Inst.NameStrategy, |
| 21902 | 21908 | ) CompileError!Air.Inst.Ref { |
| 21903 | 21909 | const pt = sema.pt; |
| 21904 | const mod = pt.zcu; | |
| 21910 | const zcu = pt.zcu; | |
| 21905 | 21911 | const gpa = sema.gpa; |
| 21906 | const ip = &mod.intern_pool; | |
| 21912 | const ip = &zcu.intern_pool; | |
| 21907 | 21913 | |
| 21908 | 21914 | // This logic must stay in sync with the structure of `std.builtin.Type.Enum` - search for `fieldValue`. |
| 21909 | 21915 | |
| 21910 | const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod)); | |
| 21916 | const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu)); | |
| 21911 | 21917 | |
| 21912 | 21918 | // The validation work here is non-trivial, and it's possible the type already exists. |
| 21913 | 21919 | // So in this first pass, let's just construct a hash to optimize for this case. If the |
| ... | ... | @@ -21957,7 +21963,7 @@ fn reifyEnum( |
| 21957 | 21963 | var done = false; |
| 21958 | 21964 | errdefer if (!done) wip_ty.cancel(ip, pt.tid); |
| 21959 | 21965 | |
| 21960 | if (tag_ty.zigTypeTag(mod) != .Int) { | |
| 21966 | if (tag_ty.zigTypeTag(zcu) != .Int) { | |
| 21961 | 21967 | return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{}); |
| 21962 | 21968 | } |
| 21963 | 21969 | |
| ... | ... | @@ -21972,8 +21978,8 @@ fn reifyEnum( |
| 21972 | 21978 | const new_namespace_index = try pt.createNamespace(.{ |
| 21973 | 21979 | .parent = block.namespace.toOptional(), |
| 21974 | 21980 | .owner_type = wip_ty.index, |
| 21975 | .file_scope = block.getFileScopeIndex(mod), | |
| 21976 | .generation = mod.generation, | |
| 21981 | .file_scope = block.getFileScopeIndex(zcu), | |
| 21982 | .generation = zcu.generation, | |
| 21977 | 21983 | }); |
| 21978 | 21984 | |
| 21979 | 21985 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); |
| ... | ... | @@ -22023,14 +22029,14 @@ fn reifyEnum( |
| 22023 | 22029 | } |
| 22024 | 22030 | } |
| 22025 | 22031 | |
| 22026 | if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(pt)) { | |
| 22032 | if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(zcu)) { | |
| 22027 | 22033 | return sema.fail(block, src, "non-exhaustive enum specified every value", .{}); |
| 22028 | 22034 | } |
| 22029 | 22035 | |
| 22030 | 22036 | codegen_type: { |
| 22031 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 22037 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 22032 | 22038 | if (block.ownerModule().strip) break :codegen_type; |
| 22033 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22039 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22034 | 22040 | } |
| 22035 | 22041 | return Air.internedToRef(wip_ty.index); |
| 22036 | 22042 | } |
| ... | ... | @@ -22046,13 +22052,13 @@ fn reifyUnion( |
| 22046 | 22052 | name_strategy: Zir.Inst.NameStrategy, |
| 22047 | 22053 | ) CompileError!Air.Inst.Ref { |
| 22048 | 22054 | const pt = sema.pt; |
| 22049 | const mod = pt.zcu; | |
| 22055 | const zcu = pt.zcu; | |
| 22050 | 22056 | const gpa = sema.gpa; |
| 22051 | const ip = &mod.intern_pool; | |
| 22057 | const ip = &zcu.intern_pool; | |
| 22052 | 22058 | |
| 22053 | 22059 | // This logic must stay in sync with the structure of `std.builtin.Type.Union` - search for `fieldValue`. |
| 22054 | 22060 | |
| 22055 | const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod)); | |
| 22061 | const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu)); | |
| 22056 | 22062 | |
| 22057 | 22063 | // The validation work here is non-trivial, and it's possible the type already exists. |
| 22058 | 22064 | // So in this first pass, let's just construct a hash to optimize for this case. If the |
| ... | ... | @@ -22084,7 +22090,7 @@ fn reifyUnion( |
| 22084 | 22090 | field_align_val.toIntern(), |
| 22085 | 22091 | }); |
| 22086 | 22092 | |
| 22087 | if (field_align_val.toUnsignedInt(pt) != 0) { | |
| 22093 | if (field_align_val.toUnsignedInt(zcu) != 0) { | |
| 22088 | 22094 | any_aligns = true; |
| 22089 | 22095 | } |
| 22090 | 22096 | } |
| ... | ... | @@ -22095,7 +22101,7 @@ fn reifyUnion( |
| 22095 | 22101 | .flags = .{ |
| 22096 | 22102 | .layout = layout, |
| 22097 | 22103 | .status = .none, |
| 22098 | .runtime_tag = if (opt_tag_type_val.optionalValue(mod) != null) | |
| 22104 | .runtime_tag = if (opt_tag_type_val.optionalValue(zcu) != null) | |
| 22099 | 22105 | .tagged |
| 22100 | 22106 | else if (layout != .auto) |
| 22101 | 22107 | .none |
| ... | ... | @@ -22139,7 +22145,7 @@ fn reifyUnion( |
| 22139 | 22145 | const field_types = try sema.arena.alloc(InternPool.Index, fields_len); |
| 22140 | 22146 | const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; |
| 22141 | 22147 | |
| 22142 | const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(mod)) |tag_type_val| tag_ty: { | |
| 22148 | const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: { | |
| 22143 | 22149 | switch (ip.indexToKey(tag_type_val.toIntern())) { |
| 22144 | 22150 | .enum_type => {}, |
| 22145 | 22151 | else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}), |
| ... | ... | @@ -22147,7 +22153,7 @@ fn reifyUnion( |
| 22147 | 22153 | const enum_tag_ty = tag_type_val.toType(); |
| 22148 | 22154 | |
| 22149 | 22155 | // We simply track which fields of the tag type have been seen. |
| 22150 | const tag_ty_fields_len = enum_tag_ty.enumFieldCount(mod); | |
| 22156 | const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu); | |
| 22151 | 22157 | var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); |
| 22152 | 22158 | |
| 22153 | 22159 | for (field_types, 0..) |*field_ty, field_idx| { |
| ... | ... | @@ -22159,7 +22165,7 @@ fn reifyUnion( |
| 22159 | 22165 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| 22160 | 22166 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| 22161 | 22167 | |
| 22162 | const enum_index = enum_tag_ty.enumFieldIndex(field_name, mod) orelse { | |
| 22168 | const enum_index = enum_tag_ty.enumFieldIndex(field_name, zcu) orelse { | |
| 22163 | 22169 | // TODO: better source location |
| 22164 | 22170 | return sema.fail(block, src, "no field named '{}' in enum '{}'", .{ |
| 22165 | 22171 | field_name.fmt(ip), enum_tag_ty.fmt(pt), |
| ... | ... | @@ -22187,7 +22193,7 @@ fn reifyUnion( |
| 22187 | 22193 | errdefer msg.destroy(gpa); |
| 22188 | 22194 | var it = seen_tags.iterator(.{ .kind = .unset }); |
| 22189 | 22195 | while (it.next()) |enum_index| { |
| 22190 | const field_name = enum_tag_ty.enumFieldName(enum_index, mod); | |
| 22196 | const field_name = enum_tag_ty.enumFieldName(enum_index, zcu); | |
| 22191 | 22197 | try sema.addFieldErrNote(enum_tag_ty, enum_index, msg, "field '{}' missing, declared here", .{ |
| 22192 | 22198 | field_name.fmt(ip), |
| 22193 | 22199 | }); |
| ... | ... | @@ -22234,7 +22240,7 @@ fn reifyUnion( |
| 22234 | 22240 | |
| 22235 | 22241 | for (field_types) |field_ty_ip| { |
| 22236 | 22242 | const field_ty = Type.fromInterned(field_ty_ip); |
| 22237 | if (field_ty.zigTypeTag(mod) == .Opaque) { | |
| 22243 | if (field_ty.zigTypeTag(zcu) == .Opaque) { | |
| 22238 | 22244 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22239 | 22245 | const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| 22240 | 22246 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -22277,17 +22283,17 @@ fn reifyUnion( |
| 22277 | 22283 | const new_namespace_index = try pt.createNamespace(.{ |
| 22278 | 22284 | .parent = block.namespace.toOptional(), |
| 22279 | 22285 | .owner_type = wip_ty.index, |
| 22280 | .file_scope = block.getFileScopeIndex(mod), | |
| 22281 | .generation = mod.generation, | |
| 22286 | .file_scope = block.getFileScopeIndex(zcu), | |
| 22287 | .generation = zcu.generation, | |
| 22282 | 22288 | }); |
| 22283 | 22289 | |
| 22284 | 22290 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); |
| 22285 | 22291 | |
| 22286 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 22292 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 22287 | 22293 | codegen_type: { |
| 22288 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 22294 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 22289 | 22295 | if (block.ownerModule().strip) break :codegen_type; |
| 22290 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22296 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22291 | 22297 | } |
| 22292 | 22298 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 22293 | 22299 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -22306,13 +22312,13 @@ fn reifyStruct( |
| 22306 | 22312 | is_tuple: bool, |
| 22307 | 22313 | ) CompileError!Air.Inst.Ref { |
| 22308 | 22314 | const pt = sema.pt; |
| 22309 | const mod = pt.zcu; | |
| 22315 | const zcu = pt.zcu; | |
| 22310 | 22316 | const gpa = sema.gpa; |
| 22311 | const ip = &mod.intern_pool; | |
| 22317 | const ip = &zcu.intern_pool; | |
| 22312 | 22318 | |
| 22313 | 22319 | // This logic must stay in sync with the structure of `std.builtin.Type.Struct` - search for `fieldValue`. |
| 22314 | 22320 | |
| 22315 | const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod)); | |
| 22321 | const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu)); | |
| 22316 | 22322 | |
| 22317 | 22323 | // The validation work here is non-trivial, and it's possible the type already exists. |
| 22318 | 22324 | // So in this first pass, let's just construct a hash to optimize for this case. If the |
| ... | ... | @@ -22343,7 +22349,7 @@ fn reifyStruct( |
| 22343 | 22349 | .needed_comptime_reason = "struct field name must be comptime-known", |
| 22344 | 22350 | }); |
| 22345 | 22351 | const field_is_comptime = field_is_comptime_val.toBool(); |
| 22346 | const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(mod)) |ptr_val| d: { | |
| 22352 | const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(zcu)) |ptr_val| d: { | |
| 22347 | 22353 | const ptr_ty = try pt.singleConstPtrType(field_type_val.toType()); |
| 22348 | 22354 | // We need to do this deref here, so we won't check for this error case later on. |
| 22349 | 22355 | const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime( |
| ... | ... | @@ -22365,7 +22371,7 @@ fn reifyStruct( |
| 22365 | 22371 | |
| 22366 | 22372 | if (field_is_comptime) any_comptime_fields = true; |
| 22367 | 22373 | if (field_default_value != .none) any_default_inits = true; |
| 22368 | switch (try field_alignment_val.orderAgainstZeroAdvanced(pt, .sema)) { | |
| 22374 | switch (try field_alignment_val.orderAgainstZeroSema(pt)) { | |
| 22369 | 22375 | .eq => {}, |
| 22370 | 22376 | .gt => any_aligned_fields = true, |
| 22371 | 22377 | .lt => unreachable, |
| ... | ... | @@ -22475,7 +22481,7 @@ fn reifyStruct( |
| 22475 | 22481 | |
| 22476 | 22482 | const field_default: InternPool.Index = d: { |
| 22477 | 22483 | if (!any_default_inits) break :d .none; |
| 22478 | const ptr_val = field_default_value_val.optionalValue(mod) orelse break :d .none; | |
| 22484 | const ptr_val = field_default_value_val.optionalValue(zcu) orelse break :d .none; | |
| 22479 | 22485 | const ptr_ty = try pt.singleConstPtrType(field_ty); |
| 22480 | 22486 | // Asserted comptime-dereferencable above. |
| 22481 | 22487 | const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?; |
| ... | ... | @@ -22492,7 +22498,7 @@ fn reifyStruct( |
| 22492 | 22498 | struct_type.field_inits.get(ip)[field_idx] = field_default; |
| 22493 | 22499 | } |
| 22494 | 22500 | |
| 22495 | if (field_ty.zigTypeTag(mod) == .Opaque) { | |
| 22501 | if (field_ty.zigTypeTag(zcu) == .Opaque) { | |
| 22496 | 22502 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22497 | 22503 | const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 22498 | 22504 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -22501,7 +22507,7 @@ fn reifyStruct( |
| 22501 | 22507 | break :msg msg; |
| 22502 | 22508 | }); |
| 22503 | 22509 | } |
| 22504 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | |
| 22510 | if (field_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 22505 | 22511 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22506 | 22512 | const msg = try sema.errMsg(src, "struct fields cannot be 'noreturn'", .{}); |
| 22507 | 22513 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -22545,10 +22551,10 @@ fn reifyStruct( |
| 22545 | 22551 | }, |
| 22546 | 22552 | else => return err, |
| 22547 | 22553 | }; |
| 22548 | fields_bit_sum += field_ty.bitSize(pt); | |
| 22554 | fields_bit_sum += field_ty.bitSize(zcu); | |
| 22549 | 22555 | } |
| 22550 | 22556 | |
| 22551 | if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| { | |
| 22557 | if (opt_backing_int_val.optionalValue(zcu)) |backing_int_val| { | |
| 22552 | 22558 | const backing_int_ty = backing_int_val.toType(); |
| 22553 | 22559 | try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum); |
| 22554 | 22560 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); |
| ... | ... | @@ -22561,17 +22567,17 @@ fn reifyStruct( |
| 22561 | 22567 | const new_namespace_index = try pt.createNamespace(.{ |
| 22562 | 22568 | .parent = block.namespace.toOptional(), |
| 22563 | 22569 | .owner_type = wip_ty.index, |
| 22564 | .file_scope = block.getFileScopeIndex(mod), | |
| 22565 | .generation = mod.generation, | |
| 22570 | .file_scope = block.getFileScopeIndex(zcu), | |
| 22571 | .generation = zcu.generation, | |
| 22566 | 22572 | }); |
| 22567 | 22573 | |
| 22568 | 22574 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); |
| 22569 | 22575 | |
| 22570 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 22576 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | |
| 22571 | 22577 | codegen_type: { |
| 22572 | if (mod.comp.config.use_llvm) break :codegen_type; | |
| 22578 | if (zcu.comp.config.use_llvm) break :codegen_type; | |
| 22573 | 22579 | if (block.ownerModule().strip) break :codegen_type; |
| 22574 | try mod.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22580 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | |
| 22575 | 22581 | } |
| 22576 | 22582 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 22577 | 22583 | try sema.addTypeReferenceEntry(src, wip_ty.index); |
| ... | ... | @@ -22649,8 +22655,8 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) |
| 22649 | 22655 | |
| 22650 | 22656 | fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22651 | 22657 | const pt = sema.pt; |
| 22652 | const mod = pt.zcu; | |
| 22653 | const ip = &mod.intern_pool; | |
| 22658 | const zcu = pt.zcu; | |
| 22659 | const ip = &zcu.intern_pool; | |
| 22654 | 22660 | |
| 22655 | 22661 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 22656 | 22662 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | ... | @@ -22674,7 +22680,7 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 22674 | 22680 | |
| 22675 | 22681 | fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22676 | 22682 | const pt = sema.pt; |
| 22677 | const mod = pt.zcu; | |
| 22683 | const zcu = pt.zcu; | |
| 22678 | 22684 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 22679 | 22685 | const src = block.nodeOffset(inst_data.src_node); |
| 22680 | 22686 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | ... | @@ -22684,10 +22690,10 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22684 | 22690 | const operand_ty = sema.typeOf(operand); |
| 22685 | 22691 | |
| 22686 | 22692 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src); |
| 22687 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; | |
| 22693 | const is_vector = dest_ty.zigTypeTag(zcu) == .Vector; | |
| 22688 | 22694 | |
| 22689 | const dest_scalar_ty = dest_ty.scalarType(mod); | |
| 22690 | const operand_scalar_ty = operand_ty.scalarType(mod); | |
| 22695 | const dest_scalar_ty = dest_ty.scalarType(zcu); | |
| 22696 | const operand_scalar_ty = operand_ty.scalarType(zcu); | |
| 22691 | 22697 | |
| 22692 | 22698 | _ = try sema.checkIntType(block, src, dest_scalar_ty); |
| 22693 | 22699 | try sema.checkFloatType(block, operand_src, operand_scalar_ty); |
| ... | ... | @@ -22695,14 +22701,14 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22695 | 22701 | if (try sema.resolveValue(operand)) |operand_val| { |
| 22696 | 22702 | const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, .truncate); |
| 22697 | 22703 | return Air.internedToRef(result_val.toIntern()); |
| 22698 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 22704 | } else if (dest_scalar_ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 22699 | 22705 | return sema.failWithNeededComptime(block, operand_src, .{ |
| 22700 | 22706 | .needed_comptime_reason = "value being casted to 'comptime_int' must be comptime-known", |
| 22701 | 22707 | }); |
| 22702 | 22708 | } |
| 22703 | 22709 | |
| 22704 | 22710 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 22705 | if (dest_scalar_ty.intInfo(mod).bits == 0) { | |
| 22711 | if (dest_scalar_ty.intInfo(zcu).bits == 0) { | |
| 22706 | 22712 | if (!is_vector) { |
| 22707 | 22713 | if (block.wantSafety()) { |
| 22708 | 22714 | const ok = try block.addBinOp(if (block.float_mode == .optimized) .cmp_eq_optimized else .cmp_eq, operand, Air.internedToRef((try pt.floatValue(operand_ty, 0.0)).toIntern())); |
| ... | ... | @@ -22711,7 +22717,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22711 | 22717 | return Air.internedToRef((try pt.intValue(dest_ty, 0)).toIntern()); |
| 22712 | 22718 | } |
| 22713 | 22719 | if (block.wantSafety()) { |
| 22714 | const len = dest_ty.vectorLen(mod); | |
| 22720 | const len = dest_ty.vectorLen(zcu); | |
| 22715 | 22721 | for (0..len) |i| { |
| 22716 | 22722 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22717 | 22723 | const elem_ref = try block.addBinOp(.array_elem_val, operand, idx_ref); |
| ... | ... | @@ -22736,7 +22742,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22736 | 22742 | } |
| 22737 | 22743 | return result; |
| 22738 | 22744 | } |
| 22739 | const len = dest_ty.vectorLen(mod); | |
| 22745 | const len = dest_ty.vectorLen(zcu); | |
| 22740 | 22746 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 22741 | 22747 | for (new_elems, 0..) |*new_elem, i| { |
| 22742 | 22748 | const idx_ref = try pt.intRef(Type.usize, i); |
| ... | ... | @@ -22757,7 +22763,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22757 | 22763 | |
| 22758 | 22764 | fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22759 | 22765 | const pt = sema.pt; |
| 22760 | const mod = pt.zcu; | |
| 22766 | const zcu = pt.zcu; | |
| 22761 | 22767 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 22762 | 22768 | const src = block.nodeOffset(inst_data.src_node); |
| 22763 | 22769 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | ... | @@ -22767,10 +22773,10 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22767 | 22773 | const operand_ty = sema.typeOf(operand); |
| 22768 | 22774 | |
| 22769 | 22775 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src); |
| 22770 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; | |
| 22776 | const is_vector = dest_ty.zigTypeTag(zcu) == .Vector; | |
| 22771 | 22777 | |
| 22772 | const dest_scalar_ty = dest_ty.scalarType(mod); | |
| 22773 | const operand_scalar_ty = operand_ty.scalarType(mod); | |
| 22778 | const dest_scalar_ty = dest_ty.scalarType(zcu); | |
| 22779 | const operand_scalar_ty = operand_ty.scalarType(zcu); | |
| 22774 | 22780 | |
| 22775 | 22781 | try sema.checkFloatType(block, src, dest_scalar_ty); |
| 22776 | 22782 | _ = try sema.checkIntType(block, operand_src, operand_scalar_ty); |
| ... | ... | @@ -22778,7 +22784,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22778 | 22784 | if (try sema.resolveValue(operand)) |operand_val| { |
| 22779 | 22785 | const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, pt, .sema); |
| 22780 | 22786 | return Air.internedToRef(result_val.toIntern()); |
| 22781 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) { | |
| 22787 | } else if (dest_scalar_ty.zigTypeTag(zcu) == .ComptimeFloat) { | |
| 22782 | 22788 | return sema.failWithNeededComptime(block, operand_src, .{ |
| 22783 | 22789 | .needed_comptime_reason = "value being casted to 'comptime_float' must be comptime-known", |
| 22784 | 22790 | }); |
| ... | ... | @@ -22788,7 +22794,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22788 | 22794 | if (!is_vector) { |
| 22789 | 22795 | return block.addTyOp(.float_from_int, dest_ty, operand); |
| 22790 | 22796 | } |
| 22791 | const len = operand_ty.vectorLen(mod); | |
| 22797 | const len = operand_ty.vectorLen(zcu); | |
| 22792 | 22798 | const new_elems = try sema.arena.alloc(Air.Inst.Ref, len); |
| 22793 | 22799 | for (new_elems, 0..) |*new_elem, i| { |
| 22794 | 22800 | const idx_ref = try pt.intRef(Type.usize, i); |
| ... | ... | @@ -22800,7 +22806,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 22800 | 22806 | |
| 22801 | 22807 | fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 22802 | 22808 | const pt = sema.pt; |
| 22803 | const mod = pt.zcu; | |
| 22809 | const zcu = pt.zcu; | |
| 22804 | 22810 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 22805 | 22811 | const src = block.nodeOffset(inst_data.src_node); |
| 22806 | 22812 | |
| ... | ... | @@ -22813,21 +22819,21 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22813 | 22819 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrFromInt"); |
| 22814 | 22820 | try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, uncoerced_operand_ty, src, operand_src); |
| 22815 | 22821 | |
| 22816 | const is_vector = dest_ty.zigTypeTag(mod) == .Vector; | |
| 22822 | const is_vector = dest_ty.zigTypeTag(zcu) == .Vector; | |
| 22817 | 22823 | const operand_ty = if (is_vector) operand_ty: { |
| 22818 | const len = dest_ty.vectorLen(mod); | |
| 22824 | const len = dest_ty.vectorLen(zcu); | |
| 22819 | 22825 | break :operand_ty try pt.vectorType(.{ .child = .usize_type, .len = len }); |
| 22820 | 22826 | } else Type.usize; |
| 22821 | 22827 | |
| 22822 | 22828 | const operand_coerced = try sema.coerce(block, operand_ty, operand_res, operand_src); |
| 22823 | 22829 | |
| 22824 | const ptr_ty = dest_ty.scalarType(mod); | |
| 22830 | const ptr_ty = dest_ty.scalarType(zcu); | |
| 22825 | 22831 | try sema.checkPtrType(block, src, ptr_ty, true); |
| 22826 | 22832 | |
| 22827 | const elem_ty = ptr_ty.elemType2(mod); | |
| 22828 | const ptr_align = try ptr_ty.ptrAlignmentAdvanced(pt, .sema); | |
| 22833 | const elem_ty = ptr_ty.elemType2(zcu); | |
| 22834 | const ptr_align = try ptr_ty.ptrAlignmentSema(pt); | |
| 22829 | 22835 | |
| 22830 | if (ptr_ty.isSlice(mod)) { | |
| 22836 | if (ptr_ty.isSlice(zcu)) { | |
| 22831 | 22837 | const msg = msg: { |
| 22832 | 22838 | const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(pt)}); |
| 22833 | 22839 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -22842,7 +22848,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22842 | 22848 | const ptr_val = try sema.ptrFromIntVal(block, operand_src, val, ptr_ty, ptr_align); |
| 22843 | 22849 | return Air.internedToRef(ptr_val.toIntern()); |
| 22844 | 22850 | } |
| 22845 | const len = dest_ty.vectorLen(mod); | |
| 22851 | const len = dest_ty.vectorLen(zcu); | |
| 22846 | 22852 | const new_elems = try sema.arena.alloc(InternPool.Index, len); |
| 22847 | 22853 | for (new_elems, 0..) |*new_elem, i| { |
| 22848 | 22854 | const elem = try val.elemValue(pt, i); |
| ... | ... | @@ -22854,7 +22860,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22854 | 22860 | .storage = .{ .elems = new_elems }, |
| 22855 | 22861 | } })); |
| 22856 | 22862 | } |
| 22857 | if (try sema.typeRequiresComptime(ptr_ty)) { | |
| 22863 | if (try ptr_ty.comptimeOnlySema(pt)) { | |
| 22858 | 22864 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22859 | 22865 | const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(pt)}); |
| 22860 | 22866 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -22865,8 +22871,8 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22865 | 22871 | } |
| 22866 | 22872 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 22867 | 22873 | if (!is_vector) { |
| 22868 | if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) { | |
| 22869 | if (!ptr_ty.isAllowzeroPtr(mod)) { | |
| 22874 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .Fn)) { | |
| 22875 | if (!ptr_ty.isAllowzeroPtr(zcu)) { | |
| 22870 | 22876 | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); |
| 22871 | 22877 | try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null); |
| 22872 | 22878 | } |
| ... | ... | @@ -22881,12 +22887,12 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22881 | 22887 | return block.addBitCast(dest_ty, operand_coerced); |
| 22882 | 22888 | } |
| 22883 | 22889 | |
| 22884 | const len = dest_ty.vectorLen(mod); | |
| 22885 | if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) { | |
| 22890 | const len = dest_ty.vectorLen(zcu); | |
| 22891 | if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .Fn)) { | |
| 22886 | 22892 | for (0..len) |i| { |
| 22887 | 22893 | const idx_ref = try pt.intRef(Type.usize, i); |
| 22888 | 22894 | const elem_coerced = try block.addBinOp(.array_elem_val, operand_coerced, idx_ref); |
| 22889 | if (!ptr_ty.isAllowzeroPtr(mod)) { | |
| 22895 | if (!ptr_ty.isAllowzeroPtr(zcu)) { | |
| 22890 | 22896 | const is_non_zero = try block.addBinOp(.cmp_neq, elem_coerced, .zero_usize); |
| 22891 | 22897 | try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null); |
| 22892 | 22898 | } |
| ... | ... | @@ -22943,16 +22949,16 @@ fn ptrFromIntVal( |
| 22943 | 22949 | |
| 22944 | 22950 | fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 22945 | 22951 | const pt = sema.pt; |
| 22946 | const mod = pt.zcu; | |
| 22947 | const ip = &mod.intern_pool; | |
| 22952 | const zcu = pt.zcu; | |
| 22953 | const ip = &zcu.intern_pool; | |
| 22948 | 22954 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 22949 | 22955 | const src = block.nodeOffset(extra.node); |
| 22950 | 22956 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 22951 | 22957 | const base_dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_opt, "@errorCast"); |
| 22952 | 22958 | const operand = try sema.resolveInst(extra.rhs); |
| 22953 | 22959 | const base_operand_ty = sema.typeOf(operand); |
| 22954 | const dest_tag = base_dest_ty.zigTypeTag(mod); | |
| 22955 | const operand_tag = base_operand_ty.zigTypeTag(mod); | |
| 22960 | const dest_tag = base_dest_ty.zigTypeTag(zcu); | |
| 22961 | const operand_tag = base_operand_ty.zigTypeTag(zcu); | |
| 22956 | 22962 | |
| 22957 | 22963 | if (dest_tag != .ErrorSet and dest_tag != .ErrorUnion) { |
| 22958 | 22964 | return sema.fail(block, src, "expected error set or error union type, found '{s}'", .{@tagName(dest_tag)}); |
| ... | ... | @@ -22964,13 +22970,13 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22964 | 22970 | return sema.fail(block, src, "cannot cast an error union type to error set", .{}); |
| 22965 | 22971 | } |
| 22966 | 22972 | if (dest_tag == .ErrorUnion and operand_tag == .ErrorUnion and |
| 22967 | base_dest_ty.errorUnionPayload(mod).toIntern() != base_operand_ty.errorUnionPayload(mod).toIntern()) | |
| 22973 | base_dest_ty.errorUnionPayload(zcu).toIntern() != base_operand_ty.errorUnionPayload(zcu).toIntern()) | |
| 22968 | 22974 | { |
| 22969 | 22975 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22970 | 22976 | const msg = try sema.errMsg(src, "payload types of error unions must match", .{}); |
| 22971 | 22977 | errdefer msg.destroy(sema.gpa); |
| 22972 | const dest_ty = base_dest_ty.errorUnionPayload(mod); | |
| 22973 | const operand_ty = base_operand_ty.errorUnionPayload(mod); | |
| 22978 | const dest_ty = base_dest_ty.errorUnionPayload(zcu); | |
| 22979 | const operand_ty = base_operand_ty.errorUnionPayload(zcu); | |
| 22974 | 22980 | try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(pt)}); |
| 22975 | 22981 | try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(pt)}); |
| 22976 | 22982 | try addDeclaredHereNote(sema, msg, dest_ty); |
| ... | ... | @@ -22978,19 +22984,19 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22978 | 22984 | break :msg msg; |
| 22979 | 22985 | }); |
| 22980 | 22986 | } |
| 22981 | const dest_ty = if (dest_tag == .ErrorUnion) base_dest_ty.errorUnionSet(mod) else base_dest_ty; | |
| 22982 | const operand_ty = if (operand_tag == .ErrorUnion) base_operand_ty.errorUnionSet(mod) else base_operand_ty; | |
| 22987 | const dest_ty = if (dest_tag == .ErrorUnion) base_dest_ty.errorUnionSet(zcu) else base_dest_ty; | |
| 22988 | const operand_ty = if (operand_tag == .ErrorUnion) base_operand_ty.errorUnionSet(zcu) else base_operand_ty; | |
| 22983 | 22989 | |
| 22984 | 22990 | // operand must be defined since it can be an invalid error value |
| 22985 | 22991 | const maybe_operand_val = try sema.resolveDefinedValue(block, operand_src, operand); |
| 22986 | 22992 | |
| 22987 | 22993 | const disjoint = disjoint: { |
| 22988 | 22994 | // Try avoiding resolving inferred error sets if we can |
| 22989 | if (!dest_ty.isAnyError(mod) and dest_ty.errorSetIsEmpty(mod)) break :disjoint true; | |
| 22990 | if (!operand_ty.isAnyError(mod) and operand_ty.errorSetIsEmpty(mod)) break :disjoint true; | |
| 22991 | if (dest_ty.isAnyError(mod)) break :disjoint false; | |
| 22992 | if (operand_ty.isAnyError(mod)) break :disjoint false; | |
| 22993 | const dest_err_names = dest_ty.errorSetNames(mod); | |
| 22995 | if (!dest_ty.isAnyError(zcu) and dest_ty.errorSetIsEmpty(zcu)) break :disjoint true; | |
| 22996 | if (!operand_ty.isAnyError(zcu) and operand_ty.errorSetIsEmpty(zcu)) break :disjoint true; | |
| 22997 | if (dest_ty.isAnyError(zcu)) break :disjoint false; | |
| 22998 | if (operand_ty.isAnyError(zcu)) break :disjoint false; | |
| 22999 | const dest_err_names = dest_ty.errorSetNames(zcu); | |
| 22994 | 23000 | for (0..dest_err_names.len) |dest_err_index| { |
| 22995 | 23001 | if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_names.get(ip)[dest_err_index])) |
| 22996 | 23002 | break :disjoint false; |
| ... | ... | @@ -23018,8 +23024,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 23018 | 23024 | } |
| 23019 | 23025 | |
| 23020 | 23026 | if (maybe_operand_val) |val| { |
| 23021 | if (!dest_ty.isAnyError(mod)) check: { | |
| 23022 | const operand_val = mod.intern_pool.indexToKey(val.toIntern()); | |
| 23027 | if (!dest_ty.isAnyError(zcu)) check: { | |
| 23028 | const operand_val = zcu.intern_pool.indexToKey(val.toIntern()); | |
| 23023 | 23029 | var error_name: InternPool.NullTerminatedString = undefined; |
| 23024 | 23030 | if (operand_tag == .ErrorUnion) { |
| 23025 | 23031 | if (operand_val.error_union.val != .err_name) break :check; |
| ... | ... | @@ -23039,9 +23045,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 23039 | 23045 | |
| 23040 | 23046 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 23041 | 23047 | const err_int_ty = try pt.errorIntType(); |
| 23042 | if (block.wantSafety() and !dest_ty.isAnyError(mod) and | |
| 23048 | if (block.wantSafety() and !dest_ty.isAnyError(zcu) and | |
| 23043 | 23049 | dest_ty.toIntern() != .adhoc_inferred_error_set_type and |
| 23044 | mod.backendSupportsFeature(.error_set_has_value)) | |
| 23050 | zcu.backendSupportsFeature(.error_set_has_value)) | |
| 23045 | 23051 | { |
| 23046 | 23052 | if (dest_tag == .ErrorUnion) { |
| 23047 | 23053 | const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand); |
| ... | ... | @@ -23116,23 +23122,23 @@ fn ptrCastFull( |
| 23116 | 23122 | operation: []const u8, |
| 23117 | 23123 | ) CompileError!Air.Inst.Ref { |
| 23118 | 23124 | const pt = sema.pt; |
| 23119 | const mod = pt.zcu; | |
| 23125 | const zcu = pt.zcu; | |
| 23120 | 23126 | const operand_ty = sema.typeOf(operand); |
| 23121 | 23127 | |
| 23122 | 23128 | try sema.checkPtrType(block, src, dest_ty, true); |
| 23123 | 23129 | try sema.checkPtrOperand(block, operand_src, operand_ty); |
| 23124 | 23130 | |
| 23125 | const src_info = operand_ty.ptrInfo(mod); | |
| 23126 | const dest_info = dest_ty.ptrInfo(mod); | |
| 23131 | const src_info = operand_ty.ptrInfo(zcu); | |
| 23132 | const dest_info = dest_ty.ptrInfo(zcu); | |
| 23127 | 23133 | |
| 23128 | 23134 | try Type.fromInterned(src_info.child).resolveLayout(pt); |
| 23129 | 23135 | try Type.fromInterned(dest_info.child).resolveLayout(pt); |
| 23130 | 23136 | |
| 23131 | 23137 | const src_slice_like = src_info.flags.size == .Slice or |
| 23132 | (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array); | |
| 23138 | (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(zcu) == .Array); | |
| 23133 | 23139 | |
| 23134 | 23140 | const dest_slice_like = dest_info.flags.size == .Slice or |
| 23135 | (dest_info.flags.size == .One and Type.fromInterned(dest_info.child).zigTypeTag(mod) == .Array); | |
| 23141 | (dest_info.flags.size == .One and Type.fromInterned(dest_info.child).zigTypeTag(zcu) == .Array); | |
| 23136 | 23142 | |
| 23137 | 23143 | if (dest_info.flags.size == .Slice and !src_slice_like) { |
| 23138 | 23144 | return sema.fail(block, src, "illegal pointer cast to slice", .{}); |
| ... | ... | @@ -23140,12 +23146,12 @@ fn ptrCastFull( |
| 23140 | 23146 | |
| 23141 | 23147 | if (dest_info.flags.size == .Slice) { |
| 23142 | 23148 | const src_elem_size = switch (src_info.flags.size) { |
| 23143 | .Slice => Type.fromInterned(src_info.child).abiSize(pt), | |
| 23149 | .Slice => Type.fromInterned(src_info.child).abiSize(zcu), | |
| 23144 | 23150 | // pointer to array |
| 23145 | .One => Type.fromInterned(src_info.child).childType(mod).abiSize(pt), | |
| 23151 | .One => Type.fromInterned(src_info.child).childType(zcu).abiSize(zcu), | |
| 23146 | 23152 | else => unreachable, |
| 23147 | 23153 | }; |
| 23148 | const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(pt); | |
| 23154 | const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(zcu); | |
| 23149 | 23155 | if (src_elem_size != dest_elem_size) { |
| 23150 | 23156 | return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation}); |
| 23151 | 23157 | } |
| ... | ... | @@ -23167,7 +23173,7 @@ fn ptrCastFull( |
| 23167 | 23173 | errdefer msg.destroy(sema.gpa); |
| 23168 | 23174 | if (dest_info.flags.size == .Many and |
| 23169 | 23175 | (src_info.flags.size == .Slice or |
| 23170 | (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array))) | |
| 23176 | (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(zcu) == .Array))) | |
| 23171 | 23177 | { |
| 23172 | 23178 | try sema.errNote(src, msg, "use 'ptr' field to convert slice to many pointer", .{}); |
| 23173 | 23179 | } else { |
| ... | ... | @@ -23180,7 +23186,7 @@ fn ptrCastFull( |
| 23180 | 23186 | check_child: { |
| 23181 | 23187 | const src_child = if (dest_info.flags.size == .Slice and src_info.flags.size == .One) blk: { |
| 23182 | 23188 | // *[n]T -> []T |
| 23183 | break :blk Type.fromInterned(src_info.child).childType(mod); | |
| 23189 | break :blk Type.fromInterned(src_info.child).childType(zcu); | |
| 23184 | 23190 | } else Type.fromInterned(src_info.child); |
| 23185 | 23191 | |
| 23186 | 23192 | const dest_child = Type.fromInterned(dest_info.child); |
| ... | ... | @@ -23190,7 +23196,7 @@ fn ptrCastFull( |
| 23190 | 23196 | dest_child, |
| 23191 | 23197 | src_child, |
| 23192 | 23198 | !dest_info.flags.is_const, |
| 23193 | mod.getTarget(), | |
| 23199 | zcu.getTarget(), | |
| 23194 | 23200 | src, |
| 23195 | 23201 | operand_src, |
| 23196 | 23202 | null, |
| ... | ... | @@ -23211,14 +23217,14 @@ fn ptrCastFull( |
| 23211 | 23217 | if (dest_info.sentinel == .none) break :check_sent; |
| 23212 | 23218 | if (src_info.flags.size == .C) break :check_sent; |
| 23213 | 23219 | if (src_info.sentinel != .none) { |
| 23214 | const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child); | |
| 23220 | const coerced_sent = try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_info.sentinel, dest_info.child); | |
| 23215 | 23221 | if (dest_info.sentinel == coerced_sent) break :check_sent; |
| 23216 | 23222 | } |
| 23217 | 23223 | if (src_slice_like and src_info.flags.size == .One and dest_info.flags.size == .Slice) { |
| 23218 | 23224 | // [*]nT -> []T |
| 23219 | 23225 | const arr_ty = Type.fromInterned(src_info.child); |
| 23220 | if (arr_ty.sentinel(mod)) |src_sentinel| { | |
| 23221 | const coerced_sent = try mod.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child); | |
| 23226 | if (arr_ty.sentinel(zcu)) |src_sentinel| { | |
| 23227 | const coerced_sent = try zcu.intern_pool.getCoerced(sema.gpa, pt.tid, src_sentinel.toIntern(), dest_info.child); | |
| 23222 | 23228 | if (dest_info.sentinel == coerced_sent) break :check_sent; |
| 23223 | 23229 | } |
| 23224 | 23230 | } |
| ... | ... | @@ -23264,8 +23270,8 @@ fn ptrCastFull( |
| 23264 | 23270 | } |
| 23265 | 23271 | |
| 23266 | 23272 | check_allowzero: { |
| 23267 | const src_allows_zero = operand_ty.ptrAllowsZero(mod); | |
| 23268 | const dest_allows_zero = dest_ty.ptrAllowsZero(mod); | |
| 23273 | const src_allows_zero = operand_ty.ptrAllowsZero(zcu); | |
| 23274 | const dest_allows_zero = dest_ty.ptrAllowsZero(zcu); | |
| 23269 | 23275 | if (!src_allows_zero) break :check_allowzero; |
| 23270 | 23276 | if (dest_allows_zero) break :check_allowzero; |
| 23271 | 23277 | |
| ... | ... | @@ -23286,12 +23292,12 @@ fn ptrCastFull( |
| 23286 | 23292 | const src_align = if (src_info.flags.alignment != .none) |
| 23287 | 23293 | src_info.flags.alignment |
| 23288 | 23294 | else |
| 23289 | Type.fromInterned(src_info.child).abiAlignment(pt); | |
| 23295 | Type.fromInterned(src_info.child).abiAlignment(zcu); | |
| 23290 | 23296 | |
| 23291 | 23297 | const dest_align = if (dest_info.flags.alignment != .none) |
| 23292 | 23298 | dest_info.flags.alignment |
| 23293 | 23299 | else |
| 23294 | Type.fromInterned(dest_info.child).abiAlignment(pt); | |
| 23300 | Type.fromInterned(dest_info.child).abiAlignment(zcu); | |
| 23295 | 23301 | |
| 23296 | 23302 | if (!flags.align_cast) { |
| 23297 | 23303 | if (dest_align.compare(.gt, src_align)) { |
| ... | ... | @@ -23327,7 +23333,7 @@ fn ptrCastFull( |
| 23327 | 23333 | } |
| 23328 | 23334 | } else { |
| 23329 | 23335 | // Some address space casts are always disallowed |
| 23330 | if (!target_util.addrSpaceCastIsValid(mod.getTarget(), src_info.flags.address_space, dest_info.flags.address_space)) { | |
| 23336 | if (!target_util.addrSpaceCastIsValid(zcu.getTarget(), src_info.flags.address_space, dest_info.flags.address_space)) { | |
| 23331 | 23337 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 23332 | 23338 | const msg = try sema.errMsg(src, "invalid address space cast", .{}); |
| 23333 | 23339 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -23363,7 +23369,7 @@ fn ptrCastFull( |
| 23363 | 23369 | } |
| 23364 | 23370 | |
| 23365 | 23371 | const ptr = if (src_info.flags.size == .Slice and dest_info.flags.size != .Slice) ptr: { |
| 23366 | if (operand_ty.zigTypeTag(mod) == .Optional) { | |
| 23372 | if (operand_ty.zigTypeTag(zcu) == .Optional) { | |
| 23367 | 23373 | break :ptr try sema.analyzeOptionalSlicePtr(block, operand_src, operand, operand_ty); |
| 23368 | 23374 | } else { |
| 23369 | 23375 | break :ptr try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty); |
| ... | ... | @@ -23375,7 +23381,7 @@ fn ptrCastFull( |
| 23375 | 23381 | var info = dest_info; |
| 23376 | 23382 | info.flags.size = .Many; |
| 23377 | 23383 | const ty = try pt.ptrTypeSema(info); |
| 23378 | if (dest_ty.zigTypeTag(mod) == .Optional) { | |
| 23384 | if (dest_ty.zigTypeTag(zcu) == .Optional) { | |
| 23379 | 23385 | break :blk try pt.optionalType(ty.toIntern()); |
| 23380 | 23386 | } else { |
| 23381 | 23387 | break :blk ty; |
| ... | ... | @@ -23385,14 +23391,14 @@ fn ptrCastFull( |
| 23385 | 23391 | // Cannot do @addrSpaceCast at comptime |
| 23386 | 23392 | if (!flags.addrspace_cast) { |
| 23387 | 23393 | if (try sema.resolveValue(ptr)) |ptr_val| { |
| 23388 | if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isUndef(mod)) { | |
| 23394 | if (!dest_ty.ptrAllowsZero(zcu) and ptr_val.isUndef(zcu)) { | |
| 23389 | 23395 | return sema.failWithUseOfUndef(block, operand_src); |
| 23390 | 23396 | } |
| 23391 | if (!dest_ty.ptrAllowsZero(mod) and ptr_val.isNull(mod)) { | |
| 23397 | if (!dest_ty.ptrAllowsZero(zcu) and ptr_val.isNull(zcu)) { | |
| 23392 | 23398 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)}); |
| 23393 | 23399 | } |
| 23394 | 23400 | if (dest_align.compare(.gt, src_align)) { |
| 23395 | if (try ptr_val.getUnsignedIntAdvanced(pt, .sema)) |addr| { | |
| 23401 | if (try ptr_val.getUnsignedIntSema(pt)) |addr| { | |
| 23396 | 23402 | if (!dest_align.check(addr)) { |
| 23397 | 23403 | return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ |
| 23398 | 23404 | addr, |
| ... | ... | @@ -23402,20 +23408,20 @@ fn ptrCastFull( |
| 23402 | 23408 | } |
| 23403 | 23409 | } |
| 23404 | 23410 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { |
| 23405 | if (ptr_val.isUndef(mod)) return pt.undefRef(dest_ty); | |
| 23406 | const arr_len = try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod)); | |
| 23407 | const ptr_val_key = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | |
| 23411 | if (ptr_val.isUndef(zcu)) return pt.undefRef(dest_ty); | |
| 23412 | const arr_len = try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(zcu)); | |
| 23413 | const ptr_val_key = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr; | |
| 23408 | 23414 | return Air.internedToRef((try pt.intern(.{ .slice = .{ |
| 23409 | 23415 | .ty = dest_ty.toIntern(), |
| 23410 | 23416 | .ptr = try pt.intern(.{ .ptr = .{ |
| 23411 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), | |
| 23417 | .ty = dest_ty.slicePtrFieldType(zcu).toIntern(), | |
| 23412 | 23418 | .base_addr = ptr_val_key.base_addr, |
| 23413 | 23419 | .byte_offset = ptr_val_key.byte_offset, |
| 23414 | 23420 | } }), |
| 23415 | 23421 | .len = arr_len.toIntern(), |
| 23416 | 23422 | } }))); |
| 23417 | 23423 | } else { |
| 23418 | assert(dest_ptr_ty.eql(dest_ty, mod)); | |
| 23424 | assert(dest_ptr_ty.eql(dest_ty, zcu)); | |
| 23419 | 23425 | return Air.internedToRef((try pt.getCoerced(ptr_val, dest_ty)).toIntern()); |
| 23420 | 23426 | } |
| 23421 | 23427 | } |
| ... | ... | @@ -23424,8 +23430,8 @@ fn ptrCastFull( |
| 23424 | 23430 | try sema.requireRuntimeBlock(block, src, null); |
| 23425 | 23431 | try sema.validateRuntimeValue(block, operand_src, ptr); |
| 23426 | 23432 | |
| 23427 | if (block.wantSafety() and operand_ty.ptrAllowsZero(mod) and !dest_ty.ptrAllowsZero(mod) and | |
| 23428 | (try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child)) or Type.fromInterned(dest_info.child).zigTypeTag(mod) == .Fn)) | |
| 23433 | if (block.wantSafety() and operand_ty.ptrAllowsZero(zcu) and !dest_ty.ptrAllowsZero(zcu) and | |
| 23434 | (try Type.fromInterned(dest_info.child).hasRuntimeBitsSema(pt) or Type.fromInterned(dest_info.child).zigTypeTag(zcu) == .Fn)) | |
| 23429 | 23435 | { |
| 23430 | 23436 | const ptr_int = try block.addUnOp(.int_from_ptr, ptr); |
| 23431 | 23437 | const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize); |
| ... | ... | @@ -23439,7 +23445,7 @@ fn ptrCastFull( |
| 23439 | 23445 | |
| 23440 | 23446 | if (block.wantSafety() and |
| 23441 | 23447 | dest_align.compare(.gt, src_align) and |
| 23442 | try sema.typeHasRuntimeBits(Type.fromInterned(dest_info.child))) | |
| 23448 | try Type.fromInterned(dest_info.child).hasRuntimeBitsSema(pt)) | |
| 23443 | 23449 | { |
| 23444 | 23450 | const align_bytes_minus_1 = dest_align.toByteUnits().? - 1; |
| 23445 | 23451 | const align_minus_1 = Air.internedToRef((try pt.intValue(Type.usize, align_bytes_minus_1)).toIntern()); |
| ... | ... | @@ -23460,7 +23466,7 @@ fn ptrCastFull( |
| 23460 | 23466 | var intermediate_info = src_info; |
| 23461 | 23467 | intermediate_info.flags.address_space = dest_info.flags.address_space; |
| 23462 | 23468 | const intermediate_ptr_ty = try pt.ptrTypeSema(intermediate_info); |
| 23463 | const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: { | |
| 23469 | const intermediate_ty = if (dest_ptr_ty.zigTypeTag(zcu) == .Optional) blk: { | |
| 23464 | 23470 | break :blk try pt.optionalType(intermediate_ptr_ty.toIntern()); |
| 23465 | 23471 | } else intermediate_ptr_ty; |
| 23466 | 23472 | const intermediate = try block.addInst(.{ |
| ... | ... | @@ -23470,7 +23476,7 @@ fn ptrCastFull( |
| 23470 | 23476 | .operand = ptr, |
| 23471 | 23477 | } }, |
| 23472 | 23478 | }); |
| 23473 | if (intermediate_ty.eql(dest_ptr_ty, mod)) { | |
| 23479 | if (intermediate_ty.eql(dest_ptr_ty, zcu)) { | |
| 23474 | 23480 | // We only changed the address space, so no need for a bitcast |
| 23475 | 23481 | break :ptr intermediate; |
| 23476 | 23482 | } |
| ... | ... | @@ -23482,7 +23488,7 @@ fn ptrCastFull( |
| 23482 | 23488 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { |
| 23483 | 23489 | // We have to construct a slice using the operand's child's array length |
| 23484 | 23490 | // Note that we know from the check at the start of the function that operand_ty is slice-like |
| 23485 | const arr_len = Air.internedToRef((try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod))).toIntern()); | |
| 23491 | const arr_len = Air.internedToRef((try pt.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(zcu))).toIntern()); | |
| 23486 | 23492 | return block.addInst(.{ |
| 23487 | 23493 | .tag = .slice, |
| 23488 | 23494 | .data = .{ .ty_pl = .{ |
| ... | ... | @@ -23494,7 +23500,7 @@ fn ptrCastFull( |
| 23494 | 23500 | } }, |
| 23495 | 23501 | }); |
| 23496 | 23502 | } else { |
| 23497 | assert(dest_ptr_ty.eql(dest_ty, mod)); | |
| 23503 | assert(dest_ptr_ty.eql(dest_ty, zcu)); | |
| 23498 | 23504 | try sema.checkKnownAllocPtr(block, operand, result_ptr); |
| 23499 | 23505 | return result_ptr; |
| 23500 | 23506 | } |
| ... | ... | @@ -23502,7 +23508,7 @@ fn ptrCastFull( |
| 23502 | 23508 | |
| 23503 | 23509 | fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 23504 | 23510 | const pt = sema.pt; |
| 23505 | const mod = pt.zcu; | |
| 23511 | const zcu = pt.zcu; | |
| 23506 | 23512 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?; |
| 23507 | 23513 | const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); |
| 23508 | 23514 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| ... | ... | @@ -23512,13 +23518,13 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 23512 | 23518 | const operand_ty = sema.typeOf(operand); |
| 23513 | 23519 | try sema.checkPtrOperand(block, operand_src, operand_ty); |
| 23514 | 23520 | |
| 23515 | var ptr_info = operand_ty.ptrInfo(mod); | |
| 23521 | var ptr_info = operand_ty.ptrInfo(zcu); | |
| 23516 | 23522 | if (flags.const_cast) ptr_info.flags.is_const = false; |
| 23517 | 23523 | if (flags.volatile_cast) ptr_info.flags.is_volatile = false; |
| 23518 | 23524 | |
| 23519 | 23525 | const dest_ty = blk: { |
| 23520 | 23526 | const dest_ty = try pt.ptrTypeSema(ptr_info); |
| 23521 | if (operand_ty.zigTypeTag(mod) == .Optional) { | |
| 23527 | if (operand_ty.zigTypeTag(zcu) == .Optional) { | |
| 23522 | 23528 | break :blk try pt.optionalType(dest_ty.toIntern()); |
| 23523 | 23529 | } |
| 23524 | 23530 | break :blk dest_ty; |
| ... | ... | @@ -23536,7 +23542,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 23536 | 23542 | |
| 23537 | 23543 | fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23538 | 23544 | const pt = sema.pt; |
| 23539 | const mod = pt.zcu; | |
| 23545 | const zcu = pt.zcu; | |
| 23540 | 23546 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 23541 | 23547 | const src = block.nodeOffset(inst_data.src_node); |
| 23542 | 23548 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | ... | @@ -23547,24 +23553,24 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23547 | 23553 | const operand_ty = sema.typeOf(operand); |
| 23548 | 23554 | const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src); |
| 23549 | 23555 | |
| 23550 | const operand_is_vector = operand_ty.zigTypeTag(mod) == .Vector; | |
| 23551 | const dest_is_vector = dest_ty.zigTypeTag(mod) == .Vector; | |
| 23556 | const operand_is_vector = operand_ty.zigTypeTag(zcu) == .Vector; | |
| 23557 | const dest_is_vector = dest_ty.zigTypeTag(zcu) == .Vector; | |
| 23552 | 23558 | if (operand_is_vector != dest_is_vector) { |
| 23553 | 23559 | return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) }); |
| 23554 | 23560 | } |
| 23555 | 23561 | |
| 23556 | if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 23562 | if (dest_scalar_ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 23557 | 23563 | return sema.coerce(block, dest_ty, operand, operand_src); |
| 23558 | 23564 | } |
| 23559 | 23565 | |
| 23560 | const dest_info = dest_scalar_ty.intInfo(mod); | |
| 23566 | const dest_info = dest_scalar_ty.intInfo(zcu); | |
| 23561 | 23567 | |
| 23562 | 23568 | if (try sema.typeHasOnePossibleValue(dest_ty)) |val| { |
| 23563 | 23569 | return Air.internedToRef(val.toIntern()); |
| 23564 | 23570 | } |
| 23565 | 23571 | |
| 23566 | if (operand_scalar_ty.zigTypeTag(mod) != .ComptimeInt) { | |
| 23567 | const operand_info = operand_ty.intInfo(mod); | |
| 23572 | if (operand_scalar_ty.zigTypeTag(zcu) != .ComptimeInt) { | |
| 23573 | const operand_info = operand_ty.intInfo(zcu); | |
| 23568 | 23574 | if (try sema.typeHasOnePossibleValue(operand_ty)) |val| { |
| 23569 | 23575 | return Air.internedToRef(val.toIntern()); |
| 23570 | 23576 | } |
| ... | ... | @@ -23595,14 +23601,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23595 | 23601 | } |
| 23596 | 23602 | |
| 23597 | 23603 | if (try sema.resolveValueIntable(operand)) |val| { |
| 23598 | if (val.isUndef(mod)) return pt.undefRef(dest_ty); | |
| 23604 | if (val.isUndef(zcu)) return pt.undefRef(dest_ty); | |
| 23599 | 23605 | if (!dest_is_vector) { |
| 23600 | 23606 | return Air.internedToRef((try pt.getCoerced( |
| 23601 | 23607 | try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, pt), |
| 23602 | 23608 | dest_ty, |
| 23603 | 23609 | )).toIntern()); |
| 23604 | 23610 | } |
| 23605 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); | |
| 23611 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(zcu)); | |
| 23606 | 23612 | for (elems, 0..) |*elem, i| { |
| 23607 | 23613 | const elem_val = try val.elemValue(pt, i); |
| 23608 | 23614 | const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, pt); |
| ... | ... | @@ -23623,38 +23629,38 @@ fn zirBitCount( |
| 23623 | 23629 | block: *Block, |
| 23624 | 23630 | inst: Zir.Inst.Index, |
| 23625 | 23631 | air_tag: Air.Inst.Tag, |
| 23626 | comptime comptimeOp: fn (val: Value, ty: Type, pt: Zcu.PerThread) u64, | |
| 23632 | comptime comptimeOp: fn (val: Value, ty: Type, zcu: *Zcu) u64, | |
| 23627 | 23633 | ) CompileError!Air.Inst.Ref { |
| 23628 | 23634 | const pt = sema.pt; |
| 23629 | const mod = pt.zcu; | |
| 23635 | const zcu = pt.zcu; | |
| 23630 | 23636 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 23631 | 23637 | const src = block.nodeOffset(inst_data.src_node); |
| 23632 | 23638 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 23633 | 23639 | const operand = try sema.resolveInst(inst_data.operand); |
| 23634 | 23640 | const operand_ty = sema.typeOf(operand); |
| 23635 | 23641 | _ = try sema.checkIntOrVector(block, operand, operand_src); |
| 23636 | const bits = operand_ty.intInfo(mod).bits; | |
| 23642 | const bits = operand_ty.intInfo(zcu).bits; | |
| 23637 | 23643 | |
| 23638 | 23644 | if (try sema.typeHasOnePossibleValue(operand_ty)) |val| { |
| 23639 | 23645 | return Air.internedToRef(val.toIntern()); |
| 23640 | 23646 | } |
| 23641 | 23647 | |
| 23642 | 23648 | const result_scalar_ty = try pt.smallestUnsignedInt(bits); |
| 23643 | switch (operand_ty.zigTypeTag(mod)) { | |
| 23649 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 23644 | 23650 | .Vector => { |
| 23645 | const vec_len = operand_ty.vectorLen(mod); | |
| 23651 | const vec_len = operand_ty.vectorLen(zcu); | |
| 23646 | 23652 | const result_ty = try pt.vectorType(.{ |
| 23647 | 23653 | .len = vec_len, |
| 23648 | 23654 | .child = result_scalar_ty.toIntern(), |
| 23649 | 23655 | }); |
| 23650 | 23656 | if (try sema.resolveValue(operand)) |val| { |
| 23651 | if (val.isUndef(mod)) return pt.undefRef(result_ty); | |
| 23657 | if (val.isUndef(zcu)) return pt.undefRef(result_ty); | |
| 23652 | 23658 | |
| 23653 | 23659 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23654 | const scalar_ty = operand_ty.scalarType(mod); | |
| 23660 | const scalar_ty = operand_ty.scalarType(zcu); | |
| 23655 | 23661 | for (elems, 0..) |*elem, i| { |
| 23656 | 23662 | const elem_val = try val.elemValue(pt, i); |
| 23657 | const count = comptimeOp(elem_val, scalar_ty, pt); | |
| 23663 | const count = comptimeOp(elem_val, scalar_ty, zcu); | |
| 23658 | 23664 | elem.* = (try pt.intValue(result_scalar_ty, count)).toIntern(); |
| 23659 | 23665 | } |
| 23660 | 23666 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| ... | ... | @@ -23668,8 +23674,8 @@ fn zirBitCount( |
| 23668 | 23674 | }, |
| 23669 | 23675 | .Int => { |
| 23670 | 23676 | if (try sema.resolveValueResolveLazy(operand)) |val| { |
| 23671 | if (val.isUndef(mod)) return pt.undefRef(result_scalar_ty); | |
| 23672 | return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, pt)); | |
| 23677 | if (val.isUndef(zcu)) return pt.undefRef(result_scalar_ty); | |
| 23678 | return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, zcu)); | |
| 23673 | 23679 | } else { |
| 23674 | 23680 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 23675 | 23681 | return block.addTyOp(air_tag, result_scalar_ty, operand); |
| ... | ... | @@ -23681,14 +23687,14 @@ fn zirBitCount( |
| 23681 | 23687 | |
| 23682 | 23688 | fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 23683 | 23689 | const pt = sema.pt; |
| 23684 | const mod = pt.zcu; | |
| 23690 | const zcu = pt.zcu; | |
| 23685 | 23691 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 23686 | 23692 | const src = block.nodeOffset(inst_data.src_node); |
| 23687 | 23693 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 23688 | 23694 | const operand = try sema.resolveInst(inst_data.operand); |
| 23689 | 23695 | const operand_ty = sema.typeOf(operand); |
| 23690 | 23696 | const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src); |
| 23691 | const bits = scalar_ty.intInfo(mod).bits; | |
| 23697 | const bits = scalar_ty.intInfo(zcu).bits; | |
| 23692 | 23698 | if (bits % 8 != 0) { |
| 23693 | 23699 | return sema.fail( |
| 23694 | 23700 | block, |
| ... | ... | @@ -23702,10 +23708,10 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23702 | 23708 | return Air.internedToRef(val.toIntern()); |
| 23703 | 23709 | } |
| 23704 | 23710 | |
| 23705 | switch (operand_ty.zigTypeTag(mod)) { | |
| 23711 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 23706 | 23712 | .Int => { |
| 23707 | 23713 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23708 | if (val.isUndef(mod)) return pt.undefRef(operand_ty); | |
| 23714 | if (val.isUndef(zcu)) return pt.undefRef(operand_ty); | |
| 23709 | 23715 | const result_val = try val.byteSwap(operand_ty, pt, sema.arena); |
| 23710 | 23716 | return Air.internedToRef(result_val.toIntern()); |
| 23711 | 23717 | } else operand_src; |
| ... | ... | @@ -23715,10 +23721,10 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23715 | 23721 | }, |
| 23716 | 23722 | .Vector => { |
| 23717 | 23723 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23718 | if (val.isUndef(mod)) | |
| 23724 | if (val.isUndef(zcu)) | |
| 23719 | 23725 | return pt.undefRef(operand_ty); |
| 23720 | 23726 | |
| 23721 | const vec_len = operand_ty.vectorLen(mod); | |
| 23727 | const vec_len = operand_ty.vectorLen(zcu); | |
| 23722 | 23728 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23723 | 23729 | for (elems, 0..) |*elem, i| { |
| 23724 | 23730 | const elem_val = try val.elemValue(pt, i); |
| ... | ... | @@ -23750,11 +23756,11 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23750 | 23756 | } |
| 23751 | 23757 | |
| 23752 | 23758 | const pt = sema.pt; |
| 23753 | const mod = pt.zcu; | |
| 23754 | switch (operand_ty.zigTypeTag(mod)) { | |
| 23759 | const zcu = pt.zcu; | |
| 23760 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 23755 | 23761 | .Int => { |
| 23756 | 23762 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23757 | if (val.isUndef(mod)) return pt.undefRef(operand_ty); | |
| 23763 | if (val.isUndef(zcu)) return pt.undefRef(operand_ty); | |
| 23758 | 23764 | const result_val = try val.bitReverse(operand_ty, pt, sema.arena); |
| 23759 | 23765 | return Air.internedToRef(result_val.toIntern()); |
| 23760 | 23766 | } else operand_src; |
| ... | ... | @@ -23764,10 +23770,10 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23764 | 23770 | }, |
| 23765 | 23771 | .Vector => { |
| 23766 | 23772 | const runtime_src = if (try sema.resolveValue(operand)) |val| { |
| 23767 | if (val.isUndef(mod)) | |
| 23773 | if (val.isUndef(zcu)) | |
| 23768 | 23774 | return pt.undefRef(operand_ty); |
| 23769 | 23775 | |
| 23770 | const vec_len = operand_ty.vectorLen(mod); | |
| 23776 | const vec_len = operand_ty.vectorLen(zcu); | |
| 23771 | 23777 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23772 | 23778 | for (elems, 0..) |*elem, i| { |
| 23773 | 23779 | const elem_val = try val.elemValue(pt, i); |
| ... | ... | @@ -23810,26 +23816,26 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23810 | 23816 | }); |
| 23811 | 23817 | |
| 23812 | 23818 | const pt = sema.pt; |
| 23813 | const mod = pt.zcu; | |
| 23814 | const ip = &mod.intern_pool; | |
| 23819 | const zcu = pt.zcu; | |
| 23820 | const ip = &zcu.intern_pool; | |
| 23815 | 23821 | try ty.resolveLayout(pt); |
| 23816 | switch (ty.zigTypeTag(mod)) { | |
| 23822 | switch (ty.zigTypeTag(zcu)) { | |
| 23817 | 23823 | .Struct => {}, |
| 23818 | 23824 | else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(pt)}), |
| 23819 | 23825 | } |
| 23820 | 23826 | |
| 23821 | const field_index = if (ty.isTuple(mod)) blk: { | |
| 23827 | const field_index = if (ty.isTuple(zcu)) blk: { | |
| 23822 | 23828 | if (field_name.eqlSlice("len", ip)) { |
| 23823 | 23829 | return sema.fail(block, src, "no offset available for 'len' field of tuple", .{}); |
| 23824 | 23830 | } |
| 23825 | 23831 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); |
| 23826 | 23832 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); |
| 23827 | 23833 | |
| 23828 | if (ty.structFieldIsComptime(field_index, mod)) { | |
| 23834 | if (ty.structFieldIsComptime(field_index, zcu)) { | |
| 23829 | 23835 | return sema.fail(block, src, "no offset available for comptime field", .{}); |
| 23830 | 23836 | } |
| 23831 | 23837 | |
| 23832 | switch (ty.containerLayout(mod)) { | |
| 23838 | switch (ty.containerLayout(zcu)) { | |
| 23833 | 23839 | .@"packed" => { |
| 23834 | 23840 | var bit_sum: u64 = 0; |
| 23835 | 23841 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -23838,17 +23844,17 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23838 | 23844 | return bit_sum; |
| 23839 | 23845 | } |
| 23840 | 23846 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 23841 | bit_sum += field_ty.bitSize(pt); | |
| 23847 | bit_sum += field_ty.bitSize(zcu); | |
| 23842 | 23848 | } else unreachable; |
| 23843 | 23849 | }, |
| 23844 | else => return ty.structFieldOffset(field_index, pt) * 8, | |
| 23850 | else => return ty.structFieldOffset(field_index, zcu) * 8, | |
| 23845 | 23851 | } |
| 23846 | 23852 | } |
| 23847 | 23853 | |
| 23848 | 23854 | fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { |
| 23849 | 23855 | const pt = sema.pt; |
| 23850 | const mod = pt.zcu; | |
| 23851 | switch (ty.zigTypeTag(mod)) { | |
| 23856 | const zcu = pt.zcu; | |
| 23857 | switch (ty.zigTypeTag(zcu)) { | |
| 23852 | 23858 | .Struct, .Enum, .Union, .Opaque => return, |
| 23853 | 23859 | else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(pt)}), |
| 23854 | 23860 | } |
| ... | ... | @@ -23857,8 +23863,8 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com |
| 23857 | 23863 | /// Returns `true` if the type was a comptime_int. |
| 23858 | 23864 | fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { |
| 23859 | 23865 | const pt = sema.pt; |
| 23860 | const mod = pt.zcu; | |
| 23861 | switch (try ty.zigTypeTagOrPoison(mod)) { | |
| 23866 | const zcu = pt.zcu; | |
| 23867 | switch (try ty.zigTypeTagOrPoison(zcu)) { | |
| 23862 | 23868 | .ComptimeInt => return true, |
| 23863 | 23869 | .Int => return false, |
| 23864 | 23870 | else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(pt)}), |
| ... | ... | @@ -23872,9 +23878,9 @@ fn checkInvalidPtrIntArithmetic( |
| 23872 | 23878 | ty: Type, |
| 23873 | 23879 | ) CompileError!void { |
| 23874 | 23880 | const pt = sema.pt; |
| 23875 | const mod = pt.zcu; | |
| 23876 | switch (try ty.zigTypeTagOrPoison(mod)) { | |
| 23877 | .Pointer => switch (ty.ptrSize(mod)) { | |
| 23881 | const zcu = pt.zcu; | |
| 23882 | switch (try ty.zigTypeTagOrPoison(zcu)) { | |
| 23883 | .Pointer => switch (ty.ptrSize(zcu)) { | |
| 23878 | 23884 | .One, .Slice => return, |
| 23879 | 23885 | .Many, .C => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"), |
| 23880 | 23886 | }, |
| ... | ... | @@ -23908,8 +23914,8 @@ fn checkPtrOperand( |
| 23908 | 23914 | ty: Type, |
| 23909 | 23915 | ) CompileError!void { |
| 23910 | 23916 | const pt = sema.pt; |
| 23911 | const mod = pt.zcu; | |
| 23912 | switch (ty.zigTypeTag(mod)) { | |
| 23917 | const zcu = pt.zcu; | |
| 23918 | switch (ty.zigTypeTag(zcu)) { | |
| 23913 | 23919 | .Pointer => return, |
| 23914 | 23920 | .Fn => { |
| 23915 | 23921 | const msg = msg: { |
| ... | ... | @@ -23926,7 +23932,7 @@ fn checkPtrOperand( |
| 23926 | 23932 | }; |
| 23927 | 23933 | return sema.failWithOwnedErrorMsg(block, msg); |
| 23928 | 23934 | }, |
| 23929 | .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return, | |
| 23935 | .Optional => if (ty.childType(zcu).zigTypeTag(zcu) == .Pointer) return, | |
| 23930 | 23936 | else => {}, |
| 23931 | 23937 | } |
| 23932 | 23938 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)}); |
| ... | ... | @@ -23940,9 +23946,9 @@ fn checkPtrType( |
| 23940 | 23946 | allow_slice: bool, |
| 23941 | 23947 | ) CompileError!void { |
| 23942 | 23948 | const pt = sema.pt; |
| 23943 | const mod = pt.zcu; | |
| 23944 | switch (ty.zigTypeTag(mod)) { | |
| 23945 | .Pointer => if (allow_slice or !ty.isSlice(mod)) return, | |
| 23949 | const zcu = pt.zcu; | |
| 23950 | switch (ty.zigTypeTag(zcu)) { | |
| 23951 | .Pointer => if (allow_slice or !ty.isSlice(zcu)) return, | |
| 23946 | 23952 | .Fn => { |
| 23947 | 23953 | const msg = msg: { |
| 23948 | 23954 | const msg = try sema.errMsg( |
| ... | ... | @@ -23958,7 +23964,7 @@ fn checkPtrType( |
| 23958 | 23964 | }; |
| 23959 | 23965 | return sema.failWithOwnedErrorMsg(block, msg); |
| 23960 | 23966 | }, |
| 23961 | .Optional => if (ty.childType(mod).zigTypeTag(mod) == .Pointer) return, | |
| 23967 | .Optional => if (ty.childType(zcu).zigTypeTag(zcu) == .Pointer) return, | |
| 23962 | 23968 | else => {}, |
| 23963 | 23969 | } |
| 23964 | 23970 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)}); |
| ... | ... | @@ -23971,10 +23977,10 @@ fn checkVectorElemType( |
| 23971 | 23977 | ty: Type, |
| 23972 | 23978 | ) CompileError!void { |
| 23973 | 23979 | const pt = sema.pt; |
| 23974 | const mod = pt.zcu; | |
| 23975 | switch (ty.zigTypeTag(mod)) { | |
| 23980 | const zcu = pt.zcu; | |
| 23981 | switch (ty.zigTypeTag(zcu)) { | |
| 23976 | 23982 | .Int, .Float, .Bool => return, |
| 23977 | .Optional, .Pointer => if (ty.isPtrAtRuntime(mod)) return, | |
| 23983 | .Optional, .Pointer => if (ty.isPtrAtRuntime(zcu)) return, | |
| 23978 | 23984 | else => {}, |
| 23979 | 23985 | } |
| 23980 | 23986 | return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(pt)}); |
| ... | ... | @@ -23987,8 +23993,8 @@ fn checkFloatType( |
| 23987 | 23993 | ty: Type, |
| 23988 | 23994 | ) CompileError!void { |
| 23989 | 23995 | const pt = sema.pt; |
| 23990 | const mod = pt.zcu; | |
| 23991 | switch (ty.zigTypeTag(mod)) { | |
| 23996 | const zcu = pt.zcu; | |
| 23997 | switch (ty.zigTypeTag(zcu)) { | |
| 23992 | 23998 | .ComptimeInt, .ComptimeFloat, .Float => {}, |
| 23993 | 23999 | else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(pt)}), |
| 23994 | 24000 | } |
| ... | ... | @@ -24001,10 +24007,10 @@ fn checkNumericType( |
| 24001 | 24007 | ty: Type, |
| 24002 | 24008 | ) CompileError!void { |
| 24003 | 24009 | const pt = sema.pt; |
| 24004 | const mod = pt.zcu; | |
| 24005 | switch (ty.zigTypeTag(mod)) { | |
| 24010 | const zcu = pt.zcu; | |
| 24011 | switch (ty.zigTypeTag(zcu)) { | |
| 24006 | 24012 | .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, |
| 24007 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 24013 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 24008 | 24014 | .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, |
| 24009 | 24015 | else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}), |
| 24010 | 24016 | }, |
| ... | ... | @@ -24023,9 +24029,9 @@ fn checkAtomicPtrOperand( |
| 24023 | 24029 | ptr_const: bool, |
| 24024 | 24030 | ) CompileError!Air.Inst.Ref { |
| 24025 | 24031 | const pt = sema.pt; |
| 24026 | const mod = pt.zcu; | |
| 24027 | var diag: Module.AtomicPtrAlignmentDiagnostics = .{}; | |
| 24028 | const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) { | |
| 24032 | const zcu = pt.zcu; | |
| 24033 | var diag: Zcu.AtomicPtrAlignmentDiagnostics = .{}; | |
| 24034 | const alignment = zcu.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) { | |
| 24029 | 24035 | error.OutOfMemory => return error.OutOfMemory, |
| 24030 | 24036 | error.FloatTooBig => return sema.fail( |
| 24031 | 24037 | block, |
| ... | ... | @@ -24056,8 +24062,8 @@ fn checkAtomicPtrOperand( |
| 24056 | 24062 | }; |
| 24057 | 24063 | |
| 24058 | 24064 | const ptr_ty = sema.typeOf(ptr); |
| 24059 | const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) { | |
| 24060 | .Pointer => ptr_ty.ptrInfo(mod), | |
| 24065 | const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(zcu)) { | |
| 24066 | .Pointer => ptr_ty.ptrInfo(zcu), | |
| 24061 | 24067 | else => { |
| 24062 | 24068 | const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data); |
| 24063 | 24069 | _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| ... | ... | @@ -24095,13 +24101,13 @@ fn checkIntOrVector( |
| 24095 | 24101 | operand_src: LazySrcLoc, |
| 24096 | 24102 | ) CompileError!Type { |
| 24097 | 24103 | const pt = sema.pt; |
| 24098 | const mod = pt.zcu; | |
| 24104 | const zcu = pt.zcu; | |
| 24099 | 24105 | const operand_ty = sema.typeOf(operand); |
| 24100 | switch (try operand_ty.zigTypeTagOrPoison(mod)) { | |
| 24106 | switch (try operand_ty.zigTypeTagOrPoison(zcu)) { | |
| 24101 | 24107 | .Int => return operand_ty, |
| 24102 | 24108 | .Vector => { |
| 24103 | const elem_ty = operand_ty.childType(mod); | |
| 24104 | switch (try elem_ty.zigTypeTagOrPoison(mod)) { | |
| 24109 | const elem_ty = operand_ty.childType(zcu); | |
| 24110 | switch (try elem_ty.zigTypeTagOrPoison(zcu)) { | |
| 24105 | 24111 | .Int => return elem_ty, |
| 24106 | 24112 | else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ |
| 24107 | 24113 | elem_ty.fmt(pt), |
| ... | ... | @@ -24121,12 +24127,12 @@ fn checkIntOrVectorAllowComptime( |
| 24121 | 24127 | operand_src: LazySrcLoc, |
| 24122 | 24128 | ) CompileError!Type { |
| 24123 | 24129 | const pt = sema.pt; |
| 24124 | const mod = pt.zcu; | |
| 24125 | switch (try operand_ty.zigTypeTagOrPoison(mod)) { | |
| 24130 | const zcu = pt.zcu; | |
| 24131 | switch (try operand_ty.zigTypeTagOrPoison(zcu)) { | |
| 24126 | 24132 | .Int, .ComptimeInt => return operand_ty, |
| 24127 | 24133 | .Vector => { |
| 24128 | const elem_ty = operand_ty.childType(mod); | |
| 24129 | switch (try elem_ty.zigTypeTagOrPoison(mod)) { | |
| 24134 | const elem_ty = operand_ty.childType(zcu); | |
| 24135 | switch (try elem_ty.zigTypeTagOrPoison(zcu)) { | |
| 24130 | 24136 | .Int, .ComptimeInt => return elem_ty, |
| 24131 | 24137 | else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ |
| 24132 | 24138 | elem_ty.fmt(pt), |
| ... | ... | @@ -24162,12 +24168,12 @@ fn checkSimdBinOp( |
| 24162 | 24168 | rhs_src: LazySrcLoc, |
| 24163 | 24169 | ) CompileError!SimdBinOp { |
| 24164 | 24170 | const pt = sema.pt; |
| 24165 | const mod = pt.zcu; | |
| 24171 | const zcu = pt.zcu; | |
| 24166 | 24172 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 24167 | 24173 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 24168 | 24174 | |
| 24169 | 24175 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 24170 | const vec_len: ?usize = if (lhs_ty.zigTypeTag(mod) == .Vector) lhs_ty.vectorLen(mod) else null; | |
| 24176 | const vec_len: ?usize = if (lhs_ty.zigTypeTag(zcu) == .Vector) lhs_ty.vectorLen(zcu) else null; | |
| 24171 | 24177 | const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{ |
| 24172 | 24178 | .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, |
| 24173 | 24179 | }); |
| ... | ... | @@ -24181,7 +24187,7 @@ fn checkSimdBinOp( |
| 24181 | 24187 | .lhs_val = try sema.resolveValue(lhs), |
| 24182 | 24188 | .rhs_val = try sema.resolveValue(rhs), |
| 24183 | 24189 | .result_ty = result_ty, |
| 24184 | .scalar_ty = result_ty.scalarType(mod), | |
| 24190 | .scalar_ty = result_ty.scalarType(zcu), | |
| 24185 | 24191 | }; |
| 24186 | 24192 | } |
| 24187 | 24193 | |
| ... | ... | @@ -24195,9 +24201,9 @@ fn checkVectorizableBinaryOperands( |
| 24195 | 24201 | rhs_src: LazySrcLoc, |
| 24196 | 24202 | ) CompileError!void { |
| 24197 | 24203 | const pt = sema.pt; |
| 24198 | const mod = pt.zcu; | |
| 24199 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod); | |
| 24200 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); | |
| 24204 | const zcu = pt.zcu; | |
| 24205 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(zcu); | |
| 24206 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(zcu); | |
| 24201 | 24207 | if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return; |
| 24202 | 24208 | |
| 24203 | 24209 | const lhs_is_vector = switch (lhs_zig_ty_tag) { |
| ... | ... | @@ -24210,8 +24216,8 @@ fn checkVectorizableBinaryOperands( |
| 24210 | 24216 | }; |
| 24211 | 24217 | |
| 24212 | 24218 | if (lhs_is_vector and rhs_is_vector) { |
| 24213 | const lhs_len = lhs_ty.arrayLen(mod); | |
| 24214 | const rhs_len = rhs_ty.arrayLen(mod); | |
| 24219 | const lhs_len = lhs_ty.arrayLen(zcu); | |
| 24220 | const rhs_len = rhs_ty.arrayLen(zcu); | |
| 24215 | 24221 | if (lhs_len != rhs_len) { |
| 24216 | 24222 | const msg = msg: { |
| 24217 | 24223 | const msg = try sema.errMsg(src, "vector length mismatch", .{}); |
| ... | ... | @@ -24246,11 +24252,11 @@ fn resolveExportOptions( |
| 24246 | 24252 | block: *Block, |
| 24247 | 24253 | src: LazySrcLoc, |
| 24248 | 24254 | zir_ref: Zir.Inst.Ref, |
| 24249 | ) CompileError!Module.Export.Options { | |
| 24255 | ) CompileError!Zcu.Export.Options { | |
| 24250 | 24256 | const pt = sema.pt; |
| 24251 | const mod = pt.zcu; | |
| 24257 | const zcu = pt.zcu; | |
| 24252 | 24258 | const gpa = sema.gpa; |
| 24253 | const ip = &mod.intern_pool; | |
| 24259 | const ip = &zcu.intern_pool; | |
| 24254 | 24260 | const export_options_ty = try pt.getBuiltinType("ExportOptions"); |
| 24255 | 24261 | const air_ref = try sema.resolveInst(zir_ref); |
| 24256 | 24262 | const options = try sema.coerce(block, export_options_ty, air_ref, src); |
| ... | ... | @@ -24269,13 +24275,13 @@ fn resolveExportOptions( |
| 24269 | 24275 | const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{ |
| 24270 | 24276 | .needed_comptime_reason = "linkage of exported value must be comptime-known", |
| 24271 | 24277 | }); |
| 24272 | const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val); | |
| 24278 | const linkage = zcu.toEnum(std.builtin.GlobalLinkage, linkage_val); | |
| 24273 | 24279 | |
| 24274 | 24280 | const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "section", .no_embedded_nulls), section_src); |
| 24275 | 24281 | const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{ |
| 24276 | 24282 | .needed_comptime_reason = "linksection of exported value must be comptime-known", |
| 24277 | 24283 | }); |
| 24278 | const section = if (section_opt_val.optionalValue(mod)) |section_val| | |
| 24284 | const section = if (section_opt_val.optionalValue(zcu)) |section_val| | |
| 24279 | 24285 | try sema.toConstString(block, section_src, Air.internedToRef(section_val.toIntern()), .{ |
| 24280 | 24286 | .needed_comptime_reason = "linksection of exported value must be comptime-known", |
| 24281 | 24287 | }) |
| ... | ... | @@ -24286,7 +24292,7 @@ fn resolveExportOptions( |
| 24286 | 24292 | const visibility_val = try sema.resolveConstDefinedValue(block, visibility_src, visibility_operand, .{ |
| 24287 | 24293 | .needed_comptime_reason = "visibility of exported value must be comptime-known", |
| 24288 | 24294 | }); |
| 24289 | const visibility = mod.toEnum(std.builtin.SymbolVisibility, visibility_val); | |
| 24295 | const visibility = zcu.toEnum(std.builtin.SymbolVisibility, visibility_val); | |
| 24290 | 24296 | |
| 24291 | 24297 | if (name.len < 1) { |
| 24292 | 24298 | return sema.fail(block, name_src, "exported symbol name cannot be empty", .{}); |
| ... | ... | @@ -24349,7 +24355,7 @@ fn zirCmpxchg( |
| 24349 | 24355 | extended: Zir.Inst.Extended.InstData, |
| 24350 | 24356 | ) CompileError!Air.Inst.Ref { |
| 24351 | 24357 | const pt = sema.pt; |
| 24352 | const mod = pt.zcu; | |
| 24358 | const zcu = pt.zcu; | |
| 24353 | 24359 | const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data; |
| 24354 | 24360 | const air_tag: Air.Inst.Tag = switch (extended.small) { |
| 24355 | 24361 | 0 => .cmpxchg_weak, |
| ... | ... | @@ -24367,7 +24373,7 @@ fn zirCmpxchg( |
| 24367 | 24373 | // zig fmt: on |
| 24368 | 24374 | const expected_value = try sema.resolveInst(extra.expected_value); |
| 24369 | 24375 | const elem_ty = sema.typeOf(expected_value); |
| 24370 | if (elem_ty.zigTypeTag(mod) == .Float) { | |
| 24376 | if (elem_ty.zigTypeTag(zcu) == .Float) { | |
| 24371 | 24377 | return sema.fail( |
| 24372 | 24378 | block, |
| 24373 | 24379 | elem_ty_src, |
| ... | ... | @@ -24411,7 +24417,7 @@ fn zirCmpxchg( |
| 24411 | 24417 | const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { |
| 24412 | 24418 | if (try sema.resolveValue(expected_value)) |expected_val| { |
| 24413 | 24419 | if (try sema.resolveValue(new_value)) |new_val| { |
| 24414 | if (expected_val.isUndef(mod) or new_val.isUndef(mod)) { | |
| 24420 | if (expected_val.isUndef(zcu) or new_val.isUndef(zcu)) { | |
| 24415 | 24421 | // TODO: this should probably cause the memory stored at the pointer |
| 24416 | 24422 | // to become undef as well |
| 24417 | 24423 | return pt.undefRef(result_ty); |
| ... | ... | @@ -24420,7 +24426,7 @@ fn zirCmpxchg( |
| 24420 | 24426 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; |
| 24421 | 24427 | const result_val = try pt.intern(.{ .opt = .{ |
| 24422 | 24428 | .ty = result_ty.toIntern(), |
| 24423 | .val = if (stored_val.eql(expected_val, elem_ty, mod)) blk: { | |
| 24429 | .val = if (stored_val.eql(expected_val, elem_ty, zcu)) blk: { | |
| 24424 | 24430 | try sema.storePtr(block, src, ptr, new_value); |
| 24425 | 24431 | break :blk .none; |
| 24426 | 24432 | } else stored_val.toIntern(), |
| ... | ... | @@ -24450,16 +24456,16 @@ fn zirCmpxchg( |
| 24450 | 24456 | |
| 24451 | 24457 | fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 24452 | 24458 | const pt = sema.pt; |
| 24453 | const mod = pt.zcu; | |
| 24459 | const zcu = pt.zcu; | |
| 24454 | 24460 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24455 | 24461 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 24456 | 24462 | const src = block.nodeOffset(inst_data.src_node); |
| 24457 | 24463 | const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 24458 | 24464 | const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat"); |
| 24459 | 24465 | |
| 24460 | if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(pt)}); | |
| 24466 | if (!dest_ty.isVector(zcu)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(pt)}); | |
| 24461 | 24467 | |
| 24462 | if (!dest_ty.hasRuntimeBits(pt)) { | |
| 24468 | if (!dest_ty.hasRuntimeBits(zcu)) { | |
| 24463 | 24469 | const empty_aggregate = try pt.intern(.{ .aggregate = .{ |
| 24464 | 24470 | .ty = dest_ty.toIntern(), |
| 24465 | 24471 | .storage = .{ .elems = &[_]InternPool.Index{} }, |
| ... | ... | @@ -24468,10 +24474,10 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 24468 | 24474 | } |
| 24469 | 24475 | |
| 24470 | 24476 | const operand = try sema.resolveInst(extra.rhs); |
| 24471 | const scalar_ty = dest_ty.childType(mod); | |
| 24477 | const scalar_ty = dest_ty.childType(zcu); | |
| 24472 | 24478 | const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src); |
| 24473 | 24479 | if (try sema.resolveValue(scalar)) |scalar_val| { |
| 24474 | if (scalar_val.isUndef(mod)) return pt.undefRef(dest_ty); | |
| 24480 | if (scalar_val.isUndef(zcu)) return pt.undefRef(dest_ty); | |
| 24475 | 24481 | return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern()); |
| 24476 | 24482 | } |
| 24477 | 24483 | |
| ... | ... | @@ -24490,23 +24496,23 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24490 | 24496 | const operand = try sema.resolveInst(extra.rhs); |
| 24491 | 24497 | const operand_ty = sema.typeOf(operand); |
| 24492 | 24498 | const pt = sema.pt; |
| 24493 | const mod = pt.zcu; | |
| 24499 | const zcu = pt.zcu; | |
| 24494 | 24500 | |
| 24495 | if (operand_ty.zigTypeTag(mod) != .Vector) { | |
| 24501 | if (operand_ty.zigTypeTag(zcu) != .Vector) { | |
| 24496 | 24502 | return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(pt)}); |
| 24497 | 24503 | } |
| 24498 | 24504 | |
| 24499 | const scalar_ty = operand_ty.childType(mod); | |
| 24505 | const scalar_ty = operand_ty.childType(zcu); | |
| 24500 | 24506 | |
| 24501 | 24507 | // Type-check depending on operation. |
| 24502 | 24508 | switch (operation) { |
| 24503 | .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) { | |
| 24509 | .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) { | |
| 24504 | 24510 | .Int, .Bool => {}, |
| 24505 | 24511 | else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{ |
| 24506 | 24512 | @tagName(operation), operand_ty.fmt(pt), |
| 24507 | 24513 | }), |
| 24508 | 24514 | }, |
| 24509 | .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) { | |
| 24515 | .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) { | |
| 24510 | 24516 | .Int, .Float => {}, |
| 24511 | 24517 | else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{ |
| 24512 | 24518 | @tagName(operation), operand_ty.fmt(pt), |
| ... | ... | @@ -24514,7 +24520,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24514 | 24520 | }, |
| 24515 | 24521 | } |
| 24516 | 24522 | |
| 24517 | const vec_len = operand_ty.vectorLen(mod); | |
| 24523 | const vec_len = operand_ty.vectorLen(zcu); | |
| 24518 | 24524 | if (vec_len == 0) { |
| 24519 | 24525 | // TODO re-evaluate if we should introduce a "neutral value" for some operations, |
| 24520 | 24526 | // e.g. zero for add and one for mul. |
| ... | ... | @@ -24522,7 +24528,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24522 | 24528 | } |
| 24523 | 24529 | |
| 24524 | 24530 | if (try sema.resolveValue(operand)) |operand_val| { |
| 24525 | if (operand_val.isUndef(mod)) return pt.undefRef(scalar_ty); | |
| 24531 | if (operand_val.isUndef(zcu)) return pt.undefRef(scalar_ty); | |
| 24526 | 24532 | |
| 24527 | 24533 | var accum: Value = try operand_val.elemValue(pt, 0); |
| 24528 | 24534 | var i: u32 = 1; |
| ... | ... | @@ -24532,8 +24538,8 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24532 | 24538 | .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, pt), |
| 24533 | 24539 | .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, pt), |
| 24534 | 24540 | .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, pt), |
| 24535 | .Min => accum = accum.numberMin(elem_val, pt), | |
| 24536 | .Max => accum = accum.numberMax(elem_val, pt), | |
| 24541 | .Min => accum = accum.numberMin(elem_val, zcu), | |
| 24542 | .Max => accum = accum.numberMax(elem_val, zcu), | |
| 24537 | 24543 | .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty), |
| 24538 | 24544 | .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, pt), |
| 24539 | 24545 | } |
| ... | ... | @@ -24553,7 +24559,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24553 | 24559 | |
| 24554 | 24560 | fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 24555 | 24561 | const pt = sema.pt; |
| 24556 | const mod = pt.zcu; | |
| 24562 | const zcu = pt.zcu; | |
| 24557 | 24563 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24558 | 24564 | const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data; |
| 24559 | 24565 | const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| ... | ... | @@ -24566,8 +24572,8 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 24566 | 24572 | var mask = try sema.resolveInst(extra.mask); |
| 24567 | 24573 | var mask_ty = sema.typeOf(mask); |
| 24568 | 24574 | |
| 24569 | const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) { | |
| 24570 | .Array, .Vector => sema.typeOf(mask).arrayLen(mod), | |
| 24575 | const mask_len = switch (sema.typeOf(mask).zigTypeTag(zcu)) { | |
| 24576 | .Array, .Vector => sema.typeOf(mask).arrayLen(zcu), | |
| 24571 | 24577 | else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(pt)}), |
| 24572 | 24578 | }; |
| 24573 | 24579 | mask_ty = try pt.vectorType(.{ |
| ... | ... | @@ -24592,6 +24598,7 @@ fn analyzeShuffle( |
| 24592 | 24598 | mask_len: u32, |
| 24593 | 24599 | ) CompileError!Air.Inst.Ref { |
| 24594 | 24600 | const pt = sema.pt; |
| 24601 | const zcu = pt.zcu; | |
| 24595 | 24602 | const a_src = block.builtinCallArgSrc(src_node, 1); |
| 24596 | 24603 | const b_src = block.builtinCallArgSrc(src_node, 2); |
| 24597 | 24604 | const mask_src = block.builtinCallArgSrc(src_node, 3); |
| ... | ... | @@ -24603,16 +24610,16 @@ fn analyzeShuffle( |
| 24603 | 24610 | .child = elem_ty.toIntern(), |
| 24604 | 24611 | }); |
| 24605 | 24612 | |
| 24606 | const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(pt.zcu)) { | |
| 24607 | .Array, .Vector => sema.typeOf(a).arrayLen(pt.zcu), | |
| 24613 | const maybe_a_len = switch (sema.typeOf(a).zigTypeTag(zcu)) { | |
| 24614 | .Array, .Vector => sema.typeOf(a).arrayLen(zcu), | |
| 24608 | 24615 | .Undefined => null, |
| 24609 | 24616 | else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{ |
| 24610 | 24617 | elem_ty.fmt(pt), |
| 24611 | 24618 | sema.typeOf(a).fmt(pt), |
| 24612 | 24619 | }), |
| 24613 | 24620 | }; |
| 24614 | const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(pt.zcu)) { | |
| 24615 | .Array, .Vector => sema.typeOf(b).arrayLen(pt.zcu), | |
| 24621 | const maybe_b_len = switch (sema.typeOf(b).zigTypeTag(zcu)) { | |
| 24622 | .Array, .Vector => sema.typeOf(b).arrayLen(zcu), | |
| 24616 | 24623 | .Undefined => null, |
| 24617 | 24624 | else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{ |
| 24618 | 24625 | elem_ty.fmt(pt), |
| ... | ... | @@ -24644,9 +24651,9 @@ fn analyzeShuffle( |
| 24644 | 24651 | |
| 24645 | 24652 | for (0..@intCast(mask_len)) |i| { |
| 24646 | 24653 | const elem = try mask.elemValue(pt, i); |
| 24647 | if (elem.isUndef(pt.zcu)) continue; | |
| 24654 | if (elem.isUndef(zcu)) continue; | |
| 24648 | 24655 | const elem_resolved = try sema.resolveLazyValue(elem); |
| 24649 | const int = elem_resolved.toSignedInt(pt); | |
| 24656 | const int = elem_resolved.toSignedInt(zcu); | |
| 24650 | 24657 | var unsigned: u32 = undefined; |
| 24651 | 24658 | var chosen: u32 = undefined; |
| 24652 | 24659 | if (int >= 0) { |
| ... | ... | @@ -24681,11 +24688,11 @@ fn analyzeShuffle( |
| 24681 | 24688 | const values = try sema.arena.alloc(InternPool.Index, mask_len); |
| 24682 | 24689 | for (values, 0..) |*value, i| { |
| 24683 | 24690 | const mask_elem_val = try mask.elemValue(pt, i); |
| 24684 | if (mask_elem_val.isUndef(pt.zcu)) { | |
| 24691 | if (mask_elem_val.isUndef(zcu)) { | |
| 24685 | 24692 | value.* = try pt.intern(.{ .undef = elem_ty.toIntern() }); |
| 24686 | 24693 | continue; |
| 24687 | 24694 | } |
| 24688 | const int = mask_elem_val.toSignedInt(pt); | |
| 24695 | const int = mask_elem_val.toSignedInt(zcu); | |
| 24689 | 24696 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int); |
| 24690 | 24697 | values[i] = (try (if (int >= 0) a_val else b_val).elemValue(pt, unsigned)).toIntern(); |
| 24691 | 24698 | } |
| ... | ... | @@ -24743,7 +24750,7 @@ fn analyzeShuffle( |
| 24743 | 24750 | |
| 24744 | 24751 | fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 24745 | 24752 | const pt = sema.pt; |
| 24746 | const mod = pt.zcu; | |
| 24753 | const zcu = pt.zcu; | |
| 24747 | 24754 | const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data; |
| 24748 | 24755 | |
| 24749 | 24756 | const src = block.nodeOffset(extra.node); |
| ... | ... | @@ -24757,8 +24764,8 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24757 | 24764 | const pred_uncoerced = try sema.resolveInst(extra.pred); |
| 24758 | 24765 | const pred_ty = sema.typeOf(pred_uncoerced); |
| 24759 | 24766 | |
| 24760 | const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) { | |
| 24761 | .Vector, .Array => pred_ty.arrayLen(mod), | |
| 24767 | const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(zcu)) { | |
| 24768 | .Vector, .Array => pred_ty.arrayLen(zcu), | |
| 24762 | 24769 | else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(pt)}), |
| 24763 | 24770 | }; |
| 24764 | 24771 | const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64)); |
| ... | ... | @@ -24781,13 +24788,13 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24781 | 24788 | const maybe_b = try sema.resolveValue(b); |
| 24782 | 24789 | |
| 24783 | 24790 | const runtime_src = if (maybe_pred) |pred_val| rs: { |
| 24784 | if (pred_val.isUndef(mod)) return pt.undefRef(vec_ty); | |
| 24791 | if (pred_val.isUndef(zcu)) return pt.undefRef(vec_ty); | |
| 24785 | 24792 | |
| 24786 | 24793 | if (maybe_a) |a_val| { |
| 24787 | if (a_val.isUndef(mod)) return pt.undefRef(vec_ty); | |
| 24794 | if (a_val.isUndef(zcu)) return pt.undefRef(vec_ty); | |
| 24788 | 24795 | |
| 24789 | 24796 | if (maybe_b) |b_val| { |
| 24790 | if (b_val.isUndef(mod)) return pt.undefRef(vec_ty); | |
| 24797 | if (b_val.isUndef(zcu)) return pt.undefRef(vec_ty); | |
| 24791 | 24798 | |
| 24792 | 24799 | const elems = try sema.gpa.alloc(InternPool.Index, vec_len); |
| 24793 | 24800 | defer sema.gpa.free(elems); |
| ... | ... | @@ -24806,16 +24813,16 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24806 | 24813 | } |
| 24807 | 24814 | } else { |
| 24808 | 24815 | if (maybe_b) |b_val| { |
| 24809 | if (b_val.isUndef(mod)) return pt.undefRef(vec_ty); | |
| 24816 | if (b_val.isUndef(zcu)) return pt.undefRef(vec_ty); | |
| 24810 | 24817 | } |
| 24811 | 24818 | break :rs a_src; |
| 24812 | 24819 | } |
| 24813 | 24820 | } else rs: { |
| 24814 | 24821 | if (maybe_a) |a_val| { |
| 24815 | if (a_val.isUndef(mod)) return pt.undefRef(vec_ty); | |
| 24822 | if (a_val.isUndef(zcu)) return pt.undefRef(vec_ty); | |
| 24816 | 24823 | } |
| 24817 | 24824 | if (maybe_b) |b_val| { |
| 24818 | if (b_val.isUndef(mod)) return pt.undefRef(vec_ty); | |
| 24825 | if (b_val.isUndef(zcu)) return pt.undefRef(vec_ty); | |
| 24819 | 24826 | } |
| 24820 | 24827 | break :rs pred_src; |
| 24821 | 24828 | }; |
| ... | ... | @@ -24882,7 +24889,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 24882 | 24889 | |
| 24883 | 24890 | fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 24884 | 24891 | const pt = sema.pt; |
| 24885 | const mod = pt.zcu; | |
| 24892 | const zcu = pt.zcu; | |
| 24886 | 24893 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24887 | 24894 | const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; |
| 24888 | 24895 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -24899,7 +24906,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 24899 | 24906 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false); |
| 24900 | 24907 | const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation); |
| 24901 | 24908 | |
| 24902 | switch (elem_ty.zigTypeTag(mod)) { | |
| 24909 | switch (elem_ty.zigTypeTag(zcu)) { | |
| 24903 | 24910 | .Enum => if (op != .Xchg) { |
| 24904 | 24911 | return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{}); |
| 24905 | 24912 | }, |
| ... | ... | @@ -24939,12 +24946,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 24939 | 24946 | .Xchg => operand_val, |
| 24940 | 24947 | .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty), |
| 24941 | 24948 | .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty), |
| 24942 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, pt), | |
| 24943 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, pt), | |
| 24944 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, pt), | |
| 24945 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, pt), | |
| 24946 | .Max => stored_val.numberMax (operand_val, pt), | |
| 24947 | .Min => stored_val.numberMin (operand_val, pt), | |
| 24949 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, pt ), | |
| 24950 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, pt ), | |
| 24951 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, pt ), | |
| 24952 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, pt ), | |
| 24953 | .Max => stored_val.numberMax (operand_val, zcu), | |
| 24954 | .Min => stored_val.numberMin (operand_val, zcu), | |
| 24948 | 24955 | // zig fmt: on |
| 24949 | 24956 | }; |
| 24950 | 24957 | try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty); |
| ... | ... | @@ -25021,19 +25028,19 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 25021 | 25028 | const maybe_mulend2 = try sema.resolveValue(mulend2); |
| 25022 | 25029 | const maybe_addend = try sema.resolveValue(addend); |
| 25023 | 25030 | const pt = sema.pt; |
| 25024 | const mod = pt.zcu; | |
| 25031 | const zcu = pt.zcu; | |
| 25025 | 25032 | |
| 25026 | switch (ty.scalarType(mod).zigTypeTag(mod)) { | |
| 25033 | switch (ty.scalarType(zcu).zigTypeTag(zcu)) { | |
| 25027 | 25034 | .ComptimeFloat, .Float => {}, |
| 25028 | 25035 | else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(pt)}), |
| 25029 | 25036 | } |
| 25030 | 25037 | |
| 25031 | 25038 | const runtime_src = if (maybe_mulend1) |mulend1_val| rs: { |
| 25032 | 25039 | if (maybe_mulend2) |mulend2_val| { |
| 25033 | if (mulend2_val.isUndef(mod)) return pt.undefRef(ty); | |
| 25040 | if (mulend2_val.isUndef(zcu)) return pt.undefRef(ty); | |
| 25034 | 25041 | |
| 25035 | 25042 | if (maybe_addend) |addend_val| { |
| 25036 | if (addend_val.isUndef(mod)) return pt.undefRef(ty); | |
| 25043 | if (addend_val.isUndef(zcu)) return pt.undefRef(ty); | |
| 25037 | 25044 | const result_val = try Value.mulAdd(ty, mulend1_val, mulend2_val, addend_val, sema.arena, pt); |
| 25038 | 25045 | return Air.internedToRef(result_val.toIntern()); |
| 25039 | 25046 | } else { |
| ... | ... | @@ -25041,16 +25048,16 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 25041 | 25048 | } |
| 25042 | 25049 | } else { |
| 25043 | 25050 | if (maybe_addend) |addend_val| { |
| 25044 | if (addend_val.isUndef(mod)) return pt.undefRef(ty); | |
| 25051 | if (addend_val.isUndef(zcu)) return pt.undefRef(ty); | |
| 25045 | 25052 | } |
| 25046 | 25053 | break :rs mulend2_src; |
| 25047 | 25054 | } |
| 25048 | 25055 | } else rs: { |
| 25049 | 25056 | if (maybe_mulend2) |mulend2_val| { |
| 25050 | if (mulend2_val.isUndef(mod)) return pt.undefRef(ty); | |
| 25057 | if (mulend2_val.isUndef(zcu)) return pt.undefRef(ty); | |
| 25051 | 25058 | } |
| 25052 | 25059 | if (maybe_addend) |addend_val| { |
| 25053 | if (addend_val.isUndef(mod)) return pt.undefRef(ty); | |
| 25060 | if (addend_val.isUndef(zcu)) return pt.undefRef(ty); | |
| 25054 | 25061 | } |
| 25055 | 25062 | break :rs mulend1_src; |
| 25056 | 25063 | }; |
| ... | ... | @@ -25073,7 +25080,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 25073 | 25080 | defer tracy.end(); |
| 25074 | 25081 | |
| 25075 | 25082 | const pt = sema.pt; |
| 25076 | const mod = pt.zcu; | |
| 25083 | const zcu = pt.zcu; | |
| 25077 | 25084 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 25078 | 25085 | const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 25079 | 25086 | const func_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| ... | ... | @@ -25089,7 +25096,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 25089 | 25096 | const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ |
| 25090 | 25097 | .needed_comptime_reason = "call modifier must be comptime-known", |
| 25091 | 25098 | }); |
| 25092 | var modifier = mod.toEnum(std.builtin.CallModifier, modifier_val); | |
| 25099 | var modifier = zcu.toEnum(std.builtin.CallModifier, modifier_val); | |
| 25093 | 25100 | switch (modifier) { |
| 25094 | 25101 | // These can be upgraded to comptime or nosuspend calls. |
| 25095 | 25102 | .auto, .never_tail, .no_async => { |
| ... | ... | @@ -25135,11 +25142,11 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 25135 | 25142 | const args = try sema.resolveInst(extra.args); |
| 25136 | 25143 | |
| 25137 | 25144 | const args_ty = sema.typeOf(args); |
| 25138 | if (!args_ty.isTuple(mod) and args_ty.toIntern() != .empty_struct_type) { | |
| 25145 | if (!args_ty.isTuple(zcu) and args_ty.toIntern() != .empty_struct_type) { | |
| 25139 | 25146 | return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)}); |
| 25140 | 25147 | } |
| 25141 | 25148 | |
| 25142 | const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(mod)); | |
| 25149 | const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(zcu)); | |
| 25143 | 25150 | for (resolved_args, 0..) |*resolved, i| { |
| 25144 | 25151 | resolved.* = try sema.tupleFieldValByIndex(block, args_src, args, @intCast(i), args_ty); |
| 25145 | 25152 | } |
| ... | ... | @@ -25219,7 +25226,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25219 | 25226 | var actual_parent_ptr_info: InternPool.Key.PtrType = .{ |
| 25220 | 25227 | .child = parent_ty.toIntern(), |
| 25221 | 25228 | .flags = .{ |
| 25222 | .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema), | |
| 25229 | .alignment = try parent_ptr_ty.ptrAlignmentSema(pt), | |
| 25223 | 25230 | .is_const = field_ptr_info.flags.is_const, |
| 25224 | 25231 | .is_volatile = field_ptr_info.flags.is_volatile, |
| 25225 | 25232 | .is_allowzero = field_ptr_info.flags.is_allowzero, |
| ... | ... | @@ -25231,7 +25238,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25231 | 25238 | var actual_field_ptr_info: InternPool.Key.PtrType = .{ |
| 25232 | 25239 | .child = field_ty.toIntern(), |
| 25233 | 25240 | .flags = .{ |
| 25234 | .alignment = try field_ptr_ty.ptrAlignmentAdvanced(pt, .sema), | |
| 25241 | .alignment = try field_ptr_ty.ptrAlignmentSema(pt), | |
| 25235 | 25242 | .is_const = field_ptr_info.flags.is_const, |
| 25236 | 25243 | .is_volatile = field_ptr_info.flags.is_volatile, |
| 25237 | 25244 | .is_allowzero = field_ptr_info.flags.is_allowzero, |
| ... | ... | @@ -25242,13 +25249,20 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25242 | 25249 | switch (parent_ty.containerLayout(zcu)) { |
| 25243 | 25250 | .auto => { |
| 25244 | 25251 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict( |
| 25245 | if (zcu.typeToStruct(parent_ty)) |struct_obj| try pt.structFieldAlignmentAdvanced( | |
| 25252 | if (zcu.typeToStruct(parent_ty)) |struct_obj| try field_ty.structFieldAlignmentAdvanced( | |
| 25246 | 25253 | struct_obj.fieldAlign(ip, field_index), |
| 25247 | field_ty, | |
| 25248 | 25254 | struct_obj.layout, |
| 25249 | 25255 | .sema, |
| 25256 | pt.zcu, | |
| 25257 | pt.tid, | |
| 25250 | 25258 | ) else if (zcu.typeToUnion(parent_ty)) |union_obj| |
| 25251 | try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema) | |
| 25259 | try Type.unionFieldNormalAlignmentAdvanced( | |
| 25260 | union_obj, | |
| 25261 | field_index, | |
| 25262 | .sema, | |
| 25263 | pt.zcu, | |
| 25264 | pt.tid, | |
| 25265 | ) | |
| 25252 | 25266 | else |
| 25253 | 25267 | actual_field_ptr_info.flags.alignment, |
| 25254 | 25268 | ); |
| ... | ... | @@ -25257,7 +25271,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25257 | 25271 | actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 }; |
| 25258 | 25272 | }, |
| 25259 | 25273 | .@"extern" => { |
| 25260 | const field_offset = parent_ty.structFieldOffset(field_index, pt); | |
| 25274 | const field_offset = parent_ty.structFieldOffset(field_index, zcu); | |
| 25261 | 25275 | actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0) |
| 25262 | 25276 | Alignment.fromLog2Units(@ctz(field_offset)) |
| 25263 | 25277 | else |
| ... | ... | @@ -25287,7 +25301,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25287 | 25301 | .Struct => switch (parent_ty.containerLayout(zcu)) { |
| 25288 | 25302 | .auto => {}, |
| 25289 | 25303 | .@"extern" => { |
| 25290 | const byte_offset = parent_ty.structFieldOffset(field_index, pt); | |
| 25304 | const byte_offset = parent_ty.structFieldOffset(field_index, zcu); | |
| 25291 | 25305 | const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty); |
| 25292 | 25306 | break :result Air.internedToRef(parent_ptr_val.toIntern()); |
| 25293 | 25307 | }, |
| ... | ... | @@ -25428,7 +25442,7 @@ fn analyzeMinMax( |
| 25428 | 25442 | assert(operands.len == operand_srcs.len); |
| 25429 | 25443 | assert(operands.len > 0); |
| 25430 | 25444 | const pt = sema.pt; |
| 25431 | const mod = pt.zcu; | |
| 25445 | const zcu = pt.zcu; | |
| 25432 | 25446 | |
| 25433 | 25447 | if (operands.len == 1) return operands[0]; |
| 25434 | 25448 | |
| ... | ... | @@ -25466,20 +25480,20 @@ fn analyzeMinMax( |
| 25466 | 25480 | switch (bounds_status) { |
| 25467 | 25481 | .unknown, .defined => refine_bounds: { |
| 25468 | 25482 | const ty = sema.typeOf(operand); |
| 25469 | if (!ty.scalarType(mod).isInt(mod) and !ty.scalarType(mod).eql(Type.comptime_int, mod)) { | |
| 25483 | if (!ty.scalarType(zcu).isInt(zcu) and !ty.scalarType(zcu).eql(Type.comptime_int, zcu)) { | |
| 25470 | 25484 | bounds_status = .non_integral; |
| 25471 | 25485 | break :refine_bounds; |
| 25472 | 25486 | } |
| 25473 | 25487 | const scalar_bounds: ?[2]Value = bounds: { |
| 25474 | if (!ty.isVector(mod)) break :bounds try uncoerced_val.intValueBounds(pt); | |
| 25488 | if (!ty.isVector(zcu)) break :bounds try uncoerced_val.intValueBounds(pt); | |
| 25475 | 25489 | var cur_bounds: [2]Value = try Value.intValueBounds(try uncoerced_val.elemValue(pt, 0), pt) orelse break :bounds null; |
| 25476 | const len = try sema.usizeCast(block, src, ty.vectorLen(mod)); | |
| 25490 | const len = try sema.usizeCast(block, src, ty.vectorLen(zcu)); | |
| 25477 | 25491 | for (1..len) |i| { |
| 25478 | 25492 | const elem = try uncoerced_val.elemValue(pt, i); |
| 25479 | 25493 | const elem_bounds = try elem.intValueBounds(pt) orelse break :bounds null; |
| 25480 | 25494 | cur_bounds = .{ |
| 25481 | Value.numberMin(elem_bounds[0], cur_bounds[0], pt), | |
| 25482 | Value.numberMax(elem_bounds[1], cur_bounds[1], pt), | |
| 25495 | Value.numberMin(elem_bounds[0], cur_bounds[0], zcu), | |
| 25496 | Value.numberMax(elem_bounds[1], cur_bounds[1], zcu), | |
| 25483 | 25497 | }; |
| 25484 | 25498 | } |
| 25485 | 25499 | break :bounds cur_bounds; |
| ... | ... | @@ -25490,8 +25504,8 @@ fn analyzeMinMax( |
| 25490 | 25504 | cur_max_scalar = bounds[1]; |
| 25491 | 25505 | bounds_status = .defined; |
| 25492 | 25506 | } else { |
| 25493 | cur_min_scalar = opFunc(cur_min_scalar, bounds[0], pt); | |
| 25494 | cur_max_scalar = opFunc(cur_max_scalar, bounds[1], pt); | |
| 25507 | cur_min_scalar = opFunc(cur_min_scalar, bounds[0], zcu); | |
| 25508 | cur_max_scalar = opFunc(cur_max_scalar, bounds[1], zcu); | |
| 25495 | 25509 | } |
| 25496 | 25510 | } |
| 25497 | 25511 | }, |
| ... | ... | @@ -25509,7 +25523,7 @@ fn analyzeMinMax( |
| 25509 | 25523 | const operand_val = try sema.resolveLazyValue(simd_op.rhs_val.?); // we checked the operand was resolvable above |
| 25510 | 25524 | |
| 25511 | 25525 | const vec_len = simd_op.len orelse { |
| 25512 | const result_val = opFunc(cur_val, operand_val, pt); | |
| 25526 | const result_val = opFunc(cur_val, operand_val, zcu); | |
| 25513 | 25527 | cur_minmax = Air.internedToRef(result_val.toIntern()); |
| 25514 | 25528 | continue; |
| 25515 | 25529 | }; |
| ... | ... | @@ -25517,7 +25531,7 @@ fn analyzeMinMax( |
| 25517 | 25531 | for (elems, 0..) |*elem, i| { |
| 25518 | 25532 | const lhs_elem_val = try cur_val.elemValue(pt, i); |
| 25519 | 25533 | const rhs_elem_val = try operand_val.elemValue(pt, i); |
| 25520 | const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, pt); | |
| 25534 | const uncoerced_elem = opFunc(lhs_elem_val, rhs_elem_val, zcu); | |
| 25521 | 25535 | elem.* = (try pt.getCoerced(uncoerced_elem, simd_op.scalar_ty)).toIntern(); |
| 25522 | 25536 | } |
| 25523 | 25537 | cur_minmax = Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| ... | ... | @@ -25537,19 +25551,19 @@ fn analyzeMinMax( |
| 25537 | 25551 | const val = (try sema.resolveValue(ct_minmax_ref)).?; |
| 25538 | 25552 | const orig_ty = sema.typeOf(ct_minmax_ref); |
| 25539 | 25553 | |
| 25540 | if (opt_runtime_idx == null and orig_ty.scalarType(mod).eql(Type.comptime_int, mod)) { | |
| 25554 | if (opt_runtime_idx == null and orig_ty.scalarType(zcu).eql(Type.comptime_int, zcu)) { | |
| 25541 | 25555 | // If all arguments were `comptime_int`, and there are no runtime args, we'll preserve that type |
| 25542 | 25556 | break :refine; |
| 25543 | 25557 | } |
| 25544 | 25558 | |
| 25545 | 25559 | // We can't refine float types |
| 25546 | if (orig_ty.scalarType(mod).isAnyFloat()) break :refine; | |
| 25560 | if (orig_ty.scalarType(zcu).isAnyFloat()) break :refine; | |
| 25547 | 25561 | |
| 25548 | 25562 | assert(bounds_status == .defined); // there was a non-comptime-int integral comptime-known arg |
| 25549 | 25563 | |
| 25550 | 25564 | const refined_scalar_ty = try pt.intFittingRange(cur_min_scalar, cur_max_scalar); |
| 25551 | const refined_ty = if (orig_ty.isVector(mod)) try pt.vectorType(.{ | |
| 25552 | .len = orig_ty.vectorLen(mod), | |
| 25565 | const refined_ty = if (orig_ty.isVector(zcu)) try pt.vectorType(.{ | |
| 25566 | .len = orig_ty.vectorLen(zcu), | |
| 25553 | 25567 | .child = refined_scalar_ty.toIntern(), |
| 25554 | 25568 | }) else refined_scalar_ty; |
| 25555 | 25569 | |
| ... | ... | @@ -25570,7 +25584,7 @@ fn analyzeMinMax( |
| 25570 | 25584 | // If the comptime-known part is undef we can avoid emitting actual instructions later |
| 25571 | 25585 | const known_undef = if (cur_minmax) |operand| blk: { |
| 25572 | 25586 | const val = (try sema.resolveValue(operand)).?; |
| 25573 | break :blk val.isUndef(mod); | |
| 25587 | break :blk val.isUndef(zcu); | |
| 25574 | 25588 | } else false; |
| 25575 | 25589 | |
| 25576 | 25590 | if (cur_minmax == null) { |
| ... | ... | @@ -25580,8 +25594,8 @@ fn analyzeMinMax( |
| 25580 | 25594 | cur_minmax = operands[0]; |
| 25581 | 25595 | cur_minmax_src = runtime_src; |
| 25582 | 25596 | runtime_known.unset(0); // don't look at this operand in the loop below |
| 25583 | const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(mod); | |
| 25584 | if (scalar_ty.isInt(mod)) { | |
| 25597 | const scalar_ty = sema.typeOf(cur_minmax.?).scalarType(zcu); | |
| 25598 | if (scalar_ty.isInt(zcu)) { | |
| 25585 | 25599 | cur_min_scalar = try scalar_ty.minInt(pt, scalar_ty); |
| 25586 | 25600 | cur_max_scalar = try scalar_ty.maxInt(pt, scalar_ty); |
| 25587 | 25601 | bounds_status = .defined; |
| ... | ... | @@ -25605,7 +25619,7 @@ fn analyzeMinMax( |
| 25605 | 25619 | // Compute the bounds of this type |
| 25606 | 25620 | switch (bounds_status) { |
| 25607 | 25621 | .unknown, .defined => refine_bounds: { |
| 25608 | const scalar_ty = sema.typeOf(rhs).scalarType(mod); | |
| 25622 | const scalar_ty = sema.typeOf(rhs).scalarType(zcu); | |
| 25609 | 25623 | if (scalar_ty.isAnyFloat()) { |
| 25610 | 25624 | bounds_status = .non_integral; |
| 25611 | 25625 | break :refine_bounds; |
| ... | ... | @@ -25617,8 +25631,8 @@ fn analyzeMinMax( |
| 25617 | 25631 | cur_max_scalar = scalar_max; |
| 25618 | 25632 | bounds_status = .defined; |
| 25619 | 25633 | } else { |
| 25620 | cur_min_scalar = opFunc(cur_min_scalar, scalar_min, pt); | |
| 25621 | cur_max_scalar = opFunc(cur_max_scalar, scalar_max, pt); | |
| 25634 | cur_min_scalar = opFunc(cur_min_scalar, scalar_min, zcu); | |
| 25635 | cur_max_scalar = opFunc(cur_max_scalar, scalar_max, zcu); | |
| 25622 | 25636 | } |
| 25623 | 25637 | }, |
| 25624 | 25638 | .non_integral => {}, |
| ... | ... | @@ -25627,18 +25641,18 @@ fn analyzeMinMax( |
| 25627 | 25641 | |
| 25628 | 25642 | // Finally, refine the type based on the known bounds. |
| 25629 | 25643 | const unrefined_ty = sema.typeOf(cur_minmax.?); |
| 25630 | if (unrefined_ty.scalarType(mod).isAnyFloat()) { | |
| 25644 | if (unrefined_ty.scalarType(zcu).isAnyFloat()) { | |
| 25631 | 25645 | // We can't refine floats, so we're done. |
| 25632 | 25646 | return cur_minmax.?; |
| 25633 | 25647 | } |
| 25634 | 25648 | assert(bounds_status == .defined); // there were integral runtime operands |
| 25635 | 25649 | const refined_scalar_ty = try pt.intFittingRange(cur_min_scalar, cur_max_scalar); |
| 25636 | const refined_ty = if (unrefined_ty.isVector(mod)) try pt.vectorType(.{ | |
| 25637 | .len = unrefined_ty.vectorLen(mod), | |
| 25650 | const refined_ty = if (unrefined_ty.isVector(zcu)) try pt.vectorType(.{ | |
| 25651 | .len = unrefined_ty.vectorLen(zcu), | |
| 25638 | 25652 | .child = refined_scalar_ty.toIntern(), |
| 25639 | 25653 | }) else refined_scalar_ty; |
| 25640 | 25654 | |
| 25641 | if (!refined_ty.eql(unrefined_ty, mod)) { | |
| 25655 | if (!refined_ty.eql(unrefined_ty, zcu)) { | |
| 25642 | 25656 | // We've reduced the type - cast the result down |
| 25643 | 25657 | return block.addTyOp(.intcast, refined_ty, cur_minmax.?); |
| 25644 | 25658 | } |
| ... | ... | @@ -25648,9 +25662,9 @@ fn analyzeMinMax( |
| 25648 | 25662 | |
| 25649 | 25663 | fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref { |
| 25650 | 25664 | const pt = sema.pt; |
| 25651 | const mod = pt.zcu; | |
| 25665 | const zcu = pt.zcu; | |
| 25652 | 25666 | const ptr_ty = sema.typeOf(ptr); |
| 25653 | const info = ptr_ty.ptrInfo(mod); | |
| 25667 | const info = ptr_ty.ptrInfo(zcu); | |
| 25654 | 25668 | if (info.flags.size == .One) { |
| 25655 | 25669 | // Already an array pointer. |
| 25656 | 25670 | return ptr; |
| ... | ... | @@ -25670,7 +25684,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A |
| 25670 | 25684 | }, |
| 25671 | 25685 | }); |
| 25672 | 25686 | const non_slice_ptr = if (info.flags.size == .Slice) |
| 25673 | try block.addTyOp(.slice_ptr, ptr_ty.slicePtrFieldType(mod), ptr) | |
| 25687 | try block.addTyOp(.slice_ptr, ptr_ty.slicePtrFieldType(zcu), ptr) | |
| 25674 | 25688 | else |
| 25675 | 25689 | ptr; |
| 25676 | 25690 | return block.addBitCast(new_ty, non_slice_ptr); |
| ... | ... | @@ -25689,10 +25703,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25689 | 25703 | const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr); |
| 25690 | 25704 | const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr); |
| 25691 | 25705 | const pt = sema.pt; |
| 25692 | const mod = pt.zcu; | |
| 25693 | const target = mod.getTarget(); | |
| 25706 | const zcu = pt.zcu; | |
| 25707 | const target = zcu.getTarget(); | |
| 25694 | 25708 | |
| 25695 | if (dest_ty.isConstPtr(mod)) { | |
| 25709 | if (dest_ty.isConstPtr(zcu)) { | |
| 25696 | 25710 | return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{}); |
| 25697 | 25711 | } |
| 25698 | 25712 | |
| ... | ... | @@ -25755,7 +25769,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25755 | 25769 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: { |
| 25756 | 25770 | if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src; |
| 25757 | 25771 | if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| { |
| 25758 | const len_u64 = (try len_val.?.getUnsignedIntAdvanced(pt, .sema)).?; | |
| 25772 | const len_u64 = try len_val.?.toUnsignedIntSema(pt); | |
| 25759 | 25773 | const len = try sema.usizeCast(block, dest_src, len_u64); |
| 25760 | 25774 | for (0..len) |i| { |
| 25761 | 25775 | const elem_index = try pt.intRef(Type.usize, i); |
| ... | ... | @@ -25798,12 +25812,12 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25798 | 25812 | // lowering. The AIR instruction requires pointers with element types of |
| 25799 | 25813 | // equal ABI size. |
| 25800 | 25814 | |
| 25801 | if (dest_ty.zigTypeTag(mod) != .Pointer or src_ty.zigTypeTag(mod) != .Pointer) { | |
| 25815 | if (dest_ty.zigTypeTag(zcu) != .Pointer or src_ty.zigTypeTag(zcu) != .Pointer) { | |
| 25802 | 25816 | return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the source or destination iterable is a tuple", .{}); |
| 25803 | 25817 | } |
| 25804 | 25818 | |
| 25805 | const dest_elem_ty = dest_ty.elemType2(mod); | |
| 25806 | const src_elem_ty = src_ty.elemType2(mod); | |
| 25819 | const dest_elem_ty = dest_ty.elemType2(zcu); | |
| 25820 | const src_elem_ty = src_ty.elemType2(zcu); | |
| 25807 | 25821 | if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src, null)) { |
| 25808 | 25822 | return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{}); |
| 25809 | 25823 | } |
| ... | ... | @@ -25827,7 +25841,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25827 | 25841 | // Change the src from slice to a many pointer, to avoid multiple ptr |
| 25828 | 25842 | // slice extractions in AIR instructions. |
| 25829 | 25843 | const new_src_ptr_ty = sema.typeOf(new_src_ptr); |
| 25830 | if (new_src_ptr_ty.isSlice(mod)) { | |
| 25844 | if (new_src_ptr_ty.isSlice(zcu)) { | |
| 25831 | 25845 | new_src_ptr = try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty); |
| 25832 | 25846 | } |
| 25833 | 25847 | } else if (dest_len == .none and len_val == null) { |
| ... | ... | @@ -25835,7 +25849,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25835 | 25849 | const dest_ptr_ptr = try sema.analyzeRef(block, dest_src, new_dest_ptr); |
| 25836 | 25850 | new_dest_ptr = try sema.analyzeSlice(block, dest_src, dest_ptr_ptr, .zero, src_len, .none, LazySrcLoc.unneeded, dest_src, dest_src, dest_src, false); |
| 25837 | 25851 | const new_src_ptr_ty = sema.typeOf(new_src_ptr); |
| 25838 | if (new_src_ptr_ty.isSlice(mod)) { | |
| 25852 | if (new_src_ptr_ty.isSlice(zcu)) { | |
| 25839 | 25853 | new_src_ptr = try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty); |
| 25840 | 25854 | } |
| 25841 | 25855 | } |
| ... | ... | @@ -25854,10 +25868,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25854 | 25868 | // Extract raw pointer from dest slice. The AIR instructions could support them, but |
| 25855 | 25869 | // it would cause redundant machine code instructions. |
| 25856 | 25870 | const new_dest_ptr_ty = sema.typeOf(new_dest_ptr); |
| 25857 | const raw_dest_ptr = if (new_dest_ptr_ty.isSlice(mod)) | |
| 25871 | const raw_dest_ptr = if (new_dest_ptr_ty.isSlice(zcu)) | |
| 25858 | 25872 | try sema.analyzeSlicePtr(block, dest_src, new_dest_ptr, new_dest_ptr_ty) |
| 25859 | else if (new_dest_ptr_ty.ptrSize(mod) == .One) ptr: { | |
| 25860 | var dest_manyptr_ty_key = mod.intern_pool.indexToKey(new_dest_ptr_ty.toIntern()).ptr_type; | |
| 25873 | else if (new_dest_ptr_ty.ptrSize(zcu) == .One) ptr: { | |
| 25874 | var dest_manyptr_ty_key = zcu.intern_pool.indexToKey(new_dest_ptr_ty.toIntern()).ptr_type; | |
| 25861 | 25875 | assert(dest_manyptr_ty_key.flags.size == .One); |
| 25862 | 25876 | dest_manyptr_ty_key.child = dest_elem_ty.toIntern(); |
| 25863 | 25877 | dest_manyptr_ty_key.flags.size = .Many; |
| ... | ... | @@ -25865,10 +25879,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25865 | 25879 | } else new_dest_ptr; |
| 25866 | 25880 | |
| 25867 | 25881 | const new_src_ptr_ty = sema.typeOf(new_src_ptr); |
| 25868 | const raw_src_ptr = if (new_src_ptr_ty.isSlice(mod)) | |
| 25882 | const raw_src_ptr = if (new_src_ptr_ty.isSlice(zcu)) | |
| 25869 | 25883 | try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty) |
| 25870 | else if (new_src_ptr_ty.ptrSize(mod) == .One) ptr: { | |
| 25871 | var src_manyptr_ty_key = mod.intern_pool.indexToKey(new_src_ptr_ty.toIntern()).ptr_type; | |
| 25884 | else if (new_src_ptr_ty.ptrSize(zcu) == .One) ptr: { | |
| 25885 | var src_manyptr_ty_key = zcu.intern_pool.indexToKey(new_src_ptr_ty.toIntern()).ptr_type; | |
| 25872 | 25886 | assert(src_manyptr_ty_key.flags.size == .One); |
| 25873 | 25887 | src_manyptr_ty_key.child = src_elem_ty.toIntern(); |
| 25874 | 25888 | src_manyptr_ty_key.flags.size = .Many; |
| ... | ... | @@ -25896,9 +25910,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25896 | 25910 | |
| 25897 | 25911 | fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 25898 | 25912 | const pt = sema.pt; |
| 25899 | const mod = pt.zcu; | |
| 25913 | const zcu = pt.zcu; | |
| 25900 | 25914 | const gpa = sema.gpa; |
| 25901 | const ip = &mod.intern_pool; | |
| 25915 | const ip = &zcu.intern_pool; | |
| 25902 | 25916 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 25903 | 25917 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 25904 | 25918 | const src = block.nodeOffset(inst_data.src_node); |
| ... | ... | @@ -25909,17 +25923,17 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25909 | 25923 | const dest_ptr_ty = sema.typeOf(dest_ptr); |
| 25910 | 25924 | try checkMemOperand(sema, block, dest_src, dest_ptr_ty); |
| 25911 | 25925 | |
| 25912 | if (dest_ptr_ty.isConstPtr(mod)) { | |
| 25926 | if (dest_ptr_ty.isConstPtr(zcu)) { | |
| 25913 | 25927 | return sema.fail(block, dest_src, "cannot memset constant pointer", .{}); |
| 25914 | 25928 | } |
| 25915 | 25929 | |
| 25916 | 25930 | const dest_elem_ty: Type = dest_elem_ty: { |
| 25917 | const ptr_info = dest_ptr_ty.ptrInfo(mod); | |
| 25931 | const ptr_info = dest_ptr_ty.ptrInfo(zcu); | |
| 25918 | 25932 | switch (ptr_info.flags.size) { |
| 25919 | 25933 | .Slice => break :dest_elem_ty Type.fromInterned(ptr_info.child), |
| 25920 | 25934 | .One => { |
| 25921 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Array) { | |
| 25922 | break :dest_elem_ty Type.fromInterned(ptr_info.child).childType(mod); | |
| 25935 | if (Type.fromInterned(ptr_info.child).zigTypeTag(zcu) == .Array) { | |
| 25936 | break :dest_elem_ty Type.fromInterned(ptr_info.child).childType(zcu); | |
| 25923 | 25937 | } |
| 25924 | 25938 | }, |
| 25925 | 25939 | .Many, .C => {}, |
| ... | ... | @@ -25940,7 +25954,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25940 | 25954 | const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src; |
| 25941 | 25955 | const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls), dest_src); |
| 25942 | 25956 | const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src; |
| 25943 | const len_u64 = (try len_val.getUnsignedIntAdvanced(pt, .sema)).?; | |
| 25957 | const len_u64 = try len_val.toUnsignedIntSema(pt); | |
| 25944 | 25958 | const len = try sema.usizeCast(block, dest_src, len_u64); |
| 25945 | 25959 | if (len == 0) { |
| 25946 | 25960 | // This AIR instruction guarantees length > 0 if it is comptime-known. |
| ... | ... | @@ -25958,12 +25972,12 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25958 | 25972 | .storage = .{ .repeated_elem = elem_val.toIntern() }, |
| 25959 | 25973 | } })); |
| 25960 | 25974 | const array_ptr_ty = ty: { |
| 25961 | var info = dest_ptr_ty.ptrInfo(mod); | |
| 25975 | var info = dest_ptr_ty.ptrInfo(zcu); | |
| 25962 | 25976 | info.flags.size = .One; |
| 25963 | 25977 | info.child = array_ty.toIntern(); |
| 25964 | 25978 | break :ty try pt.ptrType(info); |
| 25965 | 25979 | }; |
| 25966 | const raw_ptr_val = if (dest_ptr_ty.isSlice(mod)) ptr_val.slicePtr(mod) else ptr_val; | |
| 25980 | const raw_ptr_val = if (dest_ptr_ty.isSlice(zcu)) ptr_val.slicePtr(zcu) else ptr_val; | |
| 25967 | 25981 | const array_ptr_val = try pt.getCoerced(raw_ptr_val, array_ptr_ty); |
| 25968 | 25982 | return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty); |
| 25969 | 25983 | }; |
| ... | ... | @@ -26129,10 +26143,10 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26129 | 26143 | defer tracy.end(); |
| 26130 | 26144 | |
| 26131 | 26145 | const pt = sema.pt; |
| 26132 | const mod = pt.zcu; | |
| 26146 | const zcu = pt.zcu; | |
| 26133 | 26147 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 26134 | 26148 | const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); |
| 26135 | const target = mod.getTarget(); | |
| 26149 | const target = zcu.getTarget(); | |
| 26136 | 26150 | |
| 26137 | 26151 | const align_src = block.src(.{ .node_offset_fn_type_align = inst_data.src_node }); |
| 26138 | 26152 | const addrspace_src = block.src(.{ .node_offset_fn_type_addrspace = inst_data.src_node }); |
| ... | ... | @@ -26207,7 +26221,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26207 | 26221 | if (val.isGenericPoison()) { |
| 26208 | 26222 | break :blk null; |
| 26209 | 26223 | } |
| 26210 | break :blk mod.toEnum(std.builtin.AddressSpace, val); | |
| 26224 | break :blk zcu.toEnum(std.builtin.AddressSpace, val); | |
| 26211 | 26225 | } else if (extra.data.bits.has_addrspace_ref) blk: { |
| 26212 | 26226 | const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| 26213 | 26227 | extra_index += 1; |
| ... | ... | @@ -26226,7 +26240,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26226 | 26240 | error.GenericPoison => break :blk null, |
| 26227 | 26241 | else => |e| return e, |
| 26228 | 26242 | }; |
| 26229 | break :blk mod.toEnum(std.builtin.AddressSpace, addrspace_val); | |
| 26243 | break :blk zcu.toEnum(std.builtin.AddressSpace, addrspace_val); | |
| 26230 | 26244 | } else target_util.defaultAddressSpace(target, .function); |
| 26231 | 26245 | |
| 26232 | 26246 | const section: Section = if (extra.data.bits.has_section_body) blk: { |
| ... | ... | @@ -26272,7 +26286,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26272 | 26286 | if (val.isGenericPoison()) { |
| 26273 | 26287 | break :blk null; |
| 26274 | 26288 | } |
| 26275 | break :blk mod.toEnum(std.builtin.CallingConvention, val); | |
| 26289 | break :blk zcu.toEnum(std.builtin.CallingConvention, val); | |
| 26276 | 26290 | } else if (extra.data.bits.has_cc_ref) blk: { |
| 26277 | 26291 | const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| 26278 | 26292 | extra_index += 1; |
| ... | ... | @@ -26291,18 +26305,18 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26291 | 26305 | error.GenericPoison => break :blk null, |
| 26292 | 26306 | else => |e| return e, |
| 26293 | 26307 | }; |
| 26294 | break :blk mod.toEnum(std.builtin.CallingConvention, cc_val); | |
| 26308 | break :blk zcu.toEnum(std.builtin.CallingConvention, cc_val); | |
| 26295 | 26309 | } else cc: { |
| 26296 | 26310 | if (has_body) { |
| 26297 | 26311 | const decl_inst = if (sema.generic_owner != .none) decl_inst: { |
| 26298 | 26312 | // Generic instance -- use the original function declaration to |
| 26299 | 26313 | // look for the `export` syntax. |
| 26300 | const nav = mod.intern_pool.getNav(mod.funcInfo(sema.generic_owner).owner_nav); | |
| 26301 | const cau = mod.intern_pool.getCau(nav.analysis_owner.unwrap().?); | |
| 26314 | const nav = zcu.intern_pool.getNav(zcu.funcInfo(sema.generic_owner).owner_nav); | |
| 26315 | const cau = zcu.intern_pool.getCau(nav.analysis_owner.unwrap().?); | |
| 26302 | 26316 | break :decl_inst cau.zir_index; |
| 26303 | 26317 | } else sema.getOwnerCauDeclInst(); // not an instantiation so we're analyzing a function declaration Cau |
| 26304 | 26318 | |
| 26305 | const zir_decl = sema.code.getDeclaration(decl_inst.resolve(&mod.intern_pool) orelse return error.AnalysisFail)[0]; | |
| 26319 | const zir_decl = sema.code.getDeclaration(decl_inst.resolve(&zcu.intern_pool) orelse return error.AnalysisFail)[0]; | |
| 26306 | 26320 | if (zir_decl.flags.is_export) { |
| 26307 | 26321 | break :cc .C; |
| 26308 | 26322 | } |
| ... | ... | @@ -26408,7 +26422,7 @@ fn zirCDefine( |
| 26408 | 26422 | extended: Zir.Inst.Extended.InstData, |
| 26409 | 26423 | ) CompileError!Air.Inst.Ref { |
| 26410 | 26424 | const pt = sema.pt; |
| 26411 | const mod = pt.zcu; | |
| 26425 | const zcu = pt.zcu; | |
| 26412 | 26426 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 26413 | 26427 | const name_src = block.builtinCallArgSrc(extra.node, 0); |
| 26414 | 26428 | const val_src = block.builtinCallArgSrc(extra.node, 1); |
| ... | ... | @@ -26417,7 +26431,7 @@ fn zirCDefine( |
| 26417 | 26431 | .needed_comptime_reason = "name of macro being undefined must be comptime-known", |
| 26418 | 26432 | }); |
| 26419 | 26433 | const rhs = try sema.resolveInst(extra.rhs); |
| 26420 | if (sema.typeOf(rhs).zigTypeTag(mod) != .Void) { | |
| 26434 | if (sema.typeOf(rhs).zigTypeTag(zcu) != .Void) { | |
| 26421 | 26435 | const value = try sema.resolveConstString(block, val_src, extra.rhs, .{ |
| 26422 | 26436 | .needed_comptime_reason = "value of macro being undefined must be comptime-known", |
| 26423 | 26437 | }); |
| ... | ... | @@ -26490,9 +26504,9 @@ fn resolvePrefetchOptions( |
| 26490 | 26504 | zir_ref: Zir.Inst.Ref, |
| 26491 | 26505 | ) CompileError!std.builtin.PrefetchOptions { |
| 26492 | 26506 | const pt = sema.pt; |
| 26493 | const mod = pt.zcu; | |
| 26507 | const zcu = pt.zcu; | |
| 26494 | 26508 | const gpa = sema.gpa; |
| 26495 | const ip = &mod.intern_pool; | |
| 26509 | const ip = &zcu.intern_pool; | |
| 26496 | 26510 | const options_ty = try pt.getBuiltinType("PrefetchOptions"); |
| 26497 | 26511 | const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src); |
| 26498 | 26512 | |
| ... | ... | @@ -26516,9 +26530,9 @@ fn resolvePrefetchOptions( |
| 26516 | 26530 | }); |
| 26517 | 26531 | |
| 26518 | 26532 | return std.builtin.PrefetchOptions{ |
| 26519 | .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val), | |
| 26533 | .rw = zcu.toEnum(std.builtin.PrefetchOptions.Rw, rw_val), | |
| 26520 | 26534 | .locality = @intCast(try locality_val.toUnsignedIntSema(pt)), |
| 26521 | .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val), | |
| 26535 | .cache = zcu.toEnum(std.builtin.PrefetchOptions.Cache, cache_val), | |
| 26522 | 26536 | }; |
| 26523 | 26537 | } |
| 26524 | 26538 | |
| ... | ... | @@ -26562,9 +26576,9 @@ fn resolveExternOptions( |
| 26562 | 26576 | is_thread_local: bool = false, |
| 26563 | 26577 | } { |
| 26564 | 26578 | const pt = sema.pt; |
| 26565 | const mod = pt.zcu; | |
| 26579 | const zcu = pt.zcu; | |
| 26566 | 26580 | const gpa = sema.gpa; |
| 26567 | const ip = &mod.intern_pool; | |
| 26581 | const ip = &zcu.intern_pool; | |
| 26568 | 26582 | const options_inst = try sema.resolveInst(zir_ref); |
| 26569 | 26583 | const extern_options_ty = try pt.getBuiltinType("ExternOptions"); |
| 26570 | 26584 | const options = try sema.coerce(block, extern_options_ty, options_inst, src); |
| ... | ... | @@ -26588,14 +26602,14 @@ fn resolveExternOptions( |
| 26588 | 26602 | const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_ref, .{ |
| 26589 | 26603 | .needed_comptime_reason = "linkage of the extern symbol must be comptime-known", |
| 26590 | 26604 | }); |
| 26591 | const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val); | |
| 26605 | const linkage = zcu.toEnum(std.builtin.GlobalLinkage, linkage_val); | |
| 26592 | 26606 | |
| 26593 | 26607 | const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, pt.tid, "is_thread_local", .no_embedded_nulls), thread_local_src); |
| 26594 | 26608 | const is_thread_local_val = try sema.resolveConstDefinedValue(block, thread_local_src, is_thread_local, .{ |
| 26595 | 26609 | .needed_comptime_reason = "threadlocality of the extern symbol must be comptime-known", |
| 26596 | 26610 | }); |
| 26597 | 26611 | |
| 26598 | const library_name = if (library_name_val.optionalValue(mod)) |library_name_payload| library_name: { | |
| 26612 | const library_name = if (library_name_val.optionalValue(zcu)) |library_name_payload| library_name: { | |
| 26599 | 26613 | const library_name = try sema.toConstString(block, library_src, Air.internedToRef(library_name_payload.toIntern()), .{ |
| 26600 | 26614 | .needed_comptime_reason = "library in which extern symbol is must be comptime-known", |
| 26601 | 26615 | }); |
| ... | ... | @@ -26628,14 +26642,14 @@ fn zirBuiltinExtern( |
| 26628 | 26642 | extended: Zir.Inst.Extended.InstData, |
| 26629 | 26643 | ) CompileError!Air.Inst.Ref { |
| 26630 | 26644 | const pt = sema.pt; |
| 26631 | const mod = pt.zcu; | |
| 26632 | const ip = &mod.intern_pool; | |
| 26645 | const zcu = pt.zcu; | |
| 26646 | const ip = &zcu.intern_pool; | |
| 26633 | 26647 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 26634 | 26648 | const ty_src = block.builtinCallArgSrc(extra.node, 0); |
| 26635 | 26649 | const options_src = block.builtinCallArgSrc(extra.node, 1); |
| 26636 | 26650 | |
| 26637 | 26651 | var ty = try sema.resolveType(block, ty_src, extra.lhs); |
| 26638 | if (!ty.isPtrAtRuntime(mod)) { | |
| 26652 | if (!ty.isPtrAtRuntime(zcu)) { | |
| 26639 | 26653 | return sema.fail(block, ty_src, "expected (optional) pointer", .{}); |
| 26640 | 26654 | } |
| 26641 | 26655 | if (!try sema.validateExternType(ty, .other)) { |
| ... | ... | @@ -26652,10 +26666,10 @@ fn zirBuiltinExtern( |
| 26652 | 26666 | |
| 26653 | 26667 | // TODO: error for threadlocal functions, non-const functions, etc |
| 26654 | 26668 | |
| 26655 | if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) { | |
| 26669 | if (options.linkage == .weak and !ty.ptrAllowsZero(zcu)) { | |
| 26656 | 26670 | ty = try pt.optionalType(ty.toIntern()); |
| 26657 | 26671 | } |
| 26658 | const ptr_info = ty.ptrInfo(mod); | |
| 26672 | const ptr_info = ty.ptrInfo(zcu); | |
| 26659 | 26673 | |
| 26660 | 26674 | const extern_val = try pt.getExtern(.{ |
| 26661 | 26675 | .name = options.name, |
| ... | ... | @@ -26801,7 +26815,7 @@ fn validateVarType( |
| 26801 | 26815 | is_extern: bool, |
| 26802 | 26816 | ) CompileError!void { |
| 26803 | 26817 | const pt = sema.pt; |
| 26804 | const mod = pt.zcu; | |
| 26818 | const zcu = pt.zcu; | |
| 26805 | 26819 | if (is_extern) { |
| 26806 | 26820 | if (!try sema.validateExternType(var_ty, .other)) { |
| 26807 | 26821 | const msg = msg: { |
| ... | ... | @@ -26813,7 +26827,7 @@ fn validateVarType( |
| 26813 | 26827 | return sema.failWithOwnedErrorMsg(block, msg); |
| 26814 | 26828 | } |
| 26815 | 26829 | } else { |
| 26816 | if (var_ty.zigTypeTag(mod) == .Opaque) { | |
| 26830 | if (var_ty.zigTypeTag(zcu) == .Opaque) { | |
| 26817 | 26831 | return sema.fail( |
| 26818 | 26832 | block, |
| 26819 | 26833 | src, |
| ... | ... | @@ -26823,14 +26837,14 @@ fn validateVarType( |
| 26823 | 26837 | } |
| 26824 | 26838 | } |
| 26825 | 26839 | |
| 26826 | if (!try sema.typeRequiresComptime(var_ty)) return; | |
| 26840 | if (!try var_ty.comptimeOnlySema(pt)) return; | |
| 26827 | 26841 | |
| 26828 | 26842 | const msg = msg: { |
| 26829 | 26843 | const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(pt)}); |
| 26830 | 26844 | errdefer msg.destroy(sema.gpa); |
| 26831 | 26845 | |
| 26832 | 26846 | try sema.explainWhyTypeIsComptime(msg, src, var_ty); |
| 26833 | if (var_ty.zigTypeTag(mod) == .ComptimeInt or var_ty.zigTypeTag(mod) == .ComptimeFloat) { | |
| 26847 | if (var_ty.zigTypeTag(zcu) == .ComptimeInt or var_ty.zigTypeTag(zcu) == .ComptimeFloat) { | |
| 26834 | 26848 | try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{}); |
| 26835 | 26849 | } |
| 26836 | 26850 | |
| ... | ... | @@ -26843,7 +26857,7 @@ const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void); |
| 26843 | 26857 | |
| 26844 | 26858 | fn explainWhyTypeIsComptime( |
| 26845 | 26859 | sema: *Sema, |
| 26846 | msg: *Module.ErrorMsg, | |
| 26860 | msg: *Zcu.ErrorMsg, | |
| 26847 | 26861 | src_loc: LazySrcLoc, |
| 26848 | 26862 | ty: Type, |
| 26849 | 26863 | ) CompileError!void { |
| ... | ... | @@ -26856,15 +26870,15 @@ fn explainWhyTypeIsComptime( |
| 26856 | 26870 | |
| 26857 | 26871 | fn explainWhyTypeIsComptimeInner( |
| 26858 | 26872 | sema: *Sema, |
| 26859 | msg: *Module.ErrorMsg, | |
| 26873 | msg: *Zcu.ErrorMsg, | |
| 26860 | 26874 | src_loc: LazySrcLoc, |
| 26861 | 26875 | ty: Type, |
| 26862 | 26876 | type_set: *TypeSet, |
| 26863 | 26877 | ) CompileError!void { |
| 26864 | 26878 | const pt = sema.pt; |
| 26865 | const mod = pt.zcu; | |
| 26866 | const ip = &mod.intern_pool; | |
| 26867 | switch (ty.zigTypeTag(mod)) { | |
| 26879 | const zcu = pt.zcu; | |
| 26880 | const ip = &zcu.intern_pool; | |
| 26881 | switch (ty.zigTypeTag(zcu)) { | |
| 26868 | 26882 | .Bool, |
| 26869 | 26883 | .Int, |
| 26870 | 26884 | .Float, |
| ... | ... | @@ -26896,12 +26910,12 @@ fn explainWhyTypeIsComptimeInner( |
| 26896 | 26910 | }, |
| 26897 | 26911 | |
| 26898 | 26912 | .Array, .Vector => { |
| 26899 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(mod), type_set); | |
| 26913 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(zcu), type_set); | |
| 26900 | 26914 | }, |
| 26901 | 26915 | .Pointer => { |
| 26902 | const elem_ty = ty.elemType2(mod); | |
| 26903 | if (elem_ty.zigTypeTag(mod) == .Fn) { | |
| 26904 | const fn_info = mod.typeToFunc(elem_ty).?; | |
| 26916 | const elem_ty = ty.elemType2(zcu); | |
| 26917 | if (elem_ty.zigTypeTag(zcu) == .Fn) { | |
| 26918 | const fn_info = zcu.typeToFunc(elem_ty).?; | |
| 26905 | 26919 | if (fn_info.is_generic) { |
| 26906 | 26920 | try sema.errNote(src_loc, msg, "function is generic", .{}); |
| 26907 | 26921 | } |
| ... | ... | @@ -26909,25 +26923,25 @@ fn explainWhyTypeIsComptimeInner( |
| 26909 | 26923 | .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}), |
| 26910 | 26924 | else => {}, |
| 26911 | 26925 | } |
| 26912 | if (Type.fromInterned(fn_info.return_type).comptimeOnly(pt)) { | |
| 26926 | if (Type.fromInterned(fn_info.return_type).comptimeOnly(zcu)) { | |
| 26913 | 26927 | try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{}); |
| 26914 | 26928 | } |
| 26915 | 26929 | return; |
| 26916 | 26930 | } |
| 26917 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(mod), type_set); | |
| 26931 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(zcu), type_set); | |
| 26918 | 26932 | }, |
| 26919 | 26933 | |
| 26920 | 26934 | .Optional => { |
| 26921 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(mod), type_set); | |
| 26935 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(zcu), type_set); | |
| 26922 | 26936 | }, |
| 26923 | 26937 | .ErrorUnion => { |
| 26924 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(mod), type_set); | |
| 26938 | try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(zcu), type_set); | |
| 26925 | 26939 | }, |
| 26926 | 26940 | |
| 26927 | 26941 | .Struct => { |
| 26928 | 26942 | if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return; |
| 26929 | 26943 | |
| 26930 | if (mod.typeToStruct(ty)) |struct_type| { | |
| 26944 | if (zcu.typeToStruct(ty)) |struct_type| { | |
| 26931 | 26945 | for (0..struct_type.field_types.len) |i| { |
| 26932 | 26946 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 26933 | 26947 | const field_src: LazySrcLoc = .{ |
| ... | ... | @@ -26935,7 +26949,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26935 | 26949 | .offset = .{ .container_field_type = @intCast(i) }, |
| 26936 | 26950 | }; |
| 26937 | 26951 | |
| 26938 | if (try sema.typeRequiresComptime(field_ty)) { | |
| 26952 | if (try field_ty.comptimeOnlySema(pt)) { | |
| 26939 | 26953 | try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{}); |
| 26940 | 26954 | try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set); |
| 26941 | 26955 | } |
| ... | ... | @@ -26947,7 +26961,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26947 | 26961 | .Union => { |
| 26948 | 26962 | if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return; |
| 26949 | 26963 | |
| 26950 | if (mod.typeToUnion(ty)) |union_obj| { | |
| 26964 | if (zcu.typeToUnion(ty)) |union_obj| { | |
| 26951 | 26965 | for (0..union_obj.field_types.len) |i| { |
| 26952 | 26966 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[i]); |
| 26953 | 26967 | const field_src: LazySrcLoc = .{ |
| ... | ... | @@ -26955,7 +26969,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26955 | 26969 | .offset = .{ .container_field_type = @intCast(i) }, |
| 26956 | 26970 | }; |
| 26957 | 26971 | |
| 26958 | if (try sema.typeRequiresComptime(field_ty)) { | |
| 26972 | if (try field_ty.comptimeOnlySema(pt)) { | |
| 26959 | 26973 | try sema.errNote(field_src, msg, "union requires comptime because of this field", .{}); |
| 26960 | 26974 | try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set); |
| 26961 | 26975 | } |
| ... | ... | @@ -26983,8 +26997,8 @@ fn validateExternType( |
| 26983 | 26997 | position: ExternPosition, |
| 26984 | 26998 | ) !bool { |
| 26985 | 26999 | const pt = sema.pt; |
| 26986 | const mod = pt.zcu; | |
| 26987 | switch (ty.zigTypeTag(mod)) { | |
| 27000 | const zcu = pt.zcu; | |
| 27001 | switch (ty.zigTypeTag(zcu)) { | |
| 26988 | 27002 | .Type, |
| 26989 | 27003 | .ComptimeFloat, |
| 26990 | 27004 | .ComptimeInt, |
| ... | ... | @@ -27003,58 +27017,58 @@ fn validateExternType( |
| 27003 | 27017 | .AnyFrame, |
| 27004 | 27018 | => return true, |
| 27005 | 27019 | .Pointer => { |
| 27006 | if (ty.childType(mod).zigTypeTag(mod) == .Fn) { | |
| 27007 | return ty.isConstPtr(mod) and try sema.validateExternType(ty.childType(mod), .other); | |
| 27020 | if (ty.childType(zcu).zigTypeTag(zcu) == .Fn) { | |
| 27021 | return ty.isConstPtr(zcu) and try sema.validateExternType(ty.childType(zcu), .other); | |
| 27008 | 27022 | } |
| 27009 | return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty)); | |
| 27023 | return !(ty.isSlice(zcu) or try ty.comptimeOnlySema(pt)); | |
| 27010 | 27024 | }, |
| 27011 | .Int => switch (ty.intInfo(mod).bits) { | |
| 27025 | .Int => switch (ty.intInfo(zcu).bits) { | |
| 27012 | 27026 | 0, 8, 16, 32, 64, 128 => return true, |
| 27013 | 27027 | else => return false, |
| 27014 | 27028 | }, |
| 27015 | 27029 | .Fn => { |
| 27016 | 27030 | if (position != .other) return false; |
| 27017 | const target = mod.getTarget(); | |
| 27031 | const target = zcu.getTarget(); | |
| 27018 | 27032 | // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI. |
| 27019 | 27033 | // The goal is to experiment with more integrated CPU/GPU code. |
| 27020 | if (ty.fnCallingConvention(mod) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) { | |
| 27034 | if (ty.fnCallingConvention(zcu) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) { | |
| 27021 | 27035 | return true; |
| 27022 | 27036 | } |
| 27023 | return !target_util.fnCallConvAllowsZigTypes(target, ty.fnCallingConvention(mod)); | |
| 27037 | return !target_util.fnCallConvAllowsZigTypes(target, ty.fnCallingConvention(zcu)); | |
| 27024 | 27038 | }, |
| 27025 | 27039 | .Enum => { |
| 27026 | return sema.validateExternType(ty.intTagType(mod), position); | |
| 27040 | return sema.validateExternType(ty.intTagType(zcu), position); | |
| 27027 | 27041 | }, |
| 27028 | .Struct, .Union => switch (ty.containerLayout(mod)) { | |
| 27042 | .Struct, .Union => switch (ty.containerLayout(zcu)) { | |
| 27029 | 27043 | .@"extern" => return true, |
| 27030 | 27044 | .@"packed" => { |
| 27031 | const bit_size = try ty.bitSizeAdvanced(pt, .sema); | |
| 27045 | const bit_size = try ty.bitSizeSema(pt); | |
| 27032 | 27046 | switch (bit_size) { |
| 27033 | 27047 | 0, 8, 16, 32, 64, 128 => return true, |
| 27034 | 27048 | else => return false, |
| 27035 | 27049 | } |
| 27036 | 27050 | }, |
| 27037 | .auto => return !(try sema.typeHasRuntimeBits(ty)), | |
| 27051 | .auto => return !(try ty.hasRuntimeBitsSema(pt)), | |
| 27038 | 27052 | }, |
| 27039 | 27053 | .Array => { |
| 27040 | 27054 | if (position == .ret_ty or position == .param_ty) return false; |
| 27041 | return sema.validateExternType(ty.elemType2(mod), .element); | |
| 27055 | return sema.validateExternType(ty.elemType2(zcu), .element); | |
| 27042 | 27056 | }, |
| 27043 | .Vector => return sema.validateExternType(ty.elemType2(mod), .element), | |
| 27044 | .Optional => return ty.isPtrLikeOptional(mod), | |
| 27057 | .Vector => return sema.validateExternType(ty.elemType2(zcu), .element), | |
| 27058 | .Optional => return ty.isPtrLikeOptional(zcu), | |
| 27045 | 27059 | } |
| 27046 | 27060 | } |
| 27047 | 27061 | |
| 27048 | 27062 | fn explainWhyTypeIsNotExtern( |
| 27049 | 27063 | sema: *Sema, |
| 27050 | msg: *Module.ErrorMsg, | |
| 27064 | msg: *Zcu.ErrorMsg, | |
| 27051 | 27065 | src_loc: LazySrcLoc, |
| 27052 | 27066 | ty: Type, |
| 27053 | 27067 | position: ExternPosition, |
| 27054 | 27068 | ) CompileError!void { |
| 27055 | 27069 | const pt = sema.pt; |
| 27056 | const mod = pt.zcu; | |
| 27057 | switch (ty.zigTypeTag(mod)) { | |
| 27070 | const zcu = pt.zcu; | |
| 27071 | switch (ty.zigTypeTag(zcu)) { | |
| 27058 | 27072 | .Opaque, |
| 27059 | 27073 | .Bool, |
| 27060 | 27074 | .Float, |
| ... | ... | @@ -27073,13 +27087,13 @@ fn explainWhyTypeIsNotExtern( |
| 27073 | 27087 | => return, |
| 27074 | 27088 | |
| 27075 | 27089 | .Pointer => { |
| 27076 | if (ty.isSlice(mod)) { | |
| 27090 | if (ty.isSlice(zcu)) { | |
| 27077 | 27091 | try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); |
| 27078 | 27092 | } else { |
| 27079 | const pointee_ty = ty.childType(mod); | |
| 27080 | if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) { | |
| 27093 | const pointee_ty = ty.childType(zcu); | |
| 27094 | if (!ty.isConstPtr(zcu) and pointee_ty.zigTypeTag(zcu) == .Fn) { | |
| 27081 | 27095 | try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{}); |
| 27082 | } else if (try sema.typeRequiresComptime(ty)) { | |
| 27096 | } else if (try ty.comptimeOnlySema(pt)) { | |
| 27083 | 27097 | try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(pt)}); |
| 27084 | 27098 | try sema.explainWhyTypeIsComptime(msg, src_loc, ty); |
| 27085 | 27099 | } |
| ... | ... | @@ -27088,7 +27102,7 @@ fn explainWhyTypeIsNotExtern( |
| 27088 | 27102 | }, |
| 27089 | 27103 | .Void => try sema.errNote(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}), |
| 27090 | 27104 | .NoReturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}), |
| 27091 | .Int => if (!std.math.isPowerOfTwo(ty.intInfo(mod).bits)) { | |
| 27105 | .Int => if (!std.math.isPowerOfTwo(ty.intInfo(zcu).bits)) { | |
| 27092 | 27106 | try sema.errNote(src_loc, msg, "only integers with 0 or power of two bits are extern compatible", .{}); |
| 27093 | 27107 | } else { |
| 27094 | 27108 | try sema.errNote(src_loc, msg, "only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible", .{}); |
| ... | ... | @@ -27099,7 +27113,7 @@ fn explainWhyTypeIsNotExtern( |
| 27099 | 27113 | try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{}); |
| 27100 | 27114 | return; |
| 27101 | 27115 | } |
| 27102 | switch (ty.fnCallingConvention(mod)) { | |
| 27116 | switch (ty.fnCallingConvention(zcu)) { | |
| 27103 | 27117 | .Unspecified => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}), |
| 27104 | 27118 | .Async => try sema.errNote(src_loc, msg, "async function cannot be extern", .{}), |
| 27105 | 27119 | .Inline => try sema.errNote(src_loc, msg, "inline function cannot be extern", .{}), |
| ... | ... | @@ -27107,7 +27121,7 @@ fn explainWhyTypeIsNotExtern( |
| 27107 | 27121 | } |
| 27108 | 27122 | }, |
| 27109 | 27123 | .Enum => { |
| 27110 | const tag_ty = ty.intTagType(mod); | |
| 27124 | const tag_ty = ty.intTagType(zcu); | |
| 27111 | 27125 | try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(pt)}); |
| 27112 | 27126 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position); |
| 27113 | 27127 | }, |
| ... | ... | @@ -27119,9 +27133,9 @@ fn explainWhyTypeIsNotExtern( |
| 27119 | 27133 | } else if (position == .param_ty) { |
| 27120 | 27134 | return sema.errNote(src_loc, msg, "arrays are not allowed as a parameter type", .{}); |
| 27121 | 27135 | } |
| 27122 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element); | |
| 27136 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(zcu), .element); | |
| 27123 | 27137 | }, |
| 27124 | .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element), | |
| 27138 | .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(zcu), .element), | |
| 27125 | 27139 | .Optional => try sema.errNote(src_loc, msg, "only pointer like optionals are extern compatible", .{}), |
| 27126 | 27140 | } |
| 27127 | 27141 | } |
| ... | ... | @@ -27158,20 +27172,20 @@ fn validatePackedType(sema: *Sema, ty: Type) !bool { |
| 27158 | 27172 | .auto => false, |
| 27159 | 27173 | .explicit, .nonexhaustive => true, |
| 27160 | 27174 | }, |
| 27161 | .Pointer => !ty.isSlice(zcu) and !try sema.typeRequiresComptime(ty), | |
| 27175 | .Pointer => !ty.isSlice(zcu) and !try ty.comptimeOnlySema(pt), | |
| 27162 | 27176 | .Struct, .Union => ty.containerLayout(zcu) == .@"packed", |
| 27163 | 27177 | }; |
| 27164 | 27178 | } |
| 27165 | 27179 | |
| 27166 | 27180 | fn explainWhyTypeIsNotPacked( |
| 27167 | 27181 | sema: *Sema, |
| 27168 | msg: *Module.ErrorMsg, | |
| 27182 | msg: *Zcu.ErrorMsg, | |
| 27169 | 27183 | src_loc: LazySrcLoc, |
| 27170 | 27184 | ty: Type, |
| 27171 | 27185 | ) CompileError!void { |
| 27172 | 27186 | const pt = sema.pt; |
| 27173 | const mod = pt.zcu; | |
| 27174 | switch (ty.zigTypeTag(mod)) { | |
| 27187 | const zcu = pt.zcu; | |
| 27188 | switch (ty.zigTypeTag(zcu)) { | |
| 27175 | 27189 | .Void, |
| 27176 | 27190 | .Bool, |
| 27177 | 27191 | .Float, |
| ... | ... | @@ -27194,7 +27208,7 @@ fn explainWhyTypeIsNotPacked( |
| 27194 | 27208 | .Optional, |
| 27195 | 27209 | .Array, |
| 27196 | 27210 | => try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{}), |
| 27197 | .Pointer => if (ty.isSlice(mod)) { | |
| 27211 | .Pointer => if (ty.isSlice(zcu)) { | |
| 27198 | 27212 | try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); |
| 27199 | 27213 | } else { |
| 27200 | 27214 | try sema.errNote(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{}); |
| ... | ... | @@ -27211,23 +27225,23 @@ fn explainWhyTypeIsNotPacked( |
| 27211 | 27225 | |
| 27212 | 27226 | fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 27213 | 27227 | const pt = sema.pt; |
| 27214 | const mod = pt.zcu; | |
| 27228 | const zcu = pt.zcu; | |
| 27215 | 27229 | |
| 27216 | if (mod.panic_func_index == .none) { | |
| 27230 | if (zcu.panic_func_index == .none) { | |
| 27217 | 27231 | const fn_ref = try sema.analyzeNavVal(block, src, try pt.getBuiltinNav("panic")); |
| 27218 | 27232 | const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{ |
| 27219 | 27233 | .needed_comptime_reason = "panic handler must be comptime-known", |
| 27220 | 27234 | }); |
| 27221 | assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn); | |
| 27222 | assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod))); | |
| 27223 | try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern()); | |
| 27224 | mod.panic_func_index = fn_val.toIntern(); | |
| 27235 | assert(fn_val.typeOf(zcu).zigTypeTag(zcu) == .Fn); | |
| 27236 | assert(try fn_val.typeOf(zcu).fnHasRuntimeBitsSema(pt)); | |
| 27237 | try zcu.ensureFuncBodyAnalysisQueued(fn_val.toIntern()); | |
| 27238 | zcu.panic_func_index = fn_val.toIntern(); | |
| 27225 | 27239 | } |
| 27226 | 27240 | |
| 27227 | if (mod.null_stack_trace == .none) { | |
| 27241 | if (zcu.null_stack_trace == .none) { | |
| 27228 | 27242 | const stack_trace_ty = try pt.getBuiltinType("StackTrace"); |
| 27229 | 27243 | try stack_trace_ty.resolveFields(pt); |
| 27230 | const target = mod.getTarget(); | |
| 27244 | const target = zcu.getTarget(); | |
| 27231 | 27245 | const ptr_stack_trace_ty = try pt.ptrTypeSema(.{ |
| 27232 | 27246 | .child = stack_trace_ty.toIntern(), |
| 27233 | 27247 | .flags = .{ |
| ... | ... | @@ -27235,7 +27249,7 @@ fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 27235 | 27249 | }, |
| 27236 | 27250 | }); |
| 27237 | 27251 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| 27238 | mod.null_stack_trace = try pt.intern(.{ .opt = .{ | |
| 27252 | zcu.null_stack_trace = try pt.intern(.{ .opt = .{ | |
| 27239 | 27253 | .ty = opt_ptr_stack_trace_ty.toIntern(), |
| 27240 | 27254 | .val = .none, |
| 27241 | 27255 | } }); |
| ... | ... | @@ -27245,11 +27259,11 @@ fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 27245 | 27259 | /// Backends depend on panic decls being available when lowering safety-checked |
| 27246 | 27260 | /// instructions. This function ensures the panic function will be available to |
| 27247 | 27261 | /// be called during that time. |
| 27248 | fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) !InternPool.Nav.Index { | |
| 27262 | fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) !InternPool.Nav.Index { | |
| 27249 | 27263 | const pt = sema.pt; |
| 27250 | const mod = pt.zcu; | |
| 27264 | const zcu = pt.zcu; | |
| 27251 | 27265 | const gpa = sema.gpa; |
| 27252 | if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x; | |
| 27266 | if (zcu.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x; | |
| 27253 | 27267 | |
| 27254 | 27268 | try sema.prepareSimplePanic(block, src); |
| 27255 | 27269 | |
| ... | ... | @@ -27257,15 +27271,15 @@ fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module. |
| 27257 | 27271 | const msg_nav_index = (sema.namespaceLookup( |
| 27258 | 27272 | block, |
| 27259 | 27273 | LazySrcLoc.unneeded, |
| 27260 | panic_messages_ty.getNamespaceIndex(mod), | |
| 27261 | try mod.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls), | |
| 27274 | panic_messages_ty.getNamespaceIndex(zcu), | |
| 27275 | try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls), | |
| 27262 | 27276 | ) catch |err| switch (err) { |
| 27263 | 27277 | error.AnalysisFail => @panic("std.builtin.panic_messages is corrupt"), |
| 27264 | 27278 | error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, |
| 27265 | 27279 | error.OutOfMemory => |e| return e, |
| 27266 | 27280 | }).?; |
| 27267 | 27281 | try sema.ensureNavResolved(src, msg_nav_index); |
| 27268 | mod.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional(); | |
| 27282 | zcu.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional(); | |
| 27269 | 27283 | return msg_nav_index; |
| 27270 | 27284 | } |
| 27271 | 27285 | |
| ... | ... | @@ -27274,7 +27288,7 @@ fn addSafetyCheck( |
| 27274 | 27288 | parent_block: *Block, |
| 27275 | 27289 | src: LazySrcLoc, |
| 27276 | 27290 | ok: Air.Inst.Ref, |
| 27277 | panic_id: Module.PanicId, | |
| 27291 | panic_id: Zcu.PanicId, | |
| 27278 | 27292 | ) !void { |
| 27279 | 27293 | const gpa = sema.gpa; |
| 27280 | 27294 | assert(!parent_block.is_comptime); |
| ... | ... | @@ -27353,18 +27367,18 @@ fn addSafetyCheckExtra( |
| 27353 | 27367 | |
| 27354 | 27368 | fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, operation: CallOperation) !void { |
| 27355 | 27369 | const pt = sema.pt; |
| 27356 | const mod = pt.zcu; | |
| 27370 | const zcu = pt.zcu; | |
| 27357 | 27371 | |
| 27358 | if (!mod.backendSupportsFeature(.panic_fn)) { | |
| 27372 | if (!zcu.backendSupportsFeature(.panic_fn)) { | |
| 27359 | 27373 | _ = try block.addNoOp(.trap); |
| 27360 | 27374 | return; |
| 27361 | 27375 | } |
| 27362 | 27376 | |
| 27363 | 27377 | try sema.prepareSimplePanic(block, src); |
| 27364 | 27378 | |
| 27365 | const panic_func = mod.funcInfo(mod.panic_func_index); | |
| 27379 | const panic_func = zcu.funcInfo(zcu.panic_func_index); | |
| 27366 | 27380 | const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav); |
| 27367 | const null_stack_trace = Air.internedToRef(mod.null_stack_trace); | |
| 27381 | const null_stack_trace = Air.internedToRef(zcu.null_stack_trace); | |
| 27368 | 27382 | |
| 27369 | 27383 | const opt_usize_ty = try pt.optionalType(.usize_type); |
| 27370 | 27384 | const null_ret_addr = Air.internedToRef((try pt.intern(.{ .opt = .{ |
| ... | ... | @@ -27459,12 +27473,12 @@ fn panicSentinelMismatch( |
| 27459 | 27473 | ) !void { |
| 27460 | 27474 | assert(!parent_block.is_comptime); |
| 27461 | 27475 | const pt = sema.pt; |
| 27462 | const mod = pt.zcu; | |
| 27476 | const zcu = pt.zcu; | |
| 27463 | 27477 | const expected_sentinel_val = maybe_sentinel orelse return; |
| 27464 | 27478 | const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern()); |
| 27465 | 27479 | |
| 27466 | 27480 | const ptr_ty = sema.typeOf(ptr); |
| 27467 | const actual_sentinel = if (ptr_ty.isSlice(mod)) | |
| 27481 | const actual_sentinel = if (ptr_ty.isSlice(zcu)) | |
| 27468 | 27482 | try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index) |
| 27469 | 27483 | else blk: { |
| 27470 | 27484 | const elem_ptr_ty = try ptr_ty.elemPtrType(null, pt); |
| ... | ... | @@ -27472,7 +27486,7 @@ fn panicSentinelMismatch( |
| 27472 | 27486 | break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr); |
| 27473 | 27487 | }; |
| 27474 | 27488 | |
| 27475 | const ok = if (sentinel_ty.zigTypeTag(mod) == .Vector) ok: { | |
| 27489 | const ok = if (sentinel_ty.zigTypeTag(zcu) == .Vector) ok: { | |
| 27476 | 27490 | const eql = |
| 27477 | 27491 | try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq); |
| 27478 | 27492 | break :ok try parent_block.addInst(.{ |
| ... | ... | @@ -27482,7 +27496,7 @@ fn panicSentinelMismatch( |
| 27482 | 27496 | .operation = .And, |
| 27483 | 27497 | } }, |
| 27484 | 27498 | }); |
| 27485 | } else if (sentinel_ty.isSelfComparable(mod, true)) | |
| 27499 | } else if (sentinel_ty.isSelfComparable(zcu, true)) | |
| 27486 | 27500 | try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel) |
| 27487 | 27501 | else { |
| 27488 | 27502 | const panic_fn = try pt.getBuiltin("checkNonScalarSentinel"); |
| ... | ... | @@ -27532,7 +27546,7 @@ fn safetyCheckFormatted( |
| 27532 | 27546 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 27533 | 27547 | } |
| 27534 | 27548 | |
| 27535 | fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void { | |
| 27549 | fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.PanicId) CompileError!void { | |
| 27536 | 27550 | const msg_nav_index = try sema.preparePanicId(block, src, panic_id); |
| 27537 | 27551 | const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index); |
| 27538 | 27552 | try sema.panicWithMsg(block, src, msg_inst, .@"safety check"); |
| ... | ... | @@ -27568,30 +27582,30 @@ fn fieldVal( |
| 27568 | 27582 | // in `fieldPtr`. This function takes a value and returns a value. |
| 27569 | 27583 | |
| 27570 | 27584 | const pt = sema.pt; |
| 27571 | const mod = pt.zcu; | |
| 27572 | const ip = &mod.intern_pool; | |
| 27585 | const zcu = pt.zcu; | |
| 27586 | const ip = &zcu.intern_pool; | |
| 27573 | 27587 | const object_src = src; // TODO better source location |
| 27574 | 27588 | const object_ty = sema.typeOf(object); |
| 27575 | 27589 | |
| 27576 | 27590 | // Zig allows dereferencing a single pointer during field lookup. Note that |
| 27577 | 27591 | // we don't actually need to generate the dereference some field lookups, like the |
| 27578 | 27592 | // length of arrays and other comptime operations. |
| 27579 | const is_pointer_to = object_ty.isSinglePointer(mod); | |
| 27593 | const is_pointer_to = object_ty.isSinglePointer(zcu); | |
| 27580 | 27594 | |
| 27581 | 27595 | const inner_ty = if (is_pointer_to) |
| 27582 | object_ty.childType(mod) | |
| 27596 | object_ty.childType(zcu) | |
| 27583 | 27597 | else |
| 27584 | 27598 | object_ty; |
| 27585 | 27599 | |
| 27586 | switch (inner_ty.zigTypeTag(mod)) { | |
| 27600 | switch (inner_ty.zigTypeTag(zcu)) { | |
| 27587 | 27601 | .Array => { |
| 27588 | 27602 | if (field_name.eqlSlice("len", ip)) { |
| 27589 | return Air.internedToRef((try pt.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern()); | |
| 27603 | return Air.internedToRef((try pt.intValue(Type.usize, inner_ty.arrayLen(zcu))).toIntern()); | |
| 27590 | 27604 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27591 | const ptr_info = object_ty.ptrInfo(mod); | |
| 27605 | const ptr_info = object_ty.ptrInfo(zcu); | |
| 27592 | 27606 | const result_ty = try pt.ptrTypeSema(.{ |
| 27593 | .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(), | |
| 27594 | .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 27607 | .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(), | |
| 27608 | .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 27595 | 27609 | .flags = .{ |
| 27596 | 27610 | .size = .Many, |
| 27597 | 27611 | .alignment = ptr_info.flags.alignment, |
| ... | ... | @@ -27614,7 +27628,7 @@ fn fieldVal( |
| 27614 | 27628 | } |
| 27615 | 27629 | }, |
| 27616 | 27630 | .Pointer => { |
| 27617 | const ptr_info = inner_ty.ptrInfo(mod); | |
| 27631 | const ptr_info = inner_ty.ptrInfo(zcu); | |
| 27618 | 27632 | if (ptr_info.flags.size == .Slice) { |
| 27619 | 27633 | if (field_name.eqlSlice("ptr", ip)) { |
| 27620 | 27634 | const slice = if (is_pointer_to) |
| ... | ... | @@ -27647,7 +27661,7 @@ fn fieldVal( |
| 27647 | 27661 | const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?; |
| 27648 | 27662 | const child_type = val.toType(); |
| 27649 | 27663 | |
| 27650 | switch (try child_type.zigTypeTagOrPoison(mod)) { | |
| 27664 | switch (try child_type.zigTypeTagOrPoison(zcu)) { | |
| 27651 | 27665 | .ErrorSet => { |
| 27652 | 27666 | switch (ip.indexToKey(child_type.toIntern())) { |
| 27653 | 27667 | .error_set_type => |error_set_type| blk: { |
| ... | ... | @@ -27666,7 +27680,7 @@ fn fieldVal( |
| 27666 | 27680 | else => unreachable, |
| 27667 | 27681 | } |
| 27668 | 27682 | |
| 27669 | const error_set_type = if (!child_type.isAnyError(mod)) | |
| 27683 | const error_set_type = if (!child_type.isAnyError(zcu)) | |
| 27670 | 27684 | child_type |
| 27671 | 27685 | else |
| 27672 | 27686 | try pt.singleErrorSetType(field_name); |
| ... | ... | @@ -27676,12 +27690,12 @@ fn fieldVal( |
| 27676 | 27690 | } }))); |
| 27677 | 27691 | }, |
| 27678 | 27692 | .Union => { |
| 27679 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | |
| 27693 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 27680 | 27694 | return inst; |
| 27681 | 27695 | } |
| 27682 | 27696 | try child_type.resolveFields(pt); |
| 27683 | if (child_type.unionTagType(mod)) |enum_ty| { | |
| 27684 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| { | |
| 27697 | if (child_type.unionTagType(zcu)) |enum_ty| { | |
| 27698 | if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| { | |
| 27685 | 27699 | const field_index: u32 = @intCast(field_index_usize); |
| 27686 | 27700 | return Air.internedToRef((try pt.enumValueFieldIndex(enum_ty, field_index)).toIntern()); |
| 27687 | 27701 | } |
| ... | ... | @@ -27689,10 +27703,10 @@ fn fieldVal( |
| 27689 | 27703 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27690 | 27704 | }, |
| 27691 | 27705 | .Enum => { |
| 27692 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | |
| 27706 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 27693 | 27707 | return inst; |
| 27694 | 27708 | } |
| 27695 | const field_index_usize = child_type.enumFieldIndex(field_name, mod) orelse | |
| 27709 | const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse | |
| 27696 | 27710 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27697 | 27711 | const field_index: u32 = @intCast(field_index_usize); |
| 27698 | 27712 | const enum_val = try pt.enumValueFieldIndex(child_type, field_index); |
| ... | ... | @@ -27701,7 +27715,7 @@ fn fieldVal( |
| 27701 | 27715 | .Struct, .Opaque => { |
| 27702 | 27716 | switch (child_type.toIntern()) { |
| 27703 | 27717 | .empty_struct_type, .anyopaque_type => {}, // no namespace |
| 27704 | else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | |
| 27718 | else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 27705 | 27719 | return inst; |
| 27706 | 27720 | }, |
| 27707 | 27721 | } |
| ... | ... | @@ -27710,8 +27724,8 @@ fn fieldVal( |
| 27710 | 27724 | else => return sema.failWithOwnedErrorMsg(block, msg: { |
| 27711 | 27725 | const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)}); |
| 27712 | 27726 | errdefer msg.destroy(sema.gpa); |
| 27713 | if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); | |
| 27714 | if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{}); | |
| 27727 | if (child_type.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); | |
| 27728 | if (child_type.zigTypeTag(zcu) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{}); | |
| 27715 | 27729 | break :msg msg; |
| 27716 | 27730 | }), |
| 27717 | 27731 | } |
| ... | ... | @@ -27748,35 +27762,35 @@ fn fieldPtr( |
| 27748 | 27762 | // in `fieldVal`. This function takes a pointer and returns a pointer. |
| 27749 | 27763 | |
| 27750 | 27764 | const pt = sema.pt; |
| 27751 | const mod = pt.zcu; | |
| 27752 | const ip = &mod.intern_pool; | |
| 27765 | const zcu = pt.zcu; | |
| 27766 | const ip = &zcu.intern_pool; | |
| 27753 | 27767 | const object_ptr_src = src; // TODO better source location |
| 27754 | 27768 | const object_ptr_ty = sema.typeOf(object_ptr); |
| 27755 | const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) { | |
| 27756 | .Pointer => object_ptr_ty.childType(mod), | |
| 27769 | const object_ty = switch (object_ptr_ty.zigTypeTag(zcu)) { | |
| 27770 | .Pointer => object_ptr_ty.childType(zcu), | |
| 27757 | 27771 | else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(pt)}), |
| 27758 | 27772 | }; |
| 27759 | 27773 | |
| 27760 | 27774 | // Zig allows dereferencing a single pointer during field lookup. Note that |
| 27761 | 27775 | // we don't actually need to generate the dereference some field lookups, like the |
| 27762 | 27776 | // length of arrays and other comptime operations. |
| 27763 | const is_pointer_to = object_ty.isSinglePointer(mod); | |
| 27777 | const is_pointer_to = object_ty.isSinglePointer(zcu); | |
| 27764 | 27778 | |
| 27765 | 27779 | const inner_ty = if (is_pointer_to) |
| 27766 | object_ty.childType(mod) | |
| 27780 | object_ty.childType(zcu) | |
| 27767 | 27781 | else |
| 27768 | 27782 | object_ty; |
| 27769 | 27783 | |
| 27770 | switch (inner_ty.zigTypeTag(mod)) { | |
| 27784 | switch (inner_ty.zigTypeTag(zcu)) { | |
| 27771 | 27785 | .Array => { |
| 27772 | 27786 | if (field_name.eqlSlice("len", ip)) { |
| 27773 | const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod)); | |
| 27787 | const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(zcu)); | |
| 27774 | 27788 | return uavRef(sema, int_val.toIntern()); |
| 27775 | 27789 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27776 | const ptr_info = object_ty.ptrInfo(mod); | |
| 27790 | const ptr_info = object_ty.ptrInfo(zcu); | |
| 27777 | 27791 | const new_ptr_ty = try pt.ptrTypeSema(.{ |
| 27778 | .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(), | |
| 27779 | .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 27792 | .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(), | |
| 27793 | .sentinel = if (object_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 27780 | 27794 | .flags = .{ |
| 27781 | 27795 | .size = .Many, |
| 27782 | 27796 | .alignment = ptr_info.flags.alignment, |
| ... | ... | @@ -27788,10 +27802,10 @@ fn fieldPtr( |
| 27788 | 27802 | }, |
| 27789 | 27803 | .packed_offset = ptr_info.packed_offset, |
| 27790 | 27804 | }); |
| 27791 | const ptr_ptr_info = object_ptr_ty.ptrInfo(mod); | |
| 27805 | const ptr_ptr_info = object_ptr_ty.ptrInfo(zcu); | |
| 27792 | 27806 | const result_ty = try pt.ptrTypeSema(.{ |
| 27793 | 27807 | .child = new_ptr_ty.toIntern(), |
| 27794 | .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, | |
| 27808 | .sentinel = if (object_ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none, | |
| 27795 | 27809 | .flags = .{ |
| 27796 | 27810 | .alignment = ptr_ptr_info.flags.alignment, |
| 27797 | 27811 | .is_const = ptr_ptr_info.flags.is_const, |
| ... | ... | @@ -27812,7 +27826,7 @@ fn fieldPtr( |
| 27812 | 27826 | ); |
| 27813 | 27827 | } |
| 27814 | 27828 | }, |
| 27815 | .Pointer => if (inner_ty.isSlice(mod)) { | |
| 27829 | .Pointer => if (inner_ty.isSlice(zcu)) { | |
| 27816 | 27830 | const inner_ptr = if (is_pointer_to) |
| 27817 | 27831 | try sema.analyzeLoad(block, src, object_ptr, object_ptr_src) |
| 27818 | 27832 | else |
| ... | ... | @@ -27821,14 +27835,14 @@ fn fieldPtr( |
| 27821 | 27835 | const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty; |
| 27822 | 27836 | |
| 27823 | 27837 | if (field_name.eqlSlice("ptr", ip)) { |
| 27824 | const slice_ptr_ty = inner_ty.slicePtrFieldType(mod); | |
| 27838 | const slice_ptr_ty = inner_ty.slicePtrFieldType(zcu); | |
| 27825 | 27839 | |
| 27826 | 27840 | const result_ty = try pt.ptrTypeSema(.{ |
| 27827 | 27841 | .child = slice_ptr_ty.toIntern(), |
| 27828 | 27842 | .flags = .{ |
| 27829 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), | |
| 27830 | .is_volatile = attr_ptr_ty.isVolatilePtr(mod), | |
| 27831 | .address_space = attr_ptr_ty.ptrAddressSpace(mod), | |
| 27843 | .is_const = !attr_ptr_ty.ptrIsMutable(zcu), | |
| 27844 | .is_volatile = attr_ptr_ty.isVolatilePtr(zcu), | |
| 27845 | .address_space = attr_ptr_ty.ptrAddressSpace(zcu), | |
| 27832 | 27846 | }, |
| 27833 | 27847 | }); |
| 27834 | 27848 | |
| ... | ... | @@ -27844,9 +27858,9 @@ fn fieldPtr( |
| 27844 | 27858 | const result_ty = try pt.ptrTypeSema(.{ |
| 27845 | 27859 | .child = .usize_type, |
| 27846 | 27860 | .flags = .{ |
| 27847 | .is_const = !attr_ptr_ty.ptrIsMutable(mod), | |
| 27848 | .is_volatile = attr_ptr_ty.isVolatilePtr(mod), | |
| 27849 | .address_space = attr_ptr_ty.ptrAddressSpace(mod), | |
| 27861 | .is_const = !attr_ptr_ty.ptrIsMutable(zcu), | |
| 27862 | .is_volatile = attr_ptr_ty.isVolatilePtr(zcu), | |
| 27863 | .address_space = attr_ptr_ty.ptrAddressSpace(zcu), | |
| 27850 | 27864 | }, |
| 27851 | 27865 | }); |
| 27852 | 27866 | |
| ... | ... | @@ -27878,7 +27892,7 @@ fn fieldPtr( |
| 27878 | 27892 | const val = (sema.resolveDefinedValue(block, src, inner) catch unreachable).?; |
| 27879 | 27893 | const child_type = val.toType(); |
| 27880 | 27894 | |
| 27881 | switch (child_type.zigTypeTag(mod)) { | |
| 27895 | switch (child_type.zigTypeTag(zcu)) { | |
| 27882 | 27896 | .ErrorSet => { |
| 27883 | 27897 | switch (ip.indexToKey(child_type.toIntern())) { |
| 27884 | 27898 | .error_set_type => |error_set_type| blk: { |
| ... | ... | @@ -27899,7 +27913,7 @@ fn fieldPtr( |
| 27899 | 27913 | else => unreachable, |
| 27900 | 27914 | } |
| 27901 | 27915 | |
| 27902 | const error_set_type = if (!child_type.isAnyError(mod)) | |
| 27916 | const error_set_type = if (!child_type.isAnyError(zcu)) | |
| 27903 | 27917 | child_type |
| 27904 | 27918 | else |
| 27905 | 27919 | try pt.singleErrorSetType(field_name); |
| ... | ... | @@ -27909,12 +27923,12 @@ fn fieldPtr( |
| 27909 | 27923 | } })); |
| 27910 | 27924 | }, |
| 27911 | 27925 | .Union => { |
| 27912 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | |
| 27926 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 27913 | 27927 | return inst; |
| 27914 | 27928 | } |
| 27915 | 27929 | try child_type.resolveFields(pt); |
| 27916 | if (child_type.unionTagType(mod)) |enum_ty| { | |
| 27917 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| { | |
| 27930 | if (child_type.unionTagType(zcu)) |enum_ty| { | |
| 27931 | if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| { | |
| 27918 | 27932 | const field_index_u32: u32 = @intCast(field_index); |
| 27919 | 27933 | const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32); |
| 27920 | 27934 | return uavRef(sema, idx_val.toIntern()); |
| ... | ... | @@ -27923,10 +27937,10 @@ fn fieldPtr( |
| 27923 | 27937 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27924 | 27938 | }, |
| 27925 | 27939 | .Enum => { |
| 27926 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | |
| 27940 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 27927 | 27941 | return inst; |
| 27928 | 27942 | } |
| 27929 | const field_index = child_type.enumFieldIndex(field_name, mod) orelse { | |
| 27943 | const field_index = child_type.enumFieldIndex(field_name, zcu) orelse { | |
| 27930 | 27944 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27931 | 27945 | }; |
| 27932 | 27946 | const field_index_u32: u32 = @intCast(field_index); |
| ... | ... | @@ -27934,7 +27948,7 @@ fn fieldPtr( |
| 27934 | 27948 | return uavRef(sema, idx_val.toIntern()); |
| 27935 | 27949 | }, |
| 27936 | 27950 | .Struct, .Opaque => { |
| 27937 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | |
| 27951 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| { | |
| 27938 | 27952 | return inst; |
| 27939 | 27953 | } |
| 27940 | 27954 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| ... | ... | @@ -28149,18 +28163,18 @@ fn finishFieldCallBind( |
| 28149 | 28163 | object_ptr: Air.Inst.Ref, |
| 28150 | 28164 | ) CompileError!ResolvedFieldCallee { |
| 28151 | 28165 | const pt = sema.pt; |
| 28152 | const mod = pt.zcu; | |
| 28166 | const zcu = pt.zcu; | |
| 28153 | 28167 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 28154 | 28168 | .child = field_ty.toIntern(), |
| 28155 | 28169 | .flags = .{ |
| 28156 | .is_const = !ptr_ty.ptrIsMutable(mod), | |
| 28157 | .address_space = ptr_ty.ptrAddressSpace(mod), | |
| 28170 | .is_const = !ptr_ty.ptrIsMutable(zcu), | |
| 28171 | .address_space = ptr_ty.ptrAddressSpace(zcu), | |
| 28158 | 28172 | }, |
| 28159 | 28173 | }); |
| 28160 | 28174 | |
| 28161 | const container_ty = ptr_ty.childType(mod); | |
| 28162 | if (container_ty.zigTypeTag(mod) == .Struct) { | |
| 28163 | if (container_ty.structFieldIsComptime(field_index, mod)) { | |
| 28175 | const container_ty = ptr_ty.childType(zcu); | |
| 28176 | if (container_ty.zigTypeTag(zcu) == .Struct) { | |
| 28177 | if (container_ty.structFieldIsComptime(field_index, zcu)) { | |
| 28164 | 28178 | try container_ty.resolveStructFieldInits(pt); |
| 28165 | 28179 | const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?; |
| 28166 | 28180 | return .{ .direct = Air.internedToRef(default_val.toIntern()) }; |
| ... | ... | @@ -28237,26 +28251,26 @@ fn structFieldPtr( |
| 28237 | 28251 | initializing: bool, |
| 28238 | 28252 | ) CompileError!Air.Inst.Ref { |
| 28239 | 28253 | const pt = sema.pt; |
| 28240 | const mod = pt.zcu; | |
| 28241 | const ip = &mod.intern_pool; | |
| 28242 | assert(struct_ty.zigTypeTag(mod) == .Struct); | |
| 28254 | const zcu = pt.zcu; | |
| 28255 | const ip = &zcu.intern_pool; | |
| 28256 | assert(struct_ty.zigTypeTag(zcu) == .Struct); | |
| 28243 | 28257 | |
| 28244 | 28258 | try struct_ty.resolveFields(pt); |
| 28245 | 28259 | try struct_ty.resolveLayout(pt); |
| 28246 | 28260 | |
| 28247 | if (struct_ty.isTuple(mod)) { | |
| 28261 | if (struct_ty.isTuple(zcu)) { | |
| 28248 | 28262 | if (field_name.eqlSlice("len", ip)) { |
| 28249 | const len_inst = try pt.intRef(Type.usize, struct_ty.structFieldCount(mod)); | |
| 28263 | const len_inst = try pt.intRef(Type.usize, struct_ty.structFieldCount(zcu)); | |
| 28250 | 28264 | return sema.analyzeRef(block, src, len_inst); |
| 28251 | 28265 | } |
| 28252 | 28266 | const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src); |
| 28253 | 28267 | return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing); |
| 28254 | } else if (struct_ty.isAnonStruct(mod)) { | |
| 28268 | } else if (struct_ty.isAnonStruct(zcu)) { | |
| 28255 | 28269 | const field_index = try sema.anonStructFieldIndex(block, struct_ty, field_name, field_name_src); |
| 28256 | 28270 | return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing); |
| 28257 | 28271 | } |
| 28258 | 28272 | |
| 28259 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 28273 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 28260 | 28274 | |
| 28261 | 28275 | const field_index = struct_type.nameIndex(ip, field_name) orelse |
| 28262 | 28276 | return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name); |
| ... | ... | @@ -28275,9 +28289,9 @@ fn structFieldPtrByIndex( |
| 28275 | 28289 | initializing: bool, |
| 28276 | 28290 | ) CompileError!Air.Inst.Ref { |
| 28277 | 28291 | const pt = sema.pt; |
| 28278 | const mod = pt.zcu; | |
| 28279 | const ip = &mod.intern_pool; | |
| 28280 | if (struct_ty.isAnonStruct(mod)) { | |
| 28292 | const zcu = pt.zcu; | |
| 28293 | const ip = &zcu.intern_pool; | |
| 28294 | if (struct_ty.isAnonStruct(zcu)) { | |
| 28281 | 28295 | return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing); |
| 28282 | 28296 | } |
| 28283 | 28297 | |
| ... | ... | @@ -28286,10 +28300,10 @@ fn structFieldPtrByIndex( |
| 28286 | 28300 | return Air.internedToRef(val.toIntern()); |
| 28287 | 28301 | } |
| 28288 | 28302 | |
| 28289 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 28303 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 28290 | 28304 | const field_ty = struct_type.field_types.get(ip)[field_index]; |
| 28291 | 28305 | const struct_ptr_ty = sema.typeOf(struct_ptr); |
| 28292 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); | |
| 28306 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu); | |
| 28293 | 28307 | |
| 28294 | 28308 | var ptr_ty_data: InternPool.Key.PtrType = .{ |
| 28295 | 28309 | .child = field_ty, |
| ... | ... | @@ -28303,7 +28317,7 @@ fn structFieldPtrByIndex( |
| 28303 | 28317 | const parent_align = if (struct_ptr_ty_info.flags.alignment != .none) |
| 28304 | 28318 | struct_ptr_ty_info.flags.alignment |
| 28305 | 28319 | else |
| 28306 | try sema.typeAbiAlignment(Type.fromInterned(struct_ptr_ty_info.child)); | |
| 28320 | try Type.fromInterned(struct_ptr_ty_info.child).abiAlignmentSema(pt); | |
| 28307 | 28321 | |
| 28308 | 28322 | if (struct_type.layout == .@"packed") { |
| 28309 | 28323 | switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt)) { |
| ... | ... | @@ -28319,18 +28333,19 @@ fn structFieldPtrByIndex( |
| 28319 | 28333 | // For extern structs, field alignment might be bigger than type's |
| 28320 | 28334 | // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the |
| 28321 | 28335 | // second field is aligned as u32. |
| 28322 | const field_offset = struct_ty.structFieldOffset(field_index, pt); | |
| 28336 | const field_offset = struct_ty.structFieldOffset(field_index, zcu); | |
| 28323 | 28337 | ptr_ty_data.flags.alignment = if (parent_align == .none) |
| 28324 | 28338 | .none |
| 28325 | 28339 | else |
| 28326 | 28340 | @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset))); |
| 28327 | 28341 | } else { |
| 28328 | 28342 | // Our alignment is capped at the field alignment. |
| 28329 | const field_align = try pt.structFieldAlignmentAdvanced( | |
| 28343 | const field_align = try Type.fromInterned(field_ty).structFieldAlignmentAdvanced( | |
| 28330 | 28344 | struct_type.fieldAlign(ip, field_index), |
| 28331 | Type.fromInterned(field_ty), | |
| 28332 | 28345 | struct_type.layout, |
| 28333 | 28346 | .sema, |
| 28347 | pt.zcu, | |
| 28348 | pt.tid, | |
| 28334 | 28349 | ); |
| 28335 | 28350 | ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none) |
| 28336 | 28351 | field_align |
| ... | ... | @@ -28364,9 +28379,9 @@ fn structFieldVal( |
| 28364 | 28379 | struct_ty: Type, |
| 28365 | 28380 | ) CompileError!Air.Inst.Ref { |
| 28366 | 28381 | const pt = sema.pt; |
| 28367 | const mod = pt.zcu; | |
| 28368 | const ip = &mod.intern_pool; | |
| 28369 | assert(struct_ty.zigTypeTag(mod) == .Struct); | |
| 28382 | const zcu = pt.zcu; | |
| 28383 | const ip = &zcu.intern_pool; | |
| 28384 | assert(struct_ty.zigTypeTag(zcu) == .Struct); | |
| 28370 | 28385 | |
| 28371 | 28386 | try struct_ty.resolveFields(pt); |
| 28372 | 28387 | |
| ... | ... | @@ -28388,7 +28403,7 @@ fn structFieldVal( |
| 28388 | 28403 | return Air.internedToRef(field_val.toIntern()); |
| 28389 | 28404 | |
| 28390 | 28405 | if (try sema.resolveValue(struct_byval)) |struct_val| { |
| 28391 | if (struct_val.isUndef(mod)) return pt.undefRef(field_ty); | |
| 28406 | if (struct_val.isUndef(zcu)) return pt.undefRef(field_ty); | |
| 28392 | 28407 | if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| { |
| 28393 | 28408 | return Air.internedToRef(opv.toIntern()); |
| 28394 | 28409 | } |
| ... | ... | @@ -28421,9 +28436,9 @@ fn tupleFieldVal( |
| 28421 | 28436 | tuple_ty: Type, |
| 28422 | 28437 | ) CompileError!Air.Inst.Ref { |
| 28423 | 28438 | const pt = sema.pt; |
| 28424 | const mod = pt.zcu; | |
| 28425 | if (field_name.eqlSlice("len", &mod.intern_pool)) { | |
| 28426 | return pt.intRef(Type.usize, tuple_ty.structFieldCount(mod)); | |
| 28439 | const zcu = pt.zcu; | |
| 28440 | if (field_name.eqlSlice("len", &zcu.intern_pool)) { | |
| 28441 | return pt.intRef(Type.usize, tuple_ty.structFieldCount(zcu)); | |
| 28427 | 28442 | } |
| 28428 | 28443 | const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src); |
| 28429 | 28444 | return sema.tupleFieldValByIndex(block, src, tuple_byval, field_index, tuple_ty); |
| ... | ... | @@ -28461,10 +28476,10 @@ fn tupleFieldValByIndex( |
| 28461 | 28476 | tuple_ty: Type, |
| 28462 | 28477 | ) CompileError!Air.Inst.Ref { |
| 28463 | 28478 | const pt = sema.pt; |
| 28464 | const mod = pt.zcu; | |
| 28465 | const field_ty = tuple_ty.structFieldType(field_index, mod); | |
| 28479 | const zcu = pt.zcu; | |
| 28480 | const field_ty = tuple_ty.structFieldType(field_index, zcu); | |
| 28466 | 28481 | |
| 28467 | if (tuple_ty.structFieldIsComptime(field_index, mod)) | |
| 28482 | if (tuple_ty.structFieldIsComptime(field_index, zcu)) | |
| 28468 | 28483 | try tuple_ty.resolveStructFieldInits(pt); |
| 28469 | 28484 | if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| { |
| 28470 | 28485 | return Air.internedToRef(default_value.toIntern()); |
| ... | ... | @@ -28474,10 +28489,10 @@ fn tupleFieldValByIndex( |
| 28474 | 28489 | if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| { |
| 28475 | 28490 | return Air.internedToRef(opv.toIntern()); |
| 28476 | 28491 | } |
| 28477 | return switch (mod.intern_pool.indexToKey(tuple_val.toIntern())) { | |
| 28492 | return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) { | |
| 28478 | 28493 | .undef => pt.undefRef(field_ty), |
| 28479 | 28494 | .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) { |
| 28480 | .bytes => |bytes| try pt.intValue(Type.u8, bytes.at(field_index, &mod.intern_pool)), | |
| 28495 | .bytes => |bytes| try pt.intValue(Type.u8, bytes.at(field_index, &zcu.intern_pool)), | |
| 28481 | 28496 | .elems => |elems| Value.fromInterned(elems[field_index]), |
| 28482 | 28497 | .repeated_elem => |elem| Value.fromInterned(elem), |
| 28483 | 28498 | }.toIntern()), |
| ... | ... | @@ -28501,15 +28516,15 @@ fn unionFieldPtr( |
| 28501 | 28516 | initializing: bool, |
| 28502 | 28517 | ) CompileError!Air.Inst.Ref { |
| 28503 | 28518 | const pt = sema.pt; |
| 28504 | const mod = pt.zcu; | |
| 28505 | const ip = &mod.intern_pool; | |
| 28519 | const zcu = pt.zcu; | |
| 28520 | const ip = &zcu.intern_pool; | |
| 28506 | 28521 | |
| 28507 | assert(union_ty.zigTypeTag(mod) == .Union); | |
| 28522 | assert(union_ty.zigTypeTag(zcu) == .Union); | |
| 28508 | 28523 | |
| 28509 | 28524 | const union_ptr_ty = sema.typeOf(union_ptr); |
| 28510 | const union_ptr_info = union_ptr_ty.ptrInfo(mod); | |
| 28525 | const union_ptr_info = union_ptr_ty.ptrInfo(zcu); | |
| 28511 | 28526 | try union_ty.resolveFields(pt); |
| 28512 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 28527 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 28513 | 28528 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 28514 | 28529 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 28515 | 28530 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| ... | ... | @@ -28522,16 +28537,22 @@ fn unionFieldPtr( |
| 28522 | 28537 | const union_align = if (union_ptr_info.flags.alignment != .none) |
| 28523 | 28538 | union_ptr_info.flags.alignment |
| 28524 | 28539 | else |
| 28525 | try sema.typeAbiAlignment(union_ty); | |
| 28526 | const field_align = try pt.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema); | |
| 28540 | try union_ty.abiAlignmentSema(pt); | |
| 28541 | const field_align = try Type.unionFieldNormalAlignmentAdvanced( | |
| 28542 | union_obj, | |
| 28543 | field_index, | |
| 28544 | .sema, | |
| 28545 | pt.zcu, | |
| 28546 | pt.tid, | |
| 28547 | ); | |
| 28527 | 28548 | break :blk union_align.min(field_align); |
| 28528 | 28549 | } else union_ptr_info.flags.alignment, |
| 28529 | 28550 | }, |
| 28530 | 28551 | .packed_offset = union_ptr_info.packed_offset, |
| 28531 | 28552 | }); |
| 28532 | const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, mod).?); | |
| 28553 | const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?); | |
| 28533 | 28554 | |
| 28534 | if (initializing and field_ty.zigTypeTag(mod) == .NoReturn) { | |
| 28555 | if (initializing and field_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 28535 | 28556 | const msg = msg: { |
| 28536 | 28557 | const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{}); |
| 28537 | 28558 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -28556,7 +28577,7 @@ fn unionFieldPtr( |
| 28556 | 28577 | } else { |
| 28557 | 28578 | const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse |
| 28558 | 28579 | break :ct; |
| 28559 | if (union_val.isUndef(mod)) { | |
| 28580 | if (union_val.isUndef(zcu)) { | |
| 28560 | 28581 | return sema.failWithUseOfUndef(block, src); |
| 28561 | 28582 | } |
| 28562 | 28583 | const un = ip.indexToKey(union_val.toIntern()).un; |
| ... | ... | @@ -28564,8 +28585,8 @@ fn unionFieldPtr( |
| 28564 | 28585 | const tag_matches = un.tag == field_tag.toIntern(); |
| 28565 | 28586 | if (!tag_matches) { |
| 28566 | 28587 | const msg = msg: { |
| 28567 | const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), mod).?; | |
| 28568 | const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, mod); | |
| 28588 | const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?; | |
| 28589 | const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu); | |
| 28569 | 28590 | const msg = try sema.errMsg(src, "access of union field '{}' while field '{}' is active", .{ |
| 28570 | 28591 | field_name.fmt(ip), |
| 28571 | 28592 | active_field_name.fmt(ip), |
| ... | ... | @@ -28585,7 +28606,7 @@ fn unionFieldPtr( |
| 28585 | 28606 | |
| 28586 | 28607 | try sema.requireRuntimeBlock(block, src, null); |
| 28587 | 28608 | if (!initializing and union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and |
| 28588 | union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1) | |
| 28609 | union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1) | |
| 28589 | 28610 | { |
| 28590 | 28611 | const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28591 | 28612 | const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern()); |
| ... | ... | @@ -28594,7 +28615,7 @@ fn unionFieldPtr( |
| 28594 | 28615 | const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_val); |
| 28595 | 28616 | try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag); |
| 28596 | 28617 | } |
| 28597 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | |
| 28618 | if (field_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 28598 | 28619 | _ = try block.addNoOp(.unreach); |
| 28599 | 28620 | return .unreachable_value; |
| 28600 | 28621 | } |
| ... | ... | @@ -28654,7 +28675,7 @@ fn unionFieldVal( |
| 28654 | 28675 | .@"packed" => if (tag_matches) { |
| 28655 | 28676 | // Fast path - no need to use bitcast logic. |
| 28656 | 28677 | return Air.internedToRef(un.val); |
| 28657 | } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(pt, .sema), 0)) |field_val| { | |
| 28678 | } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeSema(pt), 0)) |field_val| { | |
| 28658 | 28679 | return Air.internedToRef(field_val.toIntern()); |
| 28659 | 28680 | }, |
| 28660 | 28681 | } |
| ... | ... | @@ -28688,17 +28709,17 @@ fn elemPtr( |
| 28688 | 28709 | oob_safety: bool, |
| 28689 | 28710 | ) CompileError!Air.Inst.Ref { |
| 28690 | 28711 | const pt = sema.pt; |
| 28691 | const mod = pt.zcu; | |
| 28712 | const zcu = pt.zcu; | |
| 28692 | 28713 | const indexable_ptr_src = src; // TODO better source location |
| 28693 | 28714 | const indexable_ptr_ty = sema.typeOf(indexable_ptr); |
| 28694 | 28715 | |
| 28695 | const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) { | |
| 28696 | .Pointer => indexable_ptr_ty.childType(mod), | |
| 28716 | const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(zcu)) { | |
| 28717 | .Pointer => indexable_ptr_ty.childType(zcu), | |
| 28697 | 28718 | else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}), |
| 28698 | 28719 | }; |
| 28699 | 28720 | try checkIndexable(sema, block, src, indexable_ty); |
| 28700 | 28721 | |
| 28701 | const elem_ptr = switch (indexable_ty.zigTypeTag(mod)) { | |
| 28722 | const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) { | |
| 28702 | 28723 | .Array, .Vector => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety), |
| 28703 | 28724 | .Struct => blk: { |
| 28704 | 28725 | // Tuple field access. |
| ... | ... | @@ -28732,11 +28753,11 @@ fn elemPtrOneLayerOnly( |
| 28732 | 28753 | const indexable_src = src; // TODO better source location |
| 28733 | 28754 | const indexable_ty = sema.typeOf(indexable); |
| 28734 | 28755 | const pt = sema.pt; |
| 28735 | const mod = pt.zcu; | |
| 28756 | const zcu = pt.zcu; | |
| 28736 | 28757 | |
| 28737 | 28758 | try checkIndexable(sema, block, src, indexable_ty); |
| 28738 | 28759 | |
| 28739 | switch (indexable_ty.ptrSize(mod)) { | |
| 28760 | switch (indexable_ty.ptrSize(zcu)) { | |
| 28740 | 28761 | .Slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), |
| 28741 | 28762 | .Many, .C => { |
| 28742 | 28763 | const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_src, indexable); |
| ... | ... | @@ -28754,11 +28775,11 @@ fn elemPtrOneLayerOnly( |
| 28754 | 28775 | return block.addPtrElemPtr(indexable, elem_index, result_ty); |
| 28755 | 28776 | }, |
| 28756 | 28777 | .One => { |
| 28757 | const child_ty = indexable_ty.childType(mod); | |
| 28758 | const elem_ptr = switch (child_ty.zigTypeTag(mod)) { | |
| 28778 | const child_ty = indexable_ty.childType(zcu); | |
| 28779 | const elem_ptr = switch (child_ty.zigTypeTag(zcu)) { | |
| 28759 | 28780 | .Array, .Vector => try sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety), |
| 28760 | 28781 | .Struct => blk: { |
| 28761 | assert(child_ty.isTuple(mod)); | |
| 28782 | assert(child_ty.isTuple(zcu)); | |
| 28762 | 28783 | const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ |
| 28763 | 28784 | .needed_comptime_reason = "tuple field access index must be comptime-known", |
| 28764 | 28785 | }); |
| ... | ... | @@ -28785,7 +28806,7 @@ fn elemVal( |
| 28785 | 28806 | const indexable_src = src; // TODO better source location |
| 28786 | 28807 | const indexable_ty = sema.typeOf(indexable); |
| 28787 | 28808 | const pt = sema.pt; |
| 28788 | const mod = pt.zcu; | |
| 28809 | const zcu = pt.zcu; | |
| 28789 | 28810 | |
| 28790 | 28811 | try checkIndexable(sema, block, src, indexable_ty); |
| 28791 | 28812 | |
| ... | ... | @@ -28793,8 +28814,8 @@ fn elemVal( |
| 28793 | 28814 | // index is a scalar or vector instead of unconditionally casting to usize. |
| 28794 | 28815 | const elem_index = try sema.coerce(block, Type.usize, elem_index_uncasted, elem_index_src); |
| 28795 | 28816 | |
| 28796 | switch (indexable_ty.zigTypeTag(mod)) { | |
| 28797 | .Pointer => switch (indexable_ty.ptrSize(mod)) { | |
| 28817 | switch (indexable_ty.zigTypeTag(zcu)) { | |
| 28818 | .Pointer => switch (indexable_ty.ptrSize(zcu)) { | |
| 28798 | 28819 | .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), |
| 28799 | 28820 | .Many, .C => { |
| 28800 | 28821 | const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable); |
| ... | ... | @@ -28804,7 +28825,7 @@ fn elemVal( |
| 28804 | 28825 | const indexable_val = maybe_indexable_val orelse break :rs indexable_src; |
| 28805 | 28826 | const index_val = maybe_index_val orelse break :rs elem_index_src; |
| 28806 | 28827 | const index: usize = @intCast(try index_val.toUnsignedIntSema(pt)); |
| 28807 | const elem_ty = indexable_ty.elemType2(mod); | |
| 28828 | const elem_ty = indexable_ty.elemType2(zcu); | |
| 28808 | 28829 | const many_ptr_ty = try pt.manyConstPtrType(elem_ty); |
| 28809 | 28830 | const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty); |
| 28810 | 28831 | const elem_ptr_ty = try pt.singleConstPtrType(elem_ty); |
| ... | ... | @@ -28820,12 +28841,12 @@ fn elemVal( |
| 28820 | 28841 | }, |
| 28821 | 28842 | .One => { |
| 28822 | 28843 | arr_sent: { |
| 28823 | const inner_ty = indexable_ty.childType(mod); | |
| 28824 | if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent; | |
| 28825 | const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent; | |
| 28844 | const inner_ty = indexable_ty.childType(zcu); | |
| 28845 | if (inner_ty.zigTypeTag(zcu) != .Array) break :arr_sent; | |
| 28846 | const sentinel = inner_ty.sentinel(zcu) orelse break :arr_sent; | |
| 28826 | 28847 | const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent; |
| 28827 | 28848 | const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(pt)); |
| 28828 | if (index != inner_ty.arrayLen(mod)) break :arr_sent; | |
| 28849 | if (index != inner_ty.arrayLen(zcu)) break :arr_sent; | |
| 28829 | 28850 | return Air.internedToRef(sentinel.toIntern()); |
| 28830 | 28851 | } |
| 28831 | 28852 | const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety); |
| ... | ... | @@ -28857,7 +28878,7 @@ fn validateRuntimeElemAccess( |
| 28857 | 28878 | parent_ty: Type, |
| 28858 | 28879 | parent_src: LazySrcLoc, |
| 28859 | 28880 | ) CompileError!void { |
| 28860 | if (try sema.typeRequiresComptime(elem_ty)) { | |
| 28881 | if (try elem_ty.comptimeOnlySema(sema.pt)) { | |
| 28861 | 28882 | const msg = msg: { |
| 28862 | 28883 | const msg = try sema.errMsg( |
| 28863 | 28884 | elem_index_src, |
| ... | ... | @@ -28884,11 +28905,11 @@ fn tupleFieldPtr( |
| 28884 | 28905 | init: bool, |
| 28885 | 28906 | ) CompileError!Air.Inst.Ref { |
| 28886 | 28907 | const pt = sema.pt; |
| 28887 | const mod = pt.zcu; | |
| 28908 | const zcu = pt.zcu; | |
| 28888 | 28909 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); |
| 28889 | const tuple_ty = tuple_ptr_ty.childType(mod); | |
| 28910 | const tuple_ty = tuple_ptr_ty.childType(zcu); | |
| 28890 | 28911 | try tuple_ty.resolveFields(pt); |
| 28891 | const field_count = tuple_ty.structFieldCount(mod); | |
| 28912 | const field_count = tuple_ty.structFieldCount(zcu); | |
| 28892 | 28913 | |
| 28893 | 28914 | if (field_count == 0) { |
| 28894 | 28915 | return sema.fail(block, tuple_ptr_src, "indexing into empty tuple is not allowed", .{}); |
| ... | ... | @@ -28900,17 +28921,17 @@ fn tupleFieldPtr( |
| 28900 | 28921 | }); |
| 28901 | 28922 | } |
| 28902 | 28923 | |
| 28903 | const field_ty = tuple_ty.structFieldType(field_index, mod); | |
| 28924 | const field_ty = tuple_ty.structFieldType(field_index, zcu); | |
| 28904 | 28925 | const ptr_field_ty = try pt.ptrTypeSema(.{ |
| 28905 | 28926 | .child = field_ty.toIntern(), |
| 28906 | 28927 | .flags = .{ |
| 28907 | .is_const = !tuple_ptr_ty.ptrIsMutable(mod), | |
| 28908 | .is_volatile = tuple_ptr_ty.isVolatilePtr(mod), | |
| 28909 | .address_space = tuple_ptr_ty.ptrAddressSpace(mod), | |
| 28928 | .is_const = !tuple_ptr_ty.ptrIsMutable(zcu), | |
| 28929 | .is_volatile = tuple_ptr_ty.isVolatilePtr(zcu), | |
| 28930 | .address_space = tuple_ptr_ty.ptrAddressSpace(zcu), | |
| 28910 | 28931 | }, |
| 28911 | 28932 | }); |
| 28912 | 28933 | |
| 28913 | if (tuple_ty.structFieldIsComptime(field_index, mod)) | |
| 28934 | if (tuple_ty.structFieldIsComptime(field_index, zcu)) | |
| 28914 | 28935 | try tuple_ty.resolveStructFieldInits(pt); |
| 28915 | 28936 | |
| 28916 | 28937 | if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_val| { |
| ... | ... | @@ -28943,10 +28964,10 @@ fn tupleField( |
| 28943 | 28964 | field_index: u32, |
| 28944 | 28965 | ) CompileError!Air.Inst.Ref { |
| 28945 | 28966 | const pt = sema.pt; |
| 28946 | const mod = pt.zcu; | |
| 28967 | const zcu = pt.zcu; | |
| 28947 | 28968 | const tuple_ty = sema.typeOf(tuple); |
| 28948 | 28969 | try tuple_ty.resolveFields(pt); |
| 28949 | const field_count = tuple_ty.structFieldCount(mod); | |
| 28970 | const field_count = tuple_ty.structFieldCount(zcu); | |
| 28950 | 28971 | |
| 28951 | 28972 | if (field_count == 0) { |
| 28952 | 28973 | return sema.fail(block, tuple_src, "indexing into empty tuple is not allowed", .{}); |
| ... | ... | @@ -28958,16 +28979,16 @@ fn tupleField( |
| 28958 | 28979 | }); |
| 28959 | 28980 | } |
| 28960 | 28981 | |
| 28961 | const field_ty = tuple_ty.structFieldType(field_index, mod); | |
| 28982 | const field_ty = tuple_ty.structFieldType(field_index, zcu); | |
| 28962 | 28983 | |
| 28963 | if (tuple_ty.structFieldIsComptime(field_index, mod)) | |
| 28984 | if (tuple_ty.structFieldIsComptime(field_index, zcu)) | |
| 28964 | 28985 | try tuple_ty.resolveStructFieldInits(pt); |
| 28965 | 28986 | if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| { |
| 28966 | 28987 | return Air.internedToRef(default_value.toIntern()); // comptime field |
| 28967 | 28988 | } |
| 28968 | 28989 | |
| 28969 | 28990 | if (try sema.resolveValue(tuple)) |tuple_val| { |
| 28970 | if (tuple_val.isUndef(mod)) return pt.undefRef(field_ty); | |
| 28991 | if (tuple_val.isUndef(zcu)) return pt.undefRef(field_ty); | |
| 28971 | 28992 | return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern()); |
| 28972 | 28993 | } |
| 28973 | 28994 | |
| ... | ... | @@ -28989,12 +29010,12 @@ fn elemValArray( |
| 28989 | 29010 | oob_safety: bool, |
| 28990 | 29011 | ) CompileError!Air.Inst.Ref { |
| 28991 | 29012 | const pt = sema.pt; |
| 28992 | const mod = pt.zcu; | |
| 29013 | const zcu = pt.zcu; | |
| 28993 | 29014 | const array_ty = sema.typeOf(array); |
| 28994 | const array_sent = array_ty.sentinel(mod); | |
| 28995 | const array_len = array_ty.arrayLen(mod); | |
| 29015 | const array_sent = array_ty.sentinel(zcu); | |
| 29016 | const array_len = array_ty.arrayLen(zcu); | |
| 28996 | 29017 | const array_len_s = array_len + @intFromBool(array_sent != null); |
| 28997 | const elem_ty = array_ty.childType(mod); | |
| 29018 | const elem_ty = array_ty.childType(zcu); | |
| 28998 | 29019 | |
| 28999 | 29020 | if (array_len_s == 0) { |
| 29000 | 29021 | return sema.fail(block, array_src, "indexing into empty array is not allowed", .{}); |
| ... | ... | @@ -29017,7 +29038,7 @@ fn elemValArray( |
| 29017 | 29038 | } |
| 29018 | 29039 | } |
| 29019 | 29040 | if (maybe_undef_array_val) |array_val| { |
| 29020 | if (array_val.isUndef(mod)) { | |
| 29041 | if (array_val.isUndef(zcu)) { | |
| 29021 | 29042 | return pt.undefRef(elem_ty); |
| 29022 | 29043 | } |
| 29023 | 29044 | if (maybe_index_val) |index_val| { |
| ... | ... | @@ -29058,11 +29079,11 @@ fn elemPtrArray( |
| 29058 | 29079 | oob_safety: bool, |
| 29059 | 29080 | ) CompileError!Air.Inst.Ref { |
| 29060 | 29081 | const pt = sema.pt; |
| 29061 | const mod = pt.zcu; | |
| 29082 | const zcu = pt.zcu; | |
| 29062 | 29083 | const array_ptr_ty = sema.typeOf(array_ptr); |
| 29063 | const array_ty = array_ptr_ty.childType(mod); | |
| 29064 | const array_sent = array_ty.sentinel(mod) != null; | |
| 29065 | const array_len = array_ty.arrayLen(mod); | |
| 29084 | const array_ty = array_ptr_ty.childType(zcu); | |
| 29085 | const array_sent = array_ty.sentinel(zcu) != null; | |
| 29086 | const array_len = array_ty.arrayLen(zcu); | |
| 29066 | 29087 | const array_len_s = array_len + @intFromBool(array_sent); |
| 29067 | 29088 | |
| 29068 | 29089 | if (array_len_s == 0) { |
| ... | ... | @@ -29083,7 +29104,7 @@ fn elemPtrArray( |
| 29083 | 29104 | const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, pt); |
| 29084 | 29105 | |
| 29085 | 29106 | if (maybe_undef_array_ptr_val) |array_ptr_val| { |
| 29086 | if (array_ptr_val.isUndef(mod)) { | |
| 29107 | if (array_ptr_val.isUndef(zcu)) { | |
| 29087 | 29108 | return pt.undefRef(elem_ptr_ty); |
| 29088 | 29109 | } |
| 29089 | 29110 | if (offset) |index| { |
| ... | ... | @@ -29093,7 +29114,7 @@ fn elemPtrArray( |
| 29093 | 29114 | } |
| 29094 | 29115 | |
| 29095 | 29116 | if (!init) { |
| 29096 | try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.elemType2(mod), array_ty, array_ptr_src); | |
| 29117 | try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.elemType2(zcu), array_ty, array_ptr_src); | |
| 29097 | 29118 | } |
| 29098 | 29119 | |
| 29099 | 29120 | const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src; |
| ... | ... | @@ -29120,10 +29141,10 @@ fn elemValSlice( |
| 29120 | 29141 | oob_safety: bool, |
| 29121 | 29142 | ) CompileError!Air.Inst.Ref { |
| 29122 | 29143 | const pt = sema.pt; |
| 29123 | const mod = pt.zcu; | |
| 29144 | const zcu = pt.zcu; | |
| 29124 | 29145 | const slice_ty = sema.typeOf(slice); |
| 29125 | const slice_sent = slice_ty.sentinel(mod) != null; | |
| 29126 | const elem_ty = slice_ty.elemType2(mod); | |
| 29146 | const slice_sent = slice_ty.sentinel(zcu) != null; | |
| 29147 | const elem_ty = slice_ty.elemType2(zcu); | |
| 29127 | 29148 | var runtime_src = slice_src; |
| 29128 | 29149 | |
| 29129 | 29150 | // slice must be defined since it can dereferenced as null |
| ... | ... | @@ -29178,9 +29199,9 @@ fn elemPtrSlice( |
| 29178 | 29199 | oob_safety: bool, |
| 29179 | 29200 | ) CompileError!Air.Inst.Ref { |
| 29180 | 29201 | const pt = sema.pt; |
| 29181 | const mod = pt.zcu; | |
| 29202 | const zcu = pt.zcu; | |
| 29182 | 29203 | const slice_ty = sema.typeOf(slice); |
| 29183 | const slice_sent = slice_ty.sentinel(mod) != null; | |
| 29204 | const slice_sent = slice_ty.sentinel(zcu) != null; | |
| 29184 | 29205 | |
| 29185 | 29206 | const maybe_undef_slice_val = try sema.resolveValue(slice); |
| 29186 | 29207 | // The index must not be undefined since it can be out of bounds. |
| ... | ... | @@ -29192,7 +29213,7 @@ fn elemPtrSlice( |
| 29192 | 29213 | const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt); |
| 29193 | 29214 | |
| 29194 | 29215 | if (maybe_undef_slice_val) |slice_val| { |
| 29195 | if (slice_val.isUndef(mod)) { | |
| 29216 | if (slice_val.isUndef(zcu)) { | |
| 29196 | 29217 | return pt.undefRef(elem_ptr_ty); |
| 29197 | 29218 | } |
| 29198 | 29219 | const slice_len = try slice_val.sliceLen(pt); |
| ... | ... | @@ -29217,7 +29238,7 @@ fn elemPtrSlice( |
| 29217 | 29238 | if (oob_safety and block.wantSafety()) { |
| 29218 | 29239 | const len_inst = len: { |
| 29219 | 29240 | if (maybe_undef_slice_val) |slice_val| |
| 29220 | if (!slice_val.isUndef(mod)) | |
| 29241 | if (!slice_val.isUndef(zcu)) | |
| 29221 | 29242 | break :len try pt.intRef(Type.usize, try slice_val.sliceLen(pt)); |
| 29222 | 29243 | break :len try block.addTyOp(.slice_len, Type.usize, slice); |
| 29223 | 29244 | }; |
| ... | ... | @@ -29600,7 +29621,7 @@ fn coerceExtra( |
| 29600 | 29621 | // empty tuple to zero-length slice |
| 29601 | 29622 | // note that this allows coercing to a mutable slice. |
| 29602 | 29623 | if (inst_child_ty.structFieldCount(zcu) == 0) { |
| 29603 | const align_val = try dest_ty.ptrAlignmentAdvanced(pt, .sema); | |
| 29624 | const align_val = try dest_ty.ptrAlignmentSema(pt); | |
| 29604 | 29625 | return Air.internedToRef(try pt.intern(.{ .slice = .{ |
| 29605 | 29626 | .ty = dest_ty.toIntern(), |
| 29606 | 29627 | .ptr = try pt.intern(.{ .ptr = .{ |
| ... | ... | @@ -30098,7 +30119,7 @@ const InMemoryCoercionResult = union(enum) { |
| 30098 | 30119 | return res; |
| 30099 | 30120 | } |
| 30100 | 30121 | |
| 30101 | fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void { | |
| 30122 | fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Zcu.ErrorMsg) !void { | |
| 30102 | 30123 | const pt = sema.pt; |
| 30103 | 30124 | var cur = res; |
| 30104 | 30125 | while (true) switch (cur.*) { |
| ... | ... | @@ -30364,18 +30385,18 @@ pub fn coerceInMemoryAllowed( |
| 30364 | 30385 | src_val: ?Value, |
| 30365 | 30386 | ) CompileError!InMemoryCoercionResult { |
| 30366 | 30387 | const pt = sema.pt; |
| 30367 | const mod = pt.zcu; | |
| 30388 | const zcu = pt.zcu; | |
| 30368 | 30389 | |
| 30369 | if (dest_ty.eql(src_ty, mod)) | |
| 30390 | if (dest_ty.eql(src_ty, zcu)) | |
| 30370 | 30391 | return .ok; |
| 30371 | 30392 | |
| 30372 | const dest_tag = dest_ty.zigTypeTag(mod); | |
| 30373 | const src_tag = src_ty.zigTypeTag(mod); | |
| 30393 | const dest_tag = dest_ty.zigTypeTag(zcu); | |
| 30394 | const src_tag = src_ty.zigTypeTag(zcu); | |
| 30374 | 30395 | |
| 30375 | 30396 | // Differently-named integers with the same number of bits. |
| 30376 | 30397 | if (dest_tag == .Int and src_tag == .Int) { |
| 30377 | const dest_info = dest_ty.intInfo(mod); | |
| 30378 | const src_info = src_ty.intInfo(mod); | |
| 30398 | const dest_info = dest_ty.intInfo(zcu); | |
| 30399 | const src_info = src_ty.intInfo(zcu); | |
| 30379 | 30400 | |
| 30380 | 30401 | if (dest_info.signedness == src_info.signedness and |
| 30381 | 30402 | dest_info.bits == src_info.bits) |
| ... | ... | @@ -30425,7 +30446,7 @@ pub fn coerceInMemoryAllowed( |
| 30425 | 30446 | } |
| 30426 | 30447 | |
| 30427 | 30448 | // Slices |
| 30428 | if (dest_ty.isSlice(mod) and src_ty.isSlice(mod)) { | |
| 30449 | if (dest_ty.isSlice(zcu) and src_ty.isSlice(zcu)) { | |
| 30429 | 30450 | return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src); |
| 30430 | 30451 | } |
| 30431 | 30452 | |
| ... | ... | @@ -30436,8 +30457,8 @@ pub fn coerceInMemoryAllowed( |
| 30436 | 30457 | |
| 30437 | 30458 | // Error Unions |
| 30438 | 30459 | if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) { |
| 30439 | const dest_payload = dest_ty.errorUnionPayload(mod); | |
| 30440 | const src_payload = src_ty.errorUnionPayload(mod); | |
| 30460 | const dest_payload = dest_ty.errorUnionPayload(zcu); | |
| 30461 | const src_payload = src_ty.errorUnionPayload(zcu); | |
| 30441 | 30462 | const child = try sema.coerceInMemoryAllowed(block, dest_payload, src_payload, dest_is_mut, target, dest_src, src_src, null); |
| 30442 | 30463 | if (child != .ok) { |
| 30443 | 30464 | return InMemoryCoercionResult{ .error_union_payload = .{ |
| ... | ... | @@ -30446,7 +30467,7 @@ pub fn coerceInMemoryAllowed( |
| 30446 | 30467 | .wanted = dest_payload, |
| 30447 | 30468 | } }; |
| 30448 | 30469 | } |
| 30449 | return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(mod), src_ty.errorUnionSet(mod), dest_is_mut, target, dest_src, src_src, null); | |
| 30470 | return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(zcu), src_ty.errorUnionSet(zcu), dest_is_mut, target, dest_src, src_src, null); | |
| 30450 | 30471 | } |
| 30451 | 30472 | |
| 30452 | 30473 | // Error Sets |
| ... | ... | @@ -30456,8 +30477,8 @@ pub fn coerceInMemoryAllowed( |
| 30456 | 30477 | |
| 30457 | 30478 | // Arrays |
| 30458 | 30479 | if (dest_tag == .Array and src_tag == .Array) { |
| 30459 | const dest_info = dest_ty.arrayInfo(mod); | |
| 30460 | const src_info = src_ty.arrayInfo(mod); | |
| 30480 | const dest_info = dest_ty.arrayInfo(zcu); | |
| 30481 | const src_info = src_ty.arrayInfo(zcu); | |
| 30461 | 30482 | if (dest_info.len != src_info.len) { |
| 30462 | 30483 | return InMemoryCoercionResult{ .array_len = .{ |
| 30463 | 30484 | .actual = src_info.len, |
| ... | ... | @@ -30483,7 +30504,7 @@ pub fn coerceInMemoryAllowed( |
| 30483 | 30504 | dest_info.sentinel.?.eql( |
| 30484 | 30505 | try pt.getCoerced(src_info.sentinel.?, dest_info.elem_type), |
| 30485 | 30506 | dest_info.elem_type, |
| 30486 | mod, | |
| 30507 | zcu, | |
| 30487 | 30508 | )); |
| 30488 | 30509 | if (!ok_sent) { |
| 30489 | 30510 | return InMemoryCoercionResult{ .array_sentinel = .{ |
| ... | ... | @@ -30497,8 +30518,8 @@ pub fn coerceInMemoryAllowed( |
| 30497 | 30518 | |
| 30498 | 30519 | // Vectors |
| 30499 | 30520 | if (dest_tag == .Vector and src_tag == .Vector) { |
| 30500 | const dest_len = dest_ty.vectorLen(mod); | |
| 30501 | const src_len = src_ty.vectorLen(mod); | |
| 30521 | const dest_len = dest_ty.vectorLen(zcu); | |
| 30522 | const src_len = src_ty.vectorLen(zcu); | |
| 30502 | 30523 | if (dest_len != src_len) { |
| 30503 | 30524 | return InMemoryCoercionResult{ .vector_len = .{ |
| 30504 | 30525 | .actual = src_len, |
| ... | ... | @@ -30506,8 +30527,8 @@ pub fn coerceInMemoryAllowed( |
| 30506 | 30527 | } }; |
| 30507 | 30528 | } |
| 30508 | 30529 | |
| 30509 | const dest_elem_ty = dest_ty.scalarType(mod); | |
| 30510 | const src_elem_ty = src_ty.scalarType(mod); | |
| 30530 | const dest_elem_ty = dest_ty.scalarType(zcu); | |
| 30531 | const src_elem_ty = src_ty.scalarType(zcu); | |
| 30511 | 30532 | const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src, null); |
| 30512 | 30533 | if (child != .ok) { |
| 30513 | 30534 | return InMemoryCoercionResult{ .vector_elem = .{ |
| ... | ... | @@ -30524,8 +30545,8 @@ pub fn coerceInMemoryAllowed( |
| 30524 | 30545 | if ((dest_tag == .Vector and src_tag == .Array) or |
| 30525 | 30546 | (dest_tag == .Array and src_tag == .Vector)) |
| 30526 | 30547 | { |
| 30527 | const dest_len = dest_ty.arrayLen(mod); | |
| 30528 | const src_len = src_ty.arrayLen(mod); | |
| 30548 | const dest_len = dest_ty.arrayLen(zcu); | |
| 30549 | const src_len = src_ty.arrayLen(zcu); | |
| 30529 | 30550 | if (dest_len != src_len) { |
| 30530 | 30551 | return InMemoryCoercionResult{ .array_len = .{ |
| 30531 | 30552 | .actual = src_len, |
| ... | ... | @@ -30533,8 +30554,8 @@ pub fn coerceInMemoryAllowed( |
| 30533 | 30554 | } }; |
| 30534 | 30555 | } |
| 30535 | 30556 | |
| 30536 | const dest_elem_ty = dest_ty.childType(mod); | |
| 30537 | const src_elem_ty = src_ty.childType(mod); | |
| 30557 | const dest_elem_ty = dest_ty.childType(zcu); | |
| 30558 | const src_elem_ty = src_ty.childType(zcu); | |
| 30538 | 30559 | const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src, null); |
| 30539 | 30560 | if (child != .ok) { |
| 30540 | 30561 | return InMemoryCoercionResult{ .array_elem = .{ |
| ... | ... | @@ -30545,7 +30566,7 @@ pub fn coerceInMemoryAllowed( |
| 30545 | 30566 | } |
| 30546 | 30567 | |
| 30547 | 30568 | if (dest_tag == .Array) { |
| 30548 | const dest_info = dest_ty.arrayInfo(mod); | |
| 30569 | const dest_info = dest_ty.arrayInfo(zcu); | |
| 30549 | 30570 | if (dest_info.sentinel != null) { |
| 30550 | 30571 | return InMemoryCoercionResult{ .array_sentinel = .{ |
| 30551 | 30572 | .actual = Value.@"unreachable", |
| ... | ... | @@ -30558,8 +30579,8 @@ pub fn coerceInMemoryAllowed( |
| 30558 | 30579 | // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M), |
| 30559 | 30580 | // that is to say, the padding bits are not in the same place as the array [N]iM. |
| 30560 | 30581 | // If there's no padding, the bitcast is possible. |
| 30561 | const elem_bit_size = dest_elem_ty.bitSize(pt); | |
| 30562 | const elem_abi_byte_size = dest_elem_ty.abiSize(pt); | |
| 30582 | const elem_bit_size = dest_elem_ty.bitSize(zcu); | |
| 30583 | const elem_abi_byte_size = dest_elem_ty.abiSize(zcu); | |
| 30563 | 30584 | if (elem_abi_byte_size * 8 == elem_bit_size) |
| 30564 | 30585 | return .ok; |
| 30565 | 30586 | } |
| ... | ... | @@ -30572,8 +30593,8 @@ pub fn coerceInMemoryAllowed( |
| 30572 | 30593 | .wanted = dest_ty, |
| 30573 | 30594 | } }; |
| 30574 | 30595 | } |
| 30575 | const dest_child_type = dest_ty.optionalChild(mod); | |
| 30576 | const src_child_type = src_ty.optionalChild(mod); | |
| 30596 | const dest_child_type = dest_ty.optionalChild(zcu); | |
| 30597 | const src_child_type = src_ty.optionalChild(zcu); | |
| 30577 | 30598 | |
| 30578 | 30599 | const child = try sema.coerceInMemoryAllowed(block, dest_child_type, src_child_type, dest_is_mut, target, dest_src, src_src, null); |
| 30579 | 30600 | if (child != .ok) { |
| ... | ... | @@ -30588,15 +30609,15 @@ pub fn coerceInMemoryAllowed( |
| 30588 | 30609 | } |
| 30589 | 30610 | |
| 30590 | 30611 | // Tuples (with in-memory-coercible fields) |
| 30591 | if (dest_ty.isTuple(mod) and src_ty.isTuple(mod)) tuple: { | |
| 30592 | if (dest_ty.containerLayout(mod) != src_ty.containerLayout(mod)) break :tuple; | |
| 30593 | if (dest_ty.structFieldCount(mod) != src_ty.structFieldCount(mod)) break :tuple; | |
| 30594 | const field_count = dest_ty.structFieldCount(mod); | |
| 30612 | if (dest_ty.isTuple(zcu) and src_ty.isTuple(zcu)) tuple: { | |
| 30613 | if (dest_ty.containerLayout(zcu) != src_ty.containerLayout(zcu)) break :tuple; | |
| 30614 | if (dest_ty.structFieldCount(zcu) != src_ty.structFieldCount(zcu)) break :tuple; | |
| 30615 | const field_count = dest_ty.structFieldCount(zcu); | |
| 30595 | 30616 | for (0..field_count) |field_idx| { |
| 30596 | if (dest_ty.structFieldIsComptime(field_idx, mod) != src_ty.structFieldIsComptime(field_idx, mod)) break :tuple; | |
| 30597 | if (dest_ty.structFieldAlign(field_idx, pt) != src_ty.structFieldAlign(field_idx, pt)) break :tuple; | |
| 30598 | const dest_field_ty = dest_ty.structFieldType(field_idx, mod); | |
| 30599 | const src_field_ty = src_ty.structFieldType(field_idx, mod); | |
| 30617 | if (dest_ty.structFieldIsComptime(field_idx, zcu) != src_ty.structFieldIsComptime(field_idx, zcu)) break :tuple; | |
| 30618 | if (dest_ty.structFieldAlign(field_idx, zcu) != src_ty.structFieldAlign(field_idx, zcu)) break :tuple; | |
| 30619 | const dest_field_ty = dest_ty.structFieldType(field_idx, zcu); | |
| 30620 | const src_field_ty = src_ty.structFieldType(field_idx, zcu); | |
| 30600 | 30621 | const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null); |
| 30601 | 30622 | if (field != .ok) break :tuple; |
| 30602 | 30623 | } |
| ... | ... | @@ -30618,13 +30639,13 @@ fn coerceInMemoryAllowedErrorSets( |
| 30618 | 30639 | src_src: LazySrcLoc, |
| 30619 | 30640 | ) !InMemoryCoercionResult { |
| 30620 | 30641 | const pt = sema.pt; |
| 30621 | const mod = pt.zcu; | |
| 30642 | const zcu = pt.zcu; | |
| 30622 | 30643 | const gpa = sema.gpa; |
| 30623 | const ip = &mod.intern_pool; | |
| 30644 | const ip = &zcu.intern_pool; | |
| 30624 | 30645 | |
| 30625 | 30646 | // Coercion to `anyerror`. Note that this check can return false negatives |
| 30626 | 30647 | // in case the error sets did not get resolved. |
| 30627 | if (dest_ty.isAnyError(mod)) { | |
| 30648 | if (dest_ty.isAnyError(zcu)) { | |
| 30628 | 30649 | return .ok; |
| 30629 | 30650 | } |
| 30630 | 30651 | |
| ... | ... | @@ -30669,7 +30690,7 @@ fn coerceInMemoryAllowedErrorSets( |
| 30669 | 30690 | const resolved_src_ty = try sema.resolveInferredErrorSet(block, src_src, src_ty.toIntern()); |
| 30670 | 30691 | // src anyerror status might have changed after the resolution. |
| 30671 | 30692 | if (resolved_src_ty == .anyerror_type) { |
| 30672 | // dest_ty.isAnyError(mod) == true is already checked for at this point. | |
| 30693 | // dest_ty.isAnyError(zcu) == true is already checked for at this point. | |
| 30673 | 30694 | return .from_anyerror; |
| 30674 | 30695 | } |
| 30675 | 30696 | |
| ... | ... | @@ -30717,11 +30738,11 @@ fn coerceInMemoryAllowedFns( |
| 30717 | 30738 | src_src: LazySrcLoc, |
| 30718 | 30739 | ) !InMemoryCoercionResult { |
| 30719 | 30740 | const pt = sema.pt; |
| 30720 | const mod = pt.zcu; | |
| 30721 | const ip = &mod.intern_pool; | |
| 30741 | const zcu = pt.zcu; | |
| 30742 | const ip = &zcu.intern_pool; | |
| 30722 | 30743 | |
| 30723 | const dest_info = mod.typeToFunc(dest_ty).?; | |
| 30724 | const src_info = mod.typeToFunc(src_ty).?; | |
| 30744 | const dest_info = zcu.typeToFunc(dest_ty).?; | |
| 30745 | const src_info = zcu.typeToFunc(src_ty).?; | |
| 30725 | 30746 | |
| 30726 | 30747 | { |
| 30727 | 30748 | if (dest_info.is_var_args != src_info.is_var_args) { |
| ... | ... | @@ -30922,12 +30943,12 @@ fn coerceInMemoryAllowedPtrs( |
| 30922 | 30943 | const src_align = if (src_info.flags.alignment != .none) |
| 30923 | 30944 | src_info.flags.alignment |
| 30924 | 30945 | else |
| 30925 | try sema.typeAbiAlignment(Type.fromInterned(src_info.child)); | |
| 30946 | try Type.fromInterned(src_info.child).abiAlignmentSema(pt); | |
| 30926 | 30947 | |
| 30927 | 30948 | const dest_align = if (dest_info.flags.alignment != .none) |
| 30928 | 30949 | dest_info.flags.alignment |
| 30929 | 30950 | else |
| 30930 | try sema.typeAbiAlignment(Type.fromInterned(dest_info.child)); | |
| 30951 | try Type.fromInterned(dest_info.child).abiAlignmentSema(pt); | |
| 30931 | 30952 | |
| 30932 | 30953 | if (dest_align.compare(.gt, src_align)) { |
| 30933 | 30954 | return InMemoryCoercionResult{ .ptr_alignment = .{ |
| ... | ... | @@ -31044,12 +31065,12 @@ fn storePtr2( |
| 31044 | 31065 | air_tag: Air.Inst.Tag, |
| 31045 | 31066 | ) CompileError!void { |
| 31046 | 31067 | const pt = sema.pt; |
| 31047 | const mod = pt.zcu; | |
| 31068 | const zcu = pt.zcu; | |
| 31048 | 31069 | const ptr_ty = sema.typeOf(ptr); |
| 31049 | if (ptr_ty.isConstPtr(mod)) | |
| 31070 | if (ptr_ty.isConstPtr(zcu)) | |
| 31050 | 31071 | return sema.fail(block, ptr_src, "cannot assign to constant", .{}); |
| 31051 | 31072 | |
| 31052 | const elem_ty = ptr_ty.childType(mod); | |
| 31073 | const elem_ty = ptr_ty.childType(zcu); | |
| 31053 | 31074 | |
| 31054 | 31075 | // To generate better code for tuples, we detect a tuple operand here, and |
| 31055 | 31076 | // analyze field loads and stores directly. This avoids an extra allocation + memcpy |
| ... | ... | @@ -31060,8 +31081,8 @@ fn storePtr2( |
| 31060 | 31081 | // this code does not handle tuple-to-struct coercion which requires dealing with missing |
| 31061 | 31082 | // fields. |
| 31062 | 31083 | const operand_ty = sema.typeOf(uncasted_operand); |
| 31063 | if (operand_ty.isTuple(mod) and elem_ty.zigTypeTag(mod) == .Array) { | |
| 31064 | const field_count = operand_ty.structFieldCount(mod); | |
| 31084 | if (operand_ty.isTuple(zcu) and elem_ty.zigTypeTag(zcu) == .Array) { | |
| 31085 | const field_count = operand_ty.structFieldCount(zcu); | |
| 31065 | 31086 | var i: u32 = 0; |
| 31066 | 31087 | while (i < field_count) : (i += 1) { |
| 31067 | 31088 | const elem_src = operand_src; // TODO better source location |
| ... | ... | @@ -31085,7 +31106,7 @@ fn storePtr2( |
| 31085 | 31106 | // as well as working around an LLVM bug: |
| 31086 | 31107 | // https://github.com/ziglang/zig/issues/11154 |
| 31087 | 31108 | if (sema.obtainBitCastedVectorPtr(ptr)) |vector_ptr| { |
| 31088 | const vector_ty = sema.typeOf(vector_ptr).childType(mod); | |
| 31109 | const vector_ty = sema.typeOf(vector_ptr).childType(zcu); | |
| 31089 | 31110 | const vector = sema.coerceExtra(block, vector_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) { |
| 31090 | 31111 | error.NotCoercible => unreachable, |
| 31091 | 31112 | else => |e| return e, |
| ... | ... | @@ -31119,7 +31140,7 @@ fn storePtr2( |
| 31119 | 31140 | |
| 31120 | 31141 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 31121 | 31142 | |
| 31122 | if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) { | |
| 31143 | if (ptr_ty.ptrInfo(zcu).flags.vector_index == .runtime) { | |
| 31123 | 31144 | const ptr_inst = ptr.toIndex().?; |
| 31124 | 31145 | const air_tags = sema.air_instructions.items(.tag); |
| 31125 | 31146 | if (air_tags[@intFromEnum(ptr_inst)] == .ptr_elem_ptr) { |
| ... | ... | @@ -31253,9 +31274,9 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins |
| 31253 | 31274 | /// lengths match. |
| 31254 | 31275 | fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 31255 | 31276 | const pt = sema.pt; |
| 31256 | const mod = pt.zcu; | |
| 31257 | const array_ty = sema.typeOf(ptr).childType(mod); | |
| 31258 | if (array_ty.zigTypeTag(mod) != .Array) return null; | |
| 31277 | const zcu = pt.zcu; | |
| 31278 | const array_ty = sema.typeOf(ptr).childType(zcu); | |
| 31279 | if (array_ty.zigTypeTag(zcu) != .Array) return null; | |
| 31259 | 31280 | var ptr_ref = ptr; |
| 31260 | 31281 | var ptr_inst = ptr_ref.toIndex() orelse return null; |
| 31261 | 31282 | const air_datas = sema.air_instructions.items(.data); |
| ... | ... | @@ -31263,15 +31284,15 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 31263 | 31284 | const vector_ty = while (air_tags[@intFromEnum(ptr_inst)] == .bitcast) { |
| 31264 | 31285 | ptr_ref = air_datas[@intFromEnum(ptr_inst)].ty_op.operand; |
| 31265 | 31286 | if (!sema.isKnownZigType(ptr_ref, .Pointer)) return null; |
| 31266 | const child_ty = sema.typeOf(ptr_ref).childType(mod); | |
| 31267 | if (child_ty.zigTypeTag(mod) == .Vector) break child_ty; | |
| 31287 | const child_ty = sema.typeOf(ptr_ref).childType(zcu); | |
| 31288 | if (child_ty.zigTypeTag(zcu) == .Vector) break child_ty; | |
| 31268 | 31289 | ptr_inst = ptr_ref.toIndex() orelse return null; |
| 31269 | 31290 | } else return null; |
| 31270 | 31291 | |
| 31271 | 31292 | // We have a pointer-to-array and a pointer-to-vector. If the elements and |
| 31272 | 31293 | // lengths match, return the result. |
| 31273 | if (array_ty.childType(mod).eql(vector_ty.childType(mod), mod) and | |
| 31274 | array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) | |
| 31294 | if (array_ty.childType(zcu).eql(vector_ty.childType(zcu), zcu) and | |
| 31295 | array_ty.arrayLen(zcu) == vector_ty.vectorLen(zcu)) | |
| 31275 | 31296 | { |
| 31276 | 31297 | return ptr_ref; |
| 31277 | 31298 | } else { |
| ... | ... | @@ -31347,8 +31368,8 @@ fn bitCast( |
| 31347 | 31368 | const old_ty = sema.typeOf(inst); |
| 31348 | 31369 | try old_ty.resolveLayout(pt); |
| 31349 | 31370 | |
| 31350 | const dest_bits = dest_ty.bitSize(pt); | |
| 31351 | const old_bits = old_ty.bitSize(pt); | |
| 31371 | const dest_bits = dest_ty.bitSize(zcu); | |
| 31372 | const old_bits = old_ty.bitSize(zcu); | |
| 31352 | 31373 | |
| 31353 | 31374 | if (old_bits != dest_bits) { |
| 31354 | 31375 | return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{ |
| ... | ... | @@ -31384,16 +31405,16 @@ fn coerceArrayPtrToSlice( |
| 31384 | 31405 | inst_src: LazySrcLoc, |
| 31385 | 31406 | ) CompileError!Air.Inst.Ref { |
| 31386 | 31407 | const pt = sema.pt; |
| 31387 | const mod = pt.zcu; | |
| 31408 | const zcu = pt.zcu; | |
| 31388 | 31409 | if (try sema.resolveValue(inst)) |val| { |
| 31389 | 31410 | const ptr_array_ty = sema.typeOf(inst); |
| 31390 | const array_ty = ptr_array_ty.childType(mod); | |
| 31391 | const slice_ptr_ty = dest_ty.slicePtrFieldType(mod); | |
| 31411 | const array_ty = ptr_array_ty.childType(zcu); | |
| 31412 | const slice_ptr_ty = dest_ty.slicePtrFieldType(zcu); | |
| 31392 | 31413 | const slice_ptr = try pt.getCoerced(val, slice_ptr_ty); |
| 31393 | 31414 | const slice_val = try pt.intern(.{ .slice = .{ |
| 31394 | 31415 | .ty = dest_ty.toIntern(), |
| 31395 | 31416 | .ptr = slice_ptr.toIntern(), |
| 31396 | .len = (try pt.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), | |
| 31417 | .len = (try pt.intValue(Type.usize, array_ty.arrayLen(zcu))).toIntern(), | |
| 31397 | 31418 | } }); |
| 31398 | 31419 | return Air.internedToRef(slice_val); |
| 31399 | 31420 | } |
| ... | ... | @@ -31403,12 +31424,12 @@ fn coerceArrayPtrToSlice( |
| 31403 | 31424 | |
| 31404 | 31425 | fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool { |
| 31405 | 31426 | const pt = sema.pt; |
| 31406 | const mod = pt.zcu; | |
| 31407 | const dest_info = dest_ty.ptrInfo(mod); | |
| 31408 | const inst_info = inst_ty.ptrInfo(mod); | |
| 31409 | const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(mod) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(mod) == 0 or | |
| 31410 | (Type.fromInterned(inst_info.child).arrayLen(mod) == 0 and dest_info.sentinel == .none and dest_info.flags.size != .C and dest_info.flags.size != .Many))) or | |
| 31411 | (Type.fromInterned(inst_info.child).isTuple(mod) and Type.fromInterned(inst_info.child).structFieldCount(mod) == 0); | |
| 31427 | const zcu = pt.zcu; | |
| 31428 | const dest_info = dest_ty.ptrInfo(zcu); | |
| 31429 | const inst_info = inst_ty.ptrInfo(zcu); | |
| 31430 | const len0 = (Type.fromInterned(inst_info.child).zigTypeTag(zcu) == .Array and (Type.fromInterned(inst_info.child).arrayLenIncludingSentinel(zcu) == 0 or | |
| 31431 | (Type.fromInterned(inst_info.child).arrayLen(zcu) == 0 and dest_info.sentinel == .none and dest_info.flags.size != .C and dest_info.flags.size != .Many))) or | |
| 31432 | (Type.fromInterned(inst_info.child).isTuple(zcu) and Type.fromInterned(inst_info.child).structFieldCount(zcu) == 0); | |
| 31412 | 31433 | |
| 31413 | 31434 | const ok_cv_qualifiers = |
| 31414 | 31435 | ((!inst_info.flags.is_const or dest_info.flags.is_const) or len0) and |
| ... | ... | @@ -31436,12 +31457,12 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul |
| 31436 | 31457 | const inst_align = if (inst_info.flags.alignment != .none) |
| 31437 | 31458 | inst_info.flags.alignment |
| 31438 | 31459 | else |
| 31439 | Type.fromInterned(inst_info.child).abiAlignment(pt); | |
| 31460 | Type.fromInterned(inst_info.child).abiAlignment(zcu); | |
| 31440 | 31461 | |
| 31441 | 31462 | const dest_align = if (dest_info.flags.alignment != .none) |
| 31442 | 31463 | dest_info.flags.alignment |
| 31443 | 31464 | else |
| 31444 | Type.fromInterned(dest_info.child).abiAlignment(pt); | |
| 31465 | Type.fromInterned(dest_info.child).abiAlignment(zcu); | |
| 31445 | 31466 | |
| 31446 | 31467 | if (dest_align.compare(.gt, inst_align)) { |
| 31447 | 31468 | in_memory_result.* = .{ .ptr_alignment = .{ |
| ... | ... | @@ -31461,10 +31482,10 @@ fn coerceCompatiblePtrs( |
| 31461 | 31482 | inst_src: LazySrcLoc, |
| 31462 | 31483 | ) !Air.Inst.Ref { |
| 31463 | 31484 | const pt = sema.pt; |
| 31464 | const mod = pt.zcu; | |
| 31485 | const zcu = pt.zcu; | |
| 31465 | 31486 | const inst_ty = sema.typeOf(inst); |
| 31466 | 31487 | if (try sema.resolveValue(inst)) |val| { |
| 31467 | if (!val.isUndef(mod) and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) { | |
| 31488 | if (!val.isUndef(zcu) and val.isNull(zcu) and !dest_ty.isAllowzeroPtr(zcu)) { | |
| 31468 | 31489 | return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)}); |
| 31469 | 31490 | } |
| 31470 | 31491 | // The comptime Value representation is compatible with both types. |
| ... | ... | @@ -31473,17 +31494,17 @@ fn coerceCompatiblePtrs( |
| 31473 | 31494 | ); |
| 31474 | 31495 | } |
| 31475 | 31496 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 31476 | const inst_allows_zero = inst_ty.zigTypeTag(mod) != .Pointer or inst_ty.ptrAllowsZero(mod); | |
| 31477 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(mod) and | |
| 31478 | (try sema.typeHasRuntimeBits(dest_ty.elemType2(mod)) or dest_ty.elemType2(mod).zigTypeTag(mod) == .Fn)) | |
| 31497 | const inst_allows_zero = inst_ty.zigTypeTag(zcu) != .Pointer or inst_ty.ptrAllowsZero(zcu); | |
| 31498 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu) and | |
| 31499 | (try dest_ty.elemType2(zcu).hasRuntimeBitsSema(pt) or dest_ty.elemType2(zcu).zigTypeTag(zcu) == .Fn)) | |
| 31479 | 31500 | { |
| 31480 | const actual_ptr = if (inst_ty.isSlice(mod)) | |
| 31501 | const actual_ptr = if (inst_ty.isSlice(zcu)) | |
| 31481 | 31502 | try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty) |
| 31482 | 31503 | else |
| 31483 | 31504 | inst; |
| 31484 | 31505 | const ptr_int = try block.addUnOp(.int_from_ptr, actual_ptr); |
| 31485 | 31506 | const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize); |
| 31486 | const ok = if (inst_ty.isSlice(mod)) ok: { | |
| 31507 | const ok = if (inst_ty.isSlice(zcu)) ok: { | |
| 31487 | 31508 | const len = try sema.analyzeSliceLen(block, inst_src, inst); |
| 31488 | 31509 | const len_zero = try block.addBinOp(.cmp_eq, len, .zero_usize); |
| 31489 | 31510 | break :ok try block.addBinOp(.bool_or, len_zero, is_non_zero); |
| ... | ... | @@ -31504,11 +31525,11 @@ fn coerceEnumToUnion( |
| 31504 | 31525 | inst_src: LazySrcLoc, |
| 31505 | 31526 | ) !Air.Inst.Ref { |
| 31506 | 31527 | const pt = sema.pt; |
| 31507 | const mod = pt.zcu; | |
| 31508 | const ip = &mod.intern_pool; | |
| 31528 | const zcu = pt.zcu; | |
| 31529 | const ip = &zcu.intern_pool; | |
| 31509 | 31530 | const inst_ty = sema.typeOf(inst); |
| 31510 | 31531 | |
| 31511 | const tag_ty = union_ty.unionTagType(mod) orelse { | |
| 31532 | const tag_ty = union_ty.unionTagType(zcu) orelse { | |
| 31512 | 31533 | const msg = msg: { |
| 31513 | 31534 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ |
| 31514 | 31535 | union_ty.fmt(pt), inst_ty.fmt(pt), |
| ... | ... | @@ -31529,10 +31550,10 @@ fn coerceEnumToUnion( |
| 31529 | 31550 | }); |
| 31530 | 31551 | }; |
| 31531 | 31552 | |
| 31532 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 31553 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 31533 | 31554 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 31534 | 31555 | try field_ty.resolveFields(pt); |
| 31535 | if (field_ty.zigTypeTag(mod) == .NoReturn) { | |
| 31556 | if (field_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 31536 | 31557 | const msg = msg: { |
| 31537 | 31558 | const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{}); |
| 31538 | 31559 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -31569,7 +31590,7 @@ fn coerceEnumToUnion( |
| 31569 | 31590 | |
| 31570 | 31591 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 31571 | 31592 | |
| 31572 | if (tag_ty.isNonexhaustiveEnum(mod)) { | |
| 31593 | if (tag_ty.isNonexhaustiveEnum(zcu)) { | |
| 31573 | 31594 | const msg = msg: { |
| 31574 | 31595 | const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{ |
| 31575 | 31596 | union_ty.fmt(pt), |
| ... | ... | @@ -31581,13 +31602,13 @@ fn coerceEnumToUnion( |
| 31581 | 31602 | return sema.failWithOwnedErrorMsg(block, msg); |
| 31582 | 31603 | } |
| 31583 | 31604 | |
| 31584 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 31605 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 31585 | 31606 | { |
| 31586 | var msg: ?*Module.ErrorMsg = null; | |
| 31607 | var msg: ?*Zcu.ErrorMsg = null; | |
| 31587 | 31608 | errdefer if (msg) |some| some.destroy(sema.gpa); |
| 31588 | 31609 | |
| 31589 | 31610 | for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| { |
| 31590 | if (Type.fromInterned(field_ty).zigTypeTag(mod) == .NoReturn) { | |
| 31611 | if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .NoReturn) { | |
| 31591 | 31612 | const err_msg = msg orelse try sema.errMsg( |
| 31592 | 31613 | inst_src, |
| 31593 | 31614 | "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field", |
| ... | ... | @@ -31606,7 +31627,7 @@ fn coerceEnumToUnion( |
| 31606 | 31627 | } |
| 31607 | 31628 | |
| 31608 | 31629 | // If the union has all fields 0 bits, the union value is just the enum value. |
| 31609 | if (union_ty.unionHasAllZeroBitFieldTypes(pt)) { | |
| 31630 | if (union_ty.unionHasAllZeroBitFieldTypes(zcu)) { | |
| 31610 | 31631 | return block.addBitCast(union_ty, enum_tag); |
| 31611 | 31632 | } |
| 31612 | 31633 | |
| ... | ... | @@ -31621,7 +31642,7 @@ fn coerceEnumToUnion( |
| 31621 | 31642 | for (0..union_obj.field_types.len) |field_index| { |
| 31622 | 31643 | const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index]; |
| 31623 | 31644 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 31624 | if (!(try sema.typeHasRuntimeBits(field_ty))) continue; | |
| 31645 | if (!(try field_ty.hasRuntimeBitsSema(pt))) continue; | |
| 31625 | 31646 | try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{ |
| 31626 | 31647 | field_name.fmt(ip), |
| 31627 | 31648 | field_ty.fmt(pt), |
| ... | ... | @@ -31642,8 +31663,8 @@ fn coerceAnonStructToUnion( |
| 31642 | 31663 | inst_src: LazySrcLoc, |
| 31643 | 31664 | ) !Air.Inst.Ref { |
| 31644 | 31665 | const pt = sema.pt; |
| 31645 | const mod = pt.zcu; | |
| 31646 | const ip = &mod.intern_pool; | |
| 31666 | const zcu = pt.zcu; | |
| 31667 | const ip = &zcu.intern_pool; | |
| 31647 | 31668 | const inst_ty = sema.typeOf(inst); |
| 31648 | 31669 | const field_info: union(enum) { |
| 31649 | 31670 | name: InternPool.NullTerminatedString, |
| ... | ... | @@ -31701,8 +31722,8 @@ fn coerceAnonStructToUnionPtrs( |
| 31701 | 31722 | anon_struct_src: LazySrcLoc, |
| 31702 | 31723 | ) !Air.Inst.Ref { |
| 31703 | 31724 | const pt = sema.pt; |
| 31704 | const mod = pt.zcu; | |
| 31705 | const union_ty = ptr_union_ty.childType(mod); | |
| 31725 | const zcu = pt.zcu; | |
| 31726 | const union_ty = ptr_union_ty.childType(zcu); | |
| 31706 | 31727 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); |
| 31707 | 31728 | const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src); |
| 31708 | 31729 | return sema.analyzeRef(block, union_ty_src, union_inst); |
| ... | ... | @@ -31717,8 +31738,8 @@ fn coerceAnonStructToStructPtrs( |
| 31717 | 31738 | anon_struct_src: LazySrcLoc, |
| 31718 | 31739 | ) !Air.Inst.Ref { |
| 31719 | 31740 | const pt = sema.pt; |
| 31720 | const mod = pt.zcu; | |
| 31721 | const struct_ty = ptr_struct_ty.childType(mod); | |
| 31741 | const zcu = pt.zcu; | |
| 31742 | const struct_ty = ptr_struct_ty.childType(zcu); | |
| 31722 | 31743 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); |
| 31723 | 31744 | const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src); |
| 31724 | 31745 | return sema.analyzeRef(block, struct_ty_src, struct_inst); |
| ... | ... | @@ -31734,9 +31755,9 @@ fn coerceArrayLike( |
| 31734 | 31755 | inst_src: LazySrcLoc, |
| 31735 | 31756 | ) !Air.Inst.Ref { |
| 31736 | 31757 | const pt = sema.pt; |
| 31737 | const mod = pt.zcu; | |
| 31758 | const zcu = pt.zcu; | |
| 31738 | 31759 | const inst_ty = sema.typeOf(inst); |
| 31739 | const target = mod.getTarget(); | |
| 31760 | const target = zcu.getTarget(); | |
| 31740 | 31761 | |
| 31741 | 31762 | // try coercion of the whole array |
| 31742 | 31763 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, null); |
| ... | ... | @@ -31750,8 +31771,8 @@ fn coerceArrayLike( |
| 31750 | 31771 | } |
| 31751 | 31772 | |
| 31752 | 31773 | // otherwise, try element by element |
| 31753 | const inst_len = inst_ty.arrayLen(mod); | |
| 31754 | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod)); | |
| 31774 | const inst_len = inst_ty.arrayLen(zcu); | |
| 31775 | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(zcu)); | |
| 31755 | 31776 | if (dest_len != inst_len) { |
| 31756 | 31777 | const msg = msg: { |
| 31757 | 31778 | const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ |
| ... | ... | @@ -31765,14 +31786,14 @@ fn coerceArrayLike( |
| 31765 | 31786 | return sema.failWithOwnedErrorMsg(block, msg); |
| 31766 | 31787 | } |
| 31767 | 31788 | |
| 31768 | const dest_elem_ty = dest_ty.childType(mod); | |
| 31769 | if (dest_ty.isVector(mod) and inst_ty.isVector(mod) and (try sema.resolveValue(inst)) == null) { | |
| 31770 | const inst_elem_ty = inst_ty.childType(mod); | |
| 31771 | switch (dest_elem_ty.zigTypeTag(mod)) { | |
| 31772 | .Int => if (inst_elem_ty.isInt(mod)) { | |
| 31789 | const dest_elem_ty = dest_ty.childType(zcu); | |
| 31790 | if (dest_ty.isVector(zcu) and inst_ty.isVector(zcu) and (try sema.resolveValue(inst)) == null) { | |
| 31791 | const inst_elem_ty = inst_ty.childType(zcu); | |
| 31792 | switch (dest_elem_ty.zigTypeTag(zcu)) { | |
| 31793 | .Int => if (inst_elem_ty.isInt(zcu)) { | |
| 31773 | 31794 | // integer widening |
| 31774 | const dst_info = dest_elem_ty.intInfo(mod); | |
| 31775 | const src_info = inst_elem_ty.intInfo(mod); | |
| 31795 | const dst_info = dest_elem_ty.intInfo(zcu); | |
| 31796 | const src_info = inst_elem_ty.intInfo(zcu); | |
| 31776 | 31797 | if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or |
| 31777 | 31798 | // small enough unsigned ints can get casted to large enough signed ints |
| 31778 | 31799 | (dst_info.signedness == .signed and dst_info.bits > src_info.bits)) |
| ... | ... | @@ -31835,10 +31856,10 @@ fn coerceTupleToArray( |
| 31835 | 31856 | inst_src: LazySrcLoc, |
| 31836 | 31857 | ) !Air.Inst.Ref { |
| 31837 | 31858 | const pt = sema.pt; |
| 31838 | const mod = pt.zcu; | |
| 31859 | const zcu = pt.zcu; | |
| 31839 | 31860 | const inst_ty = sema.typeOf(inst); |
| 31840 | const inst_len = inst_ty.arrayLen(mod); | |
| 31841 | const dest_len = dest_ty.arrayLen(mod); | |
| 31861 | const inst_len = inst_ty.arrayLen(zcu); | |
| 31862 | const dest_len = dest_ty.arrayLen(zcu); | |
| 31842 | 31863 | |
| 31843 | 31864 | if (dest_len != inst_len) { |
| 31844 | 31865 | const msg = msg: { |
| ... | ... | @@ -31856,13 +31877,13 @@ fn coerceTupleToArray( |
| 31856 | 31877 | const dest_elems = try sema.usizeCast(block, dest_ty_src, dest_len); |
| 31857 | 31878 | const element_vals = try sema.arena.alloc(InternPool.Index, dest_elems); |
| 31858 | 31879 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_elems); |
| 31859 | const dest_elem_ty = dest_ty.childType(mod); | |
| 31880 | const dest_elem_ty = dest_ty.childType(zcu); | |
| 31860 | 31881 | |
| 31861 | 31882 | var runtime_src: ?LazySrcLoc = null; |
| 31862 | 31883 | for (element_vals, element_refs, 0..) |*val, *ref, i_usize| { |
| 31863 | 31884 | const i: u32 = @intCast(i_usize); |
| 31864 | 31885 | if (i_usize == inst_len) { |
| 31865 | const sentinel_val = dest_ty.sentinel(mod).?; | |
| 31886 | const sentinel_val = dest_ty.sentinel(zcu).?; | |
| 31866 | 31887 | val.* = sentinel_val.toIntern(); |
| 31867 | 31888 | ref.* = Air.internedToRef(sentinel_val.toIntern()); |
| 31868 | 31889 | break; |
| ... | ... | @@ -31901,12 +31922,12 @@ fn coerceTupleToSlicePtrs( |
| 31901 | 31922 | tuple_src: LazySrcLoc, |
| 31902 | 31923 | ) !Air.Inst.Ref { |
| 31903 | 31924 | const pt = sema.pt; |
| 31904 | const mod = pt.zcu; | |
| 31905 | const tuple_ty = sema.typeOf(ptr_tuple).childType(mod); | |
| 31925 | const zcu = pt.zcu; | |
| 31926 | const tuple_ty = sema.typeOf(ptr_tuple).childType(zcu); | |
| 31906 | 31927 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 31907 | const slice_info = slice_ty.ptrInfo(mod); | |
| 31928 | const slice_info = slice_ty.ptrInfo(zcu); | |
| 31908 | 31929 | const array_ty = try pt.arrayType(.{ |
| 31909 | .len = tuple_ty.structFieldCount(mod), | |
| 31930 | .len = tuple_ty.structFieldCount(zcu), | |
| 31910 | 31931 | .sentinel = slice_info.sentinel, |
| 31911 | 31932 | .child = slice_info.child, |
| 31912 | 31933 | }); |
| ... | ... | @@ -31928,9 +31949,9 @@ fn coerceTupleToArrayPtrs( |
| 31928 | 31949 | tuple_src: LazySrcLoc, |
| 31929 | 31950 | ) !Air.Inst.Ref { |
| 31930 | 31951 | const pt = sema.pt; |
| 31931 | const mod = pt.zcu; | |
| 31952 | const zcu = pt.zcu; | |
| 31932 | 31953 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 31933 | const ptr_info = ptr_array_ty.ptrInfo(mod); | |
| 31954 | const ptr_info = ptr_array_ty.ptrInfo(zcu); | |
| 31934 | 31955 | const array_ty = Type.fromInterned(ptr_info.child); |
| 31935 | 31956 | const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); |
| 31936 | 31957 | if (ptr_info.flags.alignment != .none) { |
| ... | ... | @@ -31950,16 +31971,16 @@ fn coerceTupleToStruct( |
| 31950 | 31971 | inst_src: LazySrcLoc, |
| 31951 | 31972 | ) !Air.Inst.Ref { |
| 31952 | 31973 | const pt = sema.pt; |
| 31953 | const mod = pt.zcu; | |
| 31954 | const ip = &mod.intern_pool; | |
| 31974 | const zcu = pt.zcu; | |
| 31975 | const ip = &zcu.intern_pool; | |
| 31955 | 31976 | try struct_ty.resolveFields(pt); |
| 31956 | 31977 | try struct_ty.resolveStructFieldInits(pt); |
| 31957 | 31978 | |
| 31958 | if (struct_ty.isTupleOrAnonStruct(mod)) { | |
| 31979 | if (struct_ty.isTupleOrAnonStruct(zcu)) { | |
| 31959 | 31980 | return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src); |
| 31960 | 31981 | } |
| 31961 | 31982 | |
| 31962 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 31983 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 31963 | 31984 | const field_vals = try sema.arena.alloc(InternPool.Index, struct_type.field_types.len); |
| 31964 | 31985 | const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len); |
| 31965 | 31986 | @memset(field_refs, .none); |
| ... | ... | @@ -31973,7 +31994,7 @@ fn coerceTupleToStruct( |
| 31973 | 31994 | }; |
| 31974 | 31995 | for (0..field_count) |tuple_field_index| { |
| 31975 | 31996 | const field_src = inst_src; // TODO better source location |
| 31976 | const field_name = inst_ty.structFieldName(tuple_field_index, mod).unwrap() orelse | |
| 31997 | const field_name = inst_ty.structFieldName(tuple_field_index, zcu).unwrap() orelse | |
| 31977 | 31998 | try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{tuple_field_index}, .no_embedded_nulls); |
| 31978 | 31999 | |
| 31979 | 32000 | const struct_field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src); |
| ... | ... | @@ -32003,7 +32024,7 @@ fn coerceTupleToStruct( |
| 32003 | 32024 | } |
| 32004 | 32025 | |
| 32005 | 32026 | // Populate default field values and report errors for missing fields. |
| 32006 | var root_msg: ?*Module.ErrorMsg = null; | |
| 32027 | var root_msg: ?*Zcu.ErrorMsg = null; | |
| 32007 | 32028 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 32008 | 32029 | |
| 32009 | 32030 | for (field_refs, 0..) |*field_ref, i| { |
| ... | ... | @@ -32058,8 +32079,8 @@ fn coerceTupleToTuple( |
| 32058 | 32079 | inst_src: LazySrcLoc, |
| 32059 | 32080 | ) !Air.Inst.Ref { |
| 32060 | 32081 | const pt = sema.pt; |
| 32061 | const mod = pt.zcu; | |
| 32062 | const ip = &mod.intern_pool; | |
| 32082 | const zcu = pt.zcu; | |
| 32083 | const ip = &zcu.intern_pool; | |
| 32063 | 32084 | const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) { |
| 32064 | 32085 | .anon_struct_type => |anon_struct_type| anon_struct_type.types.len, |
| 32065 | 32086 | .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.len, |
| ... | ... | @@ -32081,7 +32102,7 @@ fn coerceTupleToTuple( |
| 32081 | 32102 | for (0..dest_field_count) |field_index_usize| { |
| 32082 | 32103 | const field_i: u32 = @intCast(field_index_usize); |
| 32083 | 32104 | const field_src = inst_src; // TODO better source location |
| 32084 | const field_name = inst_ty.structFieldName(field_index_usize, mod).unwrap() orelse | |
| 32105 | const field_name = inst_ty.structFieldName(field_index_usize, zcu).unwrap() orelse | |
| 32085 | 32106 | try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index_usize}, .no_embedded_nulls); |
| 32086 | 32107 | |
| 32087 | 32108 | if (field_name.eqlSlice("len", ip)) |
| ... | ... | @@ -32124,7 +32145,7 @@ fn coerceTupleToTuple( |
| 32124 | 32145 | } |
| 32125 | 32146 | |
| 32126 | 32147 | // Populate default field values and report errors for missing fields. |
| 32127 | var root_msg: ?*Module.ErrorMsg = null; | |
| 32148 | var root_msg: ?*Zcu.ErrorMsg = null; | |
| 32128 | 32149 | errdefer if (root_msg) |msg| msg.destroy(sema.gpa); |
| 32129 | 32150 | |
| 32130 | 32151 | for (field_refs, 0..) |*field_ref, i_usize| { |
| ... | ... | @@ -32139,7 +32160,7 @@ fn coerceTupleToTuple( |
| 32139 | 32160 | |
| 32140 | 32161 | const field_src = inst_src; // TODO better source location |
| 32141 | 32162 | if (default_val == .none) { |
| 32142 | const field_name = tuple_ty.structFieldName(i, mod).unwrap() orelse { | |
| 32163 | const field_name = tuple_ty.structFieldName(i, zcu).unwrap() orelse { | |
| 32143 | 32164 | const template = "missing tuple field: {d}"; |
| 32144 | 32165 | if (root_msg) |msg| { |
| 32145 | 32166 | try sema.errNote(field_src, msg, template, .{i}); |
| ... | ... | @@ -32308,7 +32329,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPoo |
| 32308 | 32329 | const ip = &zcu.intern_pool; |
| 32309 | 32330 | const nav_val = zcu.navValue(nav_index); |
| 32310 | 32331 | if (!ip.isFuncBody(nav_val.toIntern())) return; |
| 32311 | if (!try sema.fnHasRuntimeBits(nav_val.typeOf(zcu))) return; | |
| 32332 | if (!try nav_val.typeOf(zcu).fnHasRuntimeBitsSema(sema.pt)) return; | |
| 32312 | 32333 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() })); |
| 32313 | 32334 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); |
| 32314 | 32335 | } |
| ... | ... | @@ -32320,11 +32341,11 @@ fn analyzeRef( |
| 32320 | 32341 | operand: Air.Inst.Ref, |
| 32321 | 32342 | ) CompileError!Air.Inst.Ref { |
| 32322 | 32343 | const pt = sema.pt; |
| 32323 | const mod = pt.zcu; | |
| 32344 | const zcu = pt.zcu; | |
| 32324 | 32345 | const operand_ty = sema.typeOf(operand); |
| 32325 | 32346 | |
| 32326 | 32347 | if (try sema.resolveValue(operand)) |val| { |
| 32327 | switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 32348 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 32328 | 32349 | .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav), |
| 32329 | 32350 | .func => |f| return sema.analyzeNavRef(src, f.owner_nav), |
| 32330 | 32351 | else => return uavRef(sema, val.toIntern()), |
| ... | ... | @@ -32332,7 +32353,7 @@ fn analyzeRef( |
| 32332 | 32353 | } |
| 32333 | 32354 | |
| 32334 | 32355 | try sema.requireRuntimeBlock(block, src, null); |
| 32335 | const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local); | |
| 32356 | const address_space = target_util.defaultAddressSpace(zcu.getTarget(), .local); | |
| 32336 | 32357 | const ptr_type = try pt.ptrTypeSema(.{ |
| 32337 | 32358 | .child = operand_ty.toIntern(), |
| 32338 | 32359 | .flags = .{ |
| ... | ... | @@ -32359,13 +32380,13 @@ fn analyzeLoad( |
| 32359 | 32380 | ptr_src: LazySrcLoc, |
| 32360 | 32381 | ) CompileError!Air.Inst.Ref { |
| 32361 | 32382 | const pt = sema.pt; |
| 32362 | const mod = pt.zcu; | |
| 32383 | const zcu = pt.zcu; | |
| 32363 | 32384 | const ptr_ty = sema.typeOf(ptr); |
| 32364 | const elem_ty = switch (ptr_ty.zigTypeTag(mod)) { | |
| 32365 | .Pointer => ptr_ty.childType(mod), | |
| 32385 | const elem_ty = switch (ptr_ty.zigTypeTag(zcu)) { | |
| 32386 | .Pointer => ptr_ty.childType(zcu), | |
| 32366 | 32387 | else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}), |
| 32367 | 32388 | }; |
| 32368 | if (elem_ty.zigTypeTag(mod) == .Opaque) { | |
| 32389 | if (elem_ty.zigTypeTag(zcu) == .Opaque) { | |
| 32369 | 32390 | return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(pt)}); |
| 32370 | 32391 | } |
| 32371 | 32392 | |
| ... | ... | @@ -32379,7 +32400,7 @@ fn analyzeLoad( |
| 32379 | 32400 | } |
| 32380 | 32401 | } |
| 32381 | 32402 | |
| 32382 | if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) { | |
| 32403 | if (ptr_ty.ptrInfo(zcu).flags.vector_index == .runtime) { | |
| 32383 | 32404 | const ptr_inst = ptr.toIndex().?; |
| 32384 | 32405 | const air_tags = sema.air_instructions.items(.tag); |
| 32385 | 32406 | if (air_tags[@intFromEnum(ptr_inst)] == .ptr_elem_ptr) { |
| ... | ... | @@ -32403,11 +32424,11 @@ fn analyzeSlicePtr( |
| 32403 | 32424 | slice_ty: Type, |
| 32404 | 32425 | ) CompileError!Air.Inst.Ref { |
| 32405 | 32426 | const pt = sema.pt; |
| 32406 | const mod = pt.zcu; | |
| 32407 | const result_ty = slice_ty.slicePtrFieldType(mod); | |
| 32427 | const zcu = pt.zcu; | |
| 32428 | const result_ty = slice_ty.slicePtrFieldType(zcu); | |
| 32408 | 32429 | if (try sema.resolveValue(slice)) |val| { |
| 32409 | if (val.isUndef(mod)) return pt.undefRef(result_ty); | |
| 32410 | return Air.internedToRef(val.slicePtr(mod).toIntern()); | |
| 32430 | if (val.isUndef(zcu)) return pt.undefRef(result_ty); | |
| 32431 | return Air.internedToRef(val.slicePtr(zcu).toIntern()); | |
| 32411 | 32432 | } |
| 32412 | 32433 | try sema.requireRuntimeBlock(block, slice_src, null); |
| 32413 | 32434 | return block.addTyOp(.slice_ptr, result_ty, slice); |
| ... | ... | @@ -32421,13 +32442,13 @@ fn analyzeOptionalSlicePtr( |
| 32421 | 32442 | opt_slice_ty: Type, |
| 32422 | 32443 | ) CompileError!Air.Inst.Ref { |
| 32423 | 32444 | const pt = sema.pt; |
| 32424 | const mod = pt.zcu; | |
| 32425 | const result_ty = opt_slice_ty.optionalChild(mod).slicePtrFieldType(mod); | |
| 32445 | const zcu = pt.zcu; | |
| 32446 | const result_ty = opt_slice_ty.optionalChild(zcu).slicePtrFieldType(zcu); | |
| 32426 | 32447 | |
| 32427 | 32448 | if (try sema.resolveValue(opt_slice)) |opt_val| { |
| 32428 | if (opt_val.isUndef(mod)) return pt.undefRef(result_ty); | |
| 32429 | const slice_ptr: InternPool.Index = if (opt_val.optionalValue(mod)) |val| | |
| 32430 | val.slicePtr(mod).toIntern() | |
| 32449 | if (opt_val.isUndef(zcu)) return pt.undefRef(result_ty); | |
| 32450 | const slice_ptr: InternPool.Index = if (opt_val.optionalValue(zcu)) |val| | |
| 32451 | val.slicePtr(zcu).toIntern() | |
| 32431 | 32452 | else |
| 32432 | 32453 | .null_value; |
| 32433 | 32454 | |
| ... | ... | @@ -32447,9 +32468,9 @@ fn analyzeSliceLen( |
| 32447 | 32468 | slice_inst: Air.Inst.Ref, |
| 32448 | 32469 | ) CompileError!Air.Inst.Ref { |
| 32449 | 32470 | const pt = sema.pt; |
| 32450 | const mod = pt.zcu; | |
| 32471 | const zcu = pt.zcu; | |
| 32451 | 32472 | if (try sema.resolveValue(slice_inst)) |slice_val| { |
| 32452 | if (slice_val.isUndef(mod)) { | |
| 32473 | if (slice_val.isUndef(zcu)) { | |
| 32453 | 32474 | return pt.undefRef(Type.usize); |
| 32454 | 32475 | } |
| 32455 | 32476 | return pt.intRef(Type.usize, try slice_val.sliceLen(pt)); |
| ... | ... | @@ -32466,23 +32487,23 @@ fn analyzeIsNull( |
| 32466 | 32487 | invert_logic: bool, |
| 32467 | 32488 | ) CompileError!Air.Inst.Ref { |
| 32468 | 32489 | const pt = sema.pt; |
| 32469 | const mod = pt.zcu; | |
| 32490 | const zcu = pt.zcu; | |
| 32470 | 32491 | const result_ty = Type.bool; |
| 32471 | 32492 | if (try sema.resolveValue(operand)) |opt_val| { |
| 32472 | if (opt_val.isUndef(mod)) { | |
| 32493 | if (opt_val.isUndef(zcu)) { | |
| 32473 | 32494 | return pt.undefRef(result_ty); |
| 32474 | 32495 | } |
| 32475 | const is_null = opt_val.isNull(mod); | |
| 32496 | const is_null = opt_val.isNull(zcu); | |
| 32476 | 32497 | const bool_value = if (invert_logic) !is_null else is_null; |
| 32477 | 32498 | return if (bool_value) .bool_true else .bool_false; |
| 32478 | 32499 | } |
| 32479 | 32500 | |
| 32480 | 32501 | const inverted_non_null_res: Air.Inst.Ref = if (invert_logic) .bool_true else .bool_false; |
| 32481 | 32502 | const operand_ty = sema.typeOf(operand); |
| 32482 | if (operand_ty.zigTypeTag(mod) == .Optional and operand_ty.optionalChild(mod).zigTypeTag(mod) == .NoReturn) { | |
| 32503 | if (operand_ty.zigTypeTag(zcu) == .Optional and operand_ty.optionalChild(zcu).zigTypeTag(zcu) == .NoReturn) { | |
| 32483 | 32504 | return inverted_non_null_res; |
| 32484 | 32505 | } |
| 32485 | if (operand_ty.zigTypeTag(mod) != .Optional and !operand_ty.isPtrLikeOptional(mod)) { | |
| 32506 | if (operand_ty.zigTypeTag(zcu) != .Optional and !operand_ty.isPtrLikeOptional(zcu)) { | |
| 32486 | 32507 | return inverted_non_null_res; |
| 32487 | 32508 | } |
| 32488 | 32509 | try sema.requireRuntimeBlock(block, src, null); |
| ... | ... | @@ -32497,12 +32518,12 @@ fn analyzePtrIsNonErrComptimeOnly( |
| 32497 | 32518 | operand: Air.Inst.Ref, |
| 32498 | 32519 | ) CompileError!Air.Inst.Ref { |
| 32499 | 32520 | const pt = sema.pt; |
| 32500 | const mod = pt.zcu; | |
| 32521 | const zcu = pt.zcu; | |
| 32501 | 32522 | const ptr_ty = sema.typeOf(operand); |
| 32502 | assert(ptr_ty.zigTypeTag(mod) == .Pointer); | |
| 32503 | const child_ty = ptr_ty.childType(mod); | |
| 32523 | assert(ptr_ty.zigTypeTag(zcu) == .Pointer); | |
| 32524 | const child_ty = ptr_ty.childType(zcu); | |
| 32504 | 32525 | |
| 32505 | const child_tag = child_ty.zigTypeTag(mod); | |
| 32526 | const child_tag = child_ty.zigTypeTag(zcu); | |
| 32506 | 32527 | if (child_tag != .ErrorSet and child_tag != .ErrorUnion) return .bool_true; |
| 32507 | 32528 | if (child_tag == .ErrorSet) return .bool_false; |
| 32508 | 32529 | assert(child_tag == .ErrorUnion); |
| ... | ... | @@ -32520,16 +32541,16 @@ fn analyzeIsNonErrComptimeOnly( |
| 32520 | 32541 | operand: Air.Inst.Ref, |
| 32521 | 32542 | ) CompileError!Air.Inst.Ref { |
| 32522 | 32543 | const pt = sema.pt; |
| 32523 | const mod = pt.zcu; | |
| 32524 | const ip = &mod.intern_pool; | |
| 32544 | const zcu = pt.zcu; | |
| 32545 | const ip = &zcu.intern_pool; | |
| 32525 | 32546 | const operand_ty = sema.typeOf(operand); |
| 32526 | const ot = operand_ty.zigTypeTag(mod); | |
| 32547 | const ot = operand_ty.zigTypeTag(zcu); | |
| 32527 | 32548 | if (ot != .ErrorSet and ot != .ErrorUnion) return .bool_true; |
| 32528 | 32549 | if (ot == .ErrorSet) return .bool_false; |
| 32529 | 32550 | assert(ot == .ErrorUnion); |
| 32530 | 32551 | |
| 32531 | const payload_ty = operand_ty.errorUnionPayload(mod); | |
| 32532 | if (payload_ty.zigTypeTag(mod) == .NoReturn) { | |
| 32552 | const payload_ty = operand_ty.errorUnionPayload(zcu); | |
| 32553 | if (payload_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 32533 | 32554 | return .bool_false; |
| 32534 | 32555 | } |
| 32535 | 32556 | |
| ... | ... | @@ -32588,7 +32609,7 @@ fn analyzeIsNonErrComptimeOnly( |
| 32588 | 32609 | // If the error set is empty, we must return a comptime true or false. |
| 32589 | 32610 | // However we want to avoid unnecessarily resolving an inferred error set |
| 32590 | 32611 | // in case it is already non-empty. |
| 32591 | try mod.maybeUnresolveIes(func_index); | |
| 32612 | try zcu.maybeUnresolveIes(func_index); | |
| 32592 | 32613 | switch (ip.funcIesResolvedUnordered(func_index)) { |
| 32593 | 32614 | .anyerror_type => break :blk, |
| 32594 | 32615 | .none => {}, |
| ... | ... | @@ -32624,10 +32645,10 @@ fn analyzeIsNonErrComptimeOnly( |
| 32624 | 32645 | } |
| 32625 | 32646 | |
| 32626 | 32647 | if (maybe_operand_val) |err_union| { |
| 32627 | if (err_union.isUndef(mod)) { | |
| 32648 | if (err_union.isUndef(zcu)) { | |
| 32628 | 32649 | return pt.undefRef(Type.bool); |
| 32629 | 32650 | } |
| 32630 | if (err_union.getErrorName(mod) == .none) { | |
| 32651 | if (err_union.getErrorName(zcu) == .none) { | |
| 32631 | 32652 | return .bool_true; |
| 32632 | 32653 | } else { |
| 32633 | 32654 | return .bool_false; |
| ... | ... | @@ -32681,12 +32702,12 @@ fn analyzeSlice( |
| 32681 | 32702 | by_length: bool, |
| 32682 | 32703 | ) CompileError!Air.Inst.Ref { |
| 32683 | 32704 | const pt = sema.pt; |
| 32684 | const mod = pt.zcu; | |
| 32705 | const zcu = pt.zcu; | |
| 32685 | 32706 | // Slice expressions can operate on a variable whose type is an array. This requires |
| 32686 | 32707 | // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. |
| 32687 | 32708 | const ptr_ptr_ty = sema.typeOf(ptr_ptr); |
| 32688 | const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) { | |
| 32689 | .Pointer => ptr_ptr_ty.childType(mod), | |
| 32709 | const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(zcu)) { | |
| 32710 | .Pointer => ptr_ptr_ty.childType(zcu), | |
| 32690 | 32711 | else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(pt)}), |
| 32691 | 32712 | }; |
| 32692 | 32713 | |
| ... | ... | @@ -32695,20 +32716,20 @@ fn analyzeSlice( |
| 32695 | 32716 | var ptr_or_slice = ptr_ptr; |
| 32696 | 32717 | var elem_ty: Type = undefined; |
| 32697 | 32718 | var ptr_sentinel: ?Value = null; |
| 32698 | switch (ptr_ptr_child_ty.zigTypeTag(mod)) { | |
| 32719 | switch (ptr_ptr_child_ty.zigTypeTag(zcu)) { | |
| 32699 | 32720 | .Array => { |
| 32700 | ptr_sentinel = ptr_ptr_child_ty.sentinel(mod); | |
| 32701 | elem_ty = ptr_ptr_child_ty.childType(mod); | |
| 32721 | ptr_sentinel = ptr_ptr_child_ty.sentinel(zcu); | |
| 32722 | elem_ty = ptr_ptr_child_ty.childType(zcu); | |
| 32702 | 32723 | }, |
| 32703 | .Pointer => switch (ptr_ptr_child_ty.ptrSize(mod)) { | |
| 32724 | .Pointer => switch (ptr_ptr_child_ty.ptrSize(zcu)) { | |
| 32704 | 32725 | .One => { |
| 32705 | const double_child_ty = ptr_ptr_child_ty.childType(mod); | |
| 32726 | const double_child_ty = ptr_ptr_child_ty.childType(zcu); | |
| 32706 | 32727 | ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src); |
| 32707 | if (double_child_ty.zigTypeTag(mod) == .Array) { | |
| 32708 | ptr_sentinel = double_child_ty.sentinel(mod); | |
| 32728 | if (double_child_ty.zigTypeTag(zcu) == .Array) { | |
| 32729 | ptr_sentinel = double_child_ty.sentinel(zcu); | |
| 32709 | 32730 | slice_ty = ptr_ptr_child_ty; |
| 32710 | 32731 | array_ty = double_child_ty; |
| 32711 | elem_ty = double_child_ty.childType(mod); | |
| 32732 | elem_ty = double_child_ty.childType(zcu); | |
| 32712 | 32733 | } else { |
| 32713 | 32734 | const bounds_error_message = "slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]"; |
| 32714 | 32735 | if (uncasted_end_opt == .none) { |
| ... | ... | @@ -32777,7 +32798,7 @@ fn analyzeSlice( |
| 32777 | 32798 | .len = 1, |
| 32778 | 32799 | .child = double_child_ty.toIntern(), |
| 32779 | 32800 | }); |
| 32780 | const ptr_info = ptr_ptr_child_ty.ptrInfo(mod); | |
| 32801 | const ptr_info = ptr_ptr_child_ty.ptrInfo(zcu); | |
| 32781 | 32802 | slice_ty = try pt.ptrType(.{ |
| 32782 | 32803 | .child = array_ty.toIntern(), |
| 32783 | 32804 | .flags = .{ |
| ... | ... | @@ -32792,35 +32813,35 @@ fn analyzeSlice( |
| 32792 | 32813 | } |
| 32793 | 32814 | }, |
| 32794 | 32815 | .Many, .C => { |
| 32795 | ptr_sentinel = ptr_ptr_child_ty.sentinel(mod); | |
| 32816 | ptr_sentinel = ptr_ptr_child_ty.sentinel(zcu); | |
| 32796 | 32817 | ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src); |
| 32797 | 32818 | slice_ty = ptr_ptr_child_ty; |
| 32798 | 32819 | array_ty = ptr_ptr_child_ty; |
| 32799 | elem_ty = ptr_ptr_child_ty.childType(mod); | |
| 32820 | elem_ty = ptr_ptr_child_ty.childType(zcu); | |
| 32800 | 32821 | |
| 32801 | if (ptr_ptr_child_ty.ptrSize(mod) == .C) { | |
| 32822 | if (ptr_ptr_child_ty.ptrSize(zcu) == .C) { | |
| 32802 | 32823 | if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| { |
| 32803 | if (ptr_val.isNull(mod)) { | |
| 32824 | if (ptr_val.isNull(zcu)) { | |
| 32804 | 32825 | return sema.fail(block, src, "slice of null pointer", .{}); |
| 32805 | 32826 | } |
| 32806 | 32827 | } |
| 32807 | 32828 | } |
| 32808 | 32829 | }, |
| 32809 | 32830 | .Slice => { |
| 32810 | ptr_sentinel = ptr_ptr_child_ty.sentinel(mod); | |
| 32831 | ptr_sentinel = ptr_ptr_child_ty.sentinel(zcu); | |
| 32811 | 32832 | ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src); |
| 32812 | 32833 | slice_ty = ptr_ptr_child_ty; |
| 32813 | 32834 | array_ty = ptr_ptr_child_ty; |
| 32814 | elem_ty = ptr_ptr_child_ty.childType(mod); | |
| 32835 | elem_ty = ptr_ptr_child_ty.childType(zcu); | |
| 32815 | 32836 | }, |
| 32816 | 32837 | }, |
| 32817 | 32838 | else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(pt)}), |
| 32818 | 32839 | } |
| 32819 | 32840 | |
| 32820 | const ptr = if (slice_ty.isSlice(mod)) | |
| 32841 | const ptr = if (slice_ty.isSlice(zcu)) | |
| 32821 | 32842 | try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty) |
| 32822 | else if (array_ty.zigTypeTag(mod) == .Array) ptr: { | |
| 32823 | var manyptr_ty_key = mod.intern_pool.indexToKey(slice_ty.toIntern()).ptr_type; | |
| 32843 | else if (array_ty.zigTypeTag(zcu) == .Array) ptr: { | |
| 32844 | var manyptr_ty_key = zcu.intern_pool.indexToKey(slice_ty.toIntern()).ptr_type; | |
| 32824 | 32845 | assert(manyptr_ty_key.child == array_ty.toIntern()); |
| 32825 | 32846 | assert(manyptr_ty_key.flags.size == .One); |
| 32826 | 32847 | manyptr_ty_key.child = elem_ty.toIntern(); |
| ... | ... | @@ -32838,8 +32859,8 @@ fn analyzeSlice( |
| 32838 | 32859 | // we might learn of the length because it is a comptime-known slice value. |
| 32839 | 32860 | var end_is_len = uncasted_end_opt == .none; |
| 32840 | 32861 | const end = e: { |
| 32841 | if (array_ty.zigTypeTag(mod) == .Array) { | |
| 32842 | const len_val = try pt.intValue(Type.usize, array_ty.arrayLen(mod)); | |
| 32862 | if (array_ty.zigTypeTag(zcu) == .Array) { | |
| 32863 | const len_val = try pt.intValue(Type.usize, array_ty.arrayLen(zcu)); | |
| 32843 | 32864 | |
| 32844 | 32865 | if (!end_is_len) { |
| 32845 | 32866 | const end = if (by_length) end: { |
| ... | ... | @@ -32850,10 +32871,10 @@ fn analyzeSlice( |
| 32850 | 32871 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 32851 | 32872 | const len_s_val = try pt.intValue( |
| 32852 | 32873 | Type.usize, |
| 32853 | array_ty.arrayLenIncludingSentinel(mod), | |
| 32874 | array_ty.arrayLenIncludingSentinel(zcu), | |
| 32854 | 32875 | ); |
| 32855 | 32876 | if (!(try sema.compareAll(end_val, .lte, len_s_val, Type.usize))) { |
| 32856 | const sentinel_label: []const u8 = if (array_ty.sentinel(mod) != null) | |
| 32877 | const sentinel_label: []const u8 = if (array_ty.sentinel(zcu) != null) | |
| 32857 | 32878 | " +1 (sentinel)" |
| 32858 | 32879 | else |
| 32859 | 32880 | ""; |
| ... | ... | @@ -32873,7 +32894,7 @@ fn analyzeSlice( |
| 32873 | 32894 | // end_is_len is only true if we are NOT using the sentinel |
| 32874 | 32895 | // length. For sentinel-length, we don't want the type to |
| 32875 | 32896 | // contain the sentinel. |
| 32876 | if (end_val.eql(len_val, Type.usize, mod)) { | |
| 32897 | if (end_val.eql(len_val, Type.usize, zcu)) { | |
| 32877 | 32898 | end_is_len = true; |
| 32878 | 32899 | } |
| 32879 | 32900 | } |
| ... | ... | @@ -32881,7 +32902,7 @@ fn analyzeSlice( |
| 32881 | 32902 | } |
| 32882 | 32903 | |
| 32883 | 32904 | break :e Air.internedToRef(len_val.toIntern()); |
| 32884 | } else if (slice_ty.isSlice(mod)) { | |
| 32905 | } else if (slice_ty.isSlice(zcu)) { | |
| 32885 | 32906 | if (!end_is_len) { |
| 32886 | 32907 | const end = if (by_length) end: { |
| 32887 | 32908 | const len = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); |
| ... | ... | @@ -32890,10 +32911,10 @@ fn analyzeSlice( |
| 32890 | 32911 | } else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); |
| 32891 | 32912 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 32892 | 32913 | if (try sema.resolveValue(ptr_or_slice)) |slice_val| { |
| 32893 | if (slice_val.isUndef(mod)) { | |
| 32914 | if (slice_val.isUndef(zcu)) { | |
| 32894 | 32915 | return sema.fail(block, src, "slice of undefined", .{}); |
| 32895 | 32916 | } |
| 32896 | const has_sentinel = slice_ty.sentinel(mod) != null; | |
| 32917 | const has_sentinel = slice_ty.sentinel(zcu) != null; | |
| 32897 | 32918 | const slice_len = try slice_val.sliceLen(pt); |
| 32898 | 32919 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); |
| 32899 | 32920 | const slice_len_val_with_sentinel = try pt.intValue(Type.usize, len_plus_sent); |
| ... | ... | @@ -32919,7 +32940,7 @@ fn analyzeSlice( |
| 32919 | 32940 | // is only true if it equals the length WITHOUT the |
| 32920 | 32941 | // sentinel, so we don't add a sentinel type. |
| 32921 | 32942 | const slice_len_val = try pt.intValue(Type.usize, slice_len); |
| 32922 | if (end_val.eql(slice_len_val, Type.usize, mod)) { | |
| 32943 | if (end_val.eql(slice_len_val, Type.usize, zcu)) { | |
| 32923 | 32944 | end_is_len = true; |
| 32924 | 32945 | } |
| 32925 | 32946 | } |
| ... | ... | @@ -32976,8 +32997,8 @@ fn analyzeSlice( |
| 32976 | 32997 | checked_start_lte_end = true; |
| 32977 | 32998 | if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: { |
| 32978 | 32999 | const expected_sentinel = sentinel orelse break :sentinel_check; |
| 32979 | const start_int = start_val.getUnsignedInt(pt).?; | |
| 32980 | const end_int = end_val.getUnsignedInt(pt).?; | |
| 33000 | const start_int = start_val.toUnsignedInt(zcu); | |
| 33001 | const end_int = end_val.toUnsignedInt(zcu); | |
| 32981 | 33002 | const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int); |
| 32982 | 33003 | |
| 32983 | 33004 | const many_ptr_ty = try pt.manyConstPtrType(elem_ty); |
| ... | ... | @@ -33001,7 +33022,7 @@ fn analyzeSlice( |
| 33001 | 33022 | ), |
| 33002 | 33023 | }; |
| 33003 | 33024 | |
| 33004 | if (!actual_sentinel.eql(expected_sentinel, elem_ty, mod)) { | |
| 33025 | if (!actual_sentinel.eql(expected_sentinel, elem_ty, zcu)) { | |
| 33005 | 33026 | const msg = msg: { |
| 33006 | 33027 | const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{}); |
| 33007 | 33028 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -33041,8 +33062,8 @@ fn analyzeSlice( |
| 33041 | 33062 | try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); |
| 33042 | 33063 | const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); |
| 33043 | 33064 | |
| 33044 | const new_ptr_ty_info = new_ptr_ty.ptrInfo(mod); | |
| 33045 | const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C; | |
| 33065 | const new_ptr_ty_info = new_ptr_ty.ptrInfo(zcu); | |
| 33066 | const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(zcu) != .C; | |
| 33046 | 33067 | |
| 33047 | 33068 | if (opt_new_len_val) |new_len_val| { |
| 33048 | 33069 | const new_len_int = try new_len_val.toUnsignedIntSema(pt); |
| ... | ... | @@ -33067,17 +33088,17 @@ fn analyzeSlice( |
| 33067 | 33088 | const result = try block.addBitCast(return_ty, new_ptr); |
| 33068 | 33089 | if (block.wantSafety()) { |
| 33069 | 33090 | // requirement: slicing C ptr is non-null |
| 33070 | if (ptr_ptr_child_ty.isCPtr(mod)) { | |
| 33091 | if (ptr_ptr_child_ty.isCPtr(zcu)) { | |
| 33071 | 33092 | const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true); |
| 33072 | 33093 | try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null); |
| 33073 | 33094 | } |
| 33074 | 33095 | |
| 33075 | 33096 | bounds_check: { |
| 33076 | const actual_len = if (array_ty.zigTypeTag(mod) == .Array) | |
| 33077 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) | |
| 33078 | else if (slice_ty.isSlice(mod)) l: { | |
| 33097 | const actual_len = if (array_ty.zigTypeTag(zcu) == .Array) | |
| 33098 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(zcu)) | |
| 33099 | else if (slice_ty.isSlice(zcu)) l: { | |
| 33079 | 33100 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); |
| 33080 | break :l if (slice_ty.sentinel(mod) == null) | |
| 33101 | break :l if (slice_ty.sentinel(zcu) == null) | |
| 33081 | 33102 | slice_len_inst |
| 33082 | 33103 | else |
| 33083 | 33104 | try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); |
| ... | ... | @@ -33097,7 +33118,7 @@ fn analyzeSlice( |
| 33097 | 33118 | return result; |
| 33098 | 33119 | }; |
| 33099 | 33120 | |
| 33100 | if (!new_ptr_val.isUndef(mod)) { | |
| 33121 | if (!new_ptr_val.isUndef(zcu)) { | |
| 33101 | 33122 | return Air.internedToRef((try pt.getCoerced(new_ptr_val, return_ty)).toIntern()); |
| 33102 | 33123 | } |
| 33103 | 33124 | |
| ... | ... | @@ -33125,15 +33146,15 @@ fn analyzeSlice( |
| 33125 | 33146 | try sema.requireRuntimeBlock(block, src, runtime_src.?); |
| 33126 | 33147 | if (block.wantSafety()) { |
| 33127 | 33148 | // requirement: slicing C ptr is non-null |
| 33128 | if (ptr_ptr_child_ty.isCPtr(mod)) { | |
| 33149 | if (ptr_ptr_child_ty.isCPtr(zcu)) { | |
| 33129 | 33150 | const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true); |
| 33130 | 33151 | try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null); |
| 33131 | 33152 | } |
| 33132 | 33153 | |
| 33133 | 33154 | // requirement: end <= len |
| 33134 | const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array) | |
| 33135 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) | |
| 33136 | else if (slice_ty.isSlice(mod)) blk: { | |
| 33155 | const opt_len_inst = if (array_ty.zigTypeTag(zcu) == .Array) | |
| 33156 | try pt.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(zcu)) | |
| 33157 | else if (slice_ty.isSlice(zcu)) blk: { | |
| 33137 | 33158 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { |
| 33138 | 33159 | // we don't need to add one for sentinels because the |
| 33139 | 33160 | // underlying value data includes the sentinel |
| ... | ... | @@ -33141,7 +33162,7 @@ fn analyzeSlice( |
| 33141 | 33162 | } |
| 33142 | 33163 | |
| 33143 | 33164 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); |
| 33144 | if (slice_ty.sentinel(mod) == null) break :blk slice_len_inst; | |
| 33165 | if (slice_ty.sentinel(zcu) == null) break :blk slice_len_inst; | |
| 33145 | 33166 | |
| 33146 | 33167 | // we have to add one because slice lengths don't include the sentinel |
| 33147 | 33168 | break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); |
| ... | ... | @@ -33186,16 +33207,16 @@ fn cmpNumeric( |
| 33186 | 33207 | rhs_src: LazySrcLoc, |
| 33187 | 33208 | ) CompileError!Air.Inst.Ref { |
| 33188 | 33209 | const pt = sema.pt; |
| 33189 | const mod = pt.zcu; | |
| 33210 | const zcu = pt.zcu; | |
| 33190 | 33211 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 33191 | 33212 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 33192 | 33213 | |
| 33193 | assert(lhs_ty.isNumeric(mod)); | |
| 33194 | assert(rhs_ty.isNumeric(mod)); | |
| 33214 | assert(lhs_ty.isNumeric(zcu)); | |
| 33215 | assert(rhs_ty.isNumeric(zcu)); | |
| 33195 | 33216 | |
| 33196 | const lhs_ty_tag = lhs_ty.zigTypeTag(mod); | |
| 33197 | const rhs_ty_tag = rhs_ty.zigTypeTag(mod); | |
| 33198 | const target = mod.getTarget(); | |
| 33217 | const lhs_ty_tag = lhs_ty.zigTypeTag(zcu); | |
| 33218 | const rhs_ty_tag = rhs_ty.zigTypeTag(zcu); | |
| 33219 | const target = zcu.getTarget(); | |
| 33199 | 33220 | |
| 33200 | 33221 | // One exception to heterogeneous comparison: comptime_float needs to |
| 33201 | 33222 | // coerce to fixed-width float. |
| ... | ... | @@ -33214,28 +33235,28 @@ fn cmpNumeric( |
| 33214 | 33235 | if (try sema.resolveValue(lhs)) |lhs_val| { |
| 33215 | 33236 | if (try sema.resolveValue(rhs)) |rhs_val| { |
| 33216 | 33237 | // Compare ints: const vs. undefined (or vice versa) |
| 33217 | if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod) and rhs_val.isUndef(mod)) { | |
| 33238 | if (!lhs_val.isUndef(zcu) and (lhs_ty.isInt(zcu) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(zcu) and rhs_val.isUndef(zcu)) { | |
| 33218 | 33239 | if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(lhs_val), op, rhs_ty)) |res| { |
| 33219 | 33240 | return if (res) .bool_true else .bool_false; |
| 33220 | 33241 | } |
| 33221 | } else if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod) and lhs_val.isUndef(mod)) { | |
| 33242 | } else if (!rhs_val.isUndef(zcu) and (rhs_ty.isInt(zcu) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(zcu) and lhs_val.isUndef(zcu)) { | |
| 33222 | 33243 | if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(rhs_val), op.reverse(), lhs_ty)) |res| { |
| 33223 | 33244 | return if (res) .bool_true else .bool_false; |
| 33224 | 33245 | } |
| 33225 | 33246 | } |
| 33226 | 33247 | |
| 33227 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | |
| 33248 | if (lhs_val.isUndef(zcu) or rhs_val.isUndef(zcu)) { | |
| 33228 | 33249 | return pt.undefRef(Type.bool); |
| 33229 | 33250 | } |
| 33230 | if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) { | |
| 33251 | if (lhs_val.isNan(zcu) or rhs_val.isNan(zcu)) { | |
| 33231 | 33252 | return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false; |
| 33232 | 33253 | } |
| 33233 | return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, pt, .sema)) | |
| 33254 | return if (try Value.compareHeteroSema(lhs_val, op, rhs_val, pt)) | |
| 33234 | 33255 | .bool_true |
| 33235 | 33256 | else |
| 33236 | 33257 | .bool_false; |
| 33237 | 33258 | } else { |
| 33238 | if (!lhs_val.isUndef(mod) and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod)) { | |
| 33259 | if (!lhs_val.isUndef(zcu) and (lhs_ty.isInt(zcu) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(zcu)) { | |
| 33239 | 33260 | // Compare ints: const vs. var |
| 33240 | 33261 | if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(lhs_val), op, rhs_ty)) |res| { |
| 33241 | 33262 | return if (res) .bool_true else .bool_false; |
| ... | ... | @@ -33245,7 +33266,7 @@ fn cmpNumeric( |
| 33245 | 33266 | } |
| 33246 | 33267 | } else { |
| 33247 | 33268 | if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| { |
| 33248 | if (!rhs_val.isUndef(mod) and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod)) { | |
| 33269 | if (!rhs_val.isUndef(zcu) and (rhs_ty.isInt(zcu) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(zcu)) { | |
| 33249 | 33270 | // Compare ints: var vs. const |
| 33250 | 33271 | if (try sema.compareIntsOnlyPossibleResult(try sema.resolveLazyValue(rhs_val), op.reverse(), lhs_ty)) |res| { |
| 33251 | 33272 | return if (res) .bool_true else .bool_false; |
| ... | ... | @@ -33301,31 +33322,31 @@ fn cmpNumeric( |
| 33301 | 33322 | const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| |
| 33302 | 33323 | !(try lhs_val.compareAllWithZeroSema(.gte, pt)) |
| 33303 | 33324 | else |
| 33304 | (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod)); | |
| 33325 | (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(zcu)); | |
| 33305 | 33326 | const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| |
| 33306 | 33327 | !(try rhs_val.compareAllWithZeroSema(.gte, pt)) |
| 33307 | 33328 | else |
| 33308 | (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod)); | |
| 33329 | (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(zcu)); | |
| 33309 | 33330 | const dest_int_is_signed = lhs_is_signed or rhs_is_signed; |
| 33310 | 33331 | |
| 33311 | 33332 | var dest_float_type: ?Type = null; |
| 33312 | 33333 | |
| 33313 | 33334 | var lhs_bits: usize = undefined; |
| 33314 | 33335 | if (try sema.resolveValueResolveLazy(lhs)) |lhs_val| { |
| 33315 | if (lhs_val.isUndef(mod)) | |
| 33336 | if (lhs_val.isUndef(zcu)) | |
| 33316 | 33337 | return pt.undefRef(Type.bool); |
| 33317 | if (lhs_val.isNan(mod)) switch (op) { | |
| 33338 | if (lhs_val.isNan(zcu)) switch (op) { | |
| 33318 | 33339 | .neq => return .bool_true, |
| 33319 | 33340 | else => return .bool_false, |
| 33320 | 33341 | }; |
| 33321 | if (lhs_val.isInf(mod)) switch (op) { | |
| 33342 | if (lhs_val.isInf(zcu)) switch (op) { | |
| 33322 | 33343 | .neq => return .bool_true, |
| 33323 | 33344 | .eq => return .bool_false, |
| 33324 | .gt, .gte => return if (lhs_val.isNegativeInf(mod)) .bool_false else .bool_true, | |
| 33325 | .lt, .lte => return if (lhs_val.isNegativeInf(mod)) .bool_true else .bool_false, | |
| 33345 | .gt, .gte => return if (lhs_val.isNegativeInf(zcu)) .bool_false else .bool_true, | |
| 33346 | .lt, .lte => return if (lhs_val.isNegativeInf(zcu)) .bool_true else .bool_false, | |
| 33326 | 33347 | }; |
| 33327 | 33348 | if (!rhs_is_signed) { |
| 33328 | switch (lhs_val.orderAgainstZero(pt)) { | |
| 33349 | switch (lhs_val.orderAgainstZero(zcu)) { | |
| 33329 | 33350 | .gt => {}, |
| 33330 | 33351 | .eq => switch (op) { // LHS = 0, RHS is unsigned |
| 33331 | 33352 | .lte => return .bool_true, |
| ... | ... | @@ -33339,7 +33360,7 @@ fn cmpNumeric( |
| 33339 | 33360 | } |
| 33340 | 33361 | } |
| 33341 | 33362 | if (lhs_is_float) { |
| 33342 | if (lhs_val.floatHasFraction(mod)) { | |
| 33363 | if (lhs_val.floatHasFraction(zcu)) { | |
| 33343 | 33364 | switch (op) { |
| 33344 | 33365 | .eq => return .bool_false, |
| 33345 | 33366 | .neq => return .bool_true, |
| ... | ... | @@ -33347,9 +33368,9 @@ fn cmpNumeric( |
| 33347 | 33368 | } |
| 33348 | 33369 | } |
| 33349 | 33370 | |
| 33350 | var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, pt)); | |
| 33371 | var bigint = try float128IntPartToBigInt(sema.gpa, lhs_val.toFloat(f128, zcu)); | |
| 33351 | 33372 | defer bigint.deinit(); |
| 33352 | if (lhs_val.floatHasFraction(mod)) { | |
| 33373 | if (lhs_val.floatHasFraction(zcu)) { | |
| 33353 | 33374 | if (lhs_is_signed) { |
| 33354 | 33375 | try bigint.addScalar(&bigint, -1); |
| 33355 | 33376 | } else { |
| ... | ... | @@ -33358,32 +33379,32 @@ fn cmpNumeric( |
| 33358 | 33379 | } |
| 33359 | 33380 | lhs_bits = bigint.toConst().bitCountTwosComp(); |
| 33360 | 33381 | } else { |
| 33361 | lhs_bits = lhs_val.intBitCountTwosComp(pt); | |
| 33382 | lhs_bits = lhs_val.intBitCountTwosComp(zcu); | |
| 33362 | 33383 | } |
| 33363 | 33384 | lhs_bits += @intFromBool(!lhs_is_signed and dest_int_is_signed); |
| 33364 | 33385 | } else if (lhs_is_float) { |
| 33365 | 33386 | dest_float_type = lhs_ty; |
| 33366 | 33387 | } else { |
| 33367 | const int_info = lhs_ty.intInfo(mod); | |
| 33388 | const int_info = lhs_ty.intInfo(zcu); | |
| 33368 | 33389 | lhs_bits = int_info.bits + @intFromBool(int_info.signedness == .unsigned and dest_int_is_signed); |
| 33369 | 33390 | } |
| 33370 | 33391 | |
| 33371 | 33392 | var rhs_bits: usize = undefined; |
| 33372 | 33393 | if (try sema.resolveValueResolveLazy(rhs)) |rhs_val| { |
| 33373 | if (rhs_val.isUndef(mod)) | |
| 33394 | if (rhs_val.isUndef(zcu)) | |
| 33374 | 33395 | return pt.undefRef(Type.bool); |
| 33375 | if (rhs_val.isNan(mod)) switch (op) { | |
| 33396 | if (rhs_val.isNan(zcu)) switch (op) { | |
| 33376 | 33397 | .neq => return .bool_true, |
| 33377 | 33398 | else => return .bool_false, |
| 33378 | 33399 | }; |
| 33379 | if (rhs_val.isInf(mod)) switch (op) { | |
| 33400 | if (rhs_val.isInf(zcu)) switch (op) { | |
| 33380 | 33401 | .neq => return .bool_true, |
| 33381 | 33402 | .eq => return .bool_false, |
| 33382 | .gt, .gte => return if (rhs_val.isNegativeInf(mod)) .bool_true else .bool_false, | |
| 33383 | .lt, .lte => return if (rhs_val.isNegativeInf(mod)) .bool_false else .bool_true, | |
| 33403 | .gt, .gte => return if (rhs_val.isNegativeInf(zcu)) .bool_true else .bool_false, | |
| 33404 | .lt, .lte => return if (rhs_val.isNegativeInf(zcu)) .bool_false else .bool_true, | |
| 33384 | 33405 | }; |
| 33385 | 33406 | if (!lhs_is_signed) { |
| 33386 | switch (rhs_val.orderAgainstZero(pt)) { | |
| 33407 | switch (rhs_val.orderAgainstZero(zcu)) { | |
| 33387 | 33408 | .gt => {}, |
| 33388 | 33409 | .eq => switch (op) { // RHS = 0, LHS is unsigned |
| 33389 | 33410 | .gte => return .bool_true, |
| ... | ... | @@ -33397,7 +33418,7 @@ fn cmpNumeric( |
| 33397 | 33418 | } |
| 33398 | 33419 | } |
| 33399 | 33420 | if (rhs_is_float) { |
| 33400 | if (rhs_val.floatHasFraction(mod)) { | |
| 33421 | if (rhs_val.floatHasFraction(zcu)) { | |
| 33401 | 33422 | switch (op) { |
| 33402 | 33423 | .eq => return .bool_false, |
| 33403 | 33424 | .neq => return .bool_true, |
| ... | ... | @@ -33405,9 +33426,9 @@ fn cmpNumeric( |
| 33405 | 33426 | } |
| 33406 | 33427 | } |
| 33407 | 33428 | |
| 33408 | var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, pt)); | |
| 33429 | var bigint = try float128IntPartToBigInt(sema.gpa, rhs_val.toFloat(f128, zcu)); | |
| 33409 | 33430 | defer bigint.deinit(); |
| 33410 | if (rhs_val.floatHasFraction(mod)) { | |
| 33431 | if (rhs_val.floatHasFraction(zcu)) { | |
| 33411 | 33432 | if (rhs_is_signed) { |
| 33412 | 33433 | try bigint.addScalar(&bigint, -1); |
| 33413 | 33434 | } else { |
| ... | ... | @@ -33416,13 +33437,13 @@ fn cmpNumeric( |
| 33416 | 33437 | } |
| 33417 | 33438 | rhs_bits = bigint.toConst().bitCountTwosComp(); |
| 33418 | 33439 | } else { |
| 33419 | rhs_bits = rhs_val.intBitCountTwosComp(pt); | |
| 33440 | rhs_bits = rhs_val.intBitCountTwosComp(zcu); | |
| 33420 | 33441 | } |
| 33421 | 33442 | rhs_bits += @intFromBool(!rhs_is_signed and dest_int_is_signed); |
| 33422 | 33443 | } else if (rhs_is_float) { |
| 33423 | 33444 | dest_float_type = rhs_ty; |
| 33424 | 33445 | } else { |
| 33425 | const int_info = rhs_ty.intInfo(mod); | |
| 33446 | const int_info = rhs_ty.intInfo(zcu); | |
| 33426 | 33447 | rhs_bits = int_info.bits + @intFromBool(int_info.signedness == .unsigned and dest_int_is_signed); |
| 33427 | 33448 | } |
| 33428 | 33449 | |
| ... | ... | @@ -33450,9 +33471,9 @@ fn compareIntsOnlyPossibleResult( |
| 33450 | 33471 | rhs_ty: Type, |
| 33451 | 33472 | ) Allocator.Error!?bool { |
| 33452 | 33473 | const pt = sema.pt; |
| 33453 | const mod = pt.zcu; | |
| 33454 | const rhs_info = rhs_ty.intInfo(mod); | |
| 33455 | const vs_zero = lhs_val.orderAgainstZeroAdvanced(pt, .sema) catch unreachable; | |
| 33474 | const zcu = pt.zcu; | |
| 33475 | const rhs_info = rhs_ty.intInfo(zcu); | |
| 33476 | const vs_zero = lhs_val.orderAgainstZeroSema(pt) catch unreachable; | |
| 33456 | 33477 | const is_zero = vs_zero == .eq; |
| 33457 | 33478 | const is_negative = vs_zero == .lt; |
| 33458 | 33479 | const is_positive = vs_zero == .gt; |
| ... | ... | @@ -33484,7 +33505,7 @@ fn compareIntsOnlyPossibleResult( |
| 33484 | 33505 | }; |
| 33485 | 33506 | |
| 33486 | 33507 | const sign_adj = @intFromBool(!is_negative and rhs_info.signedness == .signed); |
| 33487 | const req_bits = lhs_val.intBitCountTwosComp(pt) + sign_adj; | |
| 33508 | const req_bits = lhs_val.intBitCountTwosComp(zcu) + sign_adj; | |
| 33488 | 33509 | |
| 33489 | 33510 | // No sized type can have more than 65535 bits. |
| 33490 | 33511 | // The RHS type operand is either a runtime value or sized (but undefined) constant. |
| ... | ... | @@ -33515,7 +33536,7 @@ fn compareIntsOnlyPossibleResult( |
| 33515 | 33536 | if (is_negative) .signed else .unsigned, |
| 33516 | 33537 | @intCast(req_bits), |
| 33517 | 33538 | ); |
| 33518 | const pop_count = lhs_val.popCount(ty, pt); | |
| 33539 | const pop_count = lhs_val.popCount(ty, zcu); | |
| 33519 | 33540 | |
| 33520 | 33541 | if (is_negative) { |
| 33521 | 33542 | break :edge .{ pop_count == 1, false }; |
| ... | ... | @@ -33546,11 +33567,11 @@ fn cmpVector( |
| 33546 | 33567 | rhs_src: LazySrcLoc, |
| 33547 | 33568 | ) CompileError!Air.Inst.Ref { |
| 33548 | 33569 | const pt = sema.pt; |
| 33549 | const mod = pt.zcu; | |
| 33570 | const zcu = pt.zcu; | |
| 33550 | 33571 | const lhs_ty = sema.typeOf(lhs); |
| 33551 | 33572 | const rhs_ty = sema.typeOf(rhs); |
| 33552 | assert(lhs_ty.zigTypeTag(mod) == .Vector); | |
| 33553 | assert(rhs_ty.zigTypeTag(mod) == .Vector); | |
| 33573 | assert(lhs_ty.zigTypeTag(zcu) == .Vector); | |
| 33574 | assert(rhs_ty.zigTypeTag(zcu) == .Vector); | |
| 33554 | 33575 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 33555 | 33576 | |
| 33556 | 33577 | const resolved_ty = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ .override = &.{ lhs_src, rhs_src } }); |
| ... | ... | @@ -33558,14 +33579,14 @@ fn cmpVector( |
| 33558 | 33579 | const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src); |
| 33559 | 33580 | |
| 33560 | 33581 | const result_ty = try pt.vectorType(.{ |
| 33561 | .len = lhs_ty.vectorLen(mod), | |
| 33582 | .len = lhs_ty.vectorLen(zcu), | |
| 33562 | 33583 | .child = .bool_type, |
| 33563 | 33584 | }); |
| 33564 | 33585 | |
| 33565 | 33586 | const runtime_src: LazySrcLoc = src: { |
| 33566 | 33587 | if (try sema.resolveValue(casted_lhs)) |lhs_val| { |
| 33567 | 33588 | if (try sema.resolveValue(casted_rhs)) |rhs_val| { |
| 33568 | if (lhs_val.isUndef(mod) or rhs_val.isUndef(mod)) { | |
| 33589 | if (lhs_val.isUndef(zcu) or rhs_val.isUndef(zcu)) { | |
| 33569 | 33590 | return pt.undefRef(result_ty); |
| 33570 | 33591 | } |
| 33571 | 33592 | const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_ty); |
| ... | ... | @@ -33608,8 +33629,8 @@ fn wrapErrorUnionPayload( |
| 33608 | 33629 | inst_src: LazySrcLoc, |
| 33609 | 33630 | ) !Air.Inst.Ref { |
| 33610 | 33631 | const pt = sema.pt; |
| 33611 | const mod = pt.zcu; | |
| 33612 | const dest_payload_ty = dest_ty.errorUnionPayload(mod); | |
| 33632 | const zcu = pt.zcu; | |
| 33633 | const dest_payload_ty = dest_ty.errorUnionPayload(zcu); | |
| 33613 | 33634 | const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false }); |
| 33614 | 33635 | if (try sema.resolveValue(coerced)) |val| { |
| 33615 | 33636 | return Air.internedToRef((try pt.intern(.{ .error_union = .{ |
| ... | ... | @@ -33629,12 +33650,12 @@ fn wrapErrorUnionSet( |
| 33629 | 33650 | inst_src: LazySrcLoc, |
| 33630 | 33651 | ) !Air.Inst.Ref { |
| 33631 | 33652 | const pt = sema.pt; |
| 33632 | const mod = pt.zcu; | |
| 33633 | const ip = &mod.intern_pool; | |
| 33653 | const zcu = pt.zcu; | |
| 33654 | const ip = &zcu.intern_pool; | |
| 33634 | 33655 | const inst_ty = sema.typeOf(inst); |
| 33635 | const dest_err_set_ty = dest_ty.errorUnionSet(mod); | |
| 33656 | const dest_err_set_ty = dest_ty.errorUnionSet(zcu); | |
| 33636 | 33657 | if (try sema.resolveValue(inst)) |val| { |
| 33637 | const expected_name = mod.intern_pool.indexToKey(val.toIntern()).err.name; | |
| 33658 | const expected_name = zcu.intern_pool.indexToKey(val.toIntern()).err.name; | |
| 33638 | 33659 | switch (dest_err_set_ty.toIntern()) { |
| 33639 | 33660 | .anyerror_type => {}, |
| 33640 | 33661 | .adhoc_inferred_error_set_type => ok: { |
| ... | ... | @@ -33658,7 +33679,7 @@ fn wrapErrorUnionSet( |
| 33658 | 33679 | .inferred_error_set_type => |func_index| ok: { |
| 33659 | 33680 | // We carefully do this in an order that avoids unnecessarily |
| 33660 | 33681 | // resolving the destination error set type. |
| 33661 | try mod.maybeUnresolveIes(func_index); | |
| 33682 | try zcu.maybeUnresolveIes(func_index); | |
| 33662 | 33683 | switch (ip.funcIesResolvedUnordered(func_index)) { |
| 33663 | 33684 | .anyerror_type => break :ok, |
| 33664 | 33685 | .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) { |
| ... | ... | @@ -33693,13 +33714,13 @@ fn unionToTag( |
| 33693 | 33714 | un_src: LazySrcLoc, |
| 33694 | 33715 | ) !Air.Inst.Ref { |
| 33695 | 33716 | const pt = sema.pt; |
| 33696 | const mod = pt.zcu; | |
| 33717 | const zcu = pt.zcu; | |
| 33697 | 33718 | if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| { |
| 33698 | 33719 | return Air.internedToRef(opv.toIntern()); |
| 33699 | 33720 | } |
| 33700 | 33721 | if (try sema.resolveValue(un)) |un_val| { |
| 33701 | const tag_val = un_val.unionTag(mod).?; | |
| 33702 | if (tag_val.isUndef(mod)) | |
| 33722 | const tag_val = un_val.unionTag(zcu).?; | |
| 33723 | if (tag_val.isUndef(zcu)) | |
| 33703 | 33724 | return try pt.undefRef(enum_ty); |
| 33704 | 33725 | return Air.internedToRef(tag_val.toIntern()); |
| 33705 | 33726 | } |
| ... | ... | @@ -33861,8 +33882,8 @@ const PeerResolveStrategy = enum { |
| 33861 | 33882 | return strat; |
| 33862 | 33883 | } |
| 33863 | 33884 | |
| 33864 | fn select(ty: Type, mod: *Module) PeerResolveStrategy { | |
| 33865 | return switch (ty.zigTypeTag(mod)) { | |
| 33885 | fn select(ty: Type, zcu: *Zcu) PeerResolveStrategy { | |
| 33886 | return switch (ty.zigTypeTag(zcu)) { | |
| 33866 | 33887 | .Type, .Void, .Bool, .Opaque, .Frame, .AnyFrame => .exact, |
| 33867 | 33888 | .NoReturn, .Undefined => .unknown, |
| 33868 | 33889 | .Null => .nullable, |
| ... | ... | @@ -33870,14 +33891,14 @@ const PeerResolveStrategy = enum { |
| 33870 | 33891 | .Int => .fixed_int, |
| 33871 | 33892 | .ComptimeFloat => .comptime_float, |
| 33872 | 33893 | .Float => .fixed_float, |
| 33873 | .Pointer => if (ty.ptrInfo(mod).flags.size == .C) .c_ptr else .ptr, | |
| 33894 | .Pointer => if (ty.ptrInfo(zcu).flags.size == .C) .c_ptr else .ptr, | |
| 33874 | 33895 | .Array => .array, |
| 33875 | 33896 | .Vector => .vector, |
| 33876 | 33897 | .Optional => .optional, |
| 33877 | 33898 | .ErrorSet => .error_set, |
| 33878 | 33899 | .ErrorUnion => .error_union, |
| 33879 | 33900 | .EnumLiteral, .Enum, .Union => .enum_or_union, |
| 33880 | .Struct => if (ty.isTupleOrAnonStruct(mod)) .coercible_struct else .exact, | |
| 33901 | .Struct => if (ty.isTupleOrAnonStruct(zcu)) .coercible_struct else .exact, | |
| 33881 | 33902 | .Fn => .func, |
| 33882 | 33903 | }; |
| 33883 | 33904 | } |
| ... | ... | @@ -33933,10 +33954,10 @@ const PeerResolveResult = union(enum) { |
| 33933 | 33954 | src: LazySrcLoc, |
| 33934 | 33955 | instructions: []const Air.Inst.Ref, |
| 33935 | 33956 | candidate_srcs: PeerTypeCandidateSrc, |
| 33936 | ) !*Module.ErrorMsg { | |
| 33957 | ) !*Zcu.ErrorMsg { | |
| 33937 | 33958 | const pt = sema.pt; |
| 33938 | 33959 | |
| 33939 | var opt_msg: ?*Module.ErrorMsg = null; | |
| 33960 | var opt_msg: ?*Zcu.ErrorMsg = null; | |
| 33940 | 33961 | errdefer if (opt_msg) |msg| msg.destroy(sema.gpa); |
| 33941 | 33962 | |
| 33942 | 33963 | // If we mention fields we'll want to include field types, so put peer types in a buffer |
| ... | ... | @@ -34053,14 +34074,14 @@ fn resolvePeerTypesInner( |
| 34053 | 34074 | peer_vals: []?Value, |
| 34054 | 34075 | ) !PeerResolveResult { |
| 34055 | 34076 | const pt = sema.pt; |
| 34056 | const mod = pt.zcu; | |
| 34057 | const ip = &mod.intern_pool; | |
| 34077 | const zcu = pt.zcu; | |
| 34078 | const ip = &zcu.intern_pool; | |
| 34058 | 34079 | |
| 34059 | 34080 | var strat_reason: usize = 0; |
| 34060 | 34081 | var s: PeerResolveStrategy = .unknown; |
| 34061 | 34082 | for (peer_tys, 0..) |opt_ty, i| { |
| 34062 | 34083 | const ty = opt_ty orelse continue; |
| 34063 | s = s.merge(PeerResolveStrategy.select(ty, mod), &strat_reason, i); | |
| 34084 | s = s.merge(PeerResolveStrategy.select(ty, zcu), &strat_reason, i); | |
| 34064 | 34085 | } |
| 34065 | 34086 | |
| 34066 | 34087 | if (s == .unknown) { |
| ... | ... | @@ -34070,14 +34091,14 @@ fn resolvePeerTypesInner( |
| 34070 | 34091 | // There was something other than noreturn and undefined, so we can ignore those peers |
| 34071 | 34092 | for (peer_tys) |*ty_ptr| { |
| 34072 | 34093 | const ty = ty_ptr.* orelse continue; |
| 34073 | switch (ty.zigTypeTag(mod)) { | |
| 34094 | switch (ty.zigTypeTag(zcu)) { | |
| 34074 | 34095 | .NoReturn, .Undefined => ty_ptr.* = null, |
| 34075 | 34096 | else => {}, |
| 34076 | 34097 | } |
| 34077 | 34098 | } |
| 34078 | 34099 | } |
| 34079 | 34100 | |
| 34080 | const target = mod.getTarget(); | |
| 34101 | const target = zcu.getTarget(); | |
| 34081 | 34102 | |
| 34082 | 34103 | switch (s) { |
| 34083 | 34104 | .unknown => unreachable, |
| ... | ... | @@ -34086,7 +34107,7 @@ fn resolvePeerTypesInner( |
| 34086 | 34107 | var final_set: ?Type = null; |
| 34087 | 34108 | for (peer_tys, 0..) |opt_ty, i| { |
| 34088 | 34109 | const ty = opt_ty orelse continue; |
| 34089 | if (ty.zigTypeTag(mod) != .ErrorSet) return .{ .conflict = .{ | |
| 34110 | if (ty.zigTypeTag(zcu) != .ErrorSet) return .{ .conflict = .{ | |
| 34090 | 34111 | .peer_idx_a = strat_reason, |
| 34091 | 34112 | .peer_idx_b = i, |
| 34092 | 34113 | } }; |
| ... | ... | @@ -34103,15 +34124,15 @@ fn resolvePeerTypesInner( |
| 34103 | 34124 | var final_set: ?Type = null; |
| 34104 | 34125 | for (peer_tys, peer_vals) |*ty_ptr, *val_ptr| { |
| 34105 | 34126 | const ty = ty_ptr.* orelse continue; |
| 34106 | const set_ty = switch (ty.zigTypeTag(mod)) { | |
| 34127 | const set_ty = switch (ty.zigTypeTag(zcu)) { | |
| 34107 | 34128 | .ErrorSet => blk: { |
| 34108 | 34129 | ty_ptr.* = null; // no payload to decide on |
| 34109 | 34130 | val_ptr.* = null; |
| 34110 | 34131 | break :blk ty; |
| 34111 | 34132 | }, |
| 34112 | 34133 | .ErrorUnion => blk: { |
| 34113 | const set_ty = ty.errorUnionSet(mod); | |
| 34114 | ty_ptr.* = ty.errorUnionPayload(mod); | |
| 34134 | const set_ty = ty.errorUnionSet(zcu); | |
| 34135 | ty_ptr.* = ty.errorUnionPayload(zcu); | |
| 34115 | 34136 | if (val_ptr.*) |eu_val| switch (ip.indexToKey(eu_val.toIntern())) { |
| 34116 | 34137 | .error_union => |eu| switch (eu.val) { |
| 34117 | 34138 | .payload => |payload_ip| val_ptr.* = Value.fromInterned(payload_ip), |
| ... | ... | @@ -34146,7 +34167,7 @@ fn resolvePeerTypesInner( |
| 34146 | 34167 | .nullable => { |
| 34147 | 34168 | for (peer_tys, 0..) |opt_ty, i| { |
| 34148 | 34169 | const ty = opt_ty orelse continue; |
| 34149 | if (!ty.eql(Type.null, mod)) return .{ .conflict = .{ | |
| 34170 | if (!ty.eql(Type.null, zcu)) return .{ .conflict = .{ | |
| 34150 | 34171 | .peer_idx_a = strat_reason, |
| 34151 | 34172 | .peer_idx_b = i, |
| 34152 | 34173 | } }; |
| ... | ... | @@ -34157,14 +34178,14 @@ fn resolvePeerTypesInner( |
| 34157 | 34178 | .optional => { |
| 34158 | 34179 | for (peer_tys, peer_vals) |*ty_ptr, *val_ptr| { |
| 34159 | 34180 | const ty = ty_ptr.* orelse continue; |
| 34160 | switch (ty.zigTypeTag(mod)) { | |
| 34181 | switch (ty.zigTypeTag(zcu)) { | |
| 34161 | 34182 | .Null => { |
| 34162 | 34183 | ty_ptr.* = null; |
| 34163 | 34184 | val_ptr.* = null; |
| 34164 | 34185 | }, |
| 34165 | 34186 | .Optional => { |
| 34166 | ty_ptr.* = ty.optionalChild(mod); | |
| 34167 | if (val_ptr.*) |opt_val| val_ptr.* = if (!opt_val.isUndef(mod)) opt_val.optionalValue(mod) else null; | |
| 34187 | ty_ptr.* = ty.optionalChild(zcu); | |
| 34188 | if (val_ptr.*) |opt_val| val_ptr.* = if (!opt_val.isUndef(zcu)) opt_val.optionalValue(zcu) else null; | |
| 34168 | 34189 | }, |
| 34169 | 34190 | else => {}, |
| 34170 | 34191 | } |
| ... | ... | @@ -34195,7 +34216,7 @@ fn resolvePeerTypesInner( |
| 34195 | 34216 | for (peer_tys, 0..) |*ty_ptr, i| { |
| 34196 | 34217 | const ty = ty_ptr.* orelse continue; |
| 34197 | 34218 | |
| 34198 | if (!ty.isArrayOrVector(mod)) { | |
| 34219 | if (!ty.isArrayOrVector(zcu)) { | |
| 34199 | 34220 | // We allow tuples of the correct length. We won't validate their elem type, since the elements can be coerced. |
| 34200 | 34221 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ |
| 34201 | 34222 | .peer_idx_a = strat_reason, |
| ... | ... | @@ -34220,29 +34241,29 @@ fn resolvePeerTypesInner( |
| 34220 | 34241 | const first_arr_idx = opt_first_arr_idx orelse { |
| 34221 | 34242 | if (opt_first_idx == null) { |
| 34222 | 34243 | opt_first_idx = i; |
| 34223 | len = ty.arrayLen(mod); | |
| 34224 | sentinel = ty.sentinel(mod); | |
| 34244 | len = ty.arrayLen(zcu); | |
| 34245 | sentinel = ty.sentinel(zcu); | |
| 34225 | 34246 | } |
| 34226 | 34247 | opt_first_arr_idx = i; |
| 34227 | elem_ty = ty.childType(mod); | |
| 34248 | elem_ty = ty.childType(zcu); | |
| 34228 | 34249 | continue; |
| 34229 | 34250 | }; |
| 34230 | 34251 | |
| 34231 | if (ty.arrayLen(mod) != len) return .{ .conflict = .{ | |
| 34252 | if (ty.arrayLen(zcu) != len) return .{ .conflict = .{ | |
| 34232 | 34253 | .peer_idx_a = first_arr_idx, |
| 34233 | 34254 | .peer_idx_b = i, |
| 34234 | 34255 | } }; |
| 34235 | 34256 | |
| 34236 | const peer_elem_ty = ty.childType(mod); | |
| 34237 | if (!peer_elem_ty.eql(elem_ty, mod)) coerce: { | |
| 34257 | const peer_elem_ty = ty.childType(zcu); | |
| 34258 | if (!peer_elem_ty.eql(elem_ty, zcu)) coerce: { | |
| 34238 | 34259 | const peer_elem_coerces_to_elem = |
| 34239 | try sema.coerceInMemoryAllowed(block, elem_ty, peer_elem_ty, false, mod.getTarget(), src, src, null); | |
| 34260 | try sema.coerceInMemoryAllowed(block, elem_ty, peer_elem_ty, false, zcu.getTarget(), src, src, null); | |
| 34240 | 34261 | if (peer_elem_coerces_to_elem == .ok) { |
| 34241 | 34262 | break :coerce; |
| 34242 | 34263 | } |
| 34243 | 34264 | |
| 34244 | 34265 | const elem_coerces_to_peer_elem = |
| 34245 | try sema.coerceInMemoryAllowed(block, peer_elem_ty, elem_ty, false, mod.getTarget(), src, src, null); | |
| 34266 | try sema.coerceInMemoryAllowed(block, peer_elem_ty, elem_ty, false, zcu.getTarget(), src, src, null); | |
| 34246 | 34267 | if (elem_coerces_to_peer_elem == .ok) { |
| 34247 | 34268 | elem_ty = peer_elem_ty; |
| 34248 | 34269 | break :coerce; |
| ... | ... | @@ -34255,8 +34276,8 @@ fn resolvePeerTypesInner( |
| 34255 | 34276 | } |
| 34256 | 34277 | |
| 34257 | 34278 | if (sentinel) |cur_sent| { |
| 34258 | if (ty.sentinel(mod)) |peer_sent| { | |
| 34259 | if (!peer_sent.eql(cur_sent, elem_ty, mod)) sentinel = null; | |
| 34279 | if (ty.sentinel(zcu)) |peer_sent| { | |
| 34280 | if (!peer_sent.eql(cur_sent, elem_ty, zcu)) sentinel = null; | |
| 34260 | 34281 | } else { |
| 34261 | 34282 | sentinel = null; |
| 34262 | 34283 | } |
| ... | ... | @@ -34279,7 +34300,7 @@ fn resolvePeerTypesInner( |
| 34279 | 34300 | for (peer_tys, peer_vals, 0..) |*ty_ptr, *val_ptr, i| { |
| 34280 | 34301 | const ty = ty_ptr.* orelse continue; |
| 34281 | 34302 | |
| 34282 | if (!ty.isArrayOrVector(mod)) { | |
| 34303 | if (!ty.isArrayOrVector(zcu)) { | |
| 34283 | 34304 | // Allow tuples of the correct length |
| 34284 | 34305 | const arr_like = sema.typeIsArrayLike(ty) orelse return .{ .conflict = .{ |
| 34285 | 34306 | .peer_idx_a = strat_reason, |
| ... | ... | @@ -34305,16 +34326,16 @@ fn resolvePeerTypesInner( |
| 34305 | 34326 | } |
| 34306 | 34327 | |
| 34307 | 34328 | if (len) |expect_len| { |
| 34308 | if (ty.arrayLen(mod) != expect_len) return .{ .conflict = .{ | |
| 34329 | if (ty.arrayLen(zcu) != expect_len) return .{ .conflict = .{ | |
| 34309 | 34330 | .peer_idx_a = first_idx, |
| 34310 | 34331 | .peer_idx_b = i, |
| 34311 | 34332 | } }; |
| 34312 | 34333 | } else { |
| 34313 | len = ty.arrayLen(mod); | |
| 34334 | len = ty.arrayLen(zcu); | |
| 34314 | 34335 | first_idx = i; |
| 34315 | 34336 | } |
| 34316 | 34337 | |
| 34317 | ty_ptr.* = ty.childType(mod); | |
| 34338 | ty_ptr.* = ty.childType(zcu); | |
| 34318 | 34339 | val_ptr.* = null; // multiple child vals, so we can't easily use them in PTR |
| 34319 | 34340 | } |
| 34320 | 34341 | |
| ... | ... | @@ -34339,7 +34360,7 @@ fn resolvePeerTypesInner( |
| 34339 | 34360 | var first_idx: usize = undefined; |
| 34340 | 34361 | for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| { |
| 34341 | 34362 | const ty = opt_ty orelse continue; |
| 34342 | switch (ty.zigTypeTag(mod)) { | |
| 34363 | switch (ty.zigTypeTag(zcu)) { | |
| 34343 | 34364 | .ComptimeInt => continue, // comptime-known integers can always coerce to C pointers |
| 34344 | 34365 | .Int => { |
| 34345 | 34366 | if (opt_val != null) { |
| ... | ... | @@ -34348,7 +34369,7 @@ fn resolvePeerTypesInner( |
| 34348 | 34369 | } else { |
| 34349 | 34370 | // Runtime-known, so check if the type is no bigger than a usize |
| 34350 | 34371 | const ptr_bits = target.ptrBitWidth(); |
| 34351 | const bits = ty.intInfo(mod).bits; | |
| 34372 | const bits = ty.intInfo(zcu).bits; | |
| 34352 | 34373 | if (bits <= ptr_bits) continue; |
| 34353 | 34374 | } |
| 34354 | 34375 | }, |
| ... | ... | @@ -34356,13 +34377,13 @@ fn resolvePeerTypesInner( |
| 34356 | 34377 | else => {}, |
| 34357 | 34378 | } |
| 34358 | 34379 | |
| 34359 | if (!ty.isPtrAtRuntime(mod)) return .{ .conflict = .{ | |
| 34380 | if (!ty.isPtrAtRuntime(zcu)) return .{ .conflict = .{ | |
| 34360 | 34381 | .peer_idx_a = strat_reason, |
| 34361 | 34382 | .peer_idx_b = i, |
| 34362 | 34383 | } }; |
| 34363 | 34384 | |
| 34364 | 34385 | // Goes through optionals |
| 34365 | const peer_info = ty.ptrInfo(mod); | |
| 34386 | const peer_info = ty.ptrInfo(zcu); | |
| 34366 | 34387 | |
| 34367 | 34388 | var ptr_info = opt_ptr_info orelse { |
| 34368 | 34389 | opt_ptr_info = peer_info; |
| ... | ... | @@ -34391,17 +34412,17 @@ fn resolvePeerTypesInner( |
| 34391 | 34412 | ptr_info.sentinel = .none; |
| 34392 | 34413 | } |
| 34393 | 34414 | |
| 34394 | // Note that the align can be always non-zero; Module.ptrType will canonicalize it | |
| 34415 | // Note that the align can be always non-zero; Zcu.ptrType will canonicalize it | |
| 34395 | 34416 | ptr_info.flags.alignment = InternPool.Alignment.min( |
| 34396 | 34417 | if (ptr_info.flags.alignment != .none) |
| 34397 | 34418 | ptr_info.flags.alignment |
| 34398 | 34419 | else |
| 34399 | Type.fromInterned(ptr_info.child).abiAlignment(pt), | |
| 34420 | Type.fromInterned(ptr_info.child).abiAlignment(zcu), | |
| 34400 | 34421 | |
| 34401 | 34422 | if (peer_info.flags.alignment != .none) |
| 34402 | 34423 | peer_info.flags.alignment |
| 34403 | 34424 | else |
| 34404 | Type.fromInterned(peer_info.child).abiAlignment(pt), | |
| 34425 | Type.fromInterned(peer_info.child).abiAlignment(zcu), | |
| 34405 | 34426 | ); |
| 34406 | 34427 | if (ptr_info.flags.address_space != peer_info.flags.address_space) { |
| 34407 | 34428 | return .{ .conflict = .{ |
| ... | ... | @@ -34438,8 +34459,8 @@ fn resolvePeerTypesInner( |
| 34438 | 34459 | |
| 34439 | 34460 | for (peer_tys, 0..) |opt_ty, i| { |
| 34440 | 34461 | const ty = opt_ty orelse continue; |
| 34441 | const peer_info: InternPool.Key.PtrType = switch (ty.zigTypeTag(mod)) { | |
| 34442 | .Pointer => ty.ptrInfo(mod), | |
| 34462 | const peer_info: InternPool.Key.PtrType = switch (ty.zigTypeTag(zcu)) { | |
| 34463 | .Pointer => ty.ptrInfo(zcu), | |
| 34443 | 34464 | .Fn => .{ |
| 34444 | 34465 | .child = ty.toIntern(), |
| 34445 | 34466 | .flags = .{ |
| ... | ... | @@ -34480,12 +34501,12 @@ fn resolvePeerTypesInner( |
| 34480 | 34501 | if (ptr_info.flags.alignment != .none) |
| 34481 | 34502 | ptr_info.flags.alignment |
| 34482 | 34503 | else |
| 34483 | try sema.typeAbiAlignment(Type.fromInterned(ptr_info.child)), | |
| 34504 | try Type.fromInterned(ptr_info.child).abiAlignmentSema(pt), | |
| 34484 | 34505 | |
| 34485 | 34506 | if (peer_info.flags.alignment != .none) |
| 34486 | 34507 | peer_info.flags.alignment |
| 34487 | 34508 | else |
| 34488 | try sema.typeAbiAlignment(Type.fromInterned(peer_info.child)), | |
| 34509 | try Type.fromInterned(peer_info.child).abiAlignmentSema(pt), | |
| 34489 | 34510 | ); |
| 34490 | 34511 | |
| 34491 | 34512 | if (ptr_info.flags.address_space != peer_info.flags.address_space) { |
| ... | ... | @@ -34747,7 +34768,7 @@ fn resolvePeerTypesInner( |
| 34747 | 34768 | first_idx = i; |
| 34748 | 34769 | continue; |
| 34749 | 34770 | }; |
| 34750 | if (ty.zigTypeTag(mod) != .Fn) return .{ .conflict = .{ | |
| 34771 | if (ty.zigTypeTag(zcu) != .Fn) return .{ .conflict = .{ | |
| 34751 | 34772 | .peer_idx_a = strat_reason, |
| 34752 | 34773 | .peer_idx_b = i, |
| 34753 | 34774 | } }; |
| ... | ... | @@ -34775,7 +34796,7 @@ fn resolvePeerTypesInner( |
| 34775 | 34796 | |
| 34776 | 34797 | for (peer_tys, 0..) |opt_ty, i| { |
| 34777 | 34798 | const ty = opt_ty orelse continue; |
| 34778 | switch (ty.zigTypeTag(mod)) { | |
| 34799 | switch (ty.zigTypeTag(zcu)) { | |
| 34779 | 34800 | .EnumLiteral, .Enum, .Union => {}, |
| 34780 | 34801 | else => return .{ .conflict = .{ |
| 34781 | 34802 | .peer_idx_a = strat_reason, |
| ... | ... | @@ -34794,32 +34815,32 @@ fn resolvePeerTypesInner( |
| 34794 | 34815 | .peer_idx_b = i, |
| 34795 | 34816 | } }; |
| 34796 | 34817 | |
| 34797 | switch (cur_ty.zigTypeTag(mod)) { | |
| 34818 | switch (cur_ty.zigTypeTag(zcu)) { | |
| 34798 | 34819 | .EnumLiteral => { |
| 34799 | 34820 | opt_cur_ty = ty; |
| 34800 | 34821 | cur_ty_idx = i; |
| 34801 | 34822 | }, |
| 34802 | .Enum => switch (ty.zigTypeTag(mod)) { | |
| 34823 | .Enum => switch (ty.zigTypeTag(zcu)) { | |
| 34803 | 34824 | .EnumLiteral => {}, |
| 34804 | 34825 | .Enum => { |
| 34805 | if (!ty.eql(cur_ty, mod)) return generic_err; | |
| 34826 | if (!ty.eql(cur_ty, zcu)) return generic_err; | |
| 34806 | 34827 | }, |
| 34807 | 34828 | .Union => { |
| 34808 | const tag_ty = ty.unionTagTypeHypothetical(mod); | |
| 34809 | if (!tag_ty.eql(cur_ty, mod)) return generic_err; | |
| 34829 | const tag_ty = ty.unionTagTypeHypothetical(zcu); | |
| 34830 | if (!tag_ty.eql(cur_ty, zcu)) return generic_err; | |
| 34810 | 34831 | opt_cur_ty = ty; |
| 34811 | 34832 | cur_ty_idx = i; |
| 34812 | 34833 | }, |
| 34813 | 34834 | else => unreachable, |
| 34814 | 34835 | }, |
| 34815 | .Union => switch (ty.zigTypeTag(mod)) { | |
| 34836 | .Union => switch (ty.zigTypeTag(zcu)) { | |
| 34816 | 34837 | .EnumLiteral => {}, |
| 34817 | 34838 | .Enum => { |
| 34818 | const cur_tag_ty = cur_ty.unionTagTypeHypothetical(mod); | |
| 34819 | if (!ty.eql(cur_tag_ty, mod)) return generic_err; | |
| 34839 | const cur_tag_ty = cur_ty.unionTagTypeHypothetical(zcu); | |
| 34840 | if (!ty.eql(cur_tag_ty, zcu)) return generic_err; | |
| 34820 | 34841 | }, |
| 34821 | 34842 | .Union => { |
| 34822 | if (!ty.eql(cur_ty, mod)) return generic_err; | |
| 34843 | if (!ty.eql(cur_ty, zcu)) return generic_err; | |
| 34823 | 34844 | }, |
| 34824 | 34845 | else => unreachable, |
| 34825 | 34846 | }, |
| ... | ... | @@ -34832,7 +34853,7 @@ fn resolvePeerTypesInner( |
| 34832 | 34853 | .comptime_int => { |
| 34833 | 34854 | for (peer_tys, 0..) |opt_ty, i| { |
| 34834 | 34855 | const ty = opt_ty orelse continue; |
| 34835 | switch (ty.zigTypeTag(mod)) { | |
| 34856 | switch (ty.zigTypeTag(zcu)) { | |
| 34836 | 34857 | .ComptimeInt => {}, |
| 34837 | 34858 | else => return .{ .conflict = .{ |
| 34838 | 34859 | .peer_idx_a = strat_reason, |
| ... | ... | @@ -34846,7 +34867,7 @@ fn resolvePeerTypesInner( |
| 34846 | 34867 | .comptime_float => { |
| 34847 | 34868 | for (peer_tys, 0..) |opt_ty, i| { |
| 34848 | 34869 | const ty = opt_ty orelse continue; |
| 34849 | switch (ty.zigTypeTag(mod)) { | |
| 34870 | switch (ty.zigTypeTag(zcu)) { | |
| 34850 | 34871 | .ComptimeInt, .ComptimeFloat => {}, |
| 34851 | 34872 | else => return .{ .conflict = .{ |
| 34852 | 34873 | .peer_idx_a = strat_reason, |
| ... | ... | @@ -34868,11 +34889,11 @@ fn resolvePeerTypesInner( |
| 34868 | 34889 | const ty = opt_ty orelse continue; |
| 34869 | 34890 | const opt_val = ptr_opt_val.*; |
| 34870 | 34891 | |
| 34871 | const peer_tag = ty.zigTypeTag(mod); | |
| 34892 | const peer_tag = ty.zigTypeTag(zcu); | |
| 34872 | 34893 | switch (peer_tag) { |
| 34873 | 34894 | .ComptimeInt => { |
| 34874 | 34895 | // If the value is undefined, we can't refine to a fixed-width int |
| 34875 | if (opt_val == null or opt_val.?.isUndef(mod)) return .{ .conflict = .{ | |
| 34896 | if (opt_val == null or opt_val.?.isUndef(zcu)) return .{ .conflict = .{ | |
| 34876 | 34897 | .peer_idx_a = strat_reason, |
| 34877 | 34898 | .peer_idx_b = i, |
| 34878 | 34899 | } }; |
| ... | ... | @@ -34889,7 +34910,7 @@ fn resolvePeerTypesInner( |
| 34889 | 34910 | |
| 34890 | 34911 | if (opt_val != null) any_comptime_known = true; |
| 34891 | 34912 | |
| 34892 | const info = ty.intInfo(mod); | |
| 34913 | const info = ty.intInfo(zcu); | |
| 34893 | 34914 | |
| 34894 | 34915 | const idx_ptr = switch (info.signedness) { |
| 34895 | 34916 | .unsigned => &idx_unsigned, |
| ... | ... | @@ -34901,7 +34922,7 @@ fn resolvePeerTypesInner( |
| 34901 | 34922 | continue; |
| 34902 | 34923 | }; |
| 34903 | 34924 | |
| 34904 | const cur_info = peer_tys[largest_idx].?.intInfo(mod); | |
| 34925 | const cur_info = peer_tys[largest_idx].?.intInfo(zcu); | |
| 34905 | 34926 | if (info.bits > cur_info.bits) { |
| 34906 | 34927 | idx_ptr.* = i; |
| 34907 | 34928 | } |
| ... | ... | @@ -34915,8 +34936,8 @@ fn resolvePeerTypesInner( |
| 34915 | 34936 | return .{ .success = peer_tys[idx_signed.?].? }; |
| 34916 | 34937 | } |
| 34917 | 34938 | |
| 34918 | const unsigned_info = peer_tys[idx_unsigned.?].?.intInfo(mod); | |
| 34919 | const signed_info = peer_tys[idx_signed.?].?.intInfo(mod); | |
| 34939 | const unsigned_info = peer_tys[idx_unsigned.?].?.intInfo(zcu); | |
| 34940 | const signed_info = peer_tys[idx_signed.?].?.intInfo(zcu); | |
| 34920 | 34941 | if (signed_info.bits > unsigned_info.bits) { |
| 34921 | 34942 | return .{ .success = peer_tys[idx_signed.?].? }; |
| 34922 | 34943 | } |
| ... | ... | @@ -34948,7 +34969,7 @@ fn resolvePeerTypesInner( |
| 34948 | 34969 | |
| 34949 | 34970 | for (peer_tys, peer_vals, 0..) |opt_ty, opt_val, i| { |
| 34950 | 34971 | const ty = opt_ty orelse continue; |
| 34951 | switch (ty.zigTypeTag(mod)) { | |
| 34972 | switch (ty.zigTypeTag(zcu)) { | |
| 34952 | 34973 | .ComptimeFloat, .ComptimeInt => {}, |
| 34953 | 34974 | .Int => { |
| 34954 | 34975 | if (opt_val == null) return .{ .conflict = .{ |
| ... | ... | @@ -34958,7 +34979,7 @@ fn resolvePeerTypesInner( |
| 34958 | 34979 | }, |
| 34959 | 34980 | .Float => { |
| 34960 | 34981 | if (opt_cur_ty) |cur_ty| { |
| 34961 | if (cur_ty.eql(ty, mod)) continue; | |
| 34982 | if (cur_ty.eql(ty, zcu)) continue; | |
| 34962 | 34983 | // Recreate the type so we eliminate any c_longdouble |
| 34963 | 34984 | const bits = @max(cur_ty.floatBits(target), ty.floatBits(target)); |
| 34964 | 34985 | opt_cur_ty = switch (bits) { |
| ... | ... | @@ -34997,7 +35018,7 @@ fn resolvePeerTypesInner( |
| 34997 | 35018 | for (peer_tys, 0..) |opt_ty, i| { |
| 34998 | 35019 | const ty = opt_ty orelse continue; |
| 34999 | 35020 | |
| 35000 | if (!ty.isTupleOrAnonStruct(mod)) { | |
| 35021 | if (!ty.isTupleOrAnonStruct(zcu)) { | |
| 35001 | 35022 | return .{ .conflict = .{ |
| 35002 | 35023 | .peer_idx_a = strat_reason, |
| 35003 | 35024 | .peer_idx_b = i, |
| ... | ... | @@ -35006,8 +35027,8 @@ fn resolvePeerTypesInner( |
| 35006 | 35027 | |
| 35007 | 35028 | const first_idx = opt_first_idx orelse { |
| 35008 | 35029 | opt_first_idx = i; |
| 35009 | is_tuple = ty.isTuple(mod); | |
| 35010 | field_count = ty.structFieldCount(mod); | |
| 35030 | is_tuple = ty.isTuple(zcu); | |
| 35031 | field_count = ty.structFieldCount(zcu); | |
| 35011 | 35032 | if (!is_tuple) { |
| 35012 | 35033 | const names = ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip); |
| 35013 | 35034 | field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names); |
| ... | ... | @@ -35015,7 +35036,7 @@ fn resolvePeerTypesInner( |
| 35015 | 35036 | continue; |
| 35016 | 35037 | }; |
| 35017 | 35038 | |
| 35018 | if (ty.isTuple(mod) != is_tuple or ty.structFieldCount(mod) != field_count) { | |
| 35039 | if (ty.isTuple(zcu) != is_tuple or ty.structFieldCount(zcu) != field_count) { | |
| 35019 | 35040 | return .{ .conflict = .{ |
| 35020 | 35041 | .peer_idx_a = first_idx, |
| 35021 | 35042 | .peer_idx_b = i, |
| ... | ... | @@ -35025,7 +35046,7 @@ fn resolvePeerTypesInner( |
| 35025 | 35046 | if (!is_tuple) { |
| 35026 | 35047 | for (field_names, 0..) |expected, field_index_usize| { |
| 35027 | 35048 | const field_index: u32 = @intCast(field_index_usize); |
| 35028 | const actual = ty.structFieldName(field_index, mod).unwrap().?; | |
| 35049 | const actual = ty.structFieldName(field_index, zcu).unwrap().?; | |
| 35029 | 35050 | if (actual == expected) continue; |
| 35030 | 35051 | return .{ .conflict = .{ |
| 35031 | 35052 | .peer_idx_a = first_idx, |
| ... | ... | @@ -35052,7 +35073,7 @@ fn resolvePeerTypesInner( |
| 35052 | 35073 | peer_field_val.* = null; |
| 35053 | 35074 | continue; |
| 35054 | 35075 | }; |
| 35055 | peer_field_ty.* = ty.structFieldType(field_index, mod); | |
| 35076 | peer_field_ty.* = ty.structFieldType(field_index, zcu); | |
| 35056 | 35077 | peer_field_val.* = if (opt_val) |val| try val.fieldValue(pt, field_index) else null; |
| 35057 | 35078 | } |
| 35058 | 35079 | |
| ... | ... | @@ -35074,7 +35095,7 @@ fn resolvePeerTypesInner( |
| 35074 | 35095 | // Already-resolved types won't be referenced by the error so it's fine |
| 35075 | 35096 | // to leave them undefined. |
| 35076 | 35097 | const ty = opt_ty orelse continue; |
| 35077 | peer_field_ty.* = ty.structFieldType(field_index, mod); | |
| 35098 | peer_field_ty.* = ty.structFieldType(field_index, zcu); | |
| 35078 | 35099 | } |
| 35079 | 35100 | |
| 35080 | 35101 | return .{ .field_error = .{ |
| ... | ... | @@ -35111,7 +35132,7 @@ fn resolvePeerTypesInner( |
| 35111 | 35132 | comptime_val = coerced_val; |
| 35112 | 35133 | continue; |
| 35113 | 35134 | }; |
| 35114 | if (!coerced_val.eql(existing, Type.fromInterned(field_ty.*), mod)) { | |
| 35135 | if (!coerced_val.eql(existing, Type.fromInterned(field_ty.*), zcu)) { | |
| 35115 | 35136 | comptime_val = null; |
| 35116 | 35137 | break; |
| 35117 | 35138 | } |
| ... | ... | @@ -35120,7 +35141,7 @@ fn resolvePeerTypesInner( |
| 35120 | 35141 | field_val.* = if (comptime_val) |v| v.toIntern() else .none; |
| 35121 | 35142 | } |
| 35122 | 35143 | |
| 35123 | const final_ty = try ip.getAnonStructType(mod.gpa, pt.tid, .{ | |
| 35144 | const final_ty = try ip.getAnonStructType(zcu.gpa, pt.tid, .{ | |
| 35124 | 35145 | .types = field_types, |
| 35125 | 35146 | .names = if (is_tuple) &.{} else field_names, |
| 35126 | 35147 | .values = field_vals, |
| ... | ... | @@ -35135,7 +35156,7 @@ fn resolvePeerTypesInner( |
| 35135 | 35156 | for (peer_tys, 0..) |opt_ty, i| { |
| 35136 | 35157 | const ty = opt_ty orelse continue; |
| 35137 | 35158 | if (expect_ty) |expect| { |
| 35138 | if (!ty.eql(expect, mod)) return .{ .conflict = .{ | |
| 35159 | if (!ty.eql(expect, zcu)) return .{ .conflict = .{ | |
| 35139 | 35160 | .peer_idx_a = first_idx, |
| 35140 | 35161 | .peer_idx_b = i, |
| 35141 | 35162 | } }; |
| ... | ... | @@ -35186,22 +35207,22 @@ const ArrayLike = struct { |
| 35186 | 35207 | }; |
| 35187 | 35208 | fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { |
| 35188 | 35209 | const pt = sema.pt; |
| 35189 | const mod = pt.zcu; | |
| 35190 | return switch (ty.zigTypeTag(mod)) { | |
| 35210 | const zcu = pt.zcu; | |
| 35211 | return switch (ty.zigTypeTag(zcu)) { | |
| 35191 | 35212 | .Array => .{ |
| 35192 | .len = ty.arrayLen(mod), | |
| 35193 | .elem_ty = ty.childType(mod), | |
| 35213 | .len = ty.arrayLen(zcu), | |
| 35214 | .elem_ty = ty.childType(zcu), | |
| 35194 | 35215 | }, |
| 35195 | 35216 | .Struct => { |
| 35196 | const field_count = ty.structFieldCount(mod); | |
| 35217 | const field_count = ty.structFieldCount(zcu); | |
| 35197 | 35218 | if (field_count == 0) return .{ |
| 35198 | 35219 | .len = 0, |
| 35199 | 35220 | .elem_ty = Type.noreturn, |
| 35200 | 35221 | }; |
| 35201 | if (!ty.isTuple(mod)) return null; | |
| 35202 | const elem_ty = ty.structFieldType(0, mod); | |
| 35222 | if (!ty.isTuple(zcu)) return null; | |
| 35223 | const elem_ty = ty.structFieldType(0, zcu); | |
| 35203 | 35224 | for (1..field_count) |i| { |
| 35204 | if (!ty.structFieldType(i, mod).eql(elem_ty, mod)) { | |
| 35225 | if (!ty.structFieldType(i, zcu).eql(elem_ty, zcu)) { | |
| 35205 | 35226 | return null; |
| 35206 | 35227 | } |
| 35207 | 35228 | } |
| ... | ... | @@ -35216,8 +35237,8 @@ fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike { |
| 35216 | 35237 | |
| 35217 | 35238 | pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void { |
| 35218 | 35239 | const pt = sema.pt; |
| 35219 | const mod = pt.zcu; | |
| 35220 | const ip = &mod.intern_pool; | |
| 35240 | const zcu = pt.zcu; | |
| 35241 | const ip = &zcu.intern_pool; | |
| 35221 | 35242 | |
| 35222 | 35243 | if (sema.fn_ret_ty_ies) |ies| { |
| 35223 | 35244 | try sema.resolveInferredErrorSetPtr(block, src, ies); |
| ... | ... | @@ -35228,14 +35249,14 @@ pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void |
| 35228 | 35249 | |
| 35229 | 35250 | pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void { |
| 35230 | 35251 | const pt = sema.pt; |
| 35231 | const mod = pt.zcu; | |
| 35232 | const ip = &mod.intern_pool; | |
| 35233 | const fn_ty_info = mod.typeToFunc(fn_ty).?; | |
| 35252 | const zcu = pt.zcu; | |
| 35253 | const ip = &zcu.intern_pool; | |
| 35254 | const fn_ty_info = zcu.typeToFunc(fn_ty).?; | |
| 35234 | 35255 | |
| 35235 | 35256 | try Type.fromInterned(fn_ty_info.return_type).resolveFully(pt); |
| 35236 | 35257 | |
| 35237 | if (mod.comp.config.any_error_tracing and | |
| 35238 | Type.fromInterned(fn_ty_info.return_type).isError(mod)) | |
| 35258 | if (zcu.comp.config.any_error_tracing and | |
| 35259 | Type.fromInterned(fn_ty_info.return_type).isError(zcu)) | |
| 35239 | 35260 | { |
| 35240 | 35261 | // Ensure the type exists so that backends can assume that. |
| 35241 | 35262 | _ = try pt.getBuiltinType("StackTrace"); |
| ... | ... | @@ -35258,9 +35279,9 @@ pub fn resolveStructAlignment( |
| 35258 | 35279 | struct_type: InternPool.LoadedStructType, |
| 35259 | 35280 | ) SemaError!void { |
| 35260 | 35281 | const pt = sema.pt; |
| 35261 | const mod = pt.zcu; | |
| 35262 | const ip = &mod.intern_pool; | |
| 35263 | const target = mod.getTarget(); | |
| 35282 | const zcu = pt.zcu; | |
| 35283 | const ip = &zcu.intern_pool; | |
| 35284 | const target = zcu.getTarget(); | |
| 35264 | 35285 | |
| 35265 | 35286 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35266 | 35287 | |
| ... | ... | @@ -35286,13 +35307,14 @@ pub fn resolveStructAlignment( |
| 35286 | 35307 | |
| 35287 | 35308 | for (0..struct_type.field_types.len) |i| { |
| 35288 | 35309 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 35289 | if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty)) | |
| 35310 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) | |
| 35290 | 35311 | continue; |
| 35291 | const field_align = try pt.structFieldAlignmentAdvanced( | |
| 35312 | const field_align = try field_ty.structFieldAlignmentAdvanced( | |
| 35292 | 35313 | struct_type.fieldAlign(ip, i), |
| 35293 | field_ty, | |
| 35294 | 35314 | struct_type.layout, |
| 35295 | 35315 | .sema, |
| 35316 | pt.zcu, | |
| 35317 | pt.tid, | |
| 35296 | 35318 | ); |
| 35297 | 35319 | alignment = alignment.maxStrict(field_align); |
| 35298 | 35320 | } |
| ... | ... | @@ -35338,14 +35360,14 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35338 | 35360 | |
| 35339 | 35361 | for (aligns, sizes, 0..) |*field_align, *field_size, i| { |
| 35340 | 35362 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 35341 | if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty)) { | |
| 35363 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) { | |
| 35342 | 35364 | struct_type.offsets.get(ip)[i] = 0; |
| 35343 | 35365 | field_size.* = 0; |
| 35344 | 35366 | field_align.* = .none; |
| 35345 | 35367 | continue; |
| 35346 | 35368 | } |
| 35347 | 35369 | |
| 35348 | field_size.* = sema.typeAbiSize(field_ty) catch |err| switch (err) { | |
| 35370 | field_size.* = field_ty.abiSizeSema(pt) catch |err| switch (err) { | |
| 35349 | 35371 | error.AnalysisFail => { |
| 35350 | 35372 | const msg = sema.err orelse return err; |
| 35351 | 35373 | try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); |
| ... | ... | @@ -35353,16 +35375,17 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35353 | 35375 | }, |
| 35354 | 35376 | else => return err, |
| 35355 | 35377 | }; |
| 35356 | field_align.* = try pt.structFieldAlignmentAdvanced( | |
| 35378 | field_align.* = try field_ty.structFieldAlignmentAdvanced( | |
| 35357 | 35379 | struct_type.fieldAlign(ip, i), |
| 35358 | field_ty, | |
| 35359 | 35380 | struct_type.layout, |
| 35360 | 35381 | .sema, |
| 35382 | pt.zcu, | |
| 35383 | pt.tid, | |
| 35361 | 35384 | ); |
| 35362 | 35385 | big_align = big_align.maxStrict(field_align.*); |
| 35363 | 35386 | } |
| 35364 | 35387 | |
| 35365 | if (struct_type.flagsUnordered(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) { | |
| 35388 | if (struct_type.flagsUnordered(ip).assumed_runtime_bits and !(try ty.hasRuntimeBitsSema(pt))) { | |
| 35366 | 35389 | const msg = try sema.errMsg( |
| 35367 | 35390 | ty.srcLoc(zcu), |
| 35368 | 35391 | "struct layout depends on it having runtime bits", |
| ... | ... | @@ -35387,7 +35410,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35387 | 35410 | |
| 35388 | 35411 | for (runtime_order, 0..) |*ro, i| { |
| 35389 | 35412 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 35390 | if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty)) { | |
| 35413 | if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) { | |
| 35391 | 35414 | ro.* = .omitted; |
| 35392 | 35415 | } else { |
| 35393 | 35416 | ro.* = @enumFromInt(i); |
| ... | ... | @@ -35440,7 +35463,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35440 | 35463 | offset = offsets[i] + sizes[i]; |
| 35441 | 35464 | } |
| 35442 | 35465 | struct_type.setLayoutResolved(ip, @intCast(big_align.forward(offset)), big_align); |
| 35443 | _ = try sema.typeRequiresComptime(ty); | |
| 35466 | _ = try ty.comptimeOnlySema(pt); | |
| 35444 | 35467 | } |
| 35445 | 35468 | |
| 35446 | 35469 | fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructType) CompileError!void { |
| ... | ... | @@ -35488,7 +35511,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp |
| 35488 | 35511 | var accumulator: u64 = 0; |
| 35489 | 35512 | for (0..struct_type.field_types.len) |i| { |
| 35490 | 35513 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 35491 | accumulator += try field_ty.bitSizeAdvanced(pt, .sema); | |
| 35514 | accumulator += try field_ty.bitSizeSema(pt); | |
| 35492 | 35515 | } |
| 35493 | 35516 | break :blk accumulator; |
| 35494 | 35517 | }; |
| ... | ... | @@ -35543,17 +35566,17 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp |
| 35543 | 35566 | |
| 35544 | 35567 | fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void { |
| 35545 | 35568 | const pt = sema.pt; |
| 35546 | const mod = pt.zcu; | |
| 35569 | const zcu = pt.zcu; | |
| 35547 | 35570 | |
| 35548 | if (!backing_int_ty.isInt(mod)) { | |
| 35571 | if (!backing_int_ty.isInt(zcu)) { | |
| 35549 | 35572 | return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(pt)}); |
| 35550 | 35573 | } |
| 35551 | if (backing_int_ty.bitSize(pt) != fields_bit_sum) { | |
| 35574 | if (backing_int_ty.bitSize(zcu) != fields_bit_sum) { | |
| 35552 | 35575 | return sema.fail( |
| 35553 | 35576 | block, |
| 35554 | 35577 | src, |
| 35555 | 35578 | "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}", |
| 35556 | .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(pt), fields_bit_sum }, | |
| 35579 | .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(zcu), fields_bit_sum }, | |
| 35557 | 35580 | ); |
| 35558 | 35581 | } |
| 35559 | 35582 | } |
| ... | ... | @@ -35573,13 +35596,13 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 35573 | 35596 | |
| 35574 | 35597 | fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 35575 | 35598 | const pt = sema.pt; |
| 35576 | const mod = pt.zcu; | |
| 35577 | if (ty.zigTypeTag(mod) == .Pointer) { | |
| 35578 | switch (ty.ptrSize(mod)) { | |
| 35599 | const zcu = pt.zcu; | |
| 35600 | if (ty.zigTypeTag(zcu) == .Pointer) { | |
| 35601 | switch (ty.ptrSize(zcu)) { | |
| 35579 | 35602 | .Slice, .Many, .C => return, |
| 35580 | 35603 | .One => { |
| 35581 | const elem_ty = ty.childType(mod); | |
| 35582 | if (elem_ty.zigTypeTag(mod) == .Array) return; | |
| 35604 | const elem_ty = ty.childType(zcu); | |
| 35605 | if (elem_ty.zigTypeTag(zcu) == .Array) return; | |
| 35583 | 35606 | // TODO https://github.com/ziglang/zig/issues/15479 |
| 35584 | 35607 | // if (elem_ty.isTuple()) return; |
| 35585 | 35608 | }, |
| ... | ... | @@ -35601,7 +35624,8 @@ pub fn resolveUnionAlignment( |
| 35601 | 35624 | ty: Type, |
| 35602 | 35625 | union_type: InternPool.LoadedUnionType, |
| 35603 | 35626 | ) SemaError!void { |
| 35604 | const zcu = sema.pt.zcu; | |
| 35627 | const pt = sema.pt; | |
| 35628 | const zcu = pt.zcu; | |
| 35605 | 35629 | const ip = &zcu.intern_pool; |
| 35606 | 35630 | const target = zcu.getTarget(); |
| 35607 | 35631 | |
| ... | ... | @@ -35621,13 +35645,13 @@ pub fn resolveUnionAlignment( |
| 35621 | 35645 | var max_align: Alignment = .@"1"; |
| 35622 | 35646 | for (0..union_type.field_types.len) |field_index| { |
| 35623 | 35647 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); |
| 35624 | if (!(try sema.typeHasRuntimeBits(field_ty))) continue; | |
| 35648 | if (!(try field_ty.hasRuntimeBitsSema(pt))) continue; | |
| 35625 | 35649 | |
| 35626 | 35650 | const explicit_align = union_type.fieldAlign(ip, field_index); |
| 35627 | 35651 | const field_align = if (explicit_align != .none) |
| 35628 | 35652 | explicit_align |
| 35629 | 35653 | else |
| 35630 | try sema.typeAbiAlignment(field_ty); | |
| 35654 | try field_ty.abiAlignmentSema(sema.pt); | |
| 35631 | 35655 | |
| 35632 | 35656 | max_align = max_align.max(field_align); |
| 35633 | 35657 | } |
| ... | ... | @@ -35635,7 +35659,7 @@ pub fn resolveUnionAlignment( |
| 35635 | 35659 | union_type.setAlignment(ip, max_align); |
| 35636 | 35660 | } |
| 35637 | 35661 | |
| 35638 | /// This logic must be kept in sync with `Module.getUnionLayout`. | |
| 35662 | /// This logic must be kept in sync with `Zcu.getUnionLayout`. | |
| 35639 | 35663 | pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35640 | 35664 | const pt = sema.pt; |
| 35641 | 35665 | const ip = &pt.zcu.intern_pool; |
| ... | ... | @@ -35670,9 +35694,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35670 | 35694 | for (0..union_type.field_types.len) |field_index| { |
| 35671 | 35695 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); |
| 35672 | 35696 | |
| 35673 | if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(pt.zcu) == .NoReturn) continue; // TODO: should this affect alignment? | |
| 35697 | if (try field_ty.comptimeOnlySema(pt) or field_ty.zigTypeTag(pt.zcu) == .NoReturn) continue; // TODO: should this affect alignment? | |
| 35674 | 35698 | |
| 35675 | max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) { | |
| 35699 | max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) { | |
| 35676 | 35700 | error.AnalysisFail => { |
| 35677 | 35701 | const msg = sema.err orelse return err; |
| 35678 | 35702 | try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{}); |
| ... | ... | @@ -35685,17 +35709,17 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35685 | 35709 | const field_align = if (explicit_align != .none) |
| 35686 | 35710 | explicit_align |
| 35687 | 35711 | else |
| 35688 | try sema.typeAbiAlignment(field_ty); | |
| 35712 | try field_ty.abiAlignmentSema(pt); | |
| 35689 | 35713 | |
| 35690 | 35714 | max_align = max_align.max(field_align); |
| 35691 | 35715 | } |
| 35692 | 35716 | |
| 35693 | 35717 | const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and |
| 35694 | try sema.typeHasRuntimeBits(Type.fromInterned(union_type.enum_tag_ty)); | |
| 35718 | try Type.fromInterned(union_type.enum_tag_ty).hasRuntimeBitsSema(pt); | |
| 35695 | 35719 | const size, const alignment, const padding = if (has_runtime_tag) layout: { |
| 35696 | 35720 | const enum_tag_type = Type.fromInterned(union_type.enum_tag_ty); |
| 35697 | const tag_align = try sema.typeAbiAlignment(enum_tag_type); | |
| 35698 | const tag_size = try sema.typeAbiSize(enum_tag_type); | |
| 35721 | const tag_align = try enum_tag_type.abiAlignmentSema(pt); | |
| 35722 | const tag_size = try enum_tag_type.abiSizeSema(pt); | |
| 35699 | 35723 | |
| 35700 | 35724 | // Put the tag before or after the payload depending on which one's |
| 35701 | 35725 | // alignment is greater. |
| ... | ... | @@ -35727,7 +35751,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35727 | 35751 | |
| 35728 | 35752 | union_type.setHaveLayout(ip, @intCast(size), padding, alignment); |
| 35729 | 35753 | |
| 35730 | if (union_type.flagsUnordered(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) { | |
| 35754 | if (union_type.flagsUnordered(ip).assumed_runtime_bits and !(try ty.hasRuntimeBitsSema(pt))) { | |
| 35731 | 35755 | const msg = try sema.errMsg( |
| 35732 | 35756 | ty.srcLoc(pt.zcu), |
| 35733 | 35757 | "union layout depends on it having runtime bits", |
| ... | ... | @@ -35746,6 +35770,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35746 | 35770 | ); |
| 35747 | 35771 | return sema.failWithOwnedErrorMsg(null, msg); |
| 35748 | 35772 | } |
| 35773 | _ = try ty.comptimeOnlySema(pt); | |
| 35749 | 35774 | } |
| 35750 | 35775 | |
| 35751 | 35776 | /// Returns `error.AnalysisFail` if any of the types (recursively) failed to |
| ... | ... | @@ -35754,9 +35779,9 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { |
| 35754 | 35779 | try sema.resolveStructLayout(ty); |
| 35755 | 35780 | |
| 35756 | 35781 | const pt = sema.pt; |
| 35757 | const mod = pt.zcu; | |
| 35758 | const ip = &mod.intern_pool; | |
| 35759 | const struct_type = mod.typeToStruct(ty).?; | |
| 35782 | const zcu = pt.zcu; | |
| 35783 | const ip = &zcu.intern_pool; | |
| 35784 | const struct_type = zcu.typeToStruct(ty).?; | |
| 35760 | 35785 | |
| 35761 | 35786 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35762 | 35787 | |
| ... | ... | @@ -35777,9 +35802,9 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { |
| 35777 | 35802 | try sema.resolveUnionLayout(ty); |
| 35778 | 35803 | |
| 35779 | 35804 | const pt = sema.pt; |
| 35780 | const mod = pt.zcu; | |
| 35781 | const ip = &mod.intern_pool; | |
| 35782 | const union_obj = mod.typeToUnion(ty).?; | |
| 35805 | const zcu = pt.zcu; | |
| 35806 | const ip = &zcu.intern_pool; | |
| 35807 | const union_obj = zcu.typeToUnion(ty).?; | |
| 35783 | 35808 | |
| 35784 | 35809 | assert(sema.owner.unwrap().cau == union_obj.cau); |
| 35785 | 35810 | |
| ... | ... | @@ -35804,7 +35829,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { |
| 35804 | 35829 | } |
| 35805 | 35830 | |
| 35806 | 35831 | // And let's not forget comptime-only status. |
| 35807 | _ = try sema.typeRequiresComptime(ty); | |
| 35832 | _ = try ty.comptimeOnlySema(pt); | |
| 35808 | 35833 | } |
| 35809 | 35834 | |
| 35810 | 35835 | pub fn resolveTypeFieldsStruct( |
| ... | ... | @@ -35950,7 +35975,7 @@ fn resolveInferredErrorSet( |
| 35950 | 35975 | try pt.ensureFuncBodyAnalyzed(func_index); |
| 35951 | 35976 | } |
| 35952 | 35977 | |
| 35953 | // This will now have been resolved by the logic at the end of `Module.analyzeFnBody` | |
| 35978 | // This will now have been resolved by the logic at the end of `Zcu.analyzeFnBody` | |
| 35954 | 35979 | // which calls `resolveInferredErrorSetPtr`. |
| 35955 | 35980 | const final_resolved_ty = func.resolvedErrorSetUnordered(ip); |
| 35956 | 35981 | assert(final_resolved_ty != .none); |
| ... | ... | @@ -35997,9 +36022,9 @@ fn resolveAdHocInferredErrorSet( |
| 35997 | 36022 | value: InternPool.Index, |
| 35998 | 36023 | ) CompileError!InternPool.Index { |
| 35999 | 36024 | const pt = sema.pt; |
| 36000 | const mod = pt.zcu; | |
| 36025 | const zcu = pt.zcu; | |
| 36001 | 36026 | const gpa = sema.gpa; |
| 36002 | const ip = &mod.intern_pool; | |
| 36027 | const ip = &zcu.intern_pool; | |
| 36003 | 36028 | const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value)); |
| 36004 | 36029 | if (new_ty == .none) return value; |
| 36005 | 36030 | return ip.getCoerced(gpa, pt.tid, value, new_ty); |
| ... | ... | @@ -36013,8 +36038,8 @@ fn resolveAdHocInferredErrorSetTy( |
| 36013 | 36038 | ) CompileError!InternPool.Index { |
| 36014 | 36039 | const ies = sema.fn_ret_ty_ies orelse return .none; |
| 36015 | 36040 | const pt = sema.pt; |
| 36016 | const mod = pt.zcu; | |
| 36017 | const ip = &mod.intern_pool; | |
| 36041 | const zcu = pt.zcu; | |
| 36042 | const ip = &zcu.intern_pool; | |
| 36018 | 36043 | const error_union_info = switch (ip.indexToKey(ty)) { |
| 36019 | 36044 | .error_union_type => |x| x, |
| 36020 | 36045 | else => return .none, |
| ... | ... | @@ -36037,8 +36062,8 @@ fn resolveInferredErrorSetTy( |
| 36037 | 36062 | ty: InternPool.Index, |
| 36038 | 36063 | ) CompileError!InternPool.Index { |
| 36039 | 36064 | const pt = sema.pt; |
| 36040 | const mod = pt.zcu; | |
| 36041 | const ip = &mod.intern_pool; | |
| 36065 | const zcu = pt.zcu; | |
| 36066 | const ip = &zcu.intern_pool; | |
| 36042 | 36067 | if (ty == .anyerror_type) return ty; |
| 36043 | 36068 | switch (ip.indexToKey(ty)) { |
| 36044 | 36069 | .error_set_type => return ty, |
| ... | ... | @@ -36845,9 +36870,9 @@ fn generateUnionTagTypeNumbered( |
| 36845 | 36870 | union_name: InternPool.NullTerminatedString, |
| 36846 | 36871 | ) !InternPool.Index { |
| 36847 | 36872 | const pt = sema.pt; |
| 36848 | const mod = pt.zcu; | |
| 36873 | const zcu = pt.zcu; | |
| 36849 | 36874 | const gpa = sema.gpa; |
| 36850 | const ip = &mod.intern_pool; | |
| 36875 | const ip = &zcu.intern_pool; | |
| 36851 | 36876 | |
| 36852 | 36877 | const name = try ip.getOrPutStringFmt( |
| 36853 | 36878 | gpa, |
| ... | ... | @@ -36881,8 +36906,8 @@ fn generateUnionTagTypeSimple( |
| 36881 | 36906 | union_name: InternPool.NullTerminatedString, |
| 36882 | 36907 | ) !InternPool.Index { |
| 36883 | 36908 | const pt = sema.pt; |
| 36884 | const mod = pt.zcu; | |
| 36885 | const ip = &mod.intern_pool; | |
| 36909 | const zcu = pt.zcu; | |
| 36910 | const ip = &zcu.intern_pool; | |
| 36886 | 36911 | const gpa = sema.gpa; |
| 36887 | 36912 | |
| 36888 | 36913 | const name = try ip.getOrPutStringFmt( |
| ... | ... | @@ -37192,7 +37217,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 37192 | 37217 | return null; |
| 37193 | 37218 | }, |
| 37194 | 37219 | .auto, .explicit => { |
| 37195 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null; | |
| 37220 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null; | |
| 37196 | 37221 | |
| 37197 | 37222 | return Value.fromInterned(switch (enum_type.names.len) { |
| 37198 | 37223 | 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }), |
| ... | ... | @@ -37279,7 +37304,7 @@ fn analyzeComptimeAlloc( |
| 37279 | 37304 | alignment: Alignment, |
| 37280 | 37305 | ) CompileError!Air.Inst.Ref { |
| 37281 | 37306 | const pt = sema.pt; |
| 37282 | const mod = pt.zcu; | |
| 37307 | const zcu = pt.zcu; | |
| 37283 | 37308 | |
| 37284 | 37309 | // Needed to make an anon decl with type `var_type` (the `finish()` call below). |
| 37285 | 37310 | _ = try sema.typeHasOnePossibleValue(var_type); |
| ... | ... | @@ -37288,7 +37313,7 @@ fn analyzeComptimeAlloc( |
| 37288 | 37313 | .child = var_type.toIntern(), |
| 37289 | 37314 | .flags = .{ |
| 37290 | 37315 | .alignment = alignment, |
| 37291 | .address_space = target_util.defaultAddressSpace(mod.getTarget(), .global_constant), | |
| 37316 | .address_space = target_util.defaultAddressSpace(zcu.getTarget(), .global_constant), | |
| 37292 | 37317 | }, |
| 37293 | 37318 | }); |
| 37294 | 37319 | |
| ... | ... | @@ -37338,13 +37363,13 @@ pub fn analyzeAsAddressSpace( |
| 37338 | 37363 | ctx: AddressSpaceContext, |
| 37339 | 37364 | ) !std.builtin.AddressSpace { |
| 37340 | 37365 | const pt = sema.pt; |
| 37341 | const mod = pt.zcu; | |
| 37366 | const zcu = pt.zcu; | |
| 37342 | 37367 | const addrspace_ty = try pt.getBuiltinType("AddressSpace"); |
| 37343 | 37368 | const coerced = try sema.coerce(block, addrspace_ty, air_ref, src); |
| 37344 | 37369 | const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ |
| 37345 | 37370 | .needed_comptime_reason = "address space must be comptime-known", |
| 37346 | 37371 | }); |
| 37347 | const address_space = mod.toEnum(std.builtin.AddressSpace, addrspace_val); | |
| 37372 | const address_space = zcu.toEnum(std.builtin.AddressSpace, addrspace_val); | |
| 37348 | 37373 | const target = pt.zcu.getTarget(); |
| 37349 | 37374 | const arch = target.cpu.arch; |
| 37350 | 37375 | |
| ... | ... | @@ -37446,13 +37471,13 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError |
| 37446 | 37471 | /// This logic must be kept in sync with `Type.isPtrLikeOptional`. |
| 37447 | 37472 | fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 37448 | 37473 | const pt = sema.pt; |
| 37449 | const mod = pt.zcu; | |
| 37450 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 37474 | const zcu = pt.zcu; | |
| 37475 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 37451 | 37476 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 37452 | 37477 | .One, .Many, .C => ty, |
| 37453 | 37478 | .Slice => null, |
| 37454 | 37479 | }, |
| 37455 | .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) { | |
| 37480 | .opt_type => |opt_child| switch (zcu.intern_pool.indexToKey(opt_child)) { | |
| 37456 | 37481 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 37457 | 37482 | .Slice, .C => null, |
| 37458 | 37483 | .Many, .One => { |
| ... | ... | @@ -37473,33 +37498,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 37473 | 37498 | }; |
| 37474 | 37499 | } |
| 37475 | 37500 | |
| 37476 | /// `generic_poison` will return false. | |
| 37477 | /// May return false negatives when structs and unions are having their field types resolved. | |
| 37478 | pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool { | |
| 37479 | return ty.comptimeOnlyAdvanced(sema.pt, .sema); | |
| 37480 | } | |
| 37481 | ||
| 37482 | pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool { | |
| 37483 | return ty.hasRuntimeBitsAdvanced(sema.pt, false, .sema) catch |err| switch (err) { | |
| 37484 | error.NeedLazy => unreachable, | |
| 37485 | else => |e| return e, | |
| 37486 | }; | |
| 37487 | } | |
| 37488 | ||
| 37489 | pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 { | |
| 37490 | const pt = sema.pt; | |
| 37491 | try ty.resolveLayout(pt); | |
| 37492 | return ty.abiSize(pt); | |
| 37493 | } | |
| 37494 | ||
| 37495 | pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment { | |
| 37496 | return (try ty.abiAlignmentAdvanced(sema.pt, .sema)).scalar; | |
| 37497 | } | |
| 37498 | ||
| 37499 | pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool { | |
| 37500 | return ty.fnHasRuntimeBitsAdvanced(sema.pt, .sema); | |
| 37501 | } | |
| 37502 | ||
| 37503 | 37501 | fn unionFieldIndex( |
| 37504 | 37502 | sema: *Sema, |
| 37505 | 37503 | block: *Block, |
| ... | ... | @@ -37508,10 +37506,10 @@ fn unionFieldIndex( |
| 37508 | 37506 | field_src: LazySrcLoc, |
| 37509 | 37507 | ) !u32 { |
| 37510 | 37508 | const pt = sema.pt; |
| 37511 | const mod = pt.zcu; | |
| 37512 | const ip = &mod.intern_pool; | |
| 37509 | const zcu = pt.zcu; | |
| 37510 | const ip = &zcu.intern_pool; | |
| 37513 | 37511 | try union_ty.resolveFields(pt); |
| 37514 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 37512 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 37515 | 37513 | const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse |
| 37516 | 37514 | return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name); |
| 37517 | 37515 | return @intCast(field_index); |
| ... | ... | @@ -37525,13 +37523,13 @@ fn structFieldIndex( |
| 37525 | 37523 | field_src: LazySrcLoc, |
| 37526 | 37524 | ) !u32 { |
| 37527 | 37525 | const pt = sema.pt; |
| 37528 | const mod = pt.zcu; | |
| 37529 | const ip = &mod.intern_pool; | |
| 37526 | const zcu = pt.zcu; | |
| 37527 | const ip = &zcu.intern_pool; | |
| 37530 | 37528 | try struct_ty.resolveFields(pt); |
| 37531 | if (struct_ty.isAnonStruct(mod)) { | |
| 37529 | if (struct_ty.isAnonStruct(zcu)) { | |
| 37532 | 37530 | return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src); |
| 37533 | 37531 | } else { |
| 37534 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 37532 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 37535 | 37533 | return struct_type.nameIndex(ip, field_name) orelse |
| 37536 | 37534 | return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name); |
| 37537 | 37535 | } |
| ... | ... | @@ -37545,8 +37543,8 @@ fn anonStructFieldIndex( |
| 37545 | 37543 | field_src: LazySrcLoc, |
| 37546 | 37544 | ) !u32 { |
| 37547 | 37545 | const pt = sema.pt; |
| 37548 | const mod = pt.zcu; | |
| 37549 | const ip = &mod.intern_pool; | |
| 37546 | const zcu = pt.zcu; | |
| 37547 | const ip = &zcu.intern_pool; | |
| 37550 | 37548 | switch (ip.indexToKey(struct_ty.toIntern())) { |
| 37551 | 37549 | .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| { |
| 37552 | 37550 | if (name == field_name) return @intCast(i); |
| ... | ... | @@ -37583,10 +37581,10 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) |
| 37583 | 37581 | |
| 37584 | 37582 | fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize) !Value { |
| 37585 | 37583 | const pt = sema.pt; |
| 37586 | const mod = pt.zcu; | |
| 37587 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 37588 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 37589 | const scalar_ty = ty.scalarType(mod); | |
| 37584 | const zcu = pt.zcu; | |
| 37585 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 37586 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 37587 | const scalar_ty = ty.scalarType(zcu); | |
| 37590 | 37588 | for (result_data, 0..) |*scalar, i| { |
| 37591 | 37589 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37592 | 37590 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -37611,15 +37609,15 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value { |
| 37611 | 37609 | const pt = sema.pt; |
| 37612 | 37610 | if (scalar_ty.toIntern() != .comptime_int_type) { |
| 37613 | 37611 | const res = try sema.intAddWithOverflowScalar(lhs, rhs, scalar_ty); |
| 37614 | if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow; | |
| 37612 | if (res.overflow_bit.compareAllWithZero(.neq, pt.zcu)) return error.Overflow; | |
| 37615 | 37613 | return res.wrapped_result; |
| 37616 | 37614 | } |
| 37617 | 37615 | // TODO is this a performance issue? maybe we should try the operation without |
| 37618 | 37616 | // resorting to BigInt first. |
| 37619 | 37617 | var lhs_space: Value.BigIntSpace = undefined; |
| 37620 | 37618 | var rhs_space: Value.BigIntSpace = undefined; |
| 37621 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); | |
| 37622 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); | |
| 37619 | const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt); | |
| 37620 | const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt); | |
| 37623 | 37621 | const limbs = try sema.arena.alloc( |
| 37624 | 37622 | std.math.big.Limb, |
| 37625 | 37623 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| ... | ... | @@ -37637,10 +37635,10 @@ fn numberAddWrapScalar( |
| 37637 | 37635 | ty: Type, |
| 37638 | 37636 | ) !Value { |
| 37639 | 37637 | const pt = sema.pt; |
| 37640 | const mod = pt.zcu; | |
| 37641 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty); | |
| 37638 | const zcu = pt.zcu; | |
| 37639 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return pt.undefValue(ty); | |
| 37642 | 37640 | |
| 37643 | if (ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 37641 | if (ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 37644 | 37642 | return sema.intAdd(lhs, rhs, ty, undefined); |
| 37645 | 37643 | } |
| 37646 | 37644 | |
| ... | ... | @@ -37701,17 +37699,18 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi |
| 37701 | 37699 | |
| 37702 | 37700 | fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value { |
| 37703 | 37701 | const pt = sema.pt; |
| 37702 | const zcu = pt.zcu; | |
| 37704 | 37703 | if (scalar_ty.toIntern() != .comptime_int_type) { |
| 37705 | 37704 | const res = try sema.intSubWithOverflowScalar(lhs, rhs, scalar_ty); |
| 37706 | if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow; | |
| 37705 | if (res.overflow_bit.compareAllWithZero(.neq, zcu)) return error.Overflow; | |
| 37707 | 37706 | return res.wrapped_result; |
| 37708 | 37707 | } |
| 37709 | 37708 | // TODO is this a performance issue? maybe we should try the operation without |
| 37710 | 37709 | // resorting to BigInt first. |
| 37711 | 37710 | var lhs_space: Value.BigIntSpace = undefined; |
| 37712 | 37711 | var rhs_space: Value.BigIntSpace = undefined; |
| 37713 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); | |
| 37714 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); | |
| 37712 | const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt); | |
| 37713 | const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt); | |
| 37715 | 37714 | const limbs = try sema.arena.alloc( |
| 37716 | 37715 | std.math.big.Limb, |
| 37717 | 37716 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| ... | ... | @@ -37729,10 +37728,10 @@ fn numberSubWrapScalar( |
| 37729 | 37728 | ty: Type, |
| 37730 | 37729 | ) !Value { |
| 37731 | 37730 | const pt = sema.pt; |
| 37732 | const mod = pt.zcu; | |
| 37733 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return pt.undefValue(ty); | |
| 37731 | const zcu = pt.zcu; | |
| 37732 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return pt.undefValue(ty); | |
| 37734 | 37733 | |
| 37735 | if (ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 37734 | if (ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 37736 | 37735 | return sema.intSub(lhs, rhs, ty, undefined); |
| 37737 | 37736 | } |
| 37738 | 37737 | |
| ... | ... | @@ -37751,12 +37750,12 @@ fn intSubWithOverflow( |
| 37751 | 37750 | ty: Type, |
| 37752 | 37751 | ) !Value.OverflowArithmeticResult { |
| 37753 | 37752 | const pt = sema.pt; |
| 37754 | const mod = pt.zcu; | |
| 37755 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 37756 | const vec_len = ty.vectorLen(mod); | |
| 37753 | const zcu = pt.zcu; | |
| 37754 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 37755 | const vec_len = ty.vectorLen(zcu); | |
| 37757 | 37756 | const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 37758 | 37757 | const result_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 37759 | const scalar_ty = ty.scalarType(mod); | |
| 37758 | const scalar_ty = ty.scalarType(zcu); | |
| 37760 | 37759 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 37761 | 37760 | const lhs_elem = try lhs.elemValue(pt, i); |
| 37762 | 37761 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -37785,10 +37784,10 @@ fn intSubWithOverflowScalar( |
| 37785 | 37784 | ty: Type, |
| 37786 | 37785 | ) !Value.OverflowArithmeticResult { |
| 37787 | 37786 | const pt = sema.pt; |
| 37788 | const mod = pt.zcu; | |
| 37789 | const info = ty.intInfo(mod); | |
| 37787 | const zcu = pt.zcu; | |
| 37788 | const info = ty.intInfo(zcu); | |
| 37790 | 37789 | |
| 37791 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { | |
| 37790 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) { | |
| 37792 | 37791 | return .{ |
| 37793 | 37792 | .overflow_bit = try pt.undefValue(Type.u1), |
| 37794 | 37793 | .wrapped_result = try pt.undefValue(ty), |
| ... | ... | @@ -37797,8 +37796,8 @@ fn intSubWithOverflowScalar( |
| 37797 | 37796 | |
| 37798 | 37797 | var lhs_space: Value.BigIntSpace = undefined; |
| 37799 | 37798 | var rhs_space: Value.BigIntSpace = undefined; |
| 37800 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); | |
| 37801 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); | |
| 37799 | const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt); | |
| 37800 | const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt); | |
| 37802 | 37801 | const limbs = try sema.arena.alloc( |
| 37803 | 37802 | std.math.big.Limb, |
| 37804 | 37803 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| ... | ... | @@ -37824,12 +37823,12 @@ fn intFromFloat( |
| 37824 | 37823 | mode: IntFromFloatMode, |
| 37825 | 37824 | ) CompileError!Value { |
| 37826 | 37825 | const pt = sema.pt; |
| 37827 | const mod = pt.zcu; | |
| 37828 | if (float_ty.zigTypeTag(mod) == .Vector) { | |
| 37829 | const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod)); | |
| 37826 | const zcu = pt.zcu; | |
| 37827 | if (float_ty.zigTypeTag(zcu) == .Vector) { | |
| 37828 | const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(zcu)); | |
| 37830 | 37829 | for (result_data, 0..) |*scalar, i| { |
| 37831 | 37830 | const elem_val = try val.elemValue(pt, i); |
| 37832 | scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern(); | |
| 37831 | scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(zcu), mode)).toIntern(); | |
| 37833 | 37832 | } |
| 37834 | 37833 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 37835 | 37834 | .ty = int_ty.toIntern(), |
| ... | ... | @@ -37873,18 +37872,18 @@ fn intFromFloatScalar( |
| 37873 | 37872 | mode: IntFromFloatMode, |
| 37874 | 37873 | ) CompileError!Value { |
| 37875 | 37874 | const pt = sema.pt; |
| 37876 | const mod = pt.zcu; | |
| 37875 | const zcu = pt.zcu; | |
| 37877 | 37876 | |
| 37878 | if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src); | |
| 37877 | if (val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src); | |
| 37879 | 37878 | |
| 37880 | if (mode == .exact and val.floatHasFraction(mod)) return sema.fail( | |
| 37879 | if (mode == .exact and val.floatHasFraction(zcu)) return sema.fail( | |
| 37881 | 37880 | block, |
| 37882 | 37881 | src, |
| 37883 | 37882 | "fractional component prevents float value '{}' from coercion to type '{}'", |
| 37884 | 37883 | .{ val.fmtValueSema(pt, sema), int_ty.fmt(pt) }, |
| 37885 | 37884 | ); |
| 37886 | 37885 | |
| 37887 | const float = val.toFloat(f128, pt); | |
| 37886 | const float = val.toFloat(f128, zcu); | |
| 37888 | 37887 | if (std.math.isNan(float)) { |
| 37889 | 37888 | return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{ |
| 37890 | 37889 | int_ty.fmt(pt), |
| ... | ... | @@ -37920,15 +37919,15 @@ fn intFitsInType( |
| 37920 | 37919 | vector_index: ?*usize, |
| 37921 | 37920 | ) CompileError!bool { |
| 37922 | 37921 | const pt = sema.pt; |
| 37923 | const mod = pt.zcu; | |
| 37922 | const zcu = pt.zcu; | |
| 37924 | 37923 | if (ty.toIntern() == .comptime_int_type) return true; |
| 37925 | const info = ty.intInfo(mod); | |
| 37924 | const info = ty.intInfo(zcu); | |
| 37926 | 37925 | switch (val.toIntern()) { |
| 37927 | 37926 | .zero_usize, .zero_u8 => return true, |
| 37928 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 37927 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 37929 | 37928 | .undef => return true, |
| 37930 | 37929 | .variable, .@"extern", .func, .ptr => { |
| 37931 | const target = mod.getTarget(); | |
| 37930 | const target = zcu.getTarget(); | |
| 37932 | 37931 | const ptr_bits = target.ptrBitWidth(); |
| 37933 | 37932 | return switch (info.signedness) { |
| 37934 | 37933 | .signed => info.bits > ptr_bits, |
| ... | ... | @@ -37945,7 +37944,7 @@ fn intFitsInType( |
| 37945 | 37944 | const max_needed_bits = @as(u16, 16) + @intFromBool(info.signedness == .signed); |
| 37946 | 37945 | // If it is u16 or bigger we know the alignment fits without resolving it. |
| 37947 | 37946 | if (info.bits >= max_needed_bits) return true; |
| 37948 | const x = try sema.typeAbiAlignment(Type.fromInterned(lazy_ty)); | |
| 37947 | const x = try Type.fromInterned(lazy_ty).abiAlignmentSema(pt); | |
| 37949 | 37948 | if (x == .none) return true; |
| 37950 | 37949 | const actual_needed_bits = @as(usize, x.toLog2Units()) + 1 + @intFromBool(info.signedness == .signed); |
| 37951 | 37950 | return info.bits >= actual_needed_bits; |
| ... | ... | @@ -37954,16 +37953,16 @@ fn intFitsInType( |
| 37954 | 37953 | const max_needed_bits = @as(u16, 64) + @intFromBool(info.signedness == .signed); |
| 37955 | 37954 | // If it is u64 or bigger we know the size fits without resolving it. |
| 37956 | 37955 | if (info.bits >= max_needed_bits) return true; |
| 37957 | const x = try sema.typeAbiSize(Type.fromInterned(lazy_ty)); | |
| 37956 | const x = try Type.fromInterned(lazy_ty).abiSizeSema(pt); | |
| 37958 | 37957 | if (x == 0) return true; |
| 37959 | 37958 | const actual_needed_bits = std.math.log2(x) + 1 + @intFromBool(info.signedness == .signed); |
| 37960 | 37959 | return info.bits >= actual_needed_bits; |
| 37961 | 37960 | }, |
| 37962 | 37961 | }, |
| 37963 | 37962 | .aggregate => |aggregate| { |
| 37964 | assert(ty.zigTypeTag(mod) == .Vector); | |
| 37963 | assert(ty.zigTypeTag(zcu) == .Vector); | |
| 37965 | 37964 | return switch (aggregate.storage) { |
| 37966 | .bytes => |bytes| for (bytes.toSlice(ty.vectorLen(mod), &mod.intern_pool), 0..) |byte, i| { | |
| 37965 | .bytes => |bytes| for (bytes.toSlice(ty.vectorLen(zcu), &zcu.intern_pool), 0..) |byte, i| { | |
| 37967 | 37966 | if (byte == 0) continue; |
| 37968 | 37967 | const actual_needed_bits = std.math.log2(byte) + 1 + @intFromBool(info.signedness == .signed); |
| 37969 | 37968 | if (info.bits >= actual_needed_bits) continue; |
| ... | ... | @@ -37975,7 +37974,7 @@ fn intFitsInType( |
| 37975 | 37974 | .elems => |elems| elems, |
| 37976 | 37975 | .repeated_elem => |elem| @as(*const [1]InternPool.Index, &elem), |
| 37977 | 37976 | }, 0..) |elem, i| { |
| 37978 | if (try sema.intFitsInType(Value.fromInterned(elem), ty.scalarType(mod), null)) continue; | |
| 37977 | if (try sema.intFitsInType(Value.fromInterned(elem), ty.scalarType(zcu), null)) continue; | |
| 37979 | 37978 | if (vector_index) |vi| vi.* = i; |
| 37980 | 37979 | break false; |
| 37981 | 37980 | } else true, |
| ... | ... | @@ -37997,15 +37996,15 @@ fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool { |
| 37997 | 37996 | /// Asserts the type is an enum. |
| 37998 | 37997 | fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool { |
| 37999 | 37998 | const pt = sema.pt; |
| 38000 | const mod = pt.zcu; | |
| 38001 | const enum_type = mod.intern_pool.loadEnumType(ty.toIntern()); | |
| 37999 | const zcu = pt.zcu; | |
| 38000 | const enum_type = zcu.intern_pool.loadEnumType(ty.toIntern()); | |
| 38002 | 38001 | assert(enum_type.tag_mode != .nonexhaustive); |
| 38003 | 38002 | // The `tagValueIndex` function call below relies on the type being the integer tag type. |
| 38004 | 38003 | // `getCoerced` assumes the value will fit the new type. |
| 38005 | 38004 | if (!(try sema.intFitsInType(int, Type.fromInterned(enum_type.tag_ty), null))) return false; |
| 38006 | 38005 | const int_coerced = try pt.getCoerced(int, Type.fromInterned(enum_type.tag_ty)); |
| 38007 | 38006 | |
| 38008 | return enum_type.tagValueIndex(&mod.intern_pool, int_coerced.toIntern()) != null; | |
| 38007 | return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null; | |
| 38009 | 38008 | } |
| 38010 | 38009 | |
| 38011 | 38010 | fn intAddWithOverflow( |
| ... | ... | @@ -38015,12 +38014,12 @@ fn intAddWithOverflow( |
| 38015 | 38014 | ty: Type, |
| 38016 | 38015 | ) !Value.OverflowArithmeticResult { |
| 38017 | 38016 | const pt = sema.pt; |
| 38018 | const mod = pt.zcu; | |
| 38019 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 38020 | const vec_len = ty.vectorLen(mod); | |
| 38017 | const zcu = pt.zcu; | |
| 38018 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 38019 | const vec_len = ty.vectorLen(zcu); | |
| 38021 | 38020 | const overflowed_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 38022 | 38021 | const result_data = try sema.arena.alloc(InternPool.Index, vec_len); |
| 38023 | const scalar_ty = ty.scalarType(mod); | |
| 38022 | const scalar_ty = ty.scalarType(zcu); | |
| 38024 | 38023 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 38025 | 38024 | const lhs_elem = try lhs.elemValue(pt, i); |
| 38026 | 38025 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -38049,10 +38048,10 @@ fn intAddWithOverflowScalar( |
| 38049 | 38048 | ty: Type, |
| 38050 | 38049 | ) !Value.OverflowArithmeticResult { |
| 38051 | 38050 | const pt = sema.pt; |
| 38052 | const mod = pt.zcu; | |
| 38053 | const info = ty.intInfo(mod); | |
| 38051 | const zcu = pt.zcu; | |
| 38052 | const info = ty.intInfo(zcu); | |
| 38054 | 38053 | |
| 38055 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { | |
| 38054 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) { | |
| 38056 | 38055 | return .{ |
| 38057 | 38056 | .overflow_bit = try pt.undefValue(Type.u1), |
| 38058 | 38057 | .wrapped_result = try pt.undefValue(ty), |
| ... | ... | @@ -38061,8 +38060,8 @@ fn intAddWithOverflowScalar( |
| 38061 | 38060 | |
| 38062 | 38061 | var lhs_space: Value.BigIntSpace = undefined; |
| 38063 | 38062 | var rhs_space: Value.BigIntSpace = undefined; |
| 38064 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, pt, .sema); | |
| 38065 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, pt, .sema); | |
| 38063 | const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt); | |
| 38064 | const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt); | |
| 38066 | 38065 | const limbs = try sema.arena.alloc( |
| 38067 | 38066 | std.math.big.Limb, |
| 38068 | 38067 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| ... | ... | @@ -38088,13 +38087,13 @@ fn compareAll( |
| 38088 | 38087 | ty: Type, |
| 38089 | 38088 | ) CompileError!bool { |
| 38090 | 38089 | const pt = sema.pt; |
| 38091 | const mod = pt.zcu; | |
| 38092 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 38090 | const zcu = pt.zcu; | |
| 38091 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 38093 | 38092 | var i: usize = 0; |
| 38094 | while (i < ty.vectorLen(mod)) : (i += 1) { | |
| 38093 | while (i < ty.vectorLen(zcu)) : (i += 1) { | |
| 38095 | 38094 | const lhs_elem = try lhs.elemValue(pt, i); |
| 38096 | 38095 | const rhs_elem = try rhs.elemValue(pt, i); |
| 38097 | if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) { | |
| 38096 | if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(zcu)))) { | |
| 38098 | 38097 | return false; |
| 38099 | 38098 | } |
| 38100 | 38099 | } |
| ... | ... | @@ -38117,7 +38116,7 @@ fn compareScalar( |
| 38117 | 38116 | switch (op) { |
| 38118 | 38117 | .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty), |
| 38119 | 38118 | .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)), |
| 38120 | else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, pt, .sema), | |
| 38119 | else => return Value.compareHeteroSema(coerced_lhs, op, coerced_rhs, pt), | |
| 38121 | 38120 | } |
| 38122 | 38121 | } |
| 38123 | 38122 | |
| ... | ... | @@ -38139,17 +38138,17 @@ fn compareVector( |
| 38139 | 38138 | ty: Type, |
| 38140 | 38139 | ) !Value { |
| 38141 | 38140 | const pt = sema.pt; |
| 38142 | const mod = pt.zcu; | |
| 38143 | assert(ty.zigTypeTag(mod) == .Vector); | |
| 38144 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 38141 | const zcu = pt.zcu; | |
| 38142 | assert(ty.zigTypeTag(zcu) == .Vector); | |
| 38143 | const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 38145 | 38144 | for (result_data, 0..) |*scalar, i| { |
| 38146 | 38145 | const lhs_elem = try lhs.elemValue(pt, i); |
| 38147 | 38146 | const rhs_elem = try rhs.elemValue(pt, i); |
| 38148 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)); | |
| 38147 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(zcu)); | |
| 38149 | 38148 | scalar.* = Value.makeBool(res_bool).toIntern(); |
| 38150 | 38149 | } |
| 38151 | 38150 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 38152 | .ty = (try pt.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(), | |
| 38151 | .ty = (try pt.vectorType(.{ .len = ty.vectorLen(zcu), .child = .bool_type })).toIntern(), | |
| 38153 | 38152 | .storage = .{ .elems = result_data }, |
| 38154 | 38153 | } })); |
| 38155 | 38154 | } |
| ... | ... | @@ -38250,8 +38249,8 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai |
| 38250 | 38249 | /// Returns true if any value contained in `val` is undefined. |
| 38251 | 38250 | fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool { |
| 38252 | 38251 | const pt = sema.pt; |
| 38253 | const mod = pt.zcu; | |
| 38254 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 38252 | const zcu = pt.zcu; | |
| 38253 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 38255 | 38254 | .undef => true, |
| 38256 | 38255 | .simple_value => |v| v == .undefined, |
| 38257 | 38256 | .slice => { |
| ... | ... | @@ -38261,7 +38260,7 @@ fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool { |
| 38261 | 38260 | return sema.anyUndef(block, src, arr); |
| 38262 | 38261 | }, |
| 38263 | 38262 | .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| { |
| 38264 | const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i]; | |
| 38263 | const elem = zcu.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i]; | |
| 38265 | 38264 | if (try sema.anyUndef(block, src, Value.fromInterned(elem))) break true; |
| 38266 | 38265 | } else false, |
| 38267 | 38266 | else => false, |
src/Sema/bitcast.zig+48-44| ... | ... | @@ -85,23 +85,23 @@ fn bitCastInner( |
| 85 | 85 | assert(val_ty.hasWellDefinedLayout(zcu)); |
| 86 | 86 | |
| 87 | 87 | const abi_pad_bits, const host_pad_bits = if (host_bits > 0) |
| 88 | .{ val_ty.abiSize(pt) * 8 - host_bits, host_bits - val_ty.bitSize(pt) } | |
| 88 | .{ val_ty.abiSize(zcu) * 8 - host_bits, host_bits - val_ty.bitSize(zcu) } | |
| 89 | 89 | else |
| 90 | .{ val_ty.abiSize(pt) * 8 - val_ty.bitSize(pt), 0 }; | |
| 90 | .{ val_ty.abiSize(zcu) * 8 - val_ty.bitSize(zcu), 0 }; | |
| 91 | 91 | |
| 92 | 92 | const skip_bits = switch (endian) { |
| 93 | 93 | .little => bit_offset + byte_offset * 8, |
| 94 | 94 | .big => if (host_bits > 0) |
| 95 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - host_bits + bit_offset | |
| 95 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - host_bits + bit_offset | |
| 96 | 96 | else |
| 97 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - dest_ty.bitSize(pt), | |
| 97 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - dest_ty.bitSize(zcu), | |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | 100 | var unpack: UnpackValueBits = .{ |
| 101 | 101 | .pt = sema.pt, |
| 102 | 102 | .arena = sema.arena, |
| 103 | 103 | .skip_bits = skip_bits, |
| 104 | .remaining_bits = dest_ty.bitSize(pt), | |
| 104 | .remaining_bits = dest_ty.bitSize(zcu), | |
| 105 | 105 | .unpacked = std.ArrayList(InternPool.Index).init(sema.arena), |
| 106 | 106 | }; |
| 107 | 107 | switch (endian) { |
| ... | ... | @@ -141,22 +141,22 @@ fn bitCastSpliceInner( |
| 141 | 141 | try val_ty.resolveLayout(pt); |
| 142 | 142 | try splice_val_ty.resolveLayout(pt); |
| 143 | 143 | |
| 144 | const splice_bits = splice_val_ty.bitSize(pt); | |
| 144 | const splice_bits = splice_val_ty.bitSize(zcu); | |
| 145 | 145 | |
| 146 | 146 | const splice_offset = switch (endian) { |
| 147 | 147 | .little => bit_offset + byte_offset * 8, |
| 148 | 148 | .big => if (host_bits > 0) |
| 149 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - host_bits + bit_offset | |
| 149 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - host_bits + bit_offset | |
| 150 | 150 | else |
| 151 | val_ty.abiSize(pt) * 8 - byte_offset * 8 - splice_bits, | |
| 151 | val_ty.abiSize(zcu) * 8 - byte_offset * 8 - splice_bits, | |
| 152 | 152 | }; |
| 153 | 153 | |
| 154 | assert(splice_offset + splice_bits <= val_ty.abiSize(pt) * 8); | |
| 154 | assert(splice_offset + splice_bits <= val_ty.abiSize(zcu) * 8); | |
| 155 | 155 | |
| 156 | 156 | const abi_pad_bits, const host_pad_bits = if (host_bits > 0) |
| 157 | .{ val_ty.abiSize(pt) * 8 - host_bits, host_bits - val_ty.bitSize(pt) } | |
| 157 | .{ val_ty.abiSize(zcu) * 8 - host_bits, host_bits - val_ty.bitSize(zcu) } | |
| 158 | 158 | else |
| 159 | .{ val_ty.abiSize(pt) * 8 - val_ty.bitSize(pt), 0 }; | |
| 159 | .{ val_ty.abiSize(zcu) * 8 - val_ty.bitSize(zcu), 0 }; | |
| 160 | 160 | |
| 161 | 161 | var unpack: UnpackValueBits = .{ |
| 162 | 162 | .pt = pt, |
| ... | ... | @@ -181,7 +181,7 @@ fn bitCastSpliceInner( |
| 181 | 181 | try unpack.add(splice_val); |
| 182 | 182 | |
| 183 | 183 | unpack.skip_bits = splice_offset + splice_bits; |
| 184 | unpack.remaining_bits = val_ty.abiSize(pt) * 8 - splice_offset - splice_bits; | |
| 184 | unpack.remaining_bits = val_ty.abiSize(zcu) * 8 - splice_offset - splice_bits; | |
| 185 | 185 | switch (endian) { |
| 186 | 186 | .little => { |
| 187 | 187 | try unpack.add(val); |
| ... | ... | @@ -229,7 +229,7 @@ const UnpackValueBits = struct { |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | 231 | const ty = val.typeOf(zcu); |
| 232 | const bit_size = ty.bitSize(pt); | |
| 232 | const bit_size = ty.bitSize(zcu); | |
| 233 | 233 | |
| 234 | 234 | if (unpack.skip_bits >= bit_size) { |
| 235 | 235 | unpack.skip_bits -= bit_size; |
| ... | ... | @@ -291,7 +291,7 @@ const UnpackValueBits = struct { |
| 291 | 291 | // The final element does not have trailing padding. |
| 292 | 292 | // Elements are reversed in packed memory on BE targets. |
| 293 | 293 | const elem_ty = ty.childType(zcu); |
| 294 | const pad_bits = elem_ty.abiSize(pt) * 8 - elem_ty.bitSize(pt); | |
| 294 | const pad_bits = elem_ty.abiSize(zcu) * 8 - elem_ty.bitSize(zcu); | |
| 295 | 295 | const len = ty.arrayLen(zcu); |
| 296 | 296 | const maybe_sent = ty.sentinel(zcu); |
| 297 | 297 | |
| ... | ... | @@ -323,12 +323,12 @@ const UnpackValueBits = struct { |
| 323 | 323 | var cur_bit_off: u64 = 0; |
| 324 | 324 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip); |
| 325 | 325 | while (it.next()) |field_idx| { |
| 326 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8; | |
| 326 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8; | |
| 327 | 327 | const pad_bits = want_bit_off - cur_bit_off; |
| 328 | 328 | const field_val = try val.fieldValue(pt, field_idx); |
| 329 | 329 | try unpack.padding(pad_bits); |
| 330 | 330 | try unpack.add(field_val); |
| 331 | cur_bit_off = want_bit_off + field_val.typeOf(zcu).bitSize(pt); | |
| 331 | cur_bit_off = want_bit_off + field_val.typeOf(zcu).bitSize(zcu); | |
| 332 | 332 | } |
| 333 | 333 | // Add trailing padding bits. |
| 334 | 334 | try unpack.padding(bit_size - cur_bit_off); |
| ... | ... | @@ -339,11 +339,11 @@ const UnpackValueBits = struct { |
| 339 | 339 | while (it.next()) |field_idx| { |
| 340 | 340 | const field_val = try val.fieldValue(pt, field_idx); |
| 341 | 341 | const field_ty = field_val.typeOf(zcu); |
| 342 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8 + field_ty.bitSize(pt); | |
| 342 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu); | |
| 343 | 343 | const pad_bits = cur_bit_off - want_bit_off; |
| 344 | 344 | try unpack.padding(pad_bits); |
| 345 | 345 | try unpack.add(field_val); |
| 346 | cur_bit_off = want_bit_off - field_ty.bitSize(pt); | |
| 346 | cur_bit_off = want_bit_off - field_ty.bitSize(zcu); | |
| 347 | 347 | } |
| 348 | 348 | assert(cur_bit_off == 0); |
| 349 | 349 | }, |
| ... | ... | @@ -366,7 +366,7 @@ const UnpackValueBits = struct { |
| 366 | 366 | // This correctly handles the case where `tag == .none`, since the payload is then |
| 367 | 367 | // either an integer or a byte array, both of which we can unpack. |
| 368 | 368 | const payload_val = Value.fromInterned(un.val); |
| 369 | const pad_bits = bit_size - payload_val.typeOf(zcu).bitSize(pt); | |
| 369 | const pad_bits = bit_size - payload_val.typeOf(zcu).bitSize(zcu); | |
| 370 | 370 | if (endian == .little or ty.containerLayout(zcu) == .@"packed") { |
| 371 | 371 | try unpack.add(payload_val); |
| 372 | 372 | try unpack.padding(pad_bits); |
| ... | ... | @@ -398,13 +398,14 @@ const UnpackValueBits = struct { |
| 398 | 398 | |
| 399 | 399 | fn primitive(unpack: *UnpackValueBits, val: Value) BitCastError!void { |
| 400 | 400 | const pt = unpack.pt; |
| 401 | const zcu = pt.zcu; | |
| 401 | 402 | |
| 402 | 403 | if (unpack.remaining_bits == 0) { |
| 403 | 404 | return; |
| 404 | 405 | } |
| 405 | 406 | |
| 406 | 407 | const ty = val.typeOf(pt.zcu); |
| 407 | const bit_size = ty.bitSize(pt); | |
| 408 | const bit_size = ty.bitSize(zcu); | |
| 408 | 409 | |
| 409 | 410 | // Note that this skips all zero-bit types. |
| 410 | 411 | if (unpack.skip_bits >= bit_size) { |
| ... | ... | @@ -429,9 +430,10 @@ const UnpackValueBits = struct { |
| 429 | 430 | |
| 430 | 431 | fn splitPrimitive(unpack: *UnpackValueBits, val: Value, bit_offset: u64, bit_count: u64) BitCastError!void { |
| 431 | 432 | const pt = unpack.pt; |
| 433 | const zcu = pt.zcu; | |
| 432 | 434 | const ty = val.typeOf(pt.zcu); |
| 433 | 435 | |
| 434 | const val_bits = ty.bitSize(pt); | |
| 436 | const val_bits = ty.bitSize(zcu); | |
| 435 | 437 | assert(bit_offset + bit_count <= val_bits); |
| 436 | 438 | |
| 437 | 439 | switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| ... | ... | @@ -499,12 +501,12 @@ const PackValueBits = struct { |
| 499 | 501 | const len = ty.arrayLen(zcu); |
| 500 | 502 | const elem_ty = ty.childType(zcu); |
| 501 | 503 | const maybe_sent = ty.sentinel(zcu); |
| 502 | const pad_bits = elem_ty.abiSize(pt) * 8 - elem_ty.bitSize(pt); | |
| 504 | const pad_bits = elem_ty.abiSize(zcu) * 8 - elem_ty.bitSize(zcu); | |
| 503 | 505 | const elems = try arena.alloc(InternPool.Index, @intCast(len)); |
| 504 | 506 | |
| 505 | 507 | if (endian == .big and maybe_sent != null) { |
| 506 | 508 | // TODO: validate sentinel was preserved! |
| 507 | try pack.padding(elem_ty.bitSize(pt)); | |
| 509 | try pack.padding(elem_ty.bitSize(zcu)); | |
| 508 | 510 | if (len != 0) try pack.padding(pad_bits); |
| 509 | 511 | } |
| 510 | 512 | |
| ... | ... | @@ -520,7 +522,7 @@ const PackValueBits = struct { |
| 520 | 522 | if (endian == .little and maybe_sent != null) { |
| 521 | 523 | // TODO: validate sentinel was preserved! |
| 522 | 524 | if (len != 0) try pack.padding(pad_bits); |
| 523 | try pack.padding(elem_ty.bitSize(pt)); | |
| 525 | try pack.padding(elem_ty.bitSize(zcu)); | |
| 524 | 526 | } |
| 525 | 527 | |
| 526 | 528 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| ... | ... | @@ -538,23 +540,23 @@ const PackValueBits = struct { |
| 538 | 540 | var cur_bit_off: u64 = 0; |
| 539 | 541 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrder(ip); |
| 540 | 542 | while (it.next()) |field_idx| { |
| 541 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8; | |
| 543 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8; | |
| 542 | 544 | try pack.padding(want_bit_off - cur_bit_off); |
| 543 | 545 | const field_ty = ty.structFieldType(field_idx, zcu); |
| 544 | 546 | elems[field_idx] = (try pack.get(field_ty)).toIntern(); |
| 545 | cur_bit_off = want_bit_off + field_ty.bitSize(pt); | |
| 547 | cur_bit_off = want_bit_off + field_ty.bitSize(zcu); | |
| 546 | 548 | } |
| 547 | try pack.padding(ty.bitSize(pt) - cur_bit_off); | |
| 549 | try pack.padding(ty.bitSize(zcu) - cur_bit_off); | |
| 548 | 550 | }, |
| 549 | 551 | .big => { |
| 550 | var cur_bit_off: u64 = ty.bitSize(pt); | |
| 552 | var cur_bit_off: u64 = ty.bitSize(zcu); | |
| 551 | 553 | var it = zcu.typeToStruct(ty).?.iterateRuntimeOrderReverse(ip); |
| 552 | 554 | while (it.next()) |field_idx| { |
| 553 | 555 | const field_ty = ty.structFieldType(field_idx, zcu); |
| 554 | const want_bit_off = ty.structFieldOffset(field_idx, pt) * 8 + field_ty.bitSize(pt); | |
| 556 | const want_bit_off = ty.structFieldOffset(field_idx, zcu) * 8 + field_ty.bitSize(zcu); | |
| 555 | 557 | try pack.padding(cur_bit_off - want_bit_off); |
| 556 | 558 | elems[field_idx] = (try pack.get(field_ty)).toIntern(); |
| 557 | cur_bit_off = want_bit_off - field_ty.bitSize(pt); | |
| 559 | cur_bit_off = want_bit_off - field_ty.bitSize(zcu); | |
| 558 | 560 | } |
| 559 | 561 | assert(cur_bit_off == 0); |
| 560 | 562 | }, |
| ... | ... | @@ -622,16 +624,16 @@ const PackValueBits = struct { |
| 622 | 624 | for (field_order, 0..) |*f, i| f.* = @intCast(i); |
| 623 | 625 | // Sort `field_order` to put the fields with the largest bit sizes first. |
| 624 | 626 | const SizeSortCtx = struct { |
| 625 | pt: Zcu.PerThread, | |
| 627 | zcu: *Zcu, | |
| 626 | 628 | field_types: []const InternPool.Index, |
| 627 | 629 | fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool { |
| 628 | 630 | const a_ty = Type.fromInterned(ctx.field_types[a_idx]); |
| 629 | 631 | const b_ty = Type.fromInterned(ctx.field_types[b_idx]); |
| 630 | return a_ty.bitSize(ctx.pt) > b_ty.bitSize(ctx.pt); | |
| 632 | return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu); | |
| 631 | 633 | } |
| 632 | 634 | }; |
| 633 | 635 | std.mem.sortUnstable(u32, field_order, SizeSortCtx{ |
| 634 | .pt = pt, | |
| 636 | .zcu = zcu, | |
| 635 | 637 | .field_types = zcu.typeToUnion(ty).?.field_types.get(ip), |
| 636 | 638 | }, SizeSortCtx.lessThan); |
| 637 | 639 | |
| ... | ... | @@ -639,7 +641,7 @@ const PackValueBits = struct { |
| 639 | 641 | |
| 640 | 642 | for (field_order) |field_idx| { |
| 641 | 643 | const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]); |
| 642 | const pad_bits = ty.bitSize(pt) - field_ty.bitSize(pt); | |
| 644 | const pad_bits = ty.bitSize(zcu) - field_ty.bitSize(zcu); | |
| 643 | 645 | if (!padding_after) try pack.padding(pad_bits); |
| 644 | 646 | const field_val = pack.get(field_ty) catch |err| switch (err) { |
| 645 | 647 | error.ReinterpretDeclRef => { |
| ... | ... | @@ -682,10 +684,11 @@ const PackValueBits = struct { |
| 682 | 684 | |
| 683 | 685 | fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value { |
| 684 | 686 | const pt = pack.pt; |
| 685 | const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(pt)); | |
| 687 | const zcu = pt.zcu; | |
| 688 | const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu)); | |
| 686 | 689 | |
| 687 | 690 | for (vals) |val| { |
| 688 | if (!Value.fromInterned(val).isUndef(pt.zcu)) break; | |
| 691 | if (!Value.fromInterned(val).isUndef(zcu)) break; | |
| 689 | 692 | } else { |
| 690 | 693 | // All bits of the value are `undefined`. |
| 691 | 694 | return pt.undefValue(want_ty); |
| ... | ... | @@ -706,8 +709,8 @@ const PackValueBits = struct { |
| 706 | 709 | ptr_cast: { |
| 707 | 710 | if (vals.len != 1) break :ptr_cast; |
| 708 | 711 | const val = Value.fromInterned(vals[0]); |
| 709 | if (!val.typeOf(pt.zcu).isPtrAtRuntime(pt.zcu)) break :ptr_cast; | |
| 710 | if (!want_ty.isPtrAtRuntime(pt.zcu)) break :ptr_cast; | |
| 712 | if (!val.typeOf(zcu).isPtrAtRuntime(zcu)) break :ptr_cast; | |
| 713 | if (!want_ty.isPtrAtRuntime(zcu)) break :ptr_cast; | |
| 711 | 714 | return pt.getCoerced(val, want_ty); |
| 712 | 715 | } |
| 713 | 716 | |
| ... | ... | @@ -717,7 +720,7 @@ const PackValueBits = struct { |
| 717 | 720 | for (vals) |ip_val| { |
| 718 | 721 | const val = Value.fromInterned(ip_val); |
| 719 | 722 | const ty = val.typeOf(pt.zcu); |
| 720 | buf_bits += ty.bitSize(pt); | |
| 723 | buf_bits += ty.bitSize(zcu); | |
| 721 | 724 | } |
| 722 | 725 | |
| 723 | 726 | const buf = try pack.arena.alloc(u8, @intCast((buf_bits + 7) / 8)); |
| ... | ... | @@ -726,11 +729,11 @@ const PackValueBits = struct { |
| 726 | 729 | var cur_bit_off: usize = 0; |
| 727 | 730 | for (vals) |ip_val| { |
| 728 | 731 | const val = Value.fromInterned(ip_val); |
| 729 | const ty = val.typeOf(pt.zcu); | |
| 730 | if (!val.isUndef(pt.zcu)) { | |
| 732 | const ty = val.typeOf(zcu); | |
| 733 | if (!val.isUndef(zcu)) { | |
| 731 | 734 | try val.writeToPackedMemory(ty, pt, buf, cur_bit_off); |
| 732 | 735 | } |
| 733 | cur_bit_off += @intCast(ty.bitSize(pt)); | |
| 736 | cur_bit_off += @intCast(ty.bitSize(zcu)); | |
| 734 | 737 | } |
| 735 | 738 | |
| 736 | 739 | return Value.readFromPackedMemory(want_ty, pt, buf, @intCast(bit_offset), pack.arena); |
| ... | ... | @@ -740,11 +743,12 @@ const PackValueBits = struct { |
| 740 | 743 | if (need_bits == 0) return .{ &.{}, 0 }; |
| 741 | 744 | |
| 742 | 745 | const pt = pack.pt; |
| 746 | const zcu = pt.zcu; | |
| 743 | 747 | |
| 744 | 748 | var bits: u64 = 0; |
| 745 | 749 | var len: usize = 0; |
| 746 | 750 | while (bits < pack.bit_offset + need_bits) { |
| 747 | bits += Value.fromInterned(pack.unpacked[len]).typeOf(pt.zcu).bitSize(pt); | |
| 751 | bits += Value.fromInterned(pack.unpacked[len]).typeOf(pt.zcu).bitSize(zcu); | |
| 748 | 752 | len += 1; |
| 749 | 753 | } |
| 750 | 754 | |
| ... | ... | @@ -757,7 +761,7 @@ const PackValueBits = struct { |
| 757 | 761 | pack.bit_offset = 0; |
| 758 | 762 | } else { |
| 759 | 763 | pack.unpacked = pack.unpacked[len - 1 ..]; |
| 760 | pack.bit_offset = Value.fromInterned(pack.unpacked[0]).typeOf(pt.zcu).bitSize(pt) - extra_bits; | |
| 764 | pack.bit_offset = Value.fromInterned(pack.unpacked[0]).typeOf(pt.zcu).bitSize(zcu) - extra_bits; | |
| 761 | 765 | } |
| 762 | 766 | |
| 763 | 767 | return .{ result_vals, result_offset }; |
src/Sema/comptime_ptr_access.zig+29-28| ... | ... | @@ -13,14 +13,15 @@ pub const ComptimeLoadResult = union(enum) { |
| 13 | 13 | |
| 14 | 14 | pub fn loadComptimePtr(sema: *Sema, block: *Block, src: LazySrcLoc, ptr: Value) !ComptimeLoadResult { |
| 15 | 15 | const pt = sema.pt; |
| 16 | const zcu = pt.zcu; | |
| 16 | 17 | const ptr_info = ptr.typeOf(pt.zcu).ptrInfo(pt.zcu); |
| 17 | 18 | // TODO: host size for vectors is terrible |
| 18 | 19 | const host_bits = switch (ptr_info.flags.vector_index) { |
| 19 | 20 | .none => ptr_info.packed_offset.host_size * 8, |
| 20 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(pt), | |
| 21 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(zcu), | |
| 21 | 22 | }; |
| 22 | 23 | const bit_offset = if (host_bits != 0) bit_offset: { |
| 23 | const child_bits = Type.fromInterned(ptr_info.child).bitSize(pt); | |
| 24 | const child_bits = Type.fromInterned(ptr_info.child).bitSize(zcu); | |
| 24 | 25 | const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 25 | 26 | .none => 0, |
| 26 | 27 | .runtime => return .runtime_load, |
| ... | ... | @@ -67,18 +68,18 @@ pub fn storeComptimePtr( |
| 67 | 68 | // TODO: host size for vectors is terrible |
| 68 | 69 | const host_bits = switch (ptr_info.flags.vector_index) { |
| 69 | 70 | .none => ptr_info.packed_offset.host_size * 8, |
| 70 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(pt), | |
| 71 | else => ptr_info.packed_offset.host_size * Type.fromInterned(ptr_info.child).bitSize(zcu), | |
| 71 | 72 | }; |
| 72 | 73 | const bit_offset = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 73 | 74 | .none => 0, |
| 74 | 75 | .runtime => return .runtime_store, |
| 75 | 76 | else => |idx| switch (zcu.getTarget().cpu.arch.endian()) { |
| 76 | .little => Type.fromInterned(ptr_info.child).bitSize(pt) * @intFromEnum(idx), | |
| 77 | .big => host_bits - Type.fromInterned(ptr_info.child).bitSize(pt) * (@intFromEnum(idx) + 1), // element order reversed on big endian | |
| 77 | .little => Type.fromInterned(ptr_info.child).bitSize(zcu) * @intFromEnum(idx), | |
| 78 | .big => host_bits - Type.fromInterned(ptr_info.child).bitSize(zcu) * (@intFromEnum(idx) + 1), // element order reversed on big endian | |
| 78 | 79 | }, |
| 79 | 80 | }; |
| 80 | 81 | const pseudo_store_ty = if (host_bits > 0) t: { |
| 81 | const need_bits = Type.fromInterned(ptr_info.child).bitSize(pt); | |
| 82 | const need_bits = Type.fromInterned(ptr_info.child).bitSize(zcu); | |
| 82 | 83 | if (need_bits + bit_offset > host_bits) { |
| 83 | 84 | return .exceeds_host_size; |
| 84 | 85 | } |
| ... | ... | @@ -166,9 +167,9 @@ pub fn storeComptimePtr( |
| 166 | 167 | .direct => |direct| .{ direct.val, 0 }, |
| 167 | 168 | .index => |index| .{ |
| 168 | 169 | index.val, |
| 169 | index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(pt), | |
| 170 | index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(zcu), | |
| 170 | 171 | }, |
| 171 | .flat_index => |flat| .{ flat.val, flat.flat_elem_index * flat.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(pt) }, | |
| 172 | .flat_index => |flat| .{ flat.val, flat.flat_elem_index * flat.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(zcu) }, | |
| 172 | 173 | .reinterpret => |reinterpret| .{ reinterpret.val, reinterpret.byte_offset }, |
| 173 | 174 | else => unreachable, |
| 174 | 175 | }; |
| ... | ... | @@ -347,8 +348,8 @@ fn loadComptimePtrInner( |
| 347 | 348 | const load_one_ty, const load_count = load_ty.arrayBase(zcu); |
| 348 | 349 | |
| 349 | 350 | const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: { |
| 350 | if (try sema.typeRequiresComptime(load_one_ty)) break :restructure_array; | |
| 351 | const elem_len = try sema.typeAbiSize(load_one_ty); | |
| 351 | if (try load_one_ty.comptimeOnlySema(pt)) break :restructure_array; | |
| 352 | const elem_len = try load_one_ty.abiSizeSema(pt); | |
| 352 | 353 | if (ptr.byte_offset % elem_len != 0) break :restructure_array; |
| 353 | 354 | break :idx @divExact(ptr.byte_offset, elem_len); |
| 354 | 355 | }; |
| ... | ... | @@ -394,12 +395,12 @@ fn loadComptimePtrInner( |
| 394 | 395 | var cur_offset = ptr.byte_offset; |
| 395 | 396 | |
| 396 | 397 | if (load_ty.zigTypeTag(zcu) == .Array and array_offset > 0) { |
| 397 | cur_offset += try sema.typeAbiSize(load_ty.childType(zcu)) * array_offset; | |
| 398 | cur_offset += try load_ty.childType(zcu).abiSizeSema(pt) * array_offset; | |
| 398 | 399 | } |
| 399 | 400 | |
| 400 | const need_bytes = if (host_bits > 0) (host_bits + 7) / 8 else try sema.typeAbiSize(load_ty); | |
| 401 | const need_bytes = if (host_bits > 0) (host_bits + 7) / 8 else try load_ty.abiSizeSema(pt); | |
| 401 | 402 | |
| 402 | if (cur_offset + need_bytes > try sema.typeAbiSize(cur_val.typeOf(zcu))) { | |
| 403 | if (cur_offset + need_bytes > try cur_val.typeOf(zcu).abiSizeSema(pt)) { | |
| 403 | 404 | return .{ .out_of_bounds = cur_val.typeOf(zcu) }; |
| 404 | 405 | } |
| 405 | 406 | |
| ... | ... | @@ -434,7 +435,7 @@ fn loadComptimePtrInner( |
| 434 | 435 | .Optional => break, // this can only be a pointer-like optional so is terminal |
| 435 | 436 | .Array => { |
| 436 | 437 | const elem_ty = cur_ty.childType(zcu); |
| 437 | const elem_size = try sema.typeAbiSize(elem_ty); | |
| 438 | const elem_size = try elem_ty.abiSizeSema(pt); | |
| 438 | 439 | const elem_idx = cur_offset / elem_size; |
| 439 | 440 | const next_elem_off = elem_size * (elem_idx + 1); |
| 440 | 441 | if (cur_offset + need_bytes <= next_elem_off) { |
| ... | ... | @@ -449,8 +450,8 @@ fn loadComptimePtrInner( |
| 449 | 450 | .auto => unreachable, // ill-defined layout |
| 450 | 451 | .@"packed" => break, // let the bitcast logic handle this |
| 451 | 452 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { |
| 452 | const start_off = cur_ty.structFieldOffset(field_idx, pt); | |
| 453 | const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu)); | |
| 453 | const start_off = cur_ty.structFieldOffset(field_idx, zcu); | |
| 454 | const end_off = start_off + try cur_ty.structFieldType(field_idx, zcu).abiSizeSema(pt); | |
| 454 | 455 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { |
| 455 | 456 | cur_val = try cur_val.getElem(sema.pt, field_idx); |
| 456 | 457 | cur_offset -= start_off; |
| ... | ... | @@ -477,7 +478,7 @@ fn loadComptimePtrInner( |
| 477 | 478 | }; |
| 478 | 479 | // The payload always has offset 0. If it's big enough |
| 479 | 480 | // to represent the whole load type, we can use it. |
| 480 | if (try sema.typeAbiSize(payload.typeOf(zcu)) >= need_bytes) { | |
| 481 | if (try payload.typeOf(zcu).abiSizeSema(pt) >= need_bytes) { | |
| 481 | 482 | cur_val = payload; |
| 482 | 483 | } else { |
| 483 | 484 | break; |
| ... | ... | @@ -746,8 +747,8 @@ fn prepareComptimePtrStore( |
| 746 | 747 | |
| 747 | 748 | const store_one_ty, const store_count = store_ty.arrayBase(zcu); |
| 748 | 749 | const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: { |
| 749 | if (try sema.typeRequiresComptime(store_one_ty)) break :restructure_array; | |
| 750 | const elem_len = try sema.typeAbiSize(store_one_ty); | |
| 750 | if (try store_one_ty.comptimeOnlySema(pt)) break :restructure_array; | |
| 751 | const elem_len = try store_one_ty.abiSizeSema(pt); | |
| 751 | 752 | if (ptr.byte_offset % elem_len != 0) break :restructure_array; |
| 752 | 753 | break :idx @divExact(ptr.byte_offset, elem_len); |
| 753 | 754 | }; |
| ... | ... | @@ -800,11 +801,11 @@ fn prepareComptimePtrStore( |
| 800 | 801 | var cur_val: *MutableValue, var cur_offset: u64 = switch (base_strat) { |
| 801 | 802 | .direct => |direct| .{ direct.val, 0 }, |
| 802 | 803 | // It's okay to do `abiSize` - the comptime-only case will be caught below. |
| 803 | .index => |index| .{ index.val, index.elem_index * try sema.typeAbiSize(index.val.typeOf(zcu).childType(zcu)) }, | |
| 804 | .index => |index| .{ index.val, index.elem_index * try index.val.typeOf(zcu).childType(zcu).abiSizeSema(pt) }, | |
| 804 | 805 | .flat_index => |flat_index| .{ |
| 805 | 806 | flat_index.val, |
| 806 | 807 | // It's okay to do `abiSize` - the comptime-only case will be caught below. |
| 807 | flat_index.flat_elem_index * try sema.typeAbiSize(flat_index.val.typeOf(zcu).arrayBase(zcu)[0]), | |
| 808 | flat_index.flat_elem_index * try flat_index.val.typeOf(zcu).arrayBase(zcu)[0].abiSizeSema(pt), | |
| 808 | 809 | }, |
| 809 | 810 | .reinterpret => |r| .{ r.val, r.byte_offset }, |
| 810 | 811 | else => unreachable, |
| ... | ... | @@ -816,12 +817,12 @@ fn prepareComptimePtrStore( |
| 816 | 817 | } |
| 817 | 818 | |
| 818 | 819 | if (store_ty.zigTypeTag(zcu) == .Array and array_offset > 0) { |
| 819 | cur_offset += try sema.typeAbiSize(store_ty.childType(zcu)) * array_offset; | |
| 820 | cur_offset += try store_ty.childType(zcu).abiSizeSema(pt) * array_offset; | |
| 820 | 821 | } |
| 821 | 822 | |
| 822 | const need_bytes = try sema.typeAbiSize(store_ty); | |
| 823 | const need_bytes = try store_ty.abiSizeSema(pt); | |
| 823 | 824 | |
| 824 | if (cur_offset + need_bytes > try sema.typeAbiSize(cur_val.typeOf(zcu))) { | |
| 825 | if (cur_offset + need_bytes > try cur_val.typeOf(zcu).abiSizeSema(pt)) { | |
| 825 | 826 | return .{ .out_of_bounds = cur_val.typeOf(zcu) }; |
| 826 | 827 | } |
| 827 | 828 | |
| ... | ... | @@ -856,7 +857,7 @@ fn prepareComptimePtrStore( |
| 856 | 857 | .Optional => break, // this can only be a pointer-like optional so is terminal |
| 857 | 858 | .Array => { |
| 858 | 859 | const elem_ty = cur_ty.childType(zcu); |
| 859 | const elem_size = try sema.typeAbiSize(elem_ty); | |
| 860 | const elem_size = try elem_ty.abiSizeSema(pt); | |
| 860 | 861 | const elem_idx = cur_offset / elem_size; |
| 861 | 862 | const next_elem_off = elem_size * (elem_idx + 1); |
| 862 | 863 | if (cur_offset + need_bytes <= next_elem_off) { |
| ... | ... | @@ -871,8 +872,8 @@ fn prepareComptimePtrStore( |
| 871 | 872 | .auto => unreachable, // ill-defined layout |
| 872 | 873 | .@"packed" => break, // let the bitcast logic handle this |
| 873 | 874 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { |
| 874 | const start_off = cur_ty.structFieldOffset(field_idx, pt); | |
| 875 | const end_off = start_off + try sema.typeAbiSize(cur_ty.structFieldType(field_idx, zcu)); | |
| 875 | const start_off = cur_ty.structFieldOffset(field_idx, zcu); | |
| 876 | const end_off = start_off + try cur_ty.structFieldType(field_idx, zcu).abiSizeSema(pt); | |
| 876 | 877 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { |
| 877 | 878 | cur_val = try cur_val.elem(pt, sema.arena, field_idx); |
| 878 | 879 | cur_offset -= start_off; |
| ... | ... | @@ -895,7 +896,7 @@ fn prepareComptimePtrStore( |
| 895 | 896 | }; |
| 896 | 897 | // The payload always has offset 0. If it's big enough |
| 897 | 898 | // to represent the whole load type, we can use it. |
| 898 | if (try sema.typeAbiSize(payload.typeOf(zcu)) >= need_bytes) { | |
| 899 | if (try payload.typeOf(zcu).abiSizeSema(pt) >= need_bytes) { | |
| 899 | 900 | cur_val = payload; |
| 900 | 901 | } else { |
| 901 | 902 | break; |
src/Type.zig+714-503| ... | ... | @@ -10,8 +10,6 @@ const Value = @import("Value.zig"); |
| 10 | 10 | const assert = std.debug.assert; |
| 11 | 11 | const Target = std.Target; |
| 12 | 12 | const Zcu = @import("Zcu.zig"); |
| 13 | /// Deprecated. | |
| 14 | const Module = Zcu; | |
| 15 | 13 | const log = std.log.scoped(.Type); |
| 16 | 14 | const target_util = @import("target.zig"); |
| 17 | 15 | const Sema = @import("Sema.zig"); |
| ... | ... | @@ -23,15 +21,15 @@ const SemaError = Zcu.SemaError; |
| 23 | 21 | |
| 24 | 22 | ip_index: InternPool.Index, |
| 25 | 23 | |
| 26 | pub fn zigTypeTag(ty: Type, mod: *const Module) std.builtin.TypeId { | |
| 27 | return ty.zigTypeTagOrPoison(mod) catch unreachable; | |
| 24 | pub fn zigTypeTag(ty: Type, zcu: *const Zcu) std.builtin.TypeId { | |
| 25 | return ty.zigTypeTagOrPoison(zcu) catch unreachable; | |
| 28 | 26 | } |
| 29 | 27 | |
| 30 | pub fn zigTypeTagOrPoison(ty: Type, mod: *const Module) error{GenericPoison}!std.builtin.TypeId { | |
| 31 | return mod.intern_pool.zigTypeTagOrPoison(ty.toIntern()); | |
| 28 | pub fn zigTypeTagOrPoison(ty: Type, zcu: *const Zcu) error{GenericPoison}!std.builtin.TypeId { | |
| 29 | return zcu.intern_pool.zigTypeTagOrPoison(ty.toIntern()); | |
| 32 | 30 | } |
| 33 | 31 | |
| 34 | pub fn baseZigTypeTag(self: Type, mod: *Module) std.builtin.TypeId { | |
| 32 | pub fn baseZigTypeTag(self: Type, mod: *Zcu) std.builtin.TypeId { | |
| 35 | 33 | return switch (self.zigTypeTag(mod)) { |
| 36 | 34 | .ErrorUnion => self.errorUnionPayload(mod).baseZigTypeTag(mod), |
| 37 | 35 | .Optional => { |
| ... | ... | @@ -41,15 +39,15 @@ pub fn baseZigTypeTag(self: Type, mod: *Module) std.builtin.TypeId { |
| 41 | 39 | }; |
| 42 | 40 | } |
| 43 | 41 | |
| 44 | pub fn isSelfComparable(ty: Type, mod: *const Module, is_equality_cmp: bool) bool { | |
| 45 | return switch (ty.zigTypeTag(mod)) { | |
| 42 | pub fn isSelfComparable(ty: Type, zcu: *const Zcu, is_equality_cmp: bool) bool { | |
| 43 | return switch (ty.zigTypeTag(zcu)) { | |
| 46 | 44 | .Int, |
| 47 | 45 | .Float, |
| 48 | 46 | .ComptimeFloat, |
| 49 | 47 | .ComptimeInt, |
| 50 | 48 | => true, |
| 51 | 49 | |
| 52 | .Vector => ty.elemType2(mod).isSelfComparable(mod, is_equality_cmp), | |
| 50 | .Vector => ty.elemType2(zcu).isSelfComparable(zcu, is_equality_cmp), | |
| 53 | 51 | |
| 54 | 52 | .Bool, |
| 55 | 53 | .Type, |
| ... | ... | @@ -72,25 +70,25 @@ pub fn isSelfComparable(ty: Type, mod: *const Module, is_equality_cmp: bool) boo |
| 72 | 70 | .Frame, |
| 73 | 71 | => false, |
| 74 | 72 | |
| 75 | .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr(mod)), | |
| 73 | .Pointer => !ty.isSlice(zcu) and (is_equality_cmp or ty.isCPtr(zcu)), | |
| 76 | 74 | .Optional => { |
| 77 | 75 | if (!is_equality_cmp) return false; |
| 78 | return ty.optionalChild(mod).isSelfComparable(mod, is_equality_cmp); | |
| 76 | return ty.optionalChild(zcu).isSelfComparable(zcu, is_equality_cmp); | |
| 79 | 77 | }, |
| 80 | 78 | }; |
| 81 | 79 | } |
| 82 | 80 | |
| 83 | 81 | /// If it is a function pointer, returns the function type. Otherwise returns null. |
| 84 | pub fn castPtrToFn(ty: Type, mod: *const Module) ?Type { | |
| 85 | if (ty.zigTypeTag(mod) != .Pointer) return null; | |
| 86 | const elem_ty = ty.childType(mod); | |
| 87 | if (elem_ty.zigTypeTag(mod) != .Fn) return null; | |
| 82 | pub fn castPtrToFn(ty: Type, zcu: *const Zcu) ?Type { | |
| 83 | if (ty.zigTypeTag(zcu) != .Pointer) return null; | |
| 84 | const elem_ty = ty.childType(zcu); | |
| 85 | if (elem_ty.zigTypeTag(zcu) != .Fn) return null; | |
| 88 | 86 | return elem_ty; |
| 89 | 87 | } |
| 90 | 88 | |
| 91 | 89 | /// Asserts the type is a pointer. |
| 92 | pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { | |
| 93 | return !mod.intern_pool.indexToKey(ty.toIntern()).ptr_type.flags.is_const; | |
| 90 | pub fn ptrIsMutable(ty: Type, zcu: *const Zcu) bool { | |
| 91 | return !zcu.intern_pool.indexToKey(ty.toIntern()).ptr_type.flags.is_const; | |
| 94 | 92 | } |
| 95 | 93 | |
| 96 | 94 | pub const ArrayInfo = struct { |
| ... | ... | @@ -99,18 +97,18 @@ pub const ArrayInfo = struct { |
| 99 | 97 | len: u64, |
| 100 | 98 | }; |
| 101 | 99 | |
| 102 | pub fn arrayInfo(self: Type, mod: *const Module) ArrayInfo { | |
| 100 | pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo { | |
| 103 | 101 | return .{ |
| 104 | .len = self.arrayLen(mod), | |
| 105 | .sentinel = self.sentinel(mod), | |
| 106 | .elem_type = self.childType(mod), | |
| 102 | .len = self.arrayLen(zcu), | |
| 103 | .sentinel = self.sentinel(zcu), | |
| 104 | .elem_type = self.childType(zcu), | |
| 107 | 105 | }; |
| 108 | 106 | } |
| 109 | 107 | |
| 110 | pub fn ptrInfo(ty: Type, mod: *const Module) InternPool.Key.PtrType { | |
| 111 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 108 | pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType { | |
| 109 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 112 | 110 | .ptr_type => |p| p, |
| 113 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | |
| 111 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 114 | 112 | .ptr_type => |p| p, |
| 115 | 113 | else => unreachable, |
| 116 | 114 | }, |
| ... | ... | @@ -118,8 +116,8 @@ pub fn ptrInfo(ty: Type, mod: *const Module) InternPool.Key.PtrType { |
| 118 | 116 | }; |
| 119 | 117 | } |
| 120 | 118 | |
| 121 | pub fn eql(a: Type, b: Type, mod: *const Module) bool { | |
| 122 | _ = mod; // TODO: remove this parameter | |
| 119 | pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool { | |
| 120 | _ = zcu; // TODO: remove this parameter | |
| 123 | 121 | // The InternPool data structure hashes based on Key to make interned objects |
| 124 | 122 | // unique. An Index can be treated simply as u32 value for the |
| 125 | 123 | // purpose of Type/Value hashing and equality. |
| ... | ... | @@ -179,8 +177,8 @@ pub fn dump( |
| 179 | 177 | /// Prints a name suitable for `@typeName`. |
| 180 | 178 | /// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels. |
| 181 | 179 | pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error!void { |
| 182 | const mod = pt.zcu; | |
| 183 | const ip = &mod.intern_pool; | |
| 180 | const zcu = pt.zcu; | |
| 181 | const ip = &zcu.intern_pool; | |
| 184 | 182 | switch (ip.indexToKey(ty.toIntern())) { |
| 185 | 183 | .int_type => |int_type| { |
| 186 | 184 | const sign_char: u8 = switch (int_type.signedness) { |
| ... | ... | @@ -190,7 +188,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 190 | 188 | return writer.print("{c}{d}", .{ sign_char, int_type.bits }); |
| 191 | 189 | }, |
| 192 | 190 | .ptr_type => { |
| 193 | const info = ty.ptrInfo(mod); | |
| 191 | const info = ty.ptrInfo(zcu); | |
| 194 | 192 | |
| 195 | 193 | if (info.sentinel != .none) switch (info.flags.size) { |
| 196 | 194 | .One, .C => unreachable, |
| ... | ... | @@ -210,7 +208,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 210 | 208 | const alignment = if (info.flags.alignment != .none) |
| 211 | 209 | info.flags.alignment |
| 212 | 210 | else |
| 213 | Type.fromInterned(info.child).abiAlignment(pt); | |
| 211 | Type.fromInterned(info.child).abiAlignment(pt.zcu); | |
| 214 | 212 | try writer.print("align({d}", .{alignment.toByteUnits() orelse 0}); |
| 215 | 213 | |
| 216 | 214 | if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) { |
| ... | ... | @@ -268,7 +266,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 268 | 266 | return; |
| 269 | 267 | }, |
| 270 | 268 | .inferred_error_set_type => |func_index| { |
| 271 | const func_nav = ip.getNav(mod.funcInfo(func_index).owner_nav); | |
| 269 | const func_nav = ip.getNav(zcu.funcInfo(func_index).owner_nav); | |
| 272 | 270 | try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{ |
| 273 | 271 | func_nav.fqn.fmt(ip), |
| 274 | 272 | }); |
| ... | ... | @@ -338,7 +336,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 338 | 336 | try writer.writeAll("comptime "); |
| 339 | 337 | } |
| 340 | 338 | if (anon_struct.names.len != 0) { |
| 341 | try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)}); | |
| 339 | try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&zcu.intern_pool)}); | |
| 342 | 340 | } |
| 343 | 341 | |
| 344 | 342 | try print(Type.fromInterned(field_ty), writer, pt); |
| ... | ... | @@ -367,7 +365,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 367 | 365 | try writer.writeAll("noinline "); |
| 368 | 366 | } |
| 369 | 367 | try writer.writeAll("fn ("); |
| 370 | const param_types = fn_info.param_types.get(&mod.intern_pool); | |
| 368 | const param_types = fn_info.param_types.get(&zcu.intern_pool); | |
| 371 | 369 | for (param_types, 0..) |param_ty, i| { |
| 372 | 370 | if (i != 0) try writer.writeAll(", "); |
| 373 | 371 | if (std.math.cast(u5, i)) |index| { |
| ... | ... | @@ -448,6 +446,21 @@ pub fn toValue(self: Type) Value { |
| 448 | 446 | |
| 449 | 447 | const RuntimeBitsError = SemaError || error{NeedLazy}; |
| 450 | 448 | |
| 449 | pub fn hasRuntimeBits(ty: Type, zcu: *Zcu) bool { | |
| 450 | return hasRuntimeBitsInner(ty, false, .eager, zcu, {}) catch unreachable; | |
| 451 | } | |
| 452 | ||
| 453 | pub fn hasRuntimeBitsSema(ty: Type, pt: Zcu.PerThread) SemaError!bool { | |
| 454 | return hasRuntimeBitsInner(ty, false, .sema, pt.zcu, pt.tid) catch |err| switch (err) { | |
| 455 | error.NeedLazy => unreachable, // this would require a resolve strat of lazy | |
| 456 | else => |e| return e, | |
| 457 | }; | |
| 458 | } | |
| 459 | ||
| 460 | pub fn hasRuntimeBitsIgnoreComptime(ty: Type, zcu: *Zcu) bool { | |
| 461 | return hasRuntimeBitsInner(ty, true, .eager, zcu, {}) catch unreachable; | |
| 462 | } | |
| 463 | ||
| 451 | 464 | /// true if and only if the type takes up space in memory at runtime. |
| 452 | 465 | /// There are two reasons a type will return false: |
| 453 | 466 | /// * the type is a comptime-only type. For example, the type `type` itself. |
| ... | ... | @@ -459,14 +472,14 @@ const RuntimeBitsError = SemaError || error{NeedLazy}; |
| 459 | 472 | /// making it one-possible-value only if the integer tag type has 0 bits. |
| 460 | 473 | /// When `ignore_comptime_only` is true, then types that are comptime-only |
| 461 | 474 | /// may return false positives. |
| 462 | pub fn hasRuntimeBitsAdvanced( | |
| 475 | pub fn hasRuntimeBitsInner( | |
| 463 | 476 | ty: Type, |
| 464 | pt: Zcu.PerThread, | |
| 465 | 477 | ignore_comptime_only: bool, |
| 466 | 478 | comptime strat: ResolveStratLazy, |
| 479 | zcu: *Zcu, | |
| 480 | tid: strat.Tid(), | |
| 467 | 481 | ) RuntimeBitsError!bool { |
| 468 | const mod = pt.zcu; | |
| 469 | const ip = &mod.intern_pool; | |
| 482 | const ip = &zcu.intern_pool; | |
| 470 | 483 | return switch (ty.toIntern()) { |
| 471 | 484 | // False because it is a comptime-only type. |
| 472 | 485 | .empty_struct_type => false, |
| ... | ... | @@ -477,26 +490,29 @@ pub fn hasRuntimeBitsAdvanced( |
| 477 | 490 | // to comptime-only types do not, with the exception of function pointers. |
| 478 | 491 | if (ignore_comptime_only) return true; |
| 479 | 492 | return switch (strat) { |
| 480 | .sema => !try ty.comptimeOnlyAdvanced(pt, .sema), | |
| 481 | .eager => !ty.comptimeOnly(pt), | |
| 493 | .sema => { | |
| 494 | const pt = strat.pt(zcu, tid); | |
| 495 | return !try ty.comptimeOnlySema(pt); | |
| 496 | }, | |
| 497 | .eager => !ty.comptimeOnly(zcu), | |
| 482 | 498 | .lazy => error.NeedLazy, |
| 483 | 499 | }; |
| 484 | 500 | }, |
| 485 | 501 | .anyframe_type => true, |
| 486 | 502 | .array_type => |array_type| return array_type.lenIncludingSentinel() > 0 and |
| 487 | try Type.fromInterned(array_type.child).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat), | |
| 503 | try Type.fromInterned(array_type.child).hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid), | |
| 488 | 504 | .vector_type => |vector_type| return vector_type.len > 0 and |
| 489 | try Type.fromInterned(vector_type.child).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat), | |
| 505 | try Type.fromInterned(vector_type.child).hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid), | |
| 490 | 506 | .opt_type => |child| { |
| 491 | 507 | const child_ty = Type.fromInterned(child); |
| 492 | if (child_ty.isNoReturn(mod)) { | |
| 508 | if (child_ty.isNoReturn(zcu)) { | |
| 493 | 509 | // Then the optional is comptime-known to be null. |
| 494 | 510 | return false; |
| 495 | 511 | } |
| 496 | 512 | if (ignore_comptime_only) return true; |
| 497 | 513 | return switch (strat) { |
| 498 | .sema => !try child_ty.comptimeOnlyAdvanced(pt, .sema), | |
| 499 | .eager => !child_ty.comptimeOnly(pt), | |
| 514 | .sema => !try child_ty.comptimeOnlyInner(.sema, zcu, tid), | |
| 515 | .eager => !child_ty.comptimeOnly(zcu), | |
| 500 | 516 | .lazy => error.NeedLazy, |
| 501 | 517 | }; |
| 502 | 518 | }, |
| ... | ... | @@ -556,14 +572,14 @@ pub fn hasRuntimeBitsAdvanced( |
| 556 | 572 | return true; |
| 557 | 573 | } |
| 558 | 574 | switch (strat) { |
| 559 | .sema => try ty.resolveFields(pt), | |
| 575 | .sema => try ty.resolveFields(strat.pt(zcu, tid)), | |
| 560 | 576 | .eager => assert(struct_type.haveFieldTypes(ip)), |
| 561 | 577 | .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy, |
| 562 | 578 | } |
| 563 | 579 | for (0..struct_type.field_types.len) |i| { |
| 564 | 580 | if (struct_type.comptime_bits.getBit(ip, i)) continue; |
| 565 | 581 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 566 | if (try field_ty.hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) | |
| 582 | if (try field_ty.hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid)) | |
| 567 | 583 | return true; |
| 568 | 584 | } else { |
| 569 | 585 | return false; |
| ... | ... | @@ -572,7 +588,12 @@ pub fn hasRuntimeBitsAdvanced( |
| 572 | 588 | .anon_struct_type => |tuple| { |
| 573 | 589 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 574 | 590 | if (val != .none) continue; // comptime field |
| 575 | if (try Type.fromInterned(field_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) return true; | |
| 591 | if (try Type.fromInterned(field_ty).hasRuntimeBitsInner( | |
| 592 | ignore_comptime_only, | |
| 593 | strat, | |
| 594 | zcu, | |
| 595 | tid, | |
| 596 | )) return true; | |
| 576 | 597 | } |
| 577 | 598 | return false; |
| 578 | 599 | }, |
| ... | ... | @@ -591,21 +612,25 @@ pub fn hasRuntimeBitsAdvanced( |
| 591 | 612 | // tag_ty will be `none` if this union's tag type is not resolved yet, |
| 592 | 613 | // in which case we want control flow to continue down below. |
| 593 | 614 | if (tag_ty != .none and |
| 594 | try Type.fromInterned(tag_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) | |
| 595 | { | |
| 615 | try Type.fromInterned(tag_ty).hasRuntimeBitsInner( | |
| 616 | ignore_comptime_only, | |
| 617 | strat, | |
| 618 | zcu, | |
| 619 | tid, | |
| 620 | )) { | |
| 596 | 621 | return true; |
| 597 | 622 | } |
| 598 | 623 | }, |
| 599 | 624 | } |
| 600 | 625 | switch (strat) { |
| 601 | .sema => try ty.resolveFields(pt), | |
| 626 | .sema => try ty.resolveFields(strat.pt(zcu, tid)), | |
| 602 | 627 | .eager => assert(union_flags.status.haveFieldTypes()), |
| 603 | 628 | .lazy => if (!union_flags.status.haveFieldTypes()) |
| 604 | 629 | return error.NeedLazy, |
| 605 | 630 | } |
| 606 | 631 | for (0..union_type.field_types.len) |field_index| { |
| 607 | 632 | const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); |
| 608 | if (try field_ty.hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat)) | |
| 633 | if (try field_ty.hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid)) | |
| 609 | 634 | return true; |
| 610 | 635 | } else { |
| 611 | 636 | return false; |
| ... | ... | @@ -613,7 +638,12 @@ pub fn hasRuntimeBitsAdvanced( |
| 613 | 638 | }, |
| 614 | 639 | |
| 615 | 640 | .opaque_type => true, |
| 616 | .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsAdvanced(pt, ignore_comptime_only, strat), | |
| 641 | .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsInner( | |
| 642 | ignore_comptime_only, | |
| 643 | strat, | |
| 644 | zcu, | |
| 645 | tid, | |
| 646 | ), | |
| 617 | 647 | |
| 618 | 648 | // values, not types |
| 619 | 649 | .undef, |
| ... | ... | @@ -643,8 +673,8 @@ pub fn hasRuntimeBitsAdvanced( |
| 643 | 673 | /// true if and only if the type has a well-defined memory layout |
| 644 | 674 | /// readFrom/writeToMemory are supported only for types with a well- |
| 645 | 675 | /// defined memory layout |
| 646 | pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { | |
| 647 | const ip = &mod.intern_pool; | |
| 676 | pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { | |
| 677 | const ip = &zcu.intern_pool; | |
| 648 | 678 | return switch (ip.indexToKey(ty.toIntern())) { |
| 649 | 679 | .int_type, |
| 650 | 680 | .vector_type, |
| ... | ... | @@ -660,8 +690,8 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { |
| 660 | 690 | .func_type, |
| 661 | 691 | => false, |
| 662 | 692 | |
| 663 | .array_type => |array_type| Type.fromInterned(array_type.child).hasWellDefinedLayout(mod), | |
| 664 | .opt_type => ty.isPtrLikeOptional(mod), | |
| 693 | .array_type => |array_type| Type.fromInterned(array_type.child).hasWellDefinedLayout(zcu), | |
| 694 | .opt_type => ty.isPtrLikeOptional(zcu), | |
| 665 | 695 | .ptr_type => |ptr_type| ptr_type.flags.size != .Slice, |
| 666 | 696 | |
| 667 | 697 | .simple_type => |t| switch (t) { |
| ... | ... | @@ -740,94 +770,99 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool { |
| 740 | 770 | }; |
| 741 | 771 | } |
| 742 | 772 | |
| 743 | pub fn hasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { | |
| 744 | return hasRuntimeBitsAdvanced(ty, pt, false, .eager) catch unreachable; | |
| 773 | pub fn fnHasRuntimeBits(ty: Type, zcu: *Zcu) bool { | |
| 774 | return ty.fnHasRuntimeBitsInner(.normal, zcu, {}) catch unreachable; | |
| 745 | 775 | } |
| 746 | 776 | |
| 747 | pub fn hasRuntimeBitsIgnoreComptime(ty: Type, pt: Zcu.PerThread) bool { | |
| 748 | return hasRuntimeBitsAdvanced(ty, pt, true, .eager) catch unreachable; | |
| 749 | } | |
| 750 | ||
| 751 | pub fn fnHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { | |
| 752 | return ty.fnHasRuntimeBitsAdvanced(pt, .normal) catch unreachable; | |
| 777 | pub fn fnHasRuntimeBitsSema(ty: Type, pt: Zcu.PerThread) SemaError!bool { | |
| 778 | return try ty.fnHasRuntimeBitsInner(.sema, pt.zcu, pt.tid); | |
| 753 | 779 | } |
| 754 | 780 | |
| 755 | 781 | /// Determines whether a function type has runtime bits, i.e. whether a |
| 756 | 782 | /// function with this type can exist at runtime. |
| 757 | 783 | /// Asserts that `ty` is a function type. |
| 758 | pub fn fnHasRuntimeBitsAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) SemaError!bool { | |
| 759 | const fn_info = pt.zcu.typeToFunc(ty).?; | |
| 784 | pub fn fnHasRuntimeBitsInner( | |
| 785 | ty: Type, | |
| 786 | comptime strat: ResolveStrat, | |
| 787 | zcu: *Zcu, | |
| 788 | tid: strat.Tid(), | |
| 789 | ) SemaError!bool { | |
| 790 | const fn_info = zcu.typeToFunc(ty).?; | |
| 760 | 791 | if (fn_info.is_generic) return false; |
| 761 | 792 | if (fn_info.is_var_args) return true; |
| 762 | 793 | if (fn_info.cc == .Inline) return false; |
| 763 | return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(pt, strat); | |
| 794 | return !try Type.fromInterned(fn_info.return_type).comptimeOnlyInner(strat, zcu, tid); | |
| 764 | 795 | } |
| 765 | 796 | |
| 766 | pub fn isFnOrHasRuntimeBits(ty: Type, pt: Zcu.PerThread) bool { | |
| 767 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 768 | .Fn => return ty.fnHasRuntimeBits(pt), | |
| 769 | else => return ty.hasRuntimeBits(pt), | |
| 797 | pub fn isFnOrHasRuntimeBits(ty: Type, zcu: *Zcu) bool { | |
| 798 | switch (ty.zigTypeTag(zcu)) { | |
| 799 | .Fn => return ty.fnHasRuntimeBits(zcu), | |
| 800 | else => return ty.hasRuntimeBits(zcu), | |
| 770 | 801 | } |
| 771 | 802 | } |
| 772 | 803 | |
| 773 | 804 | /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive. |
| 774 | pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, pt: Zcu.PerThread) bool { | |
| 775 | return switch (ty.zigTypeTag(pt.zcu)) { | |
| 805 | pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, zcu: *Zcu) bool { | |
| 806 | return switch (ty.zigTypeTag(zcu)) { | |
| 776 | 807 | .Fn => true, |
| 777 | else => return ty.hasRuntimeBitsIgnoreComptime(pt), | |
| 808 | else => return ty.hasRuntimeBitsIgnoreComptime(zcu), | |
| 778 | 809 | }; |
| 779 | 810 | } |
| 780 | 811 | |
| 781 | pub fn isNoReturn(ty: Type, mod: *Module) bool { | |
| 782 | return mod.intern_pool.isNoReturn(ty.toIntern()); | |
| 812 | pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool { | |
| 813 | return zcu.intern_pool.isNoReturn(ty.toIntern()); | |
| 783 | 814 | } |
| 784 | 815 | |
| 785 | 816 | /// Returns `none` if the pointer is naturally aligned and the element type is 0-bit. |
| 786 | pub fn ptrAlignment(ty: Type, pt: Zcu.PerThread) Alignment { | |
| 787 | return ptrAlignmentAdvanced(ty, pt, .normal) catch unreachable; | |
| 817 | pub fn ptrAlignment(ty: Type, zcu: *Zcu) Alignment { | |
| 818 | return ptrAlignmentInner(ty, .normal, zcu, {}) catch unreachable; | |
| 819 | } | |
| 820 | ||
| 821 | pub fn ptrAlignmentSema(ty: Type, pt: Zcu.PerThread) SemaError!Alignment { | |
| 822 | return try ty.ptrAlignmentInner(.sema, pt.zcu, pt.tid); | |
| 788 | 823 | } |
| 789 | 824 | |
| 790 | pub fn ptrAlignmentAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Alignment { | |
| 791 | return switch (pt.zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 825 | pub fn ptrAlignmentInner( | |
| 826 | ty: Type, | |
| 827 | comptime strat: ResolveStrat, | |
| 828 | zcu: *Zcu, | |
| 829 | tid: strat.Tid(), | |
| 830 | ) !Alignment { | |
| 831 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 792 | 832 | .ptr_type => |ptr_type| { |
| 793 | 833 | if (ptr_type.flags.alignment != .none) |
| 794 | 834 | return ptr_type.flags.alignment; |
| 795 | 835 | |
| 796 | 836 | if (strat == .sema) { |
| 797 | const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(pt, .sema); | |
| 837 | const res = try Type.fromInterned(ptr_type.child).abiAlignmentInner(.sema, zcu, tid); | |
| 798 | 838 | return res.scalar; |
| 799 | 839 | } |
| 800 | 840 | |
| 801 | return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(pt, .eager) catch unreachable).scalar; | |
| 841 | return Type.fromInterned(ptr_type.child).abiAlignment(zcu); | |
| 802 | 842 | }, |
| 803 | .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(pt, strat), | |
| 843 | .opt_type => |child| Type.fromInterned(child).ptrAlignmentInner(strat, zcu, tid), | |
| 804 | 844 | else => unreachable, |
| 805 | 845 | }; |
| 806 | 846 | } |
| 807 | 847 | |
| 808 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { | |
| 809 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 848 | pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace { | |
| 849 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 810 | 850 | .ptr_type => |ptr_type| ptr_type.flags.address_space, |
| 811 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.flags.address_space, | |
| 851 | .opt_type => |child| zcu.intern_pool.indexToKey(child).ptr_type.flags.address_space, | |
| 812 | 852 | else => unreachable, |
| 813 | 853 | }; |
| 814 | 854 | } |
| 815 | 855 | |
| 816 | /// Never returns `none`. Asserts that all necessary type resolution is already done. | |
| 817 | pub fn abiAlignment(ty: Type, pt: Zcu.PerThread) Alignment { | |
| 818 | return (ty.abiAlignmentAdvanced(pt, .eager) catch unreachable).scalar; | |
| 819 | } | |
| 820 | ||
| 821 | 856 | /// May capture a reference to `ty`. |
| 822 | 857 | /// Returned value has type `comptime_int`. |
| 823 | 858 | pub fn lazyAbiAlignment(ty: Type, pt: Zcu.PerThread) !Value { |
| 824 | switch (try ty.abiAlignmentAdvanced(pt, .lazy)) { | |
| 859 | switch (try ty.abiAlignmentInner(.lazy, pt.zcu, pt.tid)) { | |
| 825 | 860 | .val => |val| return val, |
| 826 | 861 | .scalar => |x| return pt.intValue(Type.comptime_int, x.toByteUnits() orelse 0), |
| 827 | 862 | } |
| 828 | 863 | } |
| 829 | 864 | |
| 830 | pub const AbiAlignmentAdvanced = union(enum) { | |
| 865 | pub const AbiAlignmentInner = union(enum) { | |
| 831 | 866 | scalar: Alignment, |
| 832 | 867 | val: Value, |
| 833 | 868 | }; |
| ... | ... | @@ -842,6 +877,23 @@ pub const ResolveStratLazy = enum { |
| 842 | 877 | /// Return a scalar result, performing type resolution as necessary. |
| 843 | 878 | /// This should typically be used from semantic analysis. |
| 844 | 879 | sema, |
| 880 | ||
| 881 | pub fn Tid(comptime strat: ResolveStratLazy) type { | |
| 882 | return switch (strat) { | |
| 883 | .lazy, .sema => Zcu.PerThread.Id, | |
| 884 | .eager => void, | |
| 885 | }; | |
| 886 | } | |
| 887 | ||
| 888 | pub fn pt(comptime strat: ResolveStratLazy, zcu: *Zcu, tid: strat.Tid()) switch (strat) { | |
| 889 | .lazy, .sema => Zcu.PerThread, | |
| 890 | .eager => void, | |
| 891 | } { | |
| 892 | return switch (strat) { | |
| 893 | .lazy, .sema => .{ .tid = tid, .zcu = zcu }, | |
| 894 | else => {}, | |
| 895 | }; | |
| 896 | } | |
| 845 | 897 | }; |
| 846 | 898 | |
| 847 | 899 | /// The chosen strategy can be easily optimized away in release builds. |
| ... | ... | @@ -854,6 +906,23 @@ pub const ResolveStrat = enum { |
| 854 | 906 | /// This should typically be used from semantic analysis. |
| 855 | 907 | sema, |
| 856 | 908 | |
| 909 | pub fn Tid(comptime strat: ResolveStrat) type { | |
| 910 | return switch (strat) { | |
| 911 | .sema => Zcu.PerThread.Id, | |
| 912 | .normal => void, | |
| 913 | }; | |
| 914 | } | |
| 915 | ||
| 916 | pub fn pt(comptime strat: ResolveStrat, zcu: *Zcu, tid: strat.Tid()) switch (strat) { | |
| 917 | .sema => Zcu.PerThread, | |
| 918 | .normal => void, | |
| 919 | } { | |
| 920 | return switch (strat) { | |
| 921 | .sema => .{ .tid = tid, .zcu = zcu }, | |
| 922 | .normal => {}, | |
| 923 | }; | |
| 924 | } | |
| 925 | ||
| 857 | 926 | pub inline fn toLazy(strat: ResolveStrat) ResolveStratLazy { |
| 858 | 927 | return switch (strat) { |
| 859 | 928 | .normal => .eager, |
| ... | ... | @@ -862,21 +931,31 @@ pub const ResolveStrat = enum { |
| 862 | 931 | } |
| 863 | 932 | }; |
| 864 | 933 | |
| 934 | /// Never returns `none`. Asserts that all necessary type resolution is already done. | |
| 935 | pub fn abiAlignment(ty: Type, zcu: *Zcu) Alignment { | |
| 936 | return (ty.abiAlignmentInner(.eager, zcu, {}) catch unreachable).scalar; | |
| 937 | } | |
| 938 | ||
| 939 | pub fn abiAlignmentSema(ty: Type, pt: Zcu.PerThread) SemaError!Alignment { | |
| 940 | return (try ty.abiAlignmentInner(.sema, pt.zcu, pt.tid)).scalar; | |
| 941 | } | |
| 942 | ||
| 865 | 943 | /// If you pass `eager` you will get back `scalar` and assert the type is resolved. |
| 866 | 944 | /// In this case there will be no error, guaranteed. |
| 867 | 945 | /// If you pass `lazy` you may get back `scalar` or `val`. |
| 868 | 946 | /// If `val` is returned, a reference to `ty` has been captured. |
| 869 | 947 | /// If you pass `sema` you will get back `scalar` and resolve the type if |
| 870 | 948 | /// necessary, possibly returning a CompileError. |
| 871 | pub fn abiAlignmentAdvanced( | |
| 949 | pub fn abiAlignmentInner( | |
| 872 | 950 | ty: Type, |
| 873 | pt: Zcu.PerThread, | |
| 874 | 951 | comptime strat: ResolveStratLazy, |
| 875 | ) SemaError!AbiAlignmentAdvanced { | |
| 876 | const mod = pt.zcu; | |
| 877 | const target = mod.getTarget(); | |
| 878 | const use_llvm = mod.comp.config.use_llvm; | |
| 879 | const ip = &mod.intern_pool; | |
| 952 | zcu: *Zcu, | |
| 953 | tid: strat.Tid(), | |
| 954 | ) SemaError!AbiAlignmentInner { | |
| 955 | const pt = strat.pt(zcu, tid); | |
| 956 | const target = zcu.getTarget(); | |
| 957 | const use_llvm = zcu.comp.config.use_llvm; | |
| 958 | const ip = &zcu.intern_pool; | |
| 880 | 959 | |
| 881 | 960 | switch (ty.toIntern()) { |
| 882 | 961 | .empty_struct_type => return .{ .scalar = .@"1" }, |
| ... | ... | @@ -889,22 +968,22 @@ pub fn abiAlignmentAdvanced( |
| 889 | 968 | return .{ .scalar = ptrAbiAlignment(target) }; |
| 890 | 969 | }, |
| 891 | 970 | .array_type => |array_type| { |
| 892 | return Type.fromInterned(array_type.child).abiAlignmentAdvanced(pt, strat); | |
| 971 | return Type.fromInterned(array_type.child).abiAlignmentInner(strat, zcu, tid); | |
| 893 | 972 | }, |
| 894 | 973 | .vector_type => |vector_type| { |
| 895 | 974 | if (vector_type.len == 0) return .{ .scalar = .@"1" }; |
| 896 | switch (mod.comp.getZigBackend()) { | |
| 975 | switch (zcu.comp.getZigBackend()) { | |
| 897 | 976 | else => { |
| 898 | 977 | // This is fine because the child type of a vector always has a bit-size known |
| 899 | 978 | // without needing any type resolution. |
| 900 | const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(pt)); | |
| 979 | const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(zcu)); | |
| 901 | 980 | if (elem_bits == 0) return .{ .scalar = .@"1" }; |
| 902 | 981 | const bytes = ((elem_bits * vector_type.len) + 7) / 8; |
| 903 | 982 | const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); |
| 904 | 983 | return .{ .scalar = Alignment.fromByteUnits(alignment) }; |
| 905 | 984 | }, |
| 906 | 985 | .stage2_c => { |
| 907 | return Type.fromInterned(vector_type.child).abiAlignmentAdvanced(pt, strat); | |
| 986 | return Type.fromInterned(vector_type.child).abiAlignmentInner(strat, zcu, tid); | |
| 908 | 987 | }, |
| 909 | 988 | .stage2_x86_64 => { |
| 910 | 989 | if (vector_type.child == .bool_type) { |
| ... | ... | @@ -915,7 +994,7 @@ pub fn abiAlignmentAdvanced( |
| 915 | 994 | const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); |
| 916 | 995 | return .{ .scalar = Alignment.fromByteUnits(alignment) }; |
| 917 | 996 | } |
| 918 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar); | |
| 997 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar); | |
| 919 | 998 | if (elem_bytes == 0) return .{ .scalar = .@"1" }; |
| 920 | 999 | const bytes = elem_bytes * vector_type.len; |
| 921 | 1000 | if (bytes > 32 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" }; |
| ... | ... | @@ -925,11 +1004,16 @@ pub fn abiAlignmentAdvanced( |
| 925 | 1004 | } |
| 926 | 1005 | }, |
| 927 | 1006 | |
| 928 | .opt_type => return ty.abiAlignmentAdvancedOptional(pt, strat), | |
| 929 | .error_union_type => |info| return ty.abiAlignmentAdvancedErrorUnion(pt, strat, Type.fromInterned(info.payload_type)), | |
| 1007 | .opt_type => return ty.abiAlignmentInnerOptional(strat, zcu, tid), | |
| 1008 | .error_union_type => |info| return ty.abiAlignmentInnerErrorUnion( | |
| 1009 | strat, | |
| 1010 | zcu, | |
| 1011 | tid, | |
| 1012 | Type.fromInterned(info.payload_type), | |
| 1013 | ), | |
| 930 | 1014 | |
| 931 | 1015 | .error_set_type, .inferred_error_set_type => { |
| 932 | const bits = mod.errorSetBits(); | |
| 1016 | const bits = zcu.errorSetBits(); | |
| 933 | 1017 | if (bits == 0) return .{ .scalar = .@"1" }; |
| 934 | 1018 | return .{ .scalar = intAbiAlignment(bits, target, use_llvm) }; |
| 935 | 1019 | }, |
| ... | ... | @@ -965,7 +1049,7 @@ pub fn abiAlignmentAdvanced( |
| 965 | 1049 | }, |
| 966 | 1050 | .f80 => switch (target.cTypeBitSize(.longdouble)) { |
| 967 | 1051 | 80 => return .{ .scalar = cTypeAlign(target, .longdouble) }, |
| 968 | else => return .{ .scalar = Type.u80.abiAlignment(pt) }, | |
| 1052 | else => return .{ .scalar = Type.u80.abiAlignment(zcu) }, | |
| 969 | 1053 | }, |
| 970 | 1054 | .f128 => switch (target.cTypeBitSize(.longdouble)) { |
| 971 | 1055 | 128 => return .{ .scalar = cTypeAlign(target, .longdouble) }, |
| ... | ... | @@ -973,7 +1057,7 @@ pub fn abiAlignmentAdvanced( |
| 973 | 1057 | }, |
| 974 | 1058 | |
| 975 | 1059 | .anyerror, .adhoc_inferred_error_set => { |
| 976 | const bits = mod.errorSetBits(); | |
| 1060 | const bits = zcu.errorSetBits(); | |
| 977 | 1061 | if (bits == 0) return .{ .scalar = .@"1" }; |
| 978 | 1062 | return .{ .scalar = intAbiAlignment(bits, target, use_llvm) }; |
| 979 | 1063 | }, |
| ... | ... | @@ -1003,7 +1087,7 @@ pub fn abiAlignmentAdvanced( |
| 1003 | 1087 | }, |
| 1004 | 1088 | .eager => {}, |
| 1005 | 1089 | } |
| 1006 | return .{ .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiAlignment(pt) }; | |
| 1090 | return .{ .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiAlignment(zcu) }; | |
| 1007 | 1091 | } |
| 1008 | 1092 | |
| 1009 | 1093 | if (struct_type.flagsUnordered(ip).alignment == .none) switch (strat) { |
| ... | ... | @@ -1021,11 +1105,11 @@ pub fn abiAlignmentAdvanced( |
| 1021 | 1105 | var big_align: Alignment = .@"1"; |
| 1022 | 1106 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 1023 | 1107 | if (val != .none) continue; // comptime field |
| 1024 | switch (try Type.fromInterned(field_ty).abiAlignmentAdvanced(pt, strat)) { | |
| 1108 | switch (try Type.fromInterned(field_ty).abiAlignmentInner(strat, zcu, tid)) { | |
| 1025 | 1109 | .scalar => |field_align| big_align = big_align.max(field_align), |
| 1026 | 1110 | .val => switch (strat) { |
| 1027 | 1111 | .eager => unreachable, // field type alignment not resolved |
| 1028 | .sema => unreachable, // passed to abiAlignmentAdvanced above | |
| 1112 | .sema => unreachable, // passed to abiAlignmentInner above | |
| 1029 | 1113 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1030 | 1114 | .ty = .comptime_int_type, |
| 1031 | 1115 | .storage = .{ .lazy_align = ty.toIntern() }, |
| ... | ... | @@ -1051,7 +1135,7 @@ pub fn abiAlignmentAdvanced( |
| 1051 | 1135 | }, |
| 1052 | 1136 | .opaque_type => return .{ .scalar = .@"1" }, |
| 1053 | 1137 | .enum_type => return .{ |
| 1054 | .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(pt), | |
| 1138 | .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(zcu), | |
| 1055 | 1139 | }, |
| 1056 | 1140 | |
| 1057 | 1141 | // values, not types |
| ... | ... | @@ -1079,32 +1163,37 @@ pub fn abiAlignmentAdvanced( |
| 1079 | 1163 | } |
| 1080 | 1164 | } |
| 1081 | 1165 | |
| 1082 | fn abiAlignmentAdvancedErrorUnion( | |
| 1166 | fn abiAlignmentInnerErrorUnion( | |
| 1083 | 1167 | ty: Type, |
| 1084 | pt: Zcu.PerThread, | |
| 1085 | 1168 | comptime strat: ResolveStratLazy, |
| 1169 | zcu: *Zcu, | |
| 1170 | tid: strat.Tid(), | |
| 1086 | 1171 | payload_ty: Type, |
| 1087 | ) SemaError!AbiAlignmentAdvanced { | |
| 1172 | ) SemaError!AbiAlignmentInner { | |
| 1088 | 1173 | // This code needs to be kept in sync with the equivalent switch prong |
| 1089 | // in abiSizeAdvanced. | |
| 1090 | const code_align = Type.anyerror.abiAlignment(pt); | |
| 1174 | // in abiSizeInner. | |
| 1175 | const code_align = Type.anyerror.abiAlignment(zcu); | |
| 1091 | 1176 | switch (strat) { |
| 1092 | 1177 | .eager, .sema => { |
| 1093 | if (!(payload_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { | |
| 1094 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1095 | .ty = .comptime_int_type, | |
| 1096 | .storage = .{ .lazy_align = ty.toIntern() }, | |
| 1097 | } })) }, | |
| 1178 | if (!(payload_ty.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) { | |
| 1179 | error.NeedLazy => if (strat == .lazy) { | |
| 1180 | const pt = strat.pt(zcu, tid); | |
| 1181 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1182 | .ty = .comptime_int_type, | |
| 1183 | .storage = .{ .lazy_align = ty.toIntern() }, | |
| 1184 | } })) }; | |
| 1185 | } else unreachable, | |
| 1098 | 1186 | else => |e| return e, |
| 1099 | 1187 | })) { |
| 1100 | 1188 | return .{ .scalar = code_align }; |
| 1101 | 1189 | } |
| 1102 | 1190 | return .{ .scalar = code_align.max( |
| 1103 | (try payload_ty.abiAlignmentAdvanced(pt, strat)).scalar, | |
| 1191 | (try payload_ty.abiAlignmentInner(strat, zcu, tid)).scalar, | |
| 1104 | 1192 | ) }; |
| 1105 | 1193 | }, |
| 1106 | 1194 | .lazy => { |
| 1107 | switch (try payload_ty.abiAlignmentAdvanced(pt, strat)) { | |
| 1195 | const pt = strat.pt(zcu, tid); | |
| 1196 | switch (try payload_ty.abiAlignmentInner(strat, zcu, tid)) { | |
| 1108 | 1197 | .scalar => |payload_align| return .{ .scalar = code_align.max(payload_align) }, |
| 1109 | 1198 | .val => {}, |
| 1110 | 1199 | } |
| ... | ... | @@ -1116,36 +1205,39 @@ fn abiAlignmentAdvancedErrorUnion( |
| 1116 | 1205 | } |
| 1117 | 1206 | } |
| 1118 | 1207 | |
| 1119 | fn abiAlignmentAdvancedOptional( | |
| 1208 | fn abiAlignmentInnerOptional( | |
| 1120 | 1209 | ty: Type, |
| 1121 | pt: Zcu.PerThread, | |
| 1122 | 1210 | comptime strat: ResolveStratLazy, |
| 1123 | ) SemaError!AbiAlignmentAdvanced { | |
| 1124 | const mod = pt.zcu; | |
| 1125 | const target = mod.getTarget(); | |
| 1126 | const child_type = ty.optionalChild(mod); | |
| 1127 | ||
| 1128 | switch (child_type.zigTypeTag(mod)) { | |
| 1211 | zcu: *Zcu, | |
| 1212 | tid: strat.Tid(), | |
| 1213 | ) SemaError!AbiAlignmentInner { | |
| 1214 | const pt = strat.pt(zcu, tid); | |
| 1215 | const target = zcu.getTarget(); | |
| 1216 | const child_type = ty.optionalChild(zcu); | |
| 1217 | ||
| 1218 | switch (child_type.zigTypeTag(zcu)) { | |
| 1129 | 1219 | .Pointer => return .{ .scalar = ptrAbiAlignment(target) }, |
| 1130 | .ErrorSet => return Type.anyerror.abiAlignmentAdvanced(pt, strat), | |
| 1220 | .ErrorSet => return Type.anyerror.abiAlignmentInner(strat, zcu, tid), | |
| 1131 | 1221 | .NoReturn => return .{ .scalar = .@"1" }, |
| 1132 | 1222 | else => {}, |
| 1133 | 1223 | } |
| 1134 | 1224 | |
| 1135 | 1225 | switch (strat) { |
| 1136 | 1226 | .eager, .sema => { |
| 1137 | if (!(child_type.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { | |
| 1138 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1139 | .ty = .comptime_int_type, | |
| 1140 | .storage = .{ .lazy_align = ty.toIntern() }, | |
| 1141 | } })) }, | |
| 1227 | if (!(child_type.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) { | |
| 1228 | error.NeedLazy => if (strat == .lazy) { | |
| 1229 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1230 | .ty = .comptime_int_type, | |
| 1231 | .storage = .{ .lazy_align = ty.toIntern() }, | |
| 1232 | } })) }; | |
| 1233 | } else unreachable, | |
| 1142 | 1234 | else => |e| return e, |
| 1143 | 1235 | })) { |
| 1144 | 1236 | return .{ .scalar = .@"1" }; |
| 1145 | 1237 | } |
| 1146 | return child_type.abiAlignmentAdvanced(pt, strat); | |
| 1238 | return child_type.abiAlignmentInner(strat, zcu, tid); | |
| 1147 | 1239 | }, |
| 1148 | .lazy => switch (try child_type.abiAlignmentAdvanced(pt, strat)) { | |
| 1240 | .lazy => switch (try child_type.abiAlignmentInner(strat, zcu, tid)) { | |
| 1149 | 1241 | .scalar => |x| return .{ .scalar = x.max(.@"1") }, |
| 1150 | 1242 | .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ |
| 1151 | 1243 | .ty = .comptime_int_type, |
| ... | ... | @@ -1155,40 +1247,44 @@ fn abiAlignmentAdvancedOptional( |
| 1155 | 1247 | } |
| 1156 | 1248 | } |
| 1157 | 1249 | |
| 1250 | const AbiSizeInner = union(enum) { | |
| 1251 | scalar: u64, | |
| 1252 | val: Value, | |
| 1253 | }; | |
| 1254 | ||
| 1255 | /// Asserts the type has the ABI size already resolved. | |
| 1256 | /// Types that return false for hasRuntimeBits() return 0. | |
| 1257 | pub fn abiSize(ty: Type, zcu: *Zcu) u64 { | |
| 1258 | return (abiSizeInner(ty, .eager, zcu, {}) catch unreachable).scalar; | |
| 1259 | } | |
| 1260 | ||
| 1158 | 1261 | /// May capture a reference to `ty`. |
| 1159 | 1262 | pub fn lazyAbiSize(ty: Type, pt: Zcu.PerThread) !Value { |
| 1160 | switch (try ty.abiSizeAdvanced(pt, .lazy)) { | |
| 1263 | switch (try ty.abiSizeInner(.lazy, pt.zcu, pt.tid)) { | |
| 1161 | 1264 | .val => |val| return val, |
| 1162 | 1265 | .scalar => |x| return pt.intValue(Type.comptime_int, x), |
| 1163 | 1266 | } |
| 1164 | 1267 | } |
| 1165 | 1268 | |
| 1166 | /// Asserts the type has the ABI size already resolved. | |
| 1167 | /// Types that return false for hasRuntimeBits() return 0. | |
| 1168 | pub fn abiSize(ty: Type, pt: Zcu.PerThread) u64 { | |
| 1169 | return (abiSizeAdvanced(ty, pt, .eager) catch unreachable).scalar; | |
| 1269 | pub fn abiSizeSema(ty: Type, pt: Zcu.PerThread) SemaError!u64 { | |
| 1270 | return (try abiSizeInner(ty, .sema, pt.zcu, pt.tid)).scalar; | |
| 1170 | 1271 | } |
| 1171 | 1272 | |
| 1172 | const AbiSizeAdvanced = union(enum) { | |
| 1173 | scalar: u64, | |
| 1174 | val: Value, | |
| 1175 | }; | |
| 1176 | ||
| 1177 | 1273 | /// If you pass `eager` you will get back `scalar` and assert the type is resolved. |
| 1178 | 1274 | /// In this case there will be no error, guaranteed. |
| 1179 | 1275 | /// If you pass `lazy` you may get back `scalar` or `val`. |
| 1180 | 1276 | /// If `val` is returned, a reference to `ty` has been captured. |
| 1181 | 1277 | /// If you pass `sema` you will get back `scalar` and resolve the type if |
| 1182 | 1278 | /// necessary, possibly returning a CompileError. |
| 1183 | pub fn abiSizeAdvanced( | |
| 1279 | pub fn abiSizeInner( | |
| 1184 | 1280 | ty: Type, |
| 1185 | pt: Zcu.PerThread, | |
| 1186 | 1281 | comptime strat: ResolveStratLazy, |
| 1187 | ) SemaError!AbiSizeAdvanced { | |
| 1188 | const mod = pt.zcu; | |
| 1189 | const target = mod.getTarget(); | |
| 1190 | const use_llvm = mod.comp.config.use_llvm; | |
| 1191 | const ip = &mod.intern_pool; | |
| 1282 | zcu: *Zcu, | |
| 1283 | tid: strat.Tid(), | |
| 1284 | ) SemaError!AbiSizeInner { | |
| 1285 | const target = zcu.getTarget(); | |
| 1286 | const use_llvm = zcu.comp.config.use_llvm; | |
| 1287 | const ip = &zcu.intern_pool; | |
| 1192 | 1288 | |
| 1193 | 1289 | switch (ty.toIntern()) { |
| 1194 | 1290 | .empty_struct_type => return .{ .scalar = 0 }, |
| ... | ... | @@ -1207,14 +1303,17 @@ pub fn abiSizeAdvanced( |
| 1207 | 1303 | .array_type => |array_type| { |
| 1208 | 1304 | const len = array_type.lenIncludingSentinel(); |
| 1209 | 1305 | if (len == 0) return .{ .scalar = 0 }; |
| 1210 | switch (try Type.fromInterned(array_type.child).abiSizeAdvanced(pt, strat)) { | |
| 1306 | switch (try Type.fromInterned(array_type.child).abiSizeInner(strat, zcu, tid)) { | |
| 1211 | 1307 | .scalar => |elem_size| return .{ .scalar = len * elem_size }, |
| 1212 | 1308 | .val => switch (strat) { |
| 1213 | 1309 | .sema, .eager => unreachable, |
| 1214 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1215 | .ty = .comptime_int_type, | |
| 1216 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1217 | } })) }, | |
| 1310 | .lazy => { | |
| 1311 | const pt = strat.pt(zcu, tid); | |
| 1312 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1313 | .ty = .comptime_int_type, | |
| 1314 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1315 | } })) }; | |
| 1316 | }, | |
| 1218 | 1317 | }, |
| 1219 | 1318 | } |
| 1220 | 1319 | }, |
| ... | ... | @@ -1222,41 +1321,38 @@ pub fn abiSizeAdvanced( |
| 1222 | 1321 | const sub_strat: ResolveStrat = switch (strat) { |
| 1223 | 1322 | .sema => .sema, |
| 1224 | 1323 | .eager => .normal, |
| 1225 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1226 | .ty = .comptime_int_type, | |
| 1227 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1228 | } })) }, | |
| 1229 | }; | |
| 1230 | const alignment = switch (try ty.abiAlignmentAdvanced(pt, strat)) { | |
| 1231 | .scalar => |x| x, | |
| 1232 | .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1233 | .ty = .comptime_int_type, | |
| 1234 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1235 | } })) }, | |
| 1324 | .lazy => { | |
| 1325 | const pt = strat.pt(zcu, tid); | |
| 1326 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1327 | .ty = .comptime_int_type, | |
| 1328 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1329 | } })) }; | |
| 1330 | }, | |
| 1236 | 1331 | }; |
| 1237 | const total_bytes = switch (mod.comp.getZigBackend()) { | |
| 1332 | const alignment = (try ty.abiAlignmentInner(strat, zcu, tid)).scalar; | |
| 1333 | const total_bytes = switch (zcu.comp.getZigBackend()) { | |
| 1238 | 1334 | else => total_bytes: { |
| 1239 | const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(pt, sub_strat); | |
| 1335 | const elem_bits = try Type.fromInterned(vector_type.child).bitSizeInner(sub_strat, zcu, tid); | |
| 1240 | 1336 | const total_bits = elem_bits * vector_type.len; |
| 1241 | 1337 | break :total_bytes (total_bits + 7) / 8; |
| 1242 | 1338 | }, |
| 1243 | 1339 | .stage2_c => total_bytes: { |
| 1244 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar); | |
| 1340 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar); | |
| 1245 | 1341 | break :total_bytes elem_bytes * vector_type.len; |
| 1246 | 1342 | }, |
| 1247 | 1343 | .stage2_x86_64 => total_bytes: { |
| 1248 | 1344 | if (vector_type.child == .bool_type) break :total_bytes std.math.divCeil(u32, vector_type.len, 8) catch unreachable; |
| 1249 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeAdvanced(pt, strat)).scalar); | |
| 1345 | const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar); | |
| 1250 | 1346 | break :total_bytes elem_bytes * vector_type.len; |
| 1251 | 1347 | }, |
| 1252 | 1348 | }; |
| 1253 | 1349 | return .{ .scalar = alignment.forward(total_bytes) }; |
| 1254 | 1350 | }, |
| 1255 | 1351 | |
| 1256 | .opt_type => return ty.abiSizeAdvancedOptional(pt, strat), | |
| 1352 | .opt_type => return ty.abiSizeInnerOptional(strat, zcu, tid), | |
| 1257 | 1353 | |
| 1258 | 1354 | .error_set_type, .inferred_error_set_type => { |
| 1259 | const bits = mod.errorSetBits(); | |
| 1355 | const bits = zcu.errorSetBits(); | |
| 1260 | 1356 | if (bits == 0) return .{ .scalar = 0 }; |
| 1261 | 1357 | return .{ .scalar = intAbiSize(bits, target, use_llvm) }; |
| 1262 | 1358 | }, |
| ... | ... | @@ -1264,29 +1360,35 @@ pub fn abiSizeAdvanced( |
| 1264 | 1360 | .error_union_type => |error_union_type| { |
| 1265 | 1361 | const payload_ty = Type.fromInterned(error_union_type.payload_type); |
| 1266 | 1362 | // This code needs to be kept in sync with the equivalent switch prong |
| 1267 | // in abiAlignmentAdvanced. | |
| 1268 | const code_size = Type.anyerror.abiSize(pt); | |
| 1269 | if (!(payload_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { | |
| 1270 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1271 | .ty = .comptime_int_type, | |
| 1272 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1273 | } })) }, | |
| 1363 | // in abiAlignmentInner. | |
| 1364 | const code_size = Type.anyerror.abiSize(zcu); | |
| 1365 | if (!(payload_ty.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) { | |
| 1366 | error.NeedLazy => if (strat == .lazy) { | |
| 1367 | const pt = strat.pt(zcu, tid); | |
| 1368 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1369 | .ty = .comptime_int_type, | |
| 1370 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1371 | } })) }; | |
| 1372 | } else unreachable, | |
| 1274 | 1373 | else => |e| return e, |
| 1275 | 1374 | })) { |
| 1276 | 1375 | // Same as anyerror. |
| 1277 | 1376 | return .{ .scalar = code_size }; |
| 1278 | 1377 | } |
| 1279 | const code_align = Type.anyerror.abiAlignment(pt); | |
| 1280 | const payload_align = payload_ty.abiAlignment(pt); | |
| 1281 | const payload_size = switch (try payload_ty.abiSizeAdvanced(pt, strat)) { | |
| 1378 | const code_align = Type.anyerror.abiAlignment(zcu); | |
| 1379 | const payload_align = (try payload_ty.abiAlignmentInner(strat, zcu, tid)).scalar; | |
| 1380 | const payload_size = switch (try payload_ty.abiSizeInner(strat, zcu, tid)) { | |
| 1282 | 1381 | .scalar => |elem_size| elem_size, |
| 1283 | 1382 | .val => switch (strat) { |
| 1284 | 1383 | .sema => unreachable, |
| 1285 | 1384 | .eager => unreachable, |
| 1286 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1287 | .ty = .comptime_int_type, | |
| 1288 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1289 | } })) }, | |
| 1385 | .lazy => { | |
| 1386 | const pt = strat.pt(zcu, tid); | |
| 1387 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1388 | .ty = .comptime_int_type, | |
| 1389 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1390 | } })) }; | |
| 1391 | }, | |
| 1290 | 1392 | }, |
| 1291 | 1393 | }; |
| 1292 | 1394 | |
| ... | ... | @@ -1314,7 +1416,7 @@ pub fn abiSizeAdvanced( |
| 1314 | 1416 | .f128 => return .{ .scalar = 16 }, |
| 1315 | 1417 | .f80 => switch (target.cTypeBitSize(.longdouble)) { |
| 1316 | 1418 | 80 => return .{ .scalar = target.cTypeByteSize(.longdouble) }, |
| 1317 | else => return .{ .scalar = Type.u80.abiSize(pt) }, | |
| 1419 | else => return .{ .scalar = Type.u80.abiSize(zcu) }, | |
| 1318 | 1420 | }, |
| 1319 | 1421 | |
| 1320 | 1422 | .usize, |
| ... | ... | @@ -1343,7 +1445,7 @@ pub fn abiSizeAdvanced( |
| 1343 | 1445 | => return .{ .scalar = 0 }, |
| 1344 | 1446 | |
| 1345 | 1447 | .anyerror, .adhoc_inferred_error_set => { |
| 1346 | const bits = mod.errorSetBits(); | |
| 1448 | const bits = zcu.errorSetBits(); | |
| 1347 | 1449 | if (bits == 0) return .{ .scalar = 0 }; |
| 1348 | 1450 | return .{ .scalar = intAbiSize(bits, target, use_llvm) }; |
| 1349 | 1451 | }, |
| ... | ... | @@ -1354,30 +1456,33 @@ pub fn abiSizeAdvanced( |
| 1354 | 1456 | .struct_type => { |
| 1355 | 1457 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 1356 | 1458 | switch (strat) { |
| 1357 | .sema => try ty.resolveLayout(pt), | |
| 1358 | .lazy => switch (struct_type.layout) { | |
| 1359 | .@"packed" => { | |
| 1360 | if (struct_type.backingIntTypeUnordered(ip) == .none) return .{ | |
| 1361 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1362 | .ty = .comptime_int_type, | |
| 1363 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1364 | } })), | |
| 1365 | }; | |
| 1366 | }, | |
| 1367 | .auto, .@"extern" => { | |
| 1368 | if (!struct_type.haveLayout(ip)) return .{ | |
| 1369 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1370 | .ty = .comptime_int_type, | |
| 1371 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1372 | } })), | |
| 1373 | }; | |
| 1374 | }, | |
| 1459 | .sema => try ty.resolveLayout(strat.pt(zcu, tid)), | |
| 1460 | .lazy => { | |
| 1461 | const pt = strat.pt(zcu, tid); | |
| 1462 | switch (struct_type.layout) { | |
| 1463 | .@"packed" => { | |
| 1464 | if (struct_type.backingIntTypeUnordered(ip) == .none) return .{ | |
| 1465 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1466 | .ty = .comptime_int_type, | |
| 1467 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1468 | } })), | |
| 1469 | }; | |
| 1470 | }, | |
| 1471 | .auto, .@"extern" => { | |
| 1472 | if (!struct_type.haveLayout(ip)) return .{ | |
| 1473 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1474 | .ty = .comptime_int_type, | |
| 1475 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1476 | } })), | |
| 1477 | }; | |
| 1478 | }, | |
| 1479 | } | |
| 1375 | 1480 | }, |
| 1376 | 1481 | .eager => {}, |
| 1377 | 1482 | } |
| 1378 | 1483 | switch (struct_type.layout) { |
| 1379 | 1484 | .@"packed" => return .{ |
| 1380 | .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiSize(pt), | |
| 1485 | .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiSize(zcu), | |
| 1381 | 1486 | }, |
| 1382 | 1487 | .auto, .@"extern" => { |
| 1383 | 1488 | assert(struct_type.haveLayout(ip)); |
| ... | ... | @@ -1387,25 +1492,28 @@ pub fn abiSizeAdvanced( |
| 1387 | 1492 | }, |
| 1388 | 1493 | .anon_struct_type => |tuple| { |
| 1389 | 1494 | switch (strat) { |
| 1390 | .sema => try ty.resolveLayout(pt), | |
| 1495 | .sema => try ty.resolveLayout(strat.pt(zcu, tid)), | |
| 1391 | 1496 | .lazy, .eager => {}, |
| 1392 | 1497 | } |
| 1393 | 1498 | const field_count = tuple.types.len; |
| 1394 | 1499 | if (field_count == 0) { |
| 1395 | 1500 | return .{ .scalar = 0 }; |
| 1396 | 1501 | } |
| 1397 | return .{ .scalar = ty.structFieldOffset(field_count, pt) }; | |
| 1502 | return .{ .scalar = ty.structFieldOffset(field_count, zcu) }; | |
| 1398 | 1503 | }, |
| 1399 | 1504 | |
| 1400 | 1505 | .union_type => { |
| 1401 | 1506 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 1402 | 1507 | switch (strat) { |
| 1403 | .sema => try ty.resolveLayout(pt), | |
| 1404 | .lazy => if (!union_type.flagsUnordered(ip).status.haveLayout()) return .{ | |
| 1405 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1406 | .ty = .comptime_int_type, | |
| 1407 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1408 | } })), | |
| 1508 | .sema => try ty.resolveLayout(strat.pt(zcu, tid)), | |
| 1509 | .lazy => { | |
| 1510 | const pt = strat.pt(zcu, tid); | |
| 1511 | if (!union_type.flagsUnordered(ip).status.haveLayout()) return .{ | |
| 1512 | .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1513 | .ty = .comptime_int_type, | |
| 1514 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1515 | } })), | |
| 1516 | }; | |
| 1409 | 1517 | }, |
| 1410 | 1518 | .eager => {}, |
| 1411 | 1519 | } |
| ... | ... | @@ -1414,7 +1522,7 @@ pub fn abiSizeAdvanced( |
| 1414 | 1522 | return .{ .scalar = union_type.sizeUnordered(ip) }; |
| 1415 | 1523 | }, |
| 1416 | 1524 | .opaque_type => unreachable, // no size available |
| 1417 | .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(pt) }, | |
| 1525 | .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(zcu) }, | |
| 1418 | 1526 | |
| 1419 | 1527 | // values, not types |
| 1420 | 1528 | .undef, |
| ... | ... | @@ -1441,36 +1549,39 @@ pub fn abiSizeAdvanced( |
| 1441 | 1549 | } |
| 1442 | 1550 | } |
| 1443 | 1551 | |
| 1444 | fn abiSizeAdvancedOptional( | |
| 1552 | fn abiSizeInnerOptional( | |
| 1445 | 1553 | ty: Type, |
| 1446 | pt: Zcu.PerThread, | |
| 1447 | 1554 | comptime strat: ResolveStratLazy, |
| 1448 | ) SemaError!AbiSizeAdvanced { | |
| 1449 | const mod = pt.zcu; | |
| 1450 | const child_ty = ty.optionalChild(mod); | |
| 1555 | zcu: *Zcu, | |
| 1556 | tid: strat.Tid(), | |
| 1557 | ) SemaError!AbiSizeInner { | |
| 1558 | const child_ty = ty.optionalChild(zcu); | |
| 1451 | 1559 | |
| 1452 | if (child_ty.isNoReturn(mod)) { | |
| 1560 | if (child_ty.isNoReturn(zcu)) { | |
| 1453 | 1561 | return .{ .scalar = 0 }; |
| 1454 | 1562 | } |
| 1455 | 1563 | |
| 1456 | if (!(child_ty.hasRuntimeBitsAdvanced(pt, false, strat) catch |err| switch (err) { | |
| 1457 | error.NeedLazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1458 | .ty = .comptime_int_type, | |
| 1459 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1460 | } })) }, | |
| 1564 | if (!(child_ty.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) { | |
| 1565 | error.NeedLazy => if (strat == .lazy) { | |
| 1566 | const pt = strat.pt(zcu, tid); | |
| 1567 | return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1568 | .ty = .comptime_int_type, | |
| 1569 | .storage = .{ .lazy_size = ty.toIntern() }, | |
| 1570 | } })) }; | |
| 1571 | } else unreachable, | |
| 1461 | 1572 | else => |e| return e, |
| 1462 | 1573 | })) return .{ .scalar = 1 }; |
| 1463 | 1574 | |
| 1464 | if (ty.optionalReprIsPayload(mod)) { | |
| 1465 | return child_ty.abiSizeAdvanced(pt, strat); | |
| 1575 | if (ty.optionalReprIsPayload(zcu)) { | |
| 1576 | return child_ty.abiSizeInner(strat, zcu, tid); | |
| 1466 | 1577 | } |
| 1467 | 1578 | |
| 1468 | const payload_size = switch (try child_ty.abiSizeAdvanced(pt, strat)) { | |
| 1579 | const payload_size = switch (try child_ty.abiSizeInner(strat, zcu, tid)) { | |
| 1469 | 1580 | .scalar => |elem_size| elem_size, |
| 1470 | 1581 | .val => switch (strat) { |
| 1471 | 1582 | .sema => unreachable, |
| 1472 | 1583 | .eager => unreachable, |
| 1473 | .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{ | |
| 1584 | .lazy => return .{ .val = Value.fromInterned(try strat.pt(zcu, tid).intern(.{ .int = .{ | |
| 1474 | 1585 | .ty = .comptime_int_type, |
| 1475 | 1586 | .storage = .{ .lazy_size = ty.toIntern() }, |
| 1476 | 1587 | } })) }, |
| ... | ... | @@ -1482,7 +1593,7 @@ fn abiSizeAdvancedOptional( |
| 1482 | 1593 | // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal |
| 1483 | 1594 | // to the child type's ABI alignment. |
| 1484 | 1595 | return .{ |
| 1485 | .scalar = (child_ty.abiAlignment(pt).toByteUnits() orelse 0) + payload_size, | |
| 1596 | .scalar = (child_ty.abiAlignment(zcu).toByteUnits() orelse 0) + payload_size, | |
| 1486 | 1597 | }; |
| 1487 | 1598 | } |
| 1488 | 1599 | |
| ... | ... | @@ -1600,18 +1711,22 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 { |
| 1600 | 1711 | }; |
| 1601 | 1712 | } |
| 1602 | 1713 | |
| 1603 | pub fn bitSize(ty: Type, pt: Zcu.PerThread) u64 { | |
| 1604 | return bitSizeAdvanced(ty, pt, .normal) catch unreachable; | |
| 1714 | pub fn bitSize(ty: Type, zcu: *Zcu) u64 { | |
| 1715 | return bitSizeInner(ty, .normal, zcu, {}) catch unreachable; | |
| 1716 | } | |
| 1717 | ||
| 1718 | pub fn bitSizeSema(ty: Type, pt: Zcu.PerThread) SemaError!u64 { | |
| 1719 | return bitSizeInner(ty, .sema, pt.zcu, pt.tid); | |
| 1605 | 1720 | } |
| 1606 | 1721 | |
| 1607 | pub fn bitSizeAdvanced( | |
| 1722 | pub fn bitSizeInner( | |
| 1608 | 1723 | ty: Type, |
| 1609 | pt: Zcu.PerThread, | |
| 1610 | 1724 | comptime strat: ResolveStrat, |
| 1725 | zcu: *Zcu, | |
| 1726 | tid: strat.Tid(), | |
| 1611 | 1727 | ) SemaError!u64 { |
| 1612 | const mod = pt.zcu; | |
| 1613 | const target = mod.getTarget(); | |
| 1614 | const ip = &mod.intern_pool; | |
| 1728 | const target = zcu.getTarget(); | |
| 1729 | const ip = &zcu.intern_pool; | |
| 1615 | 1730 | |
| 1616 | 1731 | const strat_lazy: ResolveStratLazy = strat.toLazy(); |
| 1617 | 1732 | |
| ... | ... | @@ -1628,30 +1743,30 @@ pub fn bitSizeAdvanced( |
| 1628 | 1743 | if (len == 0) return 0; |
| 1629 | 1744 | const elem_ty = Type.fromInterned(array_type.child); |
| 1630 | 1745 | const elem_size = @max( |
| 1631 | (try elem_ty.abiAlignmentAdvanced(pt, strat_lazy)).scalar.toByteUnits() orelse 0, | |
| 1632 | (try elem_ty.abiSizeAdvanced(pt, strat_lazy)).scalar, | |
| 1746 | (try elem_ty.abiAlignmentInner(strat_lazy, zcu, tid)).scalar.toByteUnits() orelse 0, | |
| 1747 | (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar, | |
| 1633 | 1748 | ); |
| 1634 | 1749 | if (elem_size == 0) return 0; |
| 1635 | const elem_bit_size = try elem_ty.bitSizeAdvanced(pt, strat); | |
| 1750 | const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid); | |
| 1636 | 1751 | return (len - 1) * 8 * elem_size + elem_bit_size; |
| 1637 | 1752 | }, |
| 1638 | 1753 | .vector_type => |vector_type| { |
| 1639 | 1754 | const child_ty = Type.fromInterned(vector_type.child); |
| 1640 | const elem_bit_size = try child_ty.bitSizeAdvanced(pt, strat); | |
| 1755 | const elem_bit_size = try child_ty.bitSizeInner(strat, zcu, tid); | |
| 1641 | 1756 | return elem_bit_size * vector_type.len; |
| 1642 | 1757 | }, |
| 1643 | 1758 | .opt_type => { |
| 1644 | 1759 | // Optionals and error unions are not packed so their bitsize |
| 1645 | 1760 | // includes padding bits. |
| 1646 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; | |
| 1761 | return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8; | |
| 1647 | 1762 | }, |
| 1648 | 1763 | |
| 1649 | .error_set_type, .inferred_error_set_type => return mod.errorSetBits(), | |
| 1764 | .error_set_type, .inferred_error_set_type => return zcu.errorSetBits(), | |
| 1650 | 1765 | |
| 1651 | 1766 | .error_union_type => { |
| 1652 | 1767 | // Optionals and error unions are not packed so their bitsize |
| 1653 | 1768 | // includes padding bits. |
| 1654 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; | |
| 1769 | return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8; | |
| 1655 | 1770 | }, |
| 1656 | 1771 | .func_type => unreachable, // represents machine code; not a pointer |
| 1657 | 1772 | .simple_type => |t| switch (t) { |
| ... | ... | @@ -1681,7 +1796,7 @@ pub fn bitSizeAdvanced( |
| 1681 | 1796 | |
| 1682 | 1797 | .anyerror, |
| 1683 | 1798 | .adhoc_inferred_error_set, |
| 1684 | => return mod.errorSetBits(), | |
| 1799 | => return zcu.errorSetBits(), | |
| 1685 | 1800 | |
| 1686 | 1801 | .anyopaque => unreachable, |
| 1687 | 1802 | .type => unreachable, |
| ... | ... | @@ -1697,42 +1812,46 @@ pub fn bitSizeAdvanced( |
| 1697 | 1812 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 1698 | 1813 | const is_packed = struct_type.layout == .@"packed"; |
| 1699 | 1814 | if (strat == .sema) { |
| 1815 | const pt = strat.pt(zcu, tid); | |
| 1700 | 1816 | try ty.resolveFields(pt); |
| 1701 | 1817 | if (is_packed) try ty.resolveLayout(pt); |
| 1702 | 1818 | } |
| 1703 | 1819 | if (is_packed) { |
| 1704 | return try Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).bitSizeAdvanced(pt, strat); | |
| 1820 | return try Type.fromInterned(struct_type.backingIntTypeUnordered(ip)) | |
| 1821 | .bitSizeInner(strat, zcu, tid); | |
| 1705 | 1822 | } |
| 1706 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; | |
| 1823 | return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8; | |
| 1707 | 1824 | }, |
| 1708 | 1825 | |
| 1709 | 1826 | .anon_struct_type => { |
| 1710 | if (strat == .sema) try ty.resolveFields(pt); | |
| 1711 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; | |
| 1827 | if (strat == .sema) try ty.resolveFields(strat.pt(zcu, tid)); | |
| 1828 | return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8; | |
| 1712 | 1829 | }, |
| 1713 | 1830 | |
| 1714 | 1831 | .union_type => { |
| 1715 | 1832 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 1716 | const is_packed = ty.containerLayout(mod) == .@"packed"; | |
| 1833 | const is_packed = ty.containerLayout(zcu) == .@"packed"; | |
| 1717 | 1834 | if (strat == .sema) { |
| 1835 | const pt = strat.pt(zcu, tid); | |
| 1718 | 1836 | try ty.resolveFields(pt); |
| 1719 | 1837 | if (is_packed) try ty.resolveLayout(pt); |
| 1720 | 1838 | } |
| 1721 | 1839 | if (!is_packed) { |
| 1722 | return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8; | |
| 1840 | return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8; | |
| 1723 | 1841 | } |
| 1724 | 1842 | assert(union_type.flagsUnordered(ip).status.haveFieldTypes()); |
| 1725 | 1843 | |
| 1726 | 1844 | var size: u64 = 0; |
| 1727 | 1845 | for (0..union_type.field_types.len) |field_index| { |
| 1728 | 1846 | const field_ty = union_type.field_types.get(ip)[field_index]; |
| 1729 | size = @max(size, try Type.fromInterned(field_ty).bitSizeAdvanced(pt, strat)); | |
| 1847 | size = @max(size, try Type.fromInterned(field_ty).bitSizeInner(strat, zcu, tid)); | |
| 1730 | 1848 | } |
| 1731 | 1849 | |
| 1732 | 1850 | return size; |
| 1733 | 1851 | }, |
| 1734 | 1852 | .opaque_type => unreachable, |
| 1735 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).bitSizeAdvanced(pt, strat), | |
| 1853 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty) | |
| 1854 | .bitSizeInner(strat, zcu, tid), | |
| 1736 | 1855 | |
| 1737 | 1856 | // values, not types |
| 1738 | 1857 | .undef, |
| ... | ... | @@ -1760,61 +1879,61 @@ pub fn bitSizeAdvanced( |
| 1760 | 1879 | |
| 1761 | 1880 | /// Returns true if the type's layout is already resolved and it is safe |
| 1762 | 1881 | /// to use `abiSize`, `abiAlignment` and `bitSize` on it. |
| 1763 | pub fn layoutIsResolved(ty: Type, mod: *Module) bool { | |
| 1764 | const ip = &mod.intern_pool; | |
| 1882 | pub fn layoutIsResolved(ty: Type, zcu: *const Zcu) bool { | |
| 1883 | const ip = &zcu.intern_pool; | |
| 1765 | 1884 | return switch (ip.indexToKey(ty.toIntern())) { |
| 1766 | 1885 | .struct_type => ip.loadStructType(ty.toIntern()).haveLayout(ip), |
| 1767 | 1886 | .union_type => ip.loadUnionType(ty.toIntern()).haveLayout(ip), |
| 1768 | 1887 | .array_type => |array_type| { |
| 1769 | 1888 | if (array_type.lenIncludingSentinel() == 0) return true; |
| 1770 | return Type.fromInterned(array_type.child).layoutIsResolved(mod); | |
| 1889 | return Type.fromInterned(array_type.child).layoutIsResolved(zcu); | |
| 1771 | 1890 | }, |
| 1772 | .opt_type => |child| Type.fromInterned(child).layoutIsResolved(mod), | |
| 1773 | .error_union_type => |k| Type.fromInterned(k.payload_type).layoutIsResolved(mod), | |
| 1891 | .opt_type => |child| Type.fromInterned(child).layoutIsResolved(zcu), | |
| 1892 | .error_union_type => |k| Type.fromInterned(k.payload_type).layoutIsResolved(zcu), | |
| 1774 | 1893 | else => true, |
| 1775 | 1894 | }; |
| 1776 | 1895 | } |
| 1777 | 1896 | |
| 1778 | pub fn isSinglePointer(ty: Type, mod: *const Module) bool { | |
| 1779 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1897 | pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool { | |
| 1898 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1780 | 1899 | .ptr_type => |ptr_info| ptr_info.flags.size == .One, |
| 1781 | 1900 | else => false, |
| 1782 | 1901 | }; |
| 1783 | 1902 | } |
| 1784 | 1903 | |
| 1785 | 1904 | /// Asserts `ty` is a pointer. |
| 1786 | pub fn ptrSize(ty: Type, mod: *const Module) std.builtin.Type.Pointer.Size { | |
| 1787 | return ty.ptrSizeOrNull(mod).?; | |
| 1905 | pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { | |
| 1906 | return ty.ptrSizeOrNull(zcu).?; | |
| 1788 | 1907 | } |
| 1789 | 1908 | |
| 1790 | 1909 | /// Returns `null` if `ty` is not a pointer. |
| 1791 | pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size { | |
| 1792 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1910 | pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size { | |
| 1911 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1793 | 1912 | .ptr_type => |ptr_info| ptr_info.flags.size, |
| 1794 | 1913 | else => null, |
| 1795 | 1914 | }; |
| 1796 | 1915 | } |
| 1797 | 1916 | |
| 1798 | pub fn isSlice(ty: Type, mod: *const Module) bool { | |
| 1799 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1917 | pub fn isSlice(ty: Type, zcu: *const Zcu) bool { | |
| 1918 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1800 | 1919 | .ptr_type => |ptr_type| ptr_type.flags.size == .Slice, |
| 1801 | 1920 | else => false, |
| 1802 | 1921 | }; |
| 1803 | 1922 | } |
| 1804 | 1923 | |
| 1805 | pub fn slicePtrFieldType(ty: Type, mod: *const Module) Type { | |
| 1806 | return Type.fromInterned(mod.intern_pool.slicePtrType(ty.toIntern())); | |
| 1924 | pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type { | |
| 1925 | return Type.fromInterned(zcu.intern_pool.slicePtrType(ty.toIntern())); | |
| 1807 | 1926 | } |
| 1808 | 1927 | |
| 1809 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { | |
| 1810 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1928 | pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool { | |
| 1929 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1811 | 1930 | .ptr_type => |ptr_type| ptr_type.flags.is_const, |
| 1812 | 1931 | else => false, |
| 1813 | 1932 | }; |
| 1814 | 1933 | } |
| 1815 | 1934 | |
| 1816 | pub fn isVolatilePtr(ty: Type, mod: *const Module) bool { | |
| 1817 | return isVolatilePtrIp(ty, &mod.intern_pool); | |
| 1935 | pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { | |
| 1936 | return isVolatilePtrIp(ty, &zcu.intern_pool); | |
| 1818 | 1937 | } |
| 1819 | 1938 | |
| 1820 | 1939 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { |
| ... | ... | @@ -1824,28 +1943,28 @@ pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { |
| 1824 | 1943 | }; |
| 1825 | 1944 | } |
| 1826 | 1945 | |
| 1827 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { | |
| 1828 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1946 | pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool { | |
| 1947 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1829 | 1948 | .ptr_type => |ptr_type| ptr_type.flags.is_allowzero, |
| 1830 | 1949 | .opt_type => true, |
| 1831 | 1950 | else => false, |
| 1832 | 1951 | }; |
| 1833 | 1952 | } |
| 1834 | 1953 | |
| 1835 | pub fn isCPtr(ty: Type, mod: *const Module) bool { | |
| 1836 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1954 | pub fn isCPtr(ty: Type, zcu: *const Zcu) bool { | |
| 1955 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1837 | 1956 | .ptr_type => |ptr_type| ptr_type.flags.size == .C, |
| 1838 | 1957 | else => false, |
| 1839 | 1958 | }; |
| 1840 | 1959 | } |
| 1841 | 1960 | |
| 1842 | pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { | |
| 1843 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1961 | pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool { | |
| 1962 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1844 | 1963 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1845 | 1964 | .Slice => false, |
| 1846 | 1965 | .One, .Many, .C => true, |
| 1847 | 1966 | }, |
| 1848 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | |
| 1967 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 1849 | 1968 | .ptr_type => |p| switch (p.flags.size) { |
| 1850 | 1969 | .Slice, .C => false, |
| 1851 | 1970 | .Many, .One => !p.flags.is_allowzero, |
| ... | ... | @@ -1858,17 +1977,17 @@ pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { |
| 1858 | 1977 | |
| 1859 | 1978 | /// For pointer-like optionals, returns true, otherwise returns the allowzero property |
| 1860 | 1979 | /// of pointers. |
| 1861 | pub fn ptrAllowsZero(ty: Type, mod: *const Module) bool { | |
| 1862 | if (ty.isPtrLikeOptional(mod)) { | |
| 1980 | pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool { | |
| 1981 | if (ty.isPtrLikeOptional(zcu)) { | |
| 1863 | 1982 | return true; |
| 1864 | 1983 | } |
| 1865 | return ty.ptrInfo(mod).flags.is_allowzero; | |
| 1984 | return ty.ptrInfo(zcu).flags.is_allowzero; | |
| 1866 | 1985 | } |
| 1867 | 1986 | |
| 1868 | 1987 | /// See also `isPtrLikeOptional`. |
| 1869 | pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { | |
| 1870 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 1871 | .opt_type => |child_type| child_type == .anyerror_type or switch (mod.intern_pool.indexToKey(child_type)) { | |
| 1988 | pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { | |
| 1989 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1990 | .opt_type => |child_type| child_type == .anyerror_type or switch (zcu.intern_pool.indexToKey(child_type)) { | |
| 1872 | 1991 | .ptr_type => |ptr_type| ptr_type.flags.size != .C and !ptr_type.flags.is_allowzero, |
| 1873 | 1992 | .error_set_type, .inferred_error_set_type => true, |
| 1874 | 1993 | else => false, |
| ... | ... | @@ -1881,10 +2000,10 @@ pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { |
| 1881 | 2000 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 1882 | 2001 | /// address value, using 0 for null. Note that this returns true for C pointers. |
| 1883 | 2002 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. |
| 1884 | pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { | |
| 1885 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2003 | pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool { | |
| 2004 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1886 | 2005 | .ptr_type => |ptr_type| ptr_type.flags.size == .C, |
| 1887 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | |
| 2006 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | |
| 1888 | 2007 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1889 | 2008 | .Slice, .C => false, |
| 1890 | 2009 | .Many, .One => !ptr_type.flags.is_allowzero, |
| ... | ... | @@ -1898,8 +2017,8 @@ pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { |
| 1898 | 2017 | /// For *[N]T, returns [N]T. |
| 1899 | 2018 | /// For *T, returns T. |
| 1900 | 2019 | /// For [*]T, returns T. |
| 1901 | pub fn childType(ty: Type, mod: *const Module) Type { | |
| 1902 | return childTypeIp(ty, &mod.intern_pool); | |
| 2020 | pub fn childType(ty: Type, zcu: *const Zcu) Type { | |
| 2021 | return childTypeIp(ty, &zcu.intern_pool); | |
| 1903 | 2022 | } |
| 1904 | 2023 | |
| 1905 | 2024 | pub fn childTypeIp(ty: Type, ip: *const InternPool) Type { |
| ... | ... | @@ -1915,10 +2034,10 @@ pub fn childTypeIp(ty: Type, ip: *const InternPool) Type { |
| 1915 | 2034 | /// For [N]T, returns T. |
| 1916 | 2035 | /// For []T, returns T. |
| 1917 | 2036 | /// For anyframe->T, returns T. |
| 1918 | pub fn elemType2(ty: Type, mod: *const Module) Type { | |
| 1919 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2037 | pub fn elemType2(ty: Type, zcu: *const Zcu) Type { | |
| 2038 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1920 | 2039 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1921 | .One => Type.fromInterned(ptr_type.child).shallowElemType(mod), | |
| 2040 | .One => Type.fromInterned(ptr_type.child).shallowElemType(zcu), | |
| 1922 | 2041 | .Many, .C, .Slice => Type.fromInterned(ptr_type.child), |
| 1923 | 2042 | }, |
| 1924 | 2043 | .anyframe_type => |child| { |
| ... | ... | @@ -1927,30 +2046,30 @@ pub fn elemType2(ty: Type, mod: *const Module) Type { |
| 1927 | 2046 | }, |
| 1928 | 2047 | .vector_type => |vector_type| Type.fromInterned(vector_type.child), |
| 1929 | 2048 | .array_type => |array_type| Type.fromInterned(array_type.child), |
| 1930 | .opt_type => |child| Type.fromInterned(mod.intern_pool.childType(child)), | |
| 2049 | .opt_type => |child| Type.fromInterned(zcu.intern_pool.childType(child)), | |
| 1931 | 2050 | else => unreachable, |
| 1932 | 2051 | }; |
| 1933 | 2052 | } |
| 1934 | 2053 | |
| 1935 | fn shallowElemType(child_ty: Type, mod: *const Module) Type { | |
| 1936 | return switch (child_ty.zigTypeTag(mod)) { | |
| 1937 | .Array, .Vector => child_ty.childType(mod), | |
| 2054 | fn shallowElemType(child_ty: Type, zcu: *const Zcu) Type { | |
| 2055 | return switch (child_ty.zigTypeTag(zcu)) { | |
| 2056 | .Array, .Vector => child_ty.childType(zcu), | |
| 1938 | 2057 | else => child_ty, |
| 1939 | 2058 | }; |
| 1940 | 2059 | } |
| 1941 | 2060 | |
| 1942 | 2061 | /// For vectors, returns the element type. Otherwise returns self. |
| 1943 | pub fn scalarType(ty: Type, mod: *Module) Type { | |
| 1944 | return switch (ty.zigTypeTag(mod)) { | |
| 1945 | .Vector => ty.childType(mod), | |
| 2062 | pub fn scalarType(ty: Type, zcu: *const Zcu) Type { | |
| 2063 | return switch (ty.zigTypeTag(zcu)) { | |
| 2064 | .Vector => ty.childType(zcu), | |
| 1946 | 2065 | else => ty, |
| 1947 | 2066 | }; |
| 1948 | 2067 | } |
| 1949 | 2068 | |
| 1950 | 2069 | /// Asserts that the type is an optional. |
| 1951 | 2070 | /// Note that for C pointers this returns the type unmodified. |
| 1952 | pub fn optionalChild(ty: Type, mod: *const Module) Type { | |
| 1953 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2071 | pub fn optionalChild(ty: Type, zcu: *const Zcu) Type { | |
| 2072 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 1954 | 2073 | .opt_type => |child| Type.fromInterned(child), |
| 1955 | 2074 | .ptr_type => |ptr_type| b: { |
| 1956 | 2075 | assert(ptr_type.flags.size == .C); |
| ... | ... | @@ -1962,8 +2081,8 @@ pub fn optionalChild(ty: Type, mod: *const Module) Type { |
| 1962 | 2081 | |
| 1963 | 2082 | /// Returns the tag type of a union, if the type is a union and it has a tag type. |
| 1964 | 2083 | /// Otherwise, returns `null`. |
| 1965 | pub fn unionTagType(ty: Type, mod: *Module) ?Type { | |
| 1966 | const ip = &mod.intern_pool; | |
| 2084 | pub fn unionTagType(ty: Type, zcu: *const Zcu) ?Type { | |
| 2085 | const ip = &zcu.intern_pool; | |
| 1967 | 2086 | switch (ip.indexToKey(ty.toIntern())) { |
| 1968 | 2087 | .union_type => {}, |
| 1969 | 2088 | else => return null, |
| ... | ... | @@ -1981,8 +2100,8 @@ pub fn unionTagType(ty: Type, mod: *Module) ?Type { |
| 1981 | 2100 | |
| 1982 | 2101 | /// Same as `unionTagType` but includes safety tag. |
| 1983 | 2102 | /// Codegen should use this version. |
| 1984 | pub fn unionTagTypeSafety(ty: Type, mod: *Module) ?Type { | |
| 1985 | const ip = &mod.intern_pool; | |
| 2103 | pub fn unionTagTypeSafety(ty: Type, zcu: *const Zcu) ?Type { | |
| 2104 | const ip = &zcu.intern_pool; | |
| 1986 | 2105 | return switch (ip.indexToKey(ty.toIntern())) { |
| 1987 | 2106 | .union_type => { |
| 1988 | 2107 | const union_type = ip.loadUnionType(ty.toIntern()); |
| ... | ... | @@ -1996,35 +2115,35 @@ pub fn unionTagTypeSafety(ty: Type, mod: *Module) ?Type { |
| 1996 | 2115 | |
| 1997 | 2116 | /// Asserts the type is a union; returns the tag type, even if the tag will |
| 1998 | 2117 | /// not be stored at runtime. |
| 1999 | pub fn unionTagTypeHypothetical(ty: Type, mod: *Module) Type { | |
| 2000 | const union_obj = mod.typeToUnion(ty).?; | |
| 2118 | pub fn unionTagTypeHypothetical(ty: Type, zcu: *const Zcu) Type { | |
| 2119 | const union_obj = zcu.typeToUnion(ty).?; | |
| 2001 | 2120 | return Type.fromInterned(union_obj.enum_tag_ty); |
| 2002 | 2121 | } |
| 2003 | 2122 | |
| 2004 | pub fn unionFieldType(ty: Type, enum_tag: Value, mod: *Module) ?Type { | |
| 2005 | const ip = &mod.intern_pool; | |
| 2006 | const union_obj = mod.typeToUnion(ty).?; | |
| 2123 | pub fn unionFieldType(ty: Type, enum_tag: Value, zcu: *const Zcu) ?Type { | |
| 2124 | const ip = &zcu.intern_pool; | |
| 2125 | const union_obj = zcu.typeToUnion(ty).?; | |
| 2007 | 2126 | const union_fields = union_obj.field_types.get(ip); |
| 2008 | const index = mod.unionTagFieldIndex(union_obj, enum_tag) orelse return null; | |
| 2127 | const index = zcu.unionTagFieldIndex(union_obj, enum_tag) orelse return null; | |
| 2009 | 2128 | return Type.fromInterned(union_fields[index]); |
| 2010 | 2129 | } |
| 2011 | 2130 | |
| 2012 | pub fn unionFieldTypeByIndex(ty: Type, index: usize, mod: *Module) Type { | |
| 2013 | const ip = &mod.intern_pool; | |
| 2014 | const union_obj = mod.typeToUnion(ty).?; | |
| 2131 | pub fn unionFieldTypeByIndex(ty: Type, index: usize, zcu: *const Zcu) Type { | |
| 2132 | const ip = &zcu.intern_pool; | |
| 2133 | const union_obj = zcu.typeToUnion(ty).?; | |
| 2015 | 2134 | return Type.fromInterned(union_obj.field_types.get(ip)[index]); |
| 2016 | 2135 | } |
| 2017 | 2136 | |
| 2018 | pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 { | |
| 2019 | const union_obj = mod.typeToUnion(ty).?; | |
| 2020 | return mod.unionTagFieldIndex(union_obj, enum_tag); | |
| 2137 | pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 { | |
| 2138 | const union_obj = zcu.typeToUnion(ty).?; | |
| 2139 | return zcu.unionTagFieldIndex(union_obj, enum_tag); | |
| 2021 | 2140 | } |
| 2022 | 2141 | |
| 2023 | pub fn unionHasAllZeroBitFieldTypes(ty: Type, pt: Zcu.PerThread) bool { | |
| 2024 | const ip = &pt.zcu.intern_pool; | |
| 2025 | const union_obj = pt.zcu.typeToUnion(ty).?; | |
| 2142 | pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool { | |
| 2143 | const ip = &zcu.intern_pool; | |
| 2144 | const union_obj = zcu.typeToUnion(ty).?; | |
| 2026 | 2145 | for (union_obj.field_types.get(ip)) |field_ty| { |
| 2027 | if (Type.fromInterned(field_ty).hasRuntimeBits(pt)) return false; | |
| 2146 | if (Type.fromInterned(field_ty).hasRuntimeBits(zcu)) return false; | |
| 2028 | 2147 | } |
| 2029 | 2148 | return true; |
| 2030 | 2149 | } |
| ... | ... | @@ -2032,20 +2151,21 @@ pub fn unionHasAllZeroBitFieldTypes(ty: Type, pt: Zcu.PerThread) bool { |
| 2032 | 2151 | /// Returns the type used for backing storage of this union during comptime operations. |
| 2033 | 2152 | /// Asserts the type is either an extern or packed union. |
| 2034 | 2153 | pub fn unionBackingType(ty: Type, pt: Zcu.PerThread) !Type { |
| 2035 | return switch (ty.containerLayout(pt.zcu)) { | |
| 2036 | .@"extern" => try pt.arrayType(.{ .len = ty.abiSize(pt), .child = .u8_type }), | |
| 2037 | .@"packed" => try pt.intType(.unsigned, @intCast(ty.bitSize(pt))), | |
| 2154 | const zcu = pt.zcu; | |
| 2155 | return switch (ty.containerLayout(zcu)) { | |
| 2156 | .@"extern" => try pt.arrayType(.{ .len = ty.abiSize(zcu), .child = .u8_type }), | |
| 2157 | .@"packed" => try pt.intType(.unsigned, @intCast(ty.bitSize(zcu))), | |
| 2038 | 2158 | .auto => unreachable, |
| 2039 | 2159 | }; |
| 2040 | 2160 | } |
| 2041 | 2161 | |
| 2042 | pub fn unionGetLayout(ty: Type, pt: Zcu.PerThread) Module.UnionLayout { | |
| 2043 | const union_obj = pt.zcu.intern_pool.loadUnionType(ty.toIntern()); | |
| 2044 | return pt.getUnionLayout(union_obj); | |
| 2162 | pub fn unionGetLayout(ty: Type, zcu: *Zcu) Zcu.UnionLayout { | |
| 2163 | const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern()); | |
| 2164 | return Type.getUnionLayout(union_obj, zcu); | |
| 2045 | 2165 | } |
| 2046 | 2166 | |
| 2047 | pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout { | |
| 2048 | const ip = &mod.intern_pool; | |
| 2167 | pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayout { | |
| 2168 | const ip = &zcu.intern_pool; | |
| 2049 | 2169 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2050 | 2170 | .struct_type => ip.loadStructType(ty.toIntern()).layout, |
| 2051 | 2171 | .anon_struct_type => .auto, |
| ... | ... | @@ -2055,18 +2175,18 @@ pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout |
| 2055 | 2175 | } |
| 2056 | 2176 | |
| 2057 | 2177 | /// Asserts that the type is an error union. |
| 2058 | pub fn errorUnionPayload(ty: Type, mod: *Module) Type { | |
| 2059 | return Type.fromInterned(mod.intern_pool.indexToKey(ty.toIntern()).error_union_type.payload_type); | |
| 2178 | pub fn errorUnionPayload(ty: Type, zcu: *const Zcu) Type { | |
| 2179 | return Type.fromInterned(zcu.intern_pool.indexToKey(ty.toIntern()).error_union_type.payload_type); | |
| 2060 | 2180 | } |
| 2061 | 2181 | |
| 2062 | 2182 | /// Asserts that the type is an error union. |
| 2063 | pub fn errorUnionSet(ty: Type, mod: *Module) Type { | |
| 2064 | return Type.fromInterned(mod.intern_pool.errorUnionSet(ty.toIntern())); | |
| 2183 | pub fn errorUnionSet(ty: Type, zcu: *const Zcu) Type { | |
| 2184 | return Type.fromInterned(zcu.intern_pool.errorUnionSet(ty.toIntern())); | |
| 2065 | 2185 | } |
| 2066 | 2186 | |
| 2067 | 2187 | /// Returns false for unresolved inferred error sets. |
| 2068 | pub fn errorSetIsEmpty(ty: Type, mod: *Module) bool { | |
| 2069 | const ip = &mod.intern_pool; | |
| 2188 | pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool { | |
| 2189 | const ip = &zcu.intern_pool; | |
| 2070 | 2190 | return switch (ty.toIntern()) { |
| 2071 | 2191 | .anyerror_type, .adhoc_inferred_error_set_type => false, |
| 2072 | 2192 | else => switch (ip.indexToKey(ty.toIntern())) { |
| ... | ... | @@ -2083,20 +2203,20 @@ pub fn errorSetIsEmpty(ty: Type, mod: *Module) bool { |
| 2083 | 2203 | /// Returns true if it is an error set that includes anyerror, false otherwise. |
| 2084 | 2204 | /// Note that the result may be a false negative if the type did not get error set |
| 2085 | 2205 | /// resolution prior to this call. |
| 2086 | pub fn isAnyError(ty: Type, mod: *Module) bool { | |
| 2087 | const ip = &mod.intern_pool; | |
| 2206 | pub fn isAnyError(ty: Type, zcu: *const Zcu) bool { | |
| 2207 | const ip = &zcu.intern_pool; | |
| 2088 | 2208 | return switch (ty.toIntern()) { |
| 2089 | 2209 | .anyerror_type => true, |
| 2090 | 2210 | .adhoc_inferred_error_set_type => false, |
| 2091 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2211 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 2092 | 2212 | .inferred_error_set_type => |i| ip.funcIesResolvedUnordered(i) == .anyerror_type, |
| 2093 | 2213 | else => false, |
| 2094 | 2214 | }, |
| 2095 | 2215 | }; |
| 2096 | 2216 | } |
| 2097 | 2217 | |
| 2098 | pub fn isError(ty: Type, mod: *const Module) bool { | |
| 2099 | return switch (ty.zigTypeTag(mod)) { | |
| 2218 | pub fn isError(ty: Type, zcu: *const Zcu) bool { | |
| 2219 | return switch (ty.zigTypeTag(zcu)) { | |
| 2100 | 2220 | .ErrorUnion, .ErrorSet => true, |
| 2101 | 2221 | else => false, |
| 2102 | 2222 | }; |
| ... | ... | @@ -2127,8 +2247,8 @@ pub fn errorSetHasFieldIp( |
| 2127 | 2247 | /// Returns whether ty, which must be an error set, includes an error `name`. |
| 2128 | 2248 | /// Might return a false negative if `ty` is an inferred error set and not fully |
| 2129 | 2249 | /// resolved yet. |
| 2130 | pub fn errorSetHasField(ty: Type, name: []const u8, mod: *Module) bool { | |
| 2131 | const ip = &mod.intern_pool; | |
| 2250 | pub fn errorSetHasField(ty: Type, name: []const u8, zcu: *const Zcu) bool { | |
| 2251 | const ip = &zcu.intern_pool; | |
| 2132 | 2252 | return switch (ty.toIntern()) { |
| 2133 | 2253 | .anyerror_type => true, |
| 2134 | 2254 | else => switch (ip.indexToKey(ty.toIntern())) { |
| ... | ... | @@ -2152,20 +2272,20 @@ pub fn errorSetHasField(ty: Type, name: []const u8, mod: *Module) bool { |
| 2152 | 2272 | } |
| 2153 | 2273 | |
| 2154 | 2274 | /// Asserts the type is an array or vector or struct. |
| 2155 | pub fn arrayLen(ty: Type, mod: *const Module) u64 { | |
| 2156 | return ty.arrayLenIp(&mod.intern_pool); | |
| 2275 | pub fn arrayLen(ty: Type, zcu: *const Zcu) u64 { | |
| 2276 | return ty.arrayLenIp(&zcu.intern_pool); | |
| 2157 | 2277 | } |
| 2158 | 2278 | |
| 2159 | 2279 | pub fn arrayLenIp(ty: Type, ip: *const InternPool) u64 { |
| 2160 | 2280 | return ip.aggregateTypeLen(ty.toIntern()); |
| 2161 | 2281 | } |
| 2162 | 2282 | |
| 2163 | pub fn arrayLenIncludingSentinel(ty: Type, mod: *const Module) u64 { | |
| 2164 | return mod.intern_pool.aggregateTypeLenIncludingSentinel(ty.toIntern()); | |
| 2283 | pub fn arrayLenIncludingSentinel(ty: Type, zcu: *const Zcu) u64 { | |
| 2284 | return zcu.intern_pool.aggregateTypeLenIncludingSentinel(ty.toIntern()); | |
| 2165 | 2285 | } |
| 2166 | 2286 | |
| 2167 | pub fn vectorLen(ty: Type, mod: *const Module) u32 { | |
| 2168 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2287 | pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 { | |
| 2288 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 2169 | 2289 | .vector_type => |vector_type| vector_type.len, |
| 2170 | 2290 | .anon_struct_type => |tuple| @intCast(tuple.types.len), |
| 2171 | 2291 | else => unreachable, |
| ... | ... | @@ -2173,8 +2293,8 @@ pub fn vectorLen(ty: Type, mod: *const Module) u32 { |
| 2173 | 2293 | } |
| 2174 | 2294 | |
| 2175 | 2295 | /// Asserts the type is an array, pointer or vector. |
| 2176 | pub fn sentinel(ty: Type, mod: *const Module) ?Value { | |
| 2177 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2296 | pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { | |
| 2297 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 2178 | 2298 | .vector_type, |
| 2179 | 2299 | .struct_type, |
| 2180 | 2300 | .anon_struct_type, |
| ... | ... | @@ -2188,17 +2308,17 @@ pub fn sentinel(ty: Type, mod: *const Module) ?Value { |
| 2188 | 2308 | } |
| 2189 | 2309 | |
| 2190 | 2310 | /// Returns true if and only if the type is a fixed-width integer. |
| 2191 | pub fn isInt(self: Type, mod: *const Module) bool { | |
| 2311 | pub fn isInt(self: Type, zcu: *const Zcu) bool { | |
| 2192 | 2312 | return self.toIntern() != .comptime_int_type and |
| 2193 | mod.intern_pool.isIntegerType(self.toIntern()); | |
| 2313 | zcu.intern_pool.isIntegerType(self.toIntern()); | |
| 2194 | 2314 | } |
| 2195 | 2315 | |
| 2196 | 2316 | /// Returns true if and only if the type is a fixed-width, signed integer. |
| 2197 | pub fn isSignedInt(ty: Type, mod: *const Module) bool { | |
| 2317 | pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool { | |
| 2198 | 2318 | return switch (ty.toIntern()) { |
| 2199 | .c_char_type => mod.getTarget().charSignedness() == .signed, | |
| 2319 | .c_char_type => zcu.getTarget().charSignedness() == .signed, | |
| 2200 | 2320 | .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true, |
| 2201 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2321 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 2202 | 2322 | .int_type => |int_type| int_type.signedness == .signed, |
| 2203 | 2323 | else => false, |
| 2204 | 2324 | }, |
| ... | ... | @@ -2206,11 +2326,11 @@ pub fn isSignedInt(ty: Type, mod: *const Module) bool { |
| 2206 | 2326 | } |
| 2207 | 2327 | |
| 2208 | 2328 | /// Returns true if and only if the type is a fixed-width, unsigned integer. |
| 2209 | pub fn isUnsignedInt(ty: Type, mod: *const Module) bool { | |
| 2329 | pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool { | |
| 2210 | 2330 | return switch (ty.toIntern()) { |
| 2211 | .c_char_type => mod.getTarget().charSignedness() == .unsigned, | |
| 2331 | .c_char_type => zcu.getTarget().charSignedness() == .unsigned, | |
| 2212 | 2332 | .usize_type, .c_ushort_type, .c_uint_type, .c_ulong_type, .c_ulonglong_type => true, |
| 2213 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2333 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 2214 | 2334 | .int_type => |int_type| int_type.signedness == .unsigned, |
| 2215 | 2335 | else => false, |
| 2216 | 2336 | }, |
| ... | ... | @@ -2219,27 +2339,27 @@ pub fn isUnsignedInt(ty: Type, mod: *const Module) bool { |
| 2219 | 2339 | |
| 2220 | 2340 | /// Returns true for integers, enums, error sets, and packed structs. |
| 2221 | 2341 | /// If this function returns true, then intInfo() can be called on the type. |
| 2222 | pub fn isAbiInt(ty: Type, mod: *Module) bool { | |
| 2223 | return switch (ty.zigTypeTag(mod)) { | |
| 2342 | pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool { | |
| 2343 | return switch (ty.zigTypeTag(zcu)) { | |
| 2224 | 2344 | .Int, .Enum, .ErrorSet => true, |
| 2225 | .Struct => ty.containerLayout(mod) == .@"packed", | |
| 2345 | .Struct => ty.containerLayout(zcu) == .@"packed", | |
| 2226 | 2346 | else => false, |
| 2227 | 2347 | }; |
| 2228 | 2348 | } |
| 2229 | 2349 | |
| 2230 | 2350 | /// Asserts the type is an integer, enum, error set, or vector of one of them. |
| 2231 | pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType { | |
| 2232 | const ip = &mod.intern_pool; | |
| 2233 | const target = mod.getTarget(); | |
| 2351 | pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { | |
| 2352 | const ip = &zcu.intern_pool; | |
| 2353 | const target = zcu.getTarget(); | |
| 2234 | 2354 | var ty = starting_ty; |
| 2235 | 2355 | |
| 2236 | 2356 | while (true) switch (ty.toIntern()) { |
| 2237 | 2357 | .anyerror_type, .adhoc_inferred_error_set_type => { |
| 2238 | return .{ .signedness = .unsigned, .bits = mod.errorSetBits() }; | |
| 2358 | return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }; | |
| 2239 | 2359 | }, |
| 2240 | 2360 | .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() }, |
| 2241 | 2361 | .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() }, |
| 2242 | .c_char_type => return .{ .signedness = mod.getTarget().charSignedness(), .bits = target.cTypeBitSize(.char) }, | |
| 2362 | .c_char_type => return .{ .signedness = zcu.getTarget().charSignedness(), .bits = target.cTypeBitSize(.char) }, | |
| 2243 | 2363 | .c_short_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.short) }, |
| 2244 | 2364 | .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ushort) }, |
| 2245 | 2365 | .c_int_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.int) }, |
| ... | ... | @@ -2255,7 +2375,7 @@ pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType { |
| 2255 | 2375 | .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child), |
| 2256 | 2376 | |
| 2257 | 2377 | .error_set_type, .inferred_error_set_type => { |
| 2258 | return .{ .signedness = .unsigned, .bits = mod.errorSetBits() }; | |
| 2378 | return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }; | |
| 2259 | 2379 | }, |
| 2260 | 2380 | |
| 2261 | 2381 | .anon_struct_type => unreachable, |
| ... | ... | @@ -2363,35 +2483,35 @@ pub fn floatBits(ty: Type, target: Target) u16 { |
| 2363 | 2483 | } |
| 2364 | 2484 | |
| 2365 | 2485 | /// Asserts the type is a function or a function pointer. |
| 2366 | pub fn fnReturnType(ty: Type, mod: *Module) Type { | |
| 2367 | return Type.fromInterned(mod.intern_pool.funcTypeReturnType(ty.toIntern())); | |
| 2486 | pub fn fnReturnType(ty: Type, zcu: *const Zcu) Type { | |
| 2487 | return Type.fromInterned(zcu.intern_pool.funcTypeReturnType(ty.toIntern())); | |
| 2368 | 2488 | } |
| 2369 | 2489 | |
| 2370 | 2490 | /// Asserts the type is a function. |
| 2371 | pub fn fnCallingConvention(ty: Type, mod: *Module) std.builtin.CallingConvention { | |
| 2372 | return mod.intern_pool.indexToKey(ty.toIntern()).func_type.cc; | |
| 2491 | pub fn fnCallingConvention(ty: Type, zcu: *const Zcu) std.builtin.CallingConvention { | |
| 2492 | return zcu.intern_pool.indexToKey(ty.toIntern()).func_type.cc; | |
| 2373 | 2493 | } |
| 2374 | 2494 | |
| 2375 | pub fn isValidParamType(self: Type, mod: *const Module) bool { | |
| 2376 | return switch (self.zigTypeTagOrPoison(mod) catch return true) { | |
| 2495 | pub fn isValidParamType(self: Type, zcu: *const Zcu) bool { | |
| 2496 | return switch (self.zigTypeTagOrPoison(zcu) catch return true) { | |
| 2377 | 2497 | .Opaque, .NoReturn => false, |
| 2378 | 2498 | else => true, |
| 2379 | 2499 | }; |
| 2380 | 2500 | } |
| 2381 | 2501 | |
| 2382 | pub fn isValidReturnType(self: Type, mod: *const Module) bool { | |
| 2383 | return switch (self.zigTypeTagOrPoison(mod) catch return true) { | |
| 2502 | pub fn isValidReturnType(self: Type, zcu: *const Zcu) bool { | |
| 2503 | return switch (self.zigTypeTagOrPoison(zcu) catch return true) { | |
| 2384 | 2504 | .Opaque => false, |
| 2385 | 2505 | else => true, |
| 2386 | 2506 | }; |
| 2387 | 2507 | } |
| 2388 | 2508 | |
| 2389 | 2509 | /// Asserts the type is a function. |
| 2390 | pub fn fnIsVarArgs(ty: Type, mod: *Module) bool { | |
| 2391 | return mod.intern_pool.indexToKey(ty.toIntern()).func_type.is_var_args; | |
| 2510 | pub fn fnIsVarArgs(ty: Type, zcu: *const Zcu) bool { | |
| 2511 | return zcu.intern_pool.indexToKey(ty.toIntern()).func_type.is_var_args; | |
| 2392 | 2512 | } |
| 2393 | 2513 | |
| 2394 | pub fn isNumeric(ty: Type, mod: *const Module) bool { | |
| 2514 | pub fn isNumeric(ty: Type, zcu: *const Zcu) bool { | |
| 2395 | 2515 | return switch (ty.toIntern()) { |
| 2396 | 2516 | .f16_type, |
| 2397 | 2517 | .f32_type, |
| ... | ... | @@ -2414,7 +2534,7 @@ pub fn isNumeric(ty: Type, mod: *const Module) bool { |
| 2414 | 2534 | .c_ulonglong_type, |
| 2415 | 2535 | => true, |
| 2416 | 2536 | |
| 2417 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 2537 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 2418 | 2538 | .int_type => true, |
| 2419 | 2539 | else => false, |
| 2420 | 2540 | }, |
| ... | ... | @@ -2424,9 +2544,9 @@ pub fn isNumeric(ty: Type, mod: *const Module) bool { |
| 2424 | 2544 | /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which |
| 2425 | 2545 | /// resolves field types rather than asserting they are already resolved. |
| 2426 | 2546 | pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2427 | const mod = pt.zcu; | |
| 2547 | const zcu = pt.zcu; | |
| 2428 | 2548 | var ty = starting_type; |
| 2429 | const ip = &mod.intern_pool; | |
| 2549 | const ip = &zcu.intern_pool; | |
| 2430 | 2550 | while (true) switch (ty.toIntern()) { |
| 2431 | 2551 | .empty_struct_type => return Value.empty_struct, |
| 2432 | 2552 | |
| ... | ... | @@ -2509,8 +2629,8 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2509 | 2629 | assert(struct_type.haveFieldTypes(ip)); |
| 2510 | 2630 | if (struct_type.knownNonOpv(ip)) |
| 2511 | 2631 | return null; |
| 2512 | const field_vals = try mod.gpa.alloc(InternPool.Index, struct_type.field_types.len); | |
| 2513 | defer mod.gpa.free(field_vals); | |
| 2632 | const field_vals = try zcu.gpa.alloc(InternPool.Index, struct_type.field_types.len); | |
| 2633 | defer zcu.gpa.free(field_vals); | |
| 2514 | 2634 | for (field_vals, 0..) |*field_val, i_usize| { |
| 2515 | 2635 | const i: u32 = @intCast(i_usize); |
| 2516 | 2636 | if (struct_type.fieldIsComptime(ip, i)) { |
| ... | ... | @@ -2539,8 +2659,8 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2539 | 2659 | // In this case the struct has all comptime-known fields and |
| 2540 | 2660 | // therefore has one possible value. |
| 2541 | 2661 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 2542 | const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip)); | |
| 2543 | defer mod.gpa.free(duped_values); | |
| 2662 | const duped_values = try zcu.gpa.dupe(InternPool.Index, tuple.values.get(ip)); | |
| 2663 | defer zcu.gpa.free(duped_values); | |
| 2544 | 2664 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2545 | 2665 | .ty = ty.toIntern(), |
| 2546 | 2666 | .storage = .{ .elems = duped_values }, |
| ... | ... | @@ -2583,7 +2703,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2583 | 2703 | return null; |
| 2584 | 2704 | }, |
| 2585 | 2705 | .auto, .explicit => { |
| 2586 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(pt)) return null; | |
| 2706 | if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null; | |
| 2587 | 2707 | |
| 2588 | 2708 | switch (enum_type.names.len) { |
| 2589 | 2709 | 0 => { |
| ... | ... | @@ -2635,17 +2755,25 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value { |
| 2635 | 2755 | }; |
| 2636 | 2756 | } |
| 2637 | 2757 | |
| 2638 | /// During semantic analysis, instead call `Sema.typeRequiresComptime` which | |
| 2758 | /// During semantic analysis, instead call `ty.comptimeOnlySema` which | |
| 2639 | 2759 | /// resolves field types rather than asserting they are already resolved. |
| 2640 | pub fn comptimeOnly(ty: Type, pt: Zcu.PerThread) bool { | |
| 2641 | return ty.comptimeOnlyAdvanced(pt, .normal) catch unreachable; | |
| 2760 | pub fn comptimeOnly(ty: Type, zcu: *Zcu) bool { | |
| 2761 | return ty.comptimeOnlyInner(.normal, zcu, {}) catch unreachable; | |
| 2762 | } | |
| 2763 | ||
| 2764 | pub fn comptimeOnlySema(ty: Type, pt: Zcu.PerThread) SemaError!bool { | |
| 2765 | return try ty.comptimeOnlyInner(.sema, pt.zcu, pt.tid); | |
| 2642 | 2766 | } |
| 2643 | 2767 | |
| 2644 | 2768 | /// `generic_poison` will return false. |
| 2645 | 2769 | /// May return false negatives when structs and unions are having their field types resolved. |
| 2646 | pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) SemaError!bool { | |
| 2647 | const mod = pt.zcu; | |
| 2648 | const ip = &mod.intern_pool; | |
| 2770 | pub fn comptimeOnlyInner( | |
| 2771 | ty: Type, | |
| 2772 | comptime strat: ResolveStrat, | |
| 2773 | zcu: *Zcu, | |
| 2774 | tid: strat.Tid(), | |
| 2775 | ) SemaError!bool { | |
| 2776 | const ip = &zcu.intern_pool; | |
| 2649 | 2777 | return switch (ty.toIntern()) { |
| 2650 | 2778 | .empty_struct_type => false, |
| 2651 | 2779 | |
| ... | ... | @@ -2653,20 +2781,20 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve |
| 2653 | 2781 | .int_type => false, |
| 2654 | 2782 | .ptr_type => |ptr_type| { |
| 2655 | 2783 | const child_ty = Type.fromInterned(ptr_type.child); |
| 2656 | switch (child_ty.zigTypeTag(mod)) { | |
| 2657 | .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(pt, strat), | |
| 2784 | switch (child_ty.zigTypeTag(zcu)) { | |
| 2785 | .Fn => return !try child_ty.fnHasRuntimeBitsInner(strat, zcu, tid), | |
| 2658 | 2786 | .Opaque => return false, |
| 2659 | else => return child_ty.comptimeOnlyAdvanced(pt, strat), | |
| 2787 | else => return child_ty.comptimeOnlyInner(strat, zcu, tid), | |
| 2660 | 2788 | } |
| 2661 | 2789 | }, |
| 2662 | 2790 | .anyframe_type => |child| { |
| 2663 | 2791 | if (child == .none) return false; |
| 2664 | return Type.fromInterned(child).comptimeOnlyAdvanced(pt, strat); | |
| 2792 | return Type.fromInterned(child).comptimeOnlyInner(strat, zcu, tid); | |
| 2665 | 2793 | }, |
| 2666 | .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(pt, strat), | |
| 2667 | .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(pt, strat), | |
| 2668 | .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(pt, strat), | |
| 2669 | .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(pt, strat), | |
| 2794 | .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyInner(strat, zcu, tid), | |
| 2795 | .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyInner(strat, zcu, tid), | |
| 2796 | .opt_type => |child| return Type.fromInterned(child).comptimeOnlyInner(strat, zcu, tid), | |
| 2797 | .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyInner(strat, zcu, tid), | |
| 2670 | 2798 | |
| 2671 | 2799 | .error_set_type, |
| 2672 | 2800 | .inferred_error_set_type, |
| ... | ... | @@ -2732,13 +2860,14 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve |
| 2732 | 2860 | |
| 2733 | 2861 | errdefer struct_type.setRequiresComptime(ip, .unknown); |
| 2734 | 2862 | |
| 2863 | const pt = strat.pt(zcu, tid); | |
| 2735 | 2864 | try ty.resolveFields(pt); |
| 2736 | 2865 | |
| 2737 | 2866 | for (0..struct_type.field_types.len) |i_usize| { |
| 2738 | 2867 | const i: u32 = @intCast(i_usize); |
| 2739 | 2868 | if (struct_type.fieldIsComptime(ip, i)) continue; |
| 2740 | 2869 | const field_ty = struct_type.field_types.get(ip)[i]; |
| 2741 | if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) { | |
| 2870 | if (try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) { | |
| 2742 | 2871 | // Note that this does not cause the layout to |
| 2743 | 2872 | // be considered resolved. Comptime-only types |
| 2744 | 2873 | // still maintain a layout of their |
| ... | ... | @@ -2757,7 +2886,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve |
| 2757 | 2886 | .anon_struct_type => |tuple| { |
| 2758 | 2887 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 2759 | 2888 | const have_comptime_val = val != .none; |
| 2760 | if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) return true; | |
| 2889 | if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) return true; | |
| 2761 | 2890 | } |
| 2762 | 2891 | return false; |
| 2763 | 2892 | }, |
| ... | ... | @@ -2778,11 +2907,12 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve |
| 2778 | 2907 | |
| 2779 | 2908 | errdefer union_type.setRequiresComptime(ip, .unknown); |
| 2780 | 2909 | |
| 2910 | const pt = strat.pt(zcu, tid); | |
| 2781 | 2911 | try ty.resolveFields(pt); |
| 2782 | 2912 | |
| 2783 | 2913 | for (0..union_type.field_types.len) |field_idx| { |
| 2784 | 2914 | const field_ty = union_type.field_types.get(ip)[field_idx]; |
| 2785 | if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) { | |
| 2915 | if (try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) { | |
| 2786 | 2916 | union_type.setRequiresComptime(ip, .yes); |
| 2787 | 2917 | return true; |
| 2788 | 2918 | } |
| ... | ... | @@ -2796,7 +2926,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve |
| 2796 | 2926 | |
| 2797 | 2927 | .opaque_type => false, |
| 2798 | 2928 | |
| 2799 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(pt, strat), | |
| 2929 | .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyInner(strat, zcu, tid), | |
| 2800 | 2930 | |
| 2801 | 2931 | // values, not types |
| 2802 | 2932 | .undef, |
| ... | ... | @@ -2823,53 +2953,53 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve |
| 2823 | 2953 | }; |
| 2824 | 2954 | } |
| 2825 | 2955 | |
| 2826 | pub fn isVector(ty: Type, mod: *const Module) bool { | |
| 2827 | return ty.zigTypeTag(mod) == .Vector; | |
| 2956 | pub fn isVector(ty: Type, zcu: *const Zcu) bool { | |
| 2957 | return ty.zigTypeTag(zcu) == .Vector; | |
| 2828 | 2958 | } |
| 2829 | 2959 | |
| 2830 | 2960 | /// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len. |
| 2831 | pub fn totalVectorBits(ty: Type, pt: Zcu.PerThread) u64 { | |
| 2832 | if (!ty.isVector(pt.zcu)) return 0; | |
| 2833 | const v = pt.zcu.intern_pool.indexToKey(ty.toIntern()).vector_type; | |
| 2834 | return v.len * Type.fromInterned(v.child).bitSize(pt); | |
| 2961 | pub fn totalVectorBits(ty: Type, zcu: *Zcu) u64 { | |
| 2962 | if (!ty.isVector(zcu)) return 0; | |
| 2963 | const v = zcu.intern_pool.indexToKey(ty.toIntern()).vector_type; | |
| 2964 | return v.len * Type.fromInterned(v.child).bitSize(zcu); | |
| 2835 | 2965 | } |
| 2836 | 2966 | |
| 2837 | pub fn isArrayOrVector(ty: Type, mod: *const Module) bool { | |
| 2838 | return switch (ty.zigTypeTag(mod)) { | |
| 2967 | pub fn isArrayOrVector(ty: Type, zcu: *const Zcu) bool { | |
| 2968 | return switch (ty.zigTypeTag(zcu)) { | |
| 2839 | 2969 | .Array, .Vector => true, |
| 2840 | 2970 | else => false, |
| 2841 | 2971 | }; |
| 2842 | 2972 | } |
| 2843 | 2973 | |
| 2844 | pub fn isIndexable(ty: Type, mod: *Module) bool { | |
| 2845 | return switch (ty.zigTypeTag(mod)) { | |
| 2974 | pub fn isIndexable(ty: Type, zcu: *const Zcu) bool { | |
| 2975 | return switch (ty.zigTypeTag(zcu)) { | |
| 2846 | 2976 | .Array, .Vector => true, |
| 2847 | .Pointer => switch (ty.ptrSize(mod)) { | |
| 2977 | .Pointer => switch (ty.ptrSize(zcu)) { | |
| 2848 | 2978 | .Slice, .Many, .C => true, |
| 2849 | .One => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 2979 | .One => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 2850 | 2980 | .Array, .Vector => true, |
| 2851 | .Struct => ty.childType(mod).isTuple(mod), | |
| 2981 | .Struct => ty.childType(zcu).isTuple(zcu), | |
| 2852 | 2982 | else => false, |
| 2853 | 2983 | }, |
| 2854 | 2984 | }, |
| 2855 | .Struct => ty.isTuple(mod), | |
| 2985 | .Struct => ty.isTuple(zcu), | |
| 2856 | 2986 | else => false, |
| 2857 | 2987 | }; |
| 2858 | 2988 | } |
| 2859 | 2989 | |
| 2860 | pub fn indexableHasLen(ty: Type, mod: *Module) bool { | |
| 2861 | return switch (ty.zigTypeTag(mod)) { | |
| 2990 | pub fn indexableHasLen(ty: Type, zcu: *const Zcu) bool { | |
| 2991 | return switch (ty.zigTypeTag(zcu)) { | |
| 2862 | 2992 | .Array, .Vector => true, |
| 2863 | .Pointer => switch (ty.ptrSize(mod)) { | |
| 2993 | .Pointer => switch (ty.ptrSize(zcu)) { | |
| 2864 | 2994 | .Many, .C => false, |
| 2865 | 2995 | .Slice => true, |
| 2866 | .One => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 2996 | .One => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 2867 | 2997 | .Array, .Vector => true, |
| 2868 | .Struct => ty.childType(mod).isTuple(mod), | |
| 2998 | .Struct => ty.childType(zcu).isTuple(zcu), | |
| 2869 | 2999 | else => false, |
| 2870 | 3000 | }, |
| 2871 | 3001 | }, |
| 2872 | .Struct => ty.isTuple(mod), | |
| 3002 | .Struct => ty.isTuple(zcu), | |
| 2873 | 3003 | else => false, |
| 2874 | 3004 | }; |
| 2875 | 3005 | } |
| ... | ... | @@ -2973,17 +3103,17 @@ pub fn maxIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 2973 | 3103 | } |
| 2974 | 3104 | |
| 2975 | 3105 | /// Asserts the type is an enum or a union. |
| 2976 | pub fn intTagType(ty: Type, mod: *Module) Type { | |
| 2977 | const ip = &mod.intern_pool; | |
| 3106 | pub fn intTagType(ty: Type, zcu: *const Zcu) Type { | |
| 3107 | const ip = &zcu.intern_pool; | |
| 2978 | 3108 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2979 | .union_type => Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty).intTagType(mod), | |
| 3109 | .union_type => Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty).intTagType(zcu), | |
| 2980 | 3110 | .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), |
| 2981 | 3111 | else => unreachable, |
| 2982 | 3112 | }; |
| 2983 | 3113 | } |
| 2984 | 3114 | |
| 2985 | pub fn isNonexhaustiveEnum(ty: Type, mod: *Module) bool { | |
| 2986 | const ip = &mod.intern_pool; | |
| 3115 | pub fn isNonexhaustiveEnum(ty: Type, zcu: *const Zcu) bool { | |
| 3116 | const ip = &zcu.intern_pool; | |
| 2987 | 3117 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2988 | 3118 | .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) { |
| 2989 | 3119 | .nonexhaustive => true, |
| ... | ... | @@ -2995,8 +3125,8 @@ pub fn isNonexhaustiveEnum(ty: Type, mod: *Module) bool { |
| 2995 | 3125 | |
| 2996 | 3126 | // Asserts that `ty` is an error set and not `anyerror`. |
| 2997 | 3127 | // Asserts that `ty` is resolved if it is an inferred error set. |
| 2998 | pub fn errorSetNames(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice { | |
| 2999 | const ip = &mod.intern_pool; | |
| 3128 | pub fn errorSetNames(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString.Slice { | |
| 3129 | const ip = &zcu.intern_pool; | |
| 3000 | 3130 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3001 | 3131 | .error_set_type => |x| x.names, |
| 3002 | 3132 | .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) { |
| ... | ... | @@ -3008,21 +3138,21 @@ pub fn errorSetNames(ty: Type, mod: *Module) InternPool.NullTerminatedString.Sli |
| 3008 | 3138 | }; |
| 3009 | 3139 | } |
| 3010 | 3140 | |
| 3011 | pub fn enumFields(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice { | |
| 3012 | return mod.intern_pool.loadEnumType(ty.toIntern()).names; | |
| 3141 | pub fn enumFields(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString.Slice { | |
| 3142 | return zcu.intern_pool.loadEnumType(ty.toIntern()).names; | |
| 3013 | 3143 | } |
| 3014 | 3144 | |
| 3015 | pub fn enumFieldCount(ty: Type, mod: *Module) usize { | |
| 3016 | return mod.intern_pool.loadEnumType(ty.toIntern()).names.len; | |
| 3145 | pub fn enumFieldCount(ty: Type, zcu: *const Zcu) usize { | |
| 3146 | return zcu.intern_pool.loadEnumType(ty.toIntern()).names.len; | |
| 3017 | 3147 | } |
| 3018 | 3148 | |
| 3019 | pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString { | |
| 3020 | const ip = &mod.intern_pool; | |
| 3149 | pub fn enumFieldName(ty: Type, field_index: usize, zcu: *const Zcu) InternPool.NullTerminatedString { | |
| 3150 | const ip = &zcu.intern_pool; | |
| 3021 | 3151 | return ip.loadEnumType(ty.toIntern()).names.get(ip)[field_index]; |
| 3022 | 3152 | } |
| 3023 | 3153 | |
| 3024 | pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, mod: *Module) ?u32 { | |
| 3025 | const ip = &mod.intern_pool; | |
| 3154 | pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, zcu: *const Zcu) ?u32 { | |
| 3155 | const ip = &zcu.intern_pool; | |
| 3026 | 3156 | const enum_type = ip.loadEnumType(ty.toIntern()); |
| 3027 | 3157 | return enum_type.nameIndex(ip, field_name); |
| 3028 | 3158 | } |
| ... | ... | @@ -3030,8 +3160,8 @@ pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, mod |
| 3030 | 3160 | /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or |
| 3031 | 3161 | /// an integer which represents the enum value. Returns the field index in |
| 3032 | 3162 | /// declaration order, or `null` if `enum_tag` does not match any field. |
| 3033 | pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 { | |
| 3034 | const ip = &mod.intern_pool; | |
| 3163 | pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 { | |
| 3164 | const ip = &zcu.intern_pool; | |
| 3035 | 3165 | const enum_type = ip.loadEnumType(ty.toIntern()); |
| 3036 | 3166 | const int_tag = switch (ip.indexToKey(enum_tag.toIntern())) { |
| 3037 | 3167 | .int => enum_tag.toIntern(), |
| ... | ... | @@ -3043,8 +3173,8 @@ pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 { |
| 3043 | 3173 | } |
| 3044 | 3174 | |
| 3045 | 3175 | /// Returns none in the case of a tuple which uses the integer index as the field name. |
| 3046 | pub fn structFieldName(ty: Type, index: usize, mod: *Module) InternPool.OptionalNullTerminatedString { | |
| 3047 | const ip = &mod.intern_pool; | |
| 3176 | pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.OptionalNullTerminatedString { | |
| 3177 | const ip = &zcu.intern_pool; | |
| 3048 | 3178 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3049 | 3179 | .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, index), |
| 3050 | 3180 | .anon_struct_type => |anon_struct| anon_struct.fieldName(ip, index), |
| ... | ... | @@ -3052,8 +3182,8 @@ pub fn structFieldName(ty: Type, index: usize, mod: *Module) InternPool.Optional |
| 3052 | 3182 | }; |
| 3053 | 3183 | } |
| 3054 | 3184 | |
| 3055 | pub fn structFieldCount(ty: Type, mod: *Module) u32 { | |
| 3056 | const ip = &mod.intern_pool; | |
| 3185 | pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 { | |
| 3186 | const ip = &zcu.intern_pool; | |
| 3057 | 3187 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3058 | 3188 | .struct_type => ip.loadStructType(ty.toIntern()).field_types.len, |
| 3059 | 3189 | .anon_struct_type => |anon_struct| anon_struct.types.len, |
| ... | ... | @@ -3062,8 +3192,8 @@ pub fn structFieldCount(ty: Type, mod: *Module) u32 { |
| 3062 | 3192 | } |
| 3063 | 3193 | |
| 3064 | 3194 | /// Supports structs and unions. |
| 3065 | pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type { | |
| 3066 | const ip = &mod.intern_pool; | |
| 3195 | pub fn structFieldType(ty: Type, index: usize, zcu: *const Zcu) Type { | |
| 3196 | const ip = &zcu.intern_pool; | |
| 3067 | 3197 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3068 | 3198 | .struct_type => Type.fromInterned(ip.loadStructType(ty.toIntern()).field_types.get(ip)[index]), |
| 3069 | 3199 | .union_type => { |
| ... | ... | @@ -3075,33 +3205,111 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type { |
| 3075 | 3205 | }; |
| 3076 | 3206 | } |
| 3077 | 3207 | |
| 3078 | pub fn structFieldAlign(ty: Type, index: usize, pt: Zcu.PerThread) Alignment { | |
| 3079 | return ty.structFieldAlignAdvanced(index, pt, .normal) catch unreachable; | |
| 3208 | pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment { | |
| 3209 | return ty.structFieldAlignAdvanced(index, .normal, zcu, {}) catch unreachable; | |
| 3080 | 3210 | } |
| 3081 | 3211 | |
| 3082 | pub fn structFieldAlignAdvanced(ty: Type, index: usize, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Alignment { | |
| 3083 | const ip = &pt.zcu.intern_pool; | |
| 3212 | pub fn structFieldAlignAdvanced( | |
| 3213 | ty: Type, | |
| 3214 | index: usize, | |
| 3215 | comptime strat: ResolveStrat, | |
| 3216 | zcu: *Zcu, | |
| 3217 | tid: strat.Tid(), | |
| 3218 | ) !Alignment { | |
| 3219 | const ip = &zcu.intern_pool; | |
| 3084 | 3220 | switch (ip.indexToKey(ty.toIntern())) { |
| 3085 | 3221 | .struct_type => { |
| 3086 | 3222 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 3087 | 3223 | assert(struct_type.layout != .@"packed"); |
| 3088 | 3224 | const explicit_align = struct_type.fieldAlign(ip, index); |
| 3089 | 3225 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]); |
| 3090 | return pt.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat); | |
| 3226 | return field_ty.structFieldAlignmentAdvanced( | |
| 3227 | explicit_align, | |
| 3228 | struct_type.layout, | |
| 3229 | strat, | |
| 3230 | zcu, | |
| 3231 | tid, | |
| 3232 | ); | |
| 3091 | 3233 | }, |
| 3092 | 3234 | .anon_struct_type => |anon_struct| { |
| 3093 | return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(pt, strat.toLazy())).scalar; | |
| 3235 | return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentInner( | |
| 3236 | strat.toLazy(), | |
| 3237 | zcu, | |
| 3238 | tid, | |
| 3239 | )).scalar; | |
| 3094 | 3240 | }, |
| 3095 | 3241 | .union_type => { |
| 3096 | 3242 | const union_obj = ip.loadUnionType(ty.toIntern()); |
| 3097 | return pt.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat); | |
| 3243 | return unionFieldNormalAlignmentAdvanced( | |
| 3244 | union_obj, | |
| 3245 | @intCast(index), | |
| 3246 | strat, | |
| 3247 | zcu, | |
| 3248 | tid, | |
| 3249 | ); | |
| 3098 | 3250 | }, |
| 3099 | 3251 | else => unreachable, |
| 3100 | 3252 | } |
| 3101 | 3253 | } |
| 3102 | 3254 | |
| 3103 | pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { | |
| 3104 | const ip = &mod.intern_pool; | |
| 3255 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. | |
| 3256 | /// If `strat` is `.sema`, may perform type resolution. | |
| 3257 | pub fn structFieldAlignmentAdvanced( | |
| 3258 | field_ty: Type, | |
| 3259 | explicit_alignment: InternPool.Alignment, | |
| 3260 | layout: std.builtin.Type.ContainerLayout, | |
| 3261 | comptime strat: Type.ResolveStrat, | |
| 3262 | zcu: *Zcu, | |
| 3263 | tid: strat.Tid(), | |
| 3264 | ) Zcu.SemaError!InternPool.Alignment { | |
| 3265 | assert(layout != .@"packed"); | |
| 3266 | if (explicit_alignment != .none) return explicit_alignment; | |
| 3267 | const ty_abi_align = (try field_ty.abiAlignmentInner( | |
| 3268 | strat.toLazy(), | |
| 3269 | zcu, | |
| 3270 | tid, | |
| 3271 | )).scalar; | |
| 3272 | switch (layout) { | |
| 3273 | .@"packed" => unreachable, | |
| 3274 | .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align, | |
| 3275 | .@"extern" => {}, | |
| 3276 | } | |
| 3277 | // extern | |
| 3278 | if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) { | |
| 3279 | return ty_abi_align.maxStrict(.@"16"); | |
| 3280 | } | |
| 3281 | return ty_abi_align; | |
| 3282 | } | |
| 3283 | ||
| 3284 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | |
| 3285 | pub fn unionFieldNormalAlignment( | |
| 3286 | loaded_union: InternPool.LoadedUnionType, | |
| 3287 | field_index: u32, | |
| 3288 | zcu: *Zcu, | |
| 3289 | ) InternPool.Alignment { | |
| 3290 | return unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal, zcu, {}) catch unreachable; | |
| 3291 | } | |
| 3292 | ||
| 3293 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | |
| 3294 | /// If `strat` is `.sema`, may perform type resolution. | |
| 3295 | pub fn unionFieldNormalAlignmentAdvanced( | |
| 3296 | loaded_union: InternPool.LoadedUnionType, | |
| 3297 | field_index: u32, | |
| 3298 | comptime strat: Type.ResolveStrat, | |
| 3299 | zcu: *Zcu, | |
| 3300 | tid: strat.Tid(), | |
| 3301 | ) Zcu.SemaError!InternPool.Alignment { | |
| 3302 | const ip = &zcu.intern_pool; | |
| 3303 | assert(loaded_union.flagsUnordered(ip).layout != .@"packed"); | |
| 3304 | const field_align = loaded_union.fieldAlign(ip, field_index); | |
| 3305 | if (field_align != .none) return field_align; | |
| 3306 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | |
| 3307 | if (field_ty.isNoReturn(zcu)) return .none; | |
| 3308 | return (try field_ty.abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar; | |
| 3309 | } | |
| 3310 | ||
| 3311 | pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) Value { | |
| 3312 | const ip = &zcu.intern_pool; | |
| 3105 | 3313 | switch (ip.indexToKey(ty.toIntern())) { |
| 3106 | 3314 | .struct_type => { |
| 3107 | 3315 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -3121,8 +3329,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { |
| 3121 | 3329 | } |
| 3122 | 3330 | |
| 3123 | 3331 | pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Value { |
| 3124 | const mod = pt.zcu; | |
| 3125 | const ip = &mod.intern_pool; | |
| 3332 | const zcu = pt.zcu; | |
| 3333 | const ip = &zcu.intern_pool; | |
| 3126 | 3334 | switch (ip.indexToKey(ty.toIntern())) { |
| 3127 | 3335 | .struct_type => { |
| 3128 | 3336 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -3145,8 +3353,8 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val |
| 3145 | 3353 | } |
| 3146 | 3354 | } |
| 3147 | 3355 | |
| 3148 | pub fn structFieldIsComptime(ty: Type, index: usize, mod: *Module) bool { | |
| 3149 | const ip = &mod.intern_pool; | |
| 3356 | pub fn structFieldIsComptime(ty: Type, index: usize, zcu: *const Zcu) bool { | |
| 3357 | const ip = &zcu.intern_pool; | |
| 3150 | 3358 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3151 | 3359 | .struct_type => ip.loadStructType(ty.toIntern()).fieldIsComptime(ip, index), |
| 3152 | 3360 | .anon_struct_type => |anon_struct| anon_struct.values.get(ip)[index] != .none, |
| ... | ... | @@ -3160,9 +3368,12 @@ pub const FieldOffset = struct { |
| 3160 | 3368 | }; |
| 3161 | 3369 | |
| 3162 | 3370 | /// Supports structs and unions. |
| 3163 | pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { | |
| 3164 | const mod = pt.zcu; | |
| 3165 | const ip = &mod.intern_pool; | |
| 3371 | pub fn structFieldOffset( | |
| 3372 | ty: Type, | |
| 3373 | index: usize, | |
| 3374 | zcu: *Zcu, | |
| 3375 | ) u64 { | |
| 3376 | const ip = &zcu.intern_pool; | |
| 3166 | 3377 | switch (ip.indexToKey(ty.toIntern())) { |
| 3167 | 3378 | .struct_type => { |
| 3168 | 3379 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -3176,17 +3387,17 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { |
| 3176 | 3387 | var big_align: Alignment = .none; |
| 3177 | 3388 | |
| 3178 | 3389 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 3179 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) { | |
| 3390 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) { | |
| 3180 | 3391 | // comptime field |
| 3181 | 3392 | if (i == index) return offset; |
| 3182 | 3393 | continue; |
| 3183 | 3394 | } |
| 3184 | 3395 | |
| 3185 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); | |
| 3396 | const field_align = Type.fromInterned(field_ty).abiAlignment(zcu); | |
| 3186 | 3397 | big_align = big_align.max(field_align); |
| 3187 | 3398 | offset = field_align.forward(offset); |
| 3188 | 3399 | if (i == index) return offset; |
| 3189 | offset += Type.fromInterned(field_ty).abiSize(pt); | |
| 3400 | offset += Type.fromInterned(field_ty).abiSize(zcu); | |
| 3190 | 3401 | } |
| 3191 | 3402 | offset = big_align.max(.@"1").forward(offset); |
| 3192 | 3403 | return offset; |
| ... | ... | @@ -3196,7 +3407,7 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { |
| 3196 | 3407 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 3197 | 3408 | if (!union_type.hasTag(ip)) |
| 3198 | 3409 | return 0; |
| 3199 | const layout = pt.getUnionLayout(union_type); | |
| 3410 | const layout = union_type.getUnionLayout(zcu); | |
| 3200 | 3411 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| 3201 | 3412 | // {Tag, Payload} |
| 3202 | 3413 | return layout.payload_align.forward(layout.tag_size); |
| ... | ... | @@ -3210,7 +3421,7 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { |
| 3210 | 3421 | } |
| 3211 | 3422 | } |
| 3212 | 3423 | |
| 3213 | pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc { | |
| 3424 | pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc { | |
| 3214 | 3425 | const ip = &zcu.intern_pool; |
| 3215 | 3426 | return .{ |
| 3216 | 3427 | .base_node_inst = switch (ip.indexToKey(ty.toIntern())) { |
| ... | ... | @@ -3222,11 +3433,11 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc { |
| 3222 | 3433 | }, |
| 3223 | 3434 | else => return null, |
| 3224 | 3435 | }, |
| 3225 | .offset = Module.LazySrcLoc.Offset.nodeOffset(0), | |
| 3436 | .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0), | |
| 3226 | 3437 | }; |
| 3227 | 3438 | } |
| 3228 | 3439 | |
| 3229 | pub fn srcLoc(ty: Type, zcu: *Zcu) Module.LazySrcLoc { | |
| 3440 | pub fn srcLoc(ty: Type, zcu: *Zcu) Zcu.LazySrcLoc { | |
| 3230 | 3441 | return ty.srcLocOrNull(zcu).?; |
| 3231 | 3442 | } |
| 3232 | 3443 | |
| ... | ... | @@ -3234,8 +3445,8 @@ pub fn isGenericPoison(ty: Type) bool { |
| 3234 | 3445 | return ty.toIntern() == .generic_poison_type; |
| 3235 | 3446 | } |
| 3236 | 3447 | |
| 3237 | pub fn isTuple(ty: Type, mod: *Module) bool { | |
| 3238 | const ip = &mod.intern_pool; | |
| 3448 | pub fn isTuple(ty: Type, zcu: *const Zcu) bool { | |
| 3449 | const ip = &zcu.intern_pool; | |
| 3239 | 3450 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3240 | 3451 | .struct_type => { |
| 3241 | 3452 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -3248,16 +3459,16 @@ pub fn isTuple(ty: Type, mod: *Module) bool { |
| 3248 | 3459 | }; |
| 3249 | 3460 | } |
| 3250 | 3461 | |
| 3251 | pub fn isAnonStruct(ty: Type, mod: *Module) bool { | |
| 3462 | pub fn isAnonStruct(ty: Type, zcu: *const Zcu) bool { | |
| 3252 | 3463 | if (ty.toIntern() == .empty_struct_type) return true; |
| 3253 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 3464 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 3254 | 3465 | .anon_struct_type => |anon_struct_type| anon_struct_type.names.len > 0, |
| 3255 | 3466 | else => false, |
| 3256 | 3467 | }; |
| 3257 | 3468 | } |
| 3258 | 3469 | |
| 3259 | pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool { | |
| 3260 | const ip = &mod.intern_pool; | |
| 3470 | pub fn isTupleOrAnonStruct(ty: Type, zcu: *const Zcu) bool { | |
| 3471 | const ip = &zcu.intern_pool; | |
| 3261 | 3472 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3262 | 3473 | .struct_type => { |
| 3263 | 3474 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -3270,15 +3481,15 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool { |
| 3270 | 3481 | }; |
| 3271 | 3482 | } |
| 3272 | 3483 | |
| 3273 | pub fn isSimpleTuple(ty: Type, mod: *Module) bool { | |
| 3274 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 3484 | pub fn isSimpleTuple(ty: Type, zcu: *const Zcu) bool { | |
| 3485 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 3275 | 3486 | .anon_struct_type => |anon_struct_type| anon_struct_type.names.len == 0, |
| 3276 | 3487 | else => false, |
| 3277 | 3488 | }; |
| 3278 | 3489 | } |
| 3279 | 3490 | |
| 3280 | pub fn isSimpleTupleOrAnonStruct(ty: Type, mod: *Module) bool { | |
| 3281 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | |
| 3491 | pub fn isSimpleTupleOrAnonStruct(ty: Type, zcu: *const Zcu) bool { | |
| 3492 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | |
| 3282 | 3493 | .anon_struct_type => true, |
| 3283 | 3494 | else => false, |
| 3284 | 3495 | }; |
| ... | ... | @@ -3286,11 +3497,11 @@ pub fn isSimpleTupleOrAnonStruct(ty: Type, mod: *Module) bool { |
| 3286 | 3497 | |
| 3287 | 3498 | /// Traverses optional child types and error union payloads until the type |
| 3288 | 3499 | /// is not a pointer. For `E!?u32`, returns `u32`; for `*u8`, returns `*u8`. |
| 3289 | pub fn optEuBaseType(ty: Type, mod: *Module) Type { | |
| 3500 | pub fn optEuBaseType(ty: Type, zcu: *const Zcu) Type { | |
| 3290 | 3501 | var cur = ty; |
| 3291 | while (true) switch (cur.zigTypeTag(mod)) { | |
| 3292 | .Optional => cur = cur.optionalChild(mod), | |
| 3293 | .ErrorUnion => cur = cur.errorUnionPayload(mod), | |
| 3502 | while (true) switch (cur.zigTypeTag(zcu)) { | |
| 3503 | .Optional => cur = cur.optionalChild(zcu), | |
| 3504 | .ErrorUnion => cur = cur.errorUnionPayload(zcu), | |
| 3294 | 3505 | else => return cur, |
| 3295 | 3506 | }; |
| 3296 | 3507 | } |
| ... | ... | @@ -3406,7 +3617,7 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: |
| 3406 | 3617 | if (i == field_idx) { |
| 3407 | 3618 | bit_offset = running_bits; |
| 3408 | 3619 | } |
| 3409 | running_bits += @intCast(f_ty.bitSize(pt)); | |
| 3620 | running_bits += @intCast(f_ty.bitSize(zcu)); | |
| 3410 | 3621 | } |
| 3411 | 3622 | |
| 3412 | 3623 | const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0) |
| ... | ... | @@ -3423,9 +3634,9 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx: |
| 3423 | 3634 | // targets before adding the necessary complications to this code. This will not |
| 3424 | 3635 | // cause miscompilations; it only means the field pointer uses bit masking when it |
| 3425 | 3636 | // might not be strictly necessary. |
| 3426 | if (res_bit_offset % 8 == 0 and field_ty.bitSize(pt) == field_ty.abiSize(pt) * 8 and zcu.getTarget().cpu.arch.endian() == .little) { | |
| 3637 | if (res_bit_offset % 8 == 0 and field_ty.bitSize(zcu) == field_ty.abiSize(zcu) * 8 and zcu.getTarget().cpu.arch.endian() == .little) { | |
| 3427 | 3638 | const byte_offset = res_bit_offset / 8; |
| 3428 | const new_align = Alignment.fromLog2Units(@ctz(byte_offset | parent_ptr_ty.ptrAlignment(pt).toByteUnits().?)); | |
| 3639 | const new_align = Alignment.fromLog2Units(@ctz(byte_offset | parent_ptr_ty.ptrAlignment(zcu).toByteUnits().?)); | |
| 3429 | 3640 | return .{ .byte_ptr = .{ |
| 3430 | 3641 | .offset = byte_offset, |
| 3431 | 3642 | .alignment = new_align, |
| ... | ... | @@ -3768,14 +3979,14 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type { |
| 3768 | 3979 | alignment: Alignment = .none, |
| 3769 | 3980 | vector_index: VI = .none, |
| 3770 | 3981 | } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .One) blk: { |
| 3771 | const elem_bits = elem_ty.bitSize(pt); | |
| 3982 | const elem_bits = elem_ty.bitSize(zcu); | |
| 3772 | 3983 | if (elem_bits == 0) break :blk .{}; |
| 3773 | 3984 | const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits); |
| 3774 | 3985 | if (!is_packed) break :blk .{}; |
| 3775 | 3986 | |
| 3776 | 3987 | break :blk .{ |
| 3777 | 3988 | .host_size = @intCast(parent_ty.arrayLen(zcu)), |
| 3778 | .alignment = parent_ty.abiAlignment(pt), | |
| 3989 | .alignment = parent_ty.abiAlignment(zcu), | |
| 3779 | 3990 | .vector_index = if (offset) |some| @enumFromInt(some) else .runtime, |
| 3780 | 3991 | }; |
| 3781 | 3992 | } else .{}; |
| ... | ... | @@ -3789,7 +4000,7 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type { |
| 3789 | 4000 | } |
| 3790 | 4001 | // If the addend is not a comptime-known value we can still count on |
| 3791 | 4002 | // it being a multiple of the type size. |
| 3792 | const elem_size = (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar; | |
| 4003 | const elem_size = (try elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar; | |
| 3793 | 4004 | const addend = if (offset) |off| elem_size * off else elem_size; |
| 3794 | 4005 | |
| 3795 | 4006 | // The resulting pointer is aligned to the lcd between the offset (an |
src/Value.zig+759-689| ... | ... | @@ -65,19 +65,19 @@ pub fn fmtValueSemaFull(ctx: print_value.FormatContext) std.fmt.Formatter(print_ |
| 65 | 65 | /// Converts `val` to a null-terminated string stored in the InternPool. |
| 66 | 66 | /// Asserts `val` is an array of `u8` |
| 67 | 67 | pub fn toIpString(val: Value, ty: Type, pt: Zcu.PerThread) !InternPool.NullTerminatedString { |
| 68 | const mod = pt.zcu; | |
| 69 | assert(ty.zigTypeTag(mod) == .Array); | |
| 70 | assert(ty.childType(mod).toIntern() == .u8_type); | |
| 71 | const ip = &mod.intern_pool; | |
| 72 | switch (mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage) { | |
| 73 | .bytes => |bytes| return bytes.toNullTerminatedString(ty.arrayLen(mod), ip), | |
| 74 | .elems => return arrayToIpString(val, ty.arrayLen(mod), pt), | |
| 68 | const zcu = pt.zcu; | |
| 69 | assert(ty.zigTypeTag(zcu) == .Array); | |
| 70 | assert(ty.childType(zcu).toIntern() == .u8_type); | |
| 71 | const ip = &zcu.intern_pool; | |
| 72 | switch (zcu.intern_pool.indexToKey(val.toIntern()).aggregate.storage) { | |
| 73 | .bytes => |bytes| return bytes.toNullTerminatedString(ty.arrayLen(zcu), ip), | |
| 74 | .elems => return arrayToIpString(val, ty.arrayLen(zcu), pt), | |
| 75 | 75 | .repeated_elem => |elem| { |
| 76 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt)); | |
| 77 | const len: u32 = @intCast(ty.arrayLen(mod)); | |
| 78 | const strings = ip.getLocal(pt.tid).getMutableStrings(mod.gpa); | |
| 76 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(zcu)); | |
| 77 | const len: u32 = @intCast(ty.arrayLen(zcu)); | |
| 78 | const strings = ip.getLocal(pt.tid).getMutableStrings(zcu.gpa); | |
| 79 | 79 | try strings.appendNTimes(.{byte}, len); |
| 80 | return ip.getOrPutTrailingString(mod.gpa, pt.tid, len, .no_embedded_nulls); | |
| 80 | return ip.getOrPutTrailingString(zcu.gpa, pt.tid, len, .no_embedded_nulls); | |
| 81 | 81 | }, |
| 82 | 82 | } |
| 83 | 83 | } |
| ... | ... | @@ -85,17 +85,17 @@ pub fn toIpString(val: Value, ty: Type, pt: Zcu.PerThread) !InternPool.NullTermi |
| 85 | 85 | /// Asserts that the value is representable as an array of bytes. |
| 86 | 86 | /// Copies the value into a freshly allocated slice of memory, which is owned by the caller. |
| 87 | 87 | pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) ![]u8 { |
| 88 | const mod = pt.zcu; | |
| 89 | const ip = &mod.intern_pool; | |
| 88 | const zcu = pt.zcu; | |
| 89 | const ip = &zcu.intern_pool; | |
| 90 | 90 | return switch (ip.indexToKey(val.toIntern())) { |
| 91 | 91 | .enum_literal => |enum_literal| allocator.dupe(u8, enum_literal.toSlice(ip)), |
| 92 | .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(pt), allocator, pt), | |
| 92 | .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(zcu), allocator, pt), | |
| 93 | 93 | .aggregate => |aggregate| switch (aggregate.storage) { |
| 94 | .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(mod), ip)), | |
| 95 | .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, pt), | |
| 94 | .bytes => |bytes| try allocator.dupe(u8, bytes.toSlice(ty.arrayLenIncludingSentinel(zcu), ip)), | |
| 95 | .elems => try arrayToAllocatedBytes(val, ty.arrayLen(zcu), allocator, pt), | |
| 96 | 96 | .repeated_elem => |elem| { |
| 97 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(pt)); | |
| 98 | const result = try allocator.alloc(u8, @intCast(ty.arrayLen(mod))); | |
| 97 | const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(zcu)); | |
| 98 | const result = try allocator.alloc(u8, @intCast(ty.arrayLen(zcu))); | |
| 99 | 99 | @memset(result, byte); |
| 100 | 100 | return result; |
| 101 | 101 | }, |
| ... | ... | @@ -108,15 +108,15 @@ fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, pt: Zcu.Per |
| 108 | 108 | const result = try allocator.alloc(u8, @intCast(len)); |
| 109 | 109 | for (result, 0..) |*elem, i| { |
| 110 | 110 | const elem_val = try val.elemValue(pt, i); |
| 111 | elem.* = @intCast(elem_val.toUnsignedInt(pt)); | |
| 111 | elem.* = @intCast(elem_val.toUnsignedInt(pt.zcu)); | |
| 112 | 112 | } |
| 113 | 113 | return result; |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.NullTerminatedString { |
| 117 | const mod = pt.zcu; | |
| 118 | const gpa = mod.gpa; | |
| 119 | const ip = &mod.intern_pool; | |
| 117 | const zcu = pt.zcu; | |
| 118 | const gpa = zcu.gpa; | |
| 119 | const ip = &zcu.intern_pool; | |
| 120 | 120 | const len: u32 = @intCast(len_u64); |
| 121 | 121 | const strings = ip.getLocal(pt.tid).getMutableStrings(gpa); |
| 122 | 122 | try strings.ensureUnusedCapacity(len); |
| ... | ... | @@ -126,7 +126,7 @@ fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.Null |
| 126 | 126 | const prev_len = strings.mutate.len; |
| 127 | 127 | const elem_val = try val.elemValue(pt, i); |
| 128 | 128 | assert(strings.mutate.len == prev_len); |
| 129 | const byte: u8 = @intCast(elem_val.toUnsignedInt(pt)); | |
| 129 | const byte: u8 = @intCast(elem_val.toUnsignedInt(zcu)); | |
| 130 | 130 | strings.appendAssumeCapacity(.{byte}); |
| 131 | 131 | } |
| 132 | 132 | return ip.getOrPutTrailingString(gpa, pt.tid, len, .no_embedded_nulls); |
| ... | ... | @@ -178,50 +178,55 @@ pub fn intFromEnum(val: Value, ty: Type, pt: Zcu.PerThread) Allocator.Error!Valu |
| 178 | 178 | pub const ResolveStrat = Type.ResolveStrat; |
| 179 | 179 | |
| 180 | 180 | /// Asserts the value is an integer. |
| 181 | pub fn toBigInt(val: Value, space: *BigIntSpace, pt: Zcu.PerThread) BigIntConst { | |
| 182 | return val.toBigIntAdvanced(space, pt, .normal) catch unreachable; | |
| 181 | pub fn toBigInt(val: Value, space: *BigIntSpace, zcu: *Zcu) BigIntConst { | |
| 182 | return val.toBigIntAdvanced(space, .normal, zcu, {}) catch unreachable; | |
| 183 | } | |
| 184 | ||
| 185 | pub fn toBigIntSema(val: Value, space: *BigIntSpace, pt: Zcu.PerThread) !BigIntConst { | |
| 186 | return try val.toBigIntAdvanced(space, .sema, pt.zcu, pt.tid); | |
| 183 | 187 | } |
| 184 | 188 | |
| 185 | 189 | /// Asserts the value is an integer. |
| 186 | 190 | pub fn toBigIntAdvanced( |
| 187 | 191 | val: Value, |
| 188 | 192 | space: *BigIntSpace, |
| 189 | pt: Zcu.PerThread, | |
| 190 | 193 | comptime strat: ResolveStrat, |
| 194 | zcu: *Zcu, | |
| 195 | tid: strat.Tid(), | |
| 191 | 196 | ) Module.CompileError!BigIntConst { |
| 192 | 197 | return switch (val.toIntern()) { |
| 193 | 198 | .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(), |
| 194 | 199 | .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(), |
| 195 | 200 | .null_value => BigIntMutable.init(&space.limbs, 0).toConst(), |
| 196 | else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 201 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 197 | 202 | .int => |int| switch (int.storage) { |
| 198 | 203 | .u64, .i64, .big_int => int.storage.toBigInt(space), |
| 199 | 204 | .lazy_align, .lazy_size => |ty| { |
| 200 | if (strat == .sema) try Type.fromInterned(ty).resolveLayout(pt); | |
| 205 | if (strat == .sema) try Type.fromInterned(ty).resolveLayout(strat.pt(zcu, tid)); | |
| 201 | 206 | const x = switch (int.storage) { |
| 202 | 207 | else => unreachable, |
| 203 | .lazy_align => Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0, | |
| 204 | .lazy_size => Type.fromInterned(ty).abiSize(pt), | |
| 208 | .lazy_align => Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0, | |
| 209 | .lazy_size => Type.fromInterned(ty).abiSize(zcu), | |
| 205 | 210 | }; |
| 206 | 211 | return BigIntMutable.init(&space.limbs, x).toConst(); |
| 207 | 212 | }, |
| 208 | 213 | }, |
| 209 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, pt, strat), | |
| 214 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, strat, zcu, tid), | |
| 210 | 215 | .opt, .ptr => BigIntMutable.init( |
| 211 | 216 | &space.limbs, |
| 212 | (try val.getUnsignedIntAdvanced(pt, strat)).?, | |
| 217 | (try val.getUnsignedIntInner(strat, zcu, tid)).?, | |
| 213 | 218 | ).toConst(), |
| 214 | 219 | else => unreachable, |
| 215 | 220 | }, |
| 216 | 221 | }; |
| 217 | 222 | } |
| 218 | 223 | |
| 219 | pub fn isFuncBody(val: Value, mod: *Module) bool { | |
| 220 | return mod.intern_pool.isFuncBody(val.toIntern()); | |
| 224 | pub fn isFuncBody(val: Value, zcu: *Module) bool { | |
| 225 | return zcu.intern_pool.isFuncBody(val.toIntern()); | |
| 221 | 226 | } |
| 222 | 227 | |
| 223 | pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func { | |
| 224 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 228 | pub fn getFunction(val: Value, zcu: *Module) ?InternPool.Key.Func { | |
| 229 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 225 | 230 | .func => |x| x, |
| 226 | 231 | else => null, |
| 227 | 232 | }; |
| ... | ... | @@ -236,68 +241,79 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { |
| 236 | 241 | |
| 237 | 242 | /// If the value fits in a u64, return it, otherwise null. |
| 238 | 243 | /// Asserts not undefined. |
| 239 | pub fn getUnsignedInt(val: Value, pt: Zcu.PerThread) ?u64 { | |
| 240 | return getUnsignedIntAdvanced(val, pt, .normal) catch unreachable; | |
| 244 | pub fn getUnsignedInt(val: Value, zcu: *Zcu) ?u64 { | |
| 245 | return getUnsignedIntInner(val, .normal, zcu, {}) catch unreachable; | |
| 246 | } | |
| 247 | ||
| 248 | /// Asserts the value is an integer and it fits in a u64 | |
| 249 | pub fn toUnsignedInt(val: Value, zcu: *Zcu) u64 { | |
| 250 | return getUnsignedInt(val, zcu).?; | |
| 251 | } | |
| 252 | ||
| 253 | pub fn getUnsignedIntSema(val: Value, pt: Zcu.PerThread) !?u64 { | |
| 254 | return try val.getUnsignedIntInner(.sema, pt.zcu, pt.tid); | |
| 241 | 255 | } |
| 242 | 256 | |
| 243 | 257 | /// If the value fits in a u64, return it, otherwise null. |
| 244 | 258 | /// Asserts not undefined. |
| 245 | pub fn getUnsignedIntAdvanced(val: Value, pt: Zcu.PerThread, comptime strat: ResolveStrat) !?u64 { | |
| 246 | const mod = pt.zcu; | |
| 259 | pub fn getUnsignedIntInner( | |
| 260 | val: Value, | |
| 261 | comptime strat: ResolveStrat, | |
| 262 | zcu: *Zcu, | |
| 263 | tid: strat.Tid(), | |
| 264 | ) !?u64 { | |
| 247 | 265 | return switch (val.toIntern()) { |
| 248 | 266 | .undef => unreachable, |
| 249 | 267 | .bool_false => 0, |
| 250 | 268 | .bool_true => 1, |
| 251 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 269 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 252 | 270 | .undef => unreachable, |
| 253 | 271 | .int => |int| switch (int.storage) { |
| 254 | 272 | .big_int => |big_int| big_int.to(u64) catch null, |
| 255 | 273 | .u64 => |x| x, |
| 256 | 274 | .i64 => |x| std.math.cast(u64, x), |
| 257 | .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, strat.toLazy())).scalar.toByteUnits() orelse 0, | |
| 258 | .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar, | |
| 275 | .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar.toByteUnits() orelse 0, | |
| 276 | .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeInner(strat.toLazy(), zcu, tid)).scalar, | |
| 259 | 277 | }, |
| 260 | 278 | .ptr => |ptr| switch (ptr.base_addr) { |
| 261 | 279 | .int => ptr.byte_offset, |
| 262 | 280 | .field => |field| { |
| 263 | const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(pt, strat)) orelse return null; | |
| 264 | const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod); | |
| 265 | if (strat == .sema) try struct_ty.resolveLayout(pt); | |
| 266 | return base_addr + struct_ty.structFieldOffset(@intCast(field.index), pt) + ptr.byte_offset; | |
| 281 | const base_addr = (try Value.fromInterned(field.base).getUnsignedIntInner(strat, zcu, tid)) orelse return null; | |
| 282 | const struct_ty = Value.fromInterned(field.base).typeOf(zcu).childType(zcu); | |
| 283 | if (strat == .sema) { | |
| 284 | const pt = strat.pt(zcu, tid); | |
| 285 | try struct_ty.resolveLayout(pt); | |
| 286 | } | |
| 287 | return base_addr + struct_ty.structFieldOffset(@intCast(field.index), zcu) + ptr.byte_offset; | |
| 267 | 288 | }, |
| 268 | 289 | else => null, |
| 269 | 290 | }, |
| 270 | 291 | .opt => |opt| switch (opt.val) { |
| 271 | 292 | .none => 0, |
| 272 | else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(pt, strat), | |
| 293 | else => |payload| Value.fromInterned(payload).getUnsignedIntInner(strat, zcu, tid), | |
| 273 | 294 | }, |
| 274 | 295 | else => null, |
| 275 | 296 | }, |
| 276 | 297 | }; |
| 277 | 298 | } |
| 278 | 299 | |
| 279 | /// Asserts the value is an integer and it fits in a u64 | |
| 280 | pub fn toUnsignedInt(val: Value, pt: Zcu.PerThread) u64 { | |
| 281 | return getUnsignedInt(val, pt).?; | |
| 282 | } | |
| 283 | ||
| 284 | 300 | /// Asserts the value is an integer and it fits in a u64 |
| 285 | 301 | pub fn toUnsignedIntSema(val: Value, pt: Zcu.PerThread) !u64 { |
| 286 | return (try getUnsignedIntAdvanced(val, pt, .sema)).?; | |
| 302 | return (try getUnsignedIntInner(val, .sema, pt.zcu, pt.tid)).?; | |
| 287 | 303 | } |
| 288 | 304 | |
| 289 | 305 | /// Asserts the value is an integer and it fits in a i64 |
| 290 | pub fn toSignedInt(val: Value, pt: Zcu.PerThread) i64 { | |
| 306 | pub fn toSignedInt(val: Value, zcu: *Zcu) i64 { | |
| 291 | 307 | return switch (val.toIntern()) { |
| 292 | 308 | .bool_false => 0, |
| 293 | 309 | .bool_true => 1, |
| 294 | else => switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 310 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 295 | 311 | .int => |int| switch (int.storage) { |
| 296 | 312 | .big_int => |big_int| big_int.to(i64) catch unreachable, |
| 297 | 313 | .i64 => |x| x, |
| 298 | 314 | .u64 => |x| @intCast(x), |
| 299 | .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0), | |
| 300 | .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(pt)), | |
| 315 | .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0), | |
| 316 | .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(zcu)), | |
| 301 | 317 | }, |
| 302 | 318 | else => unreachable, |
| 303 | 319 | }, |
| ... | ... | @@ -326,41 +342,41 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro |
| 326 | 342 | Unimplemented, |
| 327 | 343 | OutOfMemory, |
| 328 | 344 | }!void { |
| 329 | const mod = pt.zcu; | |
| 330 | const target = mod.getTarget(); | |
| 345 | const zcu = pt.zcu; | |
| 346 | const target = zcu.getTarget(); | |
| 331 | 347 | const endian = target.cpu.arch.endian(); |
| 332 | if (val.isUndef(mod)) { | |
| 333 | const size: usize = @intCast(ty.abiSize(pt)); | |
| 348 | if (val.isUndef(zcu)) { | |
| 349 | const size: usize = @intCast(ty.abiSize(zcu)); | |
| 334 | 350 | @memset(buffer[0..size], 0xaa); |
| 335 | 351 | return; |
| 336 | 352 | } |
| 337 | const ip = &mod.intern_pool; | |
| 338 | switch (ty.zigTypeTag(mod)) { | |
| 353 | const ip = &zcu.intern_pool; | |
| 354 | switch (ty.zigTypeTag(zcu)) { | |
| 339 | 355 | .Void => {}, |
| 340 | 356 | .Bool => { |
| 341 | 357 | buffer[0] = @intFromBool(val.toBool()); |
| 342 | 358 | }, |
| 343 | 359 | .Int, .Enum => { |
| 344 | const int_info = ty.intInfo(mod); | |
| 360 | const int_info = ty.intInfo(zcu); | |
| 345 | 361 | const bits = int_info.bits; |
| 346 | 362 | const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8); |
| 347 | 363 | |
| 348 | 364 | var bigint_buffer: BigIntSpace = undefined; |
| 349 | const bigint = val.toBigInt(&bigint_buffer, pt); | |
| 365 | const bigint = val.toBigInt(&bigint_buffer, zcu); | |
| 350 | 366 | bigint.writeTwosComplement(buffer[0..byte_count], endian); |
| 351 | 367 | }, |
| 352 | 368 | .Float => switch (ty.floatBits(target)) { |
| 353 | 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, pt)), endian), | |
| 354 | 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(val.toFloat(f32, pt)), endian), | |
| 355 | 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(val.toFloat(f64, pt)), endian), | |
| 356 | 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(val.toFloat(f80, pt)), endian), | |
| 357 | 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, pt)), endian), | |
| 369 | 16 => std.mem.writeInt(u16, buffer[0..2], @bitCast(val.toFloat(f16, zcu)), endian), | |
| 370 | 32 => std.mem.writeInt(u32, buffer[0..4], @bitCast(val.toFloat(f32, zcu)), endian), | |
| 371 | 64 => std.mem.writeInt(u64, buffer[0..8], @bitCast(val.toFloat(f64, zcu)), endian), | |
| 372 | 80 => std.mem.writeInt(u80, buffer[0..10], @bitCast(val.toFloat(f80, zcu)), endian), | |
| 373 | 128 => std.mem.writeInt(u128, buffer[0..16], @bitCast(val.toFloat(f128, zcu)), endian), | |
| 358 | 374 | else => unreachable, |
| 359 | 375 | }, |
| 360 | 376 | .Array => { |
| 361 | const len = ty.arrayLen(mod); | |
| 362 | const elem_ty = ty.childType(mod); | |
| 363 | const elem_size: usize = @intCast(elem_ty.abiSize(pt)); | |
| 377 | const len = ty.arrayLen(zcu); | |
| 378 | const elem_ty = ty.childType(zcu); | |
| 379 | const elem_size: usize = @intCast(elem_ty.abiSize(zcu)); | |
| 364 | 380 | var elem_i: usize = 0; |
| 365 | 381 | var buf_off: usize = 0; |
| 366 | 382 | while (elem_i < len) : (elem_i += 1) { |
| ... | ... | @@ -372,15 +388,15 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro |
| 372 | 388 | .Vector => { |
| 373 | 389 | // We use byte_count instead of abi_size here, so that any padding bytes |
| 374 | 390 | // follow the data bytes, on both big- and little-endian systems. |
| 375 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; | |
| 391 | const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8; | |
| 376 | 392 | return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0); |
| 377 | 393 | }, |
| 378 | 394 | .Struct => { |
| 379 | const struct_type = mod.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout; | |
| 395 | const struct_type = zcu.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout; | |
| 380 | 396 | switch (struct_type.layout) { |
| 381 | 397 | .auto => return error.IllDefinedMemoryLayout, |
| 382 | 398 | .@"extern" => for (0..struct_type.field_types.len) |field_index| { |
| 383 | const off: usize = @intCast(ty.structFieldOffset(field_index, pt)); | |
| 399 | const off: usize = @intCast(ty.structFieldOffset(field_index, zcu)); | |
| 384 | 400 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 385 | 401 | .bytes => |bytes| { |
| 386 | 402 | buffer[off] = bytes.at(field_index, ip); |
| ... | ... | @@ -393,13 +409,13 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro |
| 393 | 409 | try writeToMemory(field_val, field_ty, pt, buffer[off..]); |
| 394 | 410 | }, |
| 395 | 411 | .@"packed" => { |
| 396 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; | |
| 412 | const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8; | |
| 397 | 413 | return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0); |
| 398 | 414 | }, |
| 399 | 415 | } |
| 400 | 416 | }, |
| 401 | 417 | .ErrorSet => { |
| 402 | const bits = mod.errorSetBits(); | |
| 418 | const bits = zcu.errorSetBits(); | |
| 403 | 419 | const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8); |
| 404 | 420 | |
| 405 | 421 | const name = switch (ip.indexToKey(val.toIntern())) { |
| ... | ... | @@ -414,37 +430,37 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro |
| 414 | 430 | ).toConst(); |
| 415 | 431 | bigint.writeTwosComplement(buffer[0..byte_count], endian); |
| 416 | 432 | }, |
| 417 | .Union => switch (ty.containerLayout(mod)) { | |
| 433 | .Union => switch (ty.containerLayout(zcu)) { | |
| 418 | 434 | .auto => return error.IllDefinedMemoryLayout, // Sema is supposed to have emitted a compile error already |
| 419 | 435 | .@"extern" => { |
| 420 | if (val.unionTag(mod)) |union_tag| { | |
| 421 | const union_obj = mod.typeToUnion(ty).?; | |
| 422 | const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?; | |
| 436 | if (val.unionTag(zcu)) |union_tag| { | |
| 437 | const union_obj = zcu.typeToUnion(ty).?; | |
| 438 | const field_index = zcu.unionTagFieldIndex(union_obj, union_tag).?; | |
| 423 | 439 | const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 424 | 440 | const field_val = try val.fieldValue(pt, field_index); |
| 425 | const byte_count: usize = @intCast(field_type.abiSize(pt)); | |
| 441 | const byte_count: usize = @intCast(field_type.abiSize(zcu)); | |
| 426 | 442 | return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]); |
| 427 | 443 | } else { |
| 428 | 444 | const backing_ty = try ty.unionBackingType(pt); |
| 429 | const byte_count: usize = @intCast(backing_ty.abiSize(pt)); | |
| 430 | return writeToMemory(val.unionValue(mod), backing_ty, pt, buffer[0..byte_count]); | |
| 445 | const byte_count: usize = @intCast(backing_ty.abiSize(zcu)); | |
| 446 | return writeToMemory(val.unionValue(zcu), backing_ty, pt, buffer[0..byte_count]); | |
| 431 | 447 | } |
| 432 | 448 | }, |
| 433 | 449 | .@"packed" => { |
| 434 | 450 | const backing_ty = try ty.unionBackingType(pt); |
| 435 | const byte_count: usize = @intCast(backing_ty.abiSize(pt)); | |
| 451 | const byte_count: usize = @intCast(backing_ty.abiSize(zcu)); | |
| 436 | 452 | return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0); |
| 437 | 453 | }, |
| 438 | 454 | }, |
| 439 | 455 | .Pointer => { |
| 440 | if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout; | |
| 441 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; | |
| 456 | if (ty.isSlice(zcu)) return error.IllDefinedMemoryLayout; | |
| 457 | if (!val.ptrHasIntAddr(zcu)) return error.ReinterpretDeclRef; | |
| 442 | 458 | return val.writeToMemory(Type.usize, pt, buffer); |
| 443 | 459 | }, |
| 444 | 460 | .Optional => { |
| 445 | if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout; | |
| 446 | const child = ty.optionalChild(mod); | |
| 447 | const opt_val = val.optionalValue(mod); | |
| 461 | if (!ty.isPtrLikeOptional(zcu)) return error.IllDefinedMemoryLayout; | |
| 462 | const child = ty.optionalChild(zcu); | |
| 463 | const opt_val = val.optionalValue(zcu); | |
| 448 | 464 | if (opt_val) |some| { |
| 449 | 465 | return some.writeToMemory(child, pt, buffer); |
| 450 | 466 | } else { |
| ... | ... | @@ -466,18 +482,18 @@ pub fn writeToPackedMemory( |
| 466 | 482 | buffer: []u8, |
| 467 | 483 | bit_offset: usize, |
| 468 | 484 | ) error{ ReinterpretDeclRef, OutOfMemory }!void { |
| 469 | const mod = pt.zcu; | |
| 470 | const ip = &mod.intern_pool; | |
| 471 | const target = mod.getTarget(); | |
| 485 | const zcu = pt.zcu; | |
| 486 | const ip = &zcu.intern_pool; | |
| 487 | const target = zcu.getTarget(); | |
| 472 | 488 | const endian = target.cpu.arch.endian(); |
| 473 | if (val.isUndef(mod)) { | |
| 474 | const bit_size: usize = @intCast(ty.bitSize(pt)); | |
| 489 | if (val.isUndef(zcu)) { | |
| 490 | const bit_size: usize = @intCast(ty.bitSize(zcu)); | |
| 475 | 491 | if (bit_size != 0) { |
| 476 | 492 | std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian); |
| 477 | 493 | } |
| 478 | 494 | return; |
| 479 | 495 | } |
| 480 | switch (ty.zigTypeTag(mod)) { | |
| 496 | switch (ty.zigTypeTag(zcu)) { | |
| 481 | 497 | .Void => {}, |
| 482 | 498 | .Bool => { |
| 483 | 499 | const byte_index = switch (endian) { |
| ... | ... | @@ -492,34 +508,34 @@ pub fn writeToPackedMemory( |
| 492 | 508 | }, |
| 493 | 509 | .Int, .Enum => { |
| 494 | 510 | if (buffer.len == 0) return; |
| 495 | const bits = ty.intInfo(mod).bits; | |
| 511 | const bits = ty.intInfo(zcu).bits; | |
| 496 | 512 | if (bits == 0) return; |
| 497 | 513 | |
| 498 | 514 | switch (ip.indexToKey((try val.intFromEnum(ty, pt)).toIntern()).int.storage) { |
| 499 | 515 | inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian), |
| 500 | 516 | .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian), |
| 501 | 517 | .lazy_align => |lazy_align| { |
| 502 | const num = Type.fromInterned(lazy_align).abiAlignment(pt).toByteUnits() orelse 0; | |
| 518 | const num = Type.fromInterned(lazy_align).abiAlignment(zcu).toByteUnits() orelse 0; | |
| 503 | 519 | std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian); |
| 504 | 520 | }, |
| 505 | 521 | .lazy_size => |lazy_size| { |
| 506 | const num = Type.fromInterned(lazy_size).abiSize(pt); | |
| 522 | const num = Type.fromInterned(lazy_size).abiSize(zcu); | |
| 507 | 523 | std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian); |
| 508 | 524 | }, |
| 509 | 525 | } |
| 510 | 526 | }, |
| 511 | 527 | .Float => switch (ty.floatBits(target)) { |
| 512 | 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, pt)), endian), | |
| 513 | 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(val.toFloat(f32, pt)), endian), | |
| 514 | 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(val.toFloat(f64, pt)), endian), | |
| 515 | 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(val.toFloat(f80, pt)), endian), | |
| 516 | 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, pt)), endian), | |
| 528 | 16 => std.mem.writePackedInt(u16, buffer, bit_offset, @bitCast(val.toFloat(f16, zcu)), endian), | |
| 529 | 32 => std.mem.writePackedInt(u32, buffer, bit_offset, @bitCast(val.toFloat(f32, zcu)), endian), | |
| 530 | 64 => std.mem.writePackedInt(u64, buffer, bit_offset, @bitCast(val.toFloat(f64, zcu)), endian), | |
| 531 | 80 => std.mem.writePackedInt(u80, buffer, bit_offset, @bitCast(val.toFloat(f80, zcu)), endian), | |
| 532 | 128 => std.mem.writePackedInt(u128, buffer, bit_offset, @bitCast(val.toFloat(f128, zcu)), endian), | |
| 517 | 533 | else => unreachable, |
| 518 | 534 | }, |
| 519 | 535 | .Vector => { |
| 520 | const elem_ty = ty.childType(mod); | |
| 521 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt)); | |
| 522 | const len: usize = @intCast(ty.arrayLen(mod)); | |
| 536 | const elem_ty = ty.childType(zcu); | |
| 537 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(zcu)); | |
| 538 | const len: usize = @intCast(ty.arrayLen(zcu)); | |
| 523 | 539 | |
| 524 | 540 | var bits: u16 = 0; |
| 525 | 541 | var elem_i: usize = 0; |
| ... | ... | @@ -544,37 +560,37 @@ pub fn writeToPackedMemory( |
| 544 | 560 | .repeated_elem => |elem| elem, |
| 545 | 561 | }); |
| 546 | 562 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 547 | const field_bits: u16 = @intCast(field_ty.bitSize(pt)); | |
| 563 | const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); | |
| 548 | 564 | try field_val.writeToPackedMemory(field_ty, pt, buffer, bit_offset + bits); |
| 549 | 565 | bits += field_bits; |
| 550 | 566 | } |
| 551 | 567 | }, |
| 552 | 568 | .Union => { |
| 553 | const union_obj = mod.typeToUnion(ty).?; | |
| 569 | const union_obj = zcu.typeToUnion(ty).?; | |
| 554 | 570 | switch (union_obj.flagsUnordered(ip).layout) { |
| 555 | 571 | .auto, .@"extern" => unreachable, // Handled in non-packed writeToMemory |
| 556 | 572 | .@"packed" => { |
| 557 | if (val.unionTag(mod)) |union_tag| { | |
| 558 | const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?; | |
| 573 | if (val.unionTag(zcu)) |union_tag| { | |
| 574 | const field_index = zcu.unionTagFieldIndex(union_obj, union_tag).?; | |
| 559 | 575 | const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 560 | 576 | const field_val = try val.fieldValue(pt, field_index); |
| 561 | 577 | return field_val.writeToPackedMemory(field_type, pt, buffer, bit_offset); |
| 562 | 578 | } else { |
| 563 | 579 | const backing_ty = try ty.unionBackingType(pt); |
| 564 | return val.unionValue(mod).writeToPackedMemory(backing_ty, pt, buffer, bit_offset); | |
| 580 | return val.unionValue(zcu).writeToPackedMemory(backing_ty, pt, buffer, bit_offset); | |
| 565 | 581 | } |
| 566 | 582 | }, |
| 567 | 583 | } |
| 568 | 584 | }, |
| 569 | 585 | .Pointer => { |
| 570 | assert(!ty.isSlice(mod)); // No well defined layout. | |
| 571 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; | |
| 586 | assert(!ty.isSlice(zcu)); // No well defined layout. | |
| 587 | if (!val.ptrHasIntAddr(zcu)) return error.ReinterpretDeclRef; | |
| 572 | 588 | return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset); |
| 573 | 589 | }, |
| 574 | 590 | .Optional => { |
| 575 | assert(ty.isPtrLikeOptional(mod)); | |
| 576 | const child = ty.optionalChild(mod); | |
| 577 | const opt_val = val.optionalValue(mod); | |
| 591 | assert(ty.isPtrLikeOptional(zcu)); | |
| 592 | const child = ty.optionalChild(zcu); | |
| 593 | const opt_val = val.optionalValue(zcu); | |
| 578 | 594 | if (opt_val) |some| { |
| 579 | 595 | return some.writeToPackedMemory(child, pt, buffer, bit_offset); |
| 580 | 596 | } else { |
| ... | ... | @@ -599,11 +615,11 @@ pub fn readFromMemory( |
| 599 | 615 | Unimplemented, |
| 600 | 616 | OutOfMemory, |
| 601 | 617 | }!Value { |
| 602 | const mod = pt.zcu; | |
| 603 | const ip = &mod.intern_pool; | |
| 604 | const target = mod.getTarget(); | |
| 618 | const zcu = pt.zcu; | |
| 619 | const ip = &zcu.intern_pool; | |
| 620 | const target = zcu.getTarget(); | |
| 605 | 621 | const endian = target.cpu.arch.endian(); |
| 606 | switch (ty.zigTypeTag(mod)) { | |
| 622 | switch (ty.zigTypeTag(zcu)) { | |
| 607 | 623 | .Void => return Value.void, |
| 608 | 624 | .Bool => { |
| 609 | 625 | if (buffer[0] == 0) { |
| ... | ... | @@ -615,24 +631,24 @@ pub fn readFromMemory( |
| 615 | 631 | .Int, .Enum => |ty_tag| { |
| 616 | 632 | const int_ty = switch (ty_tag) { |
| 617 | 633 | .Int => ty, |
| 618 | .Enum => ty.intTagType(mod), | |
| 634 | .Enum => ty.intTagType(zcu), | |
| 619 | 635 | else => unreachable, |
| 620 | 636 | }; |
| 621 | const int_info = int_ty.intInfo(mod); | |
| 637 | const int_info = int_ty.intInfo(zcu); | |
| 622 | 638 | const bits = int_info.bits; |
| 623 | 639 | const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8); |
| 624 | if (bits == 0 or buffer.len == 0) return mod.getCoerced(try mod.intValue(int_ty, 0), ty); | |
| 640 | if (bits == 0 or buffer.len == 0) return zcu.getCoerced(try zcu.intValue(int_ty, 0), ty); | |
| 625 | 641 | |
| 626 | 642 | if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 |
| 627 | 643 | .signed => { |
| 628 | 644 | const val = std.mem.readVarInt(i64, buffer[0..byte_count], endian); |
| 629 | 645 | const result = (val << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits)); |
| 630 | return mod.getCoerced(try mod.intValue(int_ty, result), ty); | |
| 646 | return zcu.getCoerced(try zcu.intValue(int_ty, result), ty); | |
| 631 | 647 | }, |
| 632 | 648 | .unsigned => { |
| 633 | 649 | const val = std.mem.readVarInt(u64, buffer[0..byte_count], endian); |
| 634 | 650 | const result = (val << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits)); |
| 635 | return mod.getCoerced(try mod.intValue(int_ty, result), ty); | |
| 651 | return zcu.getCoerced(try zcu.intValue(int_ty, result), ty); | |
| 636 | 652 | }, |
| 637 | 653 | } else { // Slow path, we have to construct a big-int |
| 638 | 654 | const Limb = std.math.big.Limb; |
| ... | ... | @@ -641,7 +657,7 @@ pub fn readFromMemory( |
| 641 | 657 | |
| 642 | 658 | var bigint = BigIntMutable.init(limbs_buffer, 0); |
| 643 | 659 | bigint.readTwosComplement(buffer[0..byte_count], bits, endian, int_info.signedness); |
| 644 | return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty); | |
| 660 | return zcu.getCoerced(try zcu.intValue_big(int_ty, bigint.toConst()), ty); | |
| 645 | 661 | } |
| 646 | 662 | }, |
| 647 | 663 | .Float => return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -656,12 +672,12 @@ pub fn readFromMemory( |
| 656 | 672 | }, |
| 657 | 673 | } })), |
| 658 | 674 | .Array => { |
| 659 | const elem_ty = ty.childType(mod); | |
| 660 | const elem_size = elem_ty.abiSize(pt); | |
| 661 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod))); | |
| 675 | const elem_ty = ty.childType(zcu); | |
| 676 | const elem_size = elem_ty.abiSize(zcu); | |
| 677 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(zcu))); | |
| 662 | 678 | var offset: usize = 0; |
| 663 | 679 | for (elems) |*elem| { |
| 664 | elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern(); | |
| 680 | elem.* = (try readFromMemory(elem_ty, zcu, buffer[offset..], arena)).toIntern(); | |
| 665 | 681 | offset += @intCast(elem_size); |
| 666 | 682 | } |
| 667 | 683 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| ... | ... | @@ -672,11 +688,11 @@ pub fn readFromMemory( |
| 672 | 688 | .Vector => { |
| 673 | 689 | // We use byte_count instead of abi_size here, so that any padding bytes |
| 674 | 690 | // follow the data bytes, on both big- and little-endian systems. |
| 675 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; | |
| 676 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); | |
| 691 | const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8; | |
| 692 | return readFromPackedMemory(ty, zcu, buffer[0..byte_count], 0, arena); | |
| 677 | 693 | }, |
| 678 | 694 | .Struct => { |
| 679 | const struct_type = mod.typeToStruct(ty).?; | |
| 695 | const struct_type = zcu.typeToStruct(ty).?; | |
| 680 | 696 | switch (struct_type.layout) { |
| 681 | 697 | .auto => unreachable, // Sema is supposed to have emitted a compile error already |
| 682 | 698 | .@"extern" => { |
| ... | ... | @@ -684,9 +700,9 @@ pub fn readFromMemory( |
| 684 | 700 | const field_vals = try arena.alloc(InternPool.Index, field_types.len); |
| 685 | 701 | for (field_vals, 0..) |*field_val, i| { |
| 686 | 702 | const field_ty = Type.fromInterned(field_types.get(ip)[i]); |
| 687 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); | |
| 688 | const sz: usize = @intCast(field_ty.abiSize(pt)); | |
| 689 | field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern(); | |
| 703 | const off: usize = @intCast(ty.structFieldOffset(i, zcu)); | |
| 704 | const sz: usize = @intCast(field_ty.abiSize(zcu)); | |
| 705 | field_val.* = (try readFromMemory(field_ty, zcu, buffer[off..(off + sz)], arena)).toIntern(); | |
| 690 | 706 | } |
| 691 | 707 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 692 | 708 | .ty = ty.toIntern(), |
| ... | ... | @@ -694,29 +710,29 @@ pub fn readFromMemory( |
| 694 | 710 | } })); |
| 695 | 711 | }, |
| 696 | 712 | .@"packed" => { |
| 697 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; | |
| 698 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); | |
| 713 | const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8; | |
| 714 | return readFromPackedMemory(ty, zcu, buffer[0..byte_count], 0, arena); | |
| 699 | 715 | }, |
| 700 | 716 | } |
| 701 | 717 | }, |
| 702 | 718 | .ErrorSet => { |
| 703 | const bits = mod.errorSetBits(); | |
| 719 | const bits = zcu.errorSetBits(); | |
| 704 | 720 | const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8); |
| 705 | 721 | const int = std.mem.readVarInt(u64, buffer[0..byte_count], endian); |
| 706 | 722 | const index = (int << @as(u6, @intCast(64 - bits))) >> @as(u6, @intCast(64 - bits)); |
| 707 | const name = mod.global_error_set.keys()[@intCast(index)]; | |
| 723 | const name = zcu.global_error_set.keys()[@intCast(index)]; | |
| 708 | 724 | |
| 709 | 725 | return Value.fromInterned(try pt.intern(.{ .err = .{ |
| 710 | 726 | .ty = ty.toIntern(), |
| 711 | 727 | .name = name, |
| 712 | 728 | } })); |
| 713 | 729 | }, |
| 714 | .Union => switch (ty.containerLayout(mod)) { | |
| 730 | .Union => switch (ty.containerLayout(zcu)) { | |
| 715 | 731 | .auto => return error.IllDefinedMemoryLayout, |
| 716 | 732 | .@"extern" => { |
| 717 | const union_size = ty.abiSize(pt); | |
| 718 | const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type }); | |
| 719 | const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern(); | |
| 733 | const union_size = ty.abiSize(zcu); | |
| 734 | const array_ty = try zcu.arrayType(.{ .len = union_size, .child = .u8_type }); | |
| 735 | const val = (try readFromMemory(array_ty, zcu, buffer, arena)).toIntern(); | |
| 720 | 736 | return Value.fromInterned(try pt.intern(.{ .un = .{ |
| 721 | 737 | .ty = ty.toIntern(), |
| 722 | 738 | .tag = .none, |
| ... | ... | @@ -724,23 +740,23 @@ pub fn readFromMemory( |
| 724 | 740 | } })); |
| 725 | 741 | }, |
| 726 | 742 | .@"packed" => { |
| 727 | const byte_count = (@as(usize, @intCast(ty.bitSize(pt))) + 7) / 8; | |
| 728 | return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena); | |
| 743 | const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8; | |
| 744 | return readFromPackedMemory(ty, zcu, buffer[0..byte_count], 0, arena); | |
| 729 | 745 | }, |
| 730 | 746 | }, |
| 731 | 747 | .Pointer => { |
| 732 | assert(!ty.isSlice(mod)); // No well defined layout. | |
| 733 | const int_val = try readFromMemory(Type.usize, mod, buffer, arena); | |
| 748 | assert(!ty.isSlice(zcu)); // No well defined layout. | |
| 749 | const int_val = try readFromMemory(Type.usize, zcu, buffer, arena); | |
| 734 | 750 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 735 | 751 | .ty = ty.toIntern(), |
| 736 | 752 | .base_addr = .int, |
| 737 | .byte_offset = int_val.toUnsignedInt(pt), | |
| 753 | .byte_offset = int_val.toUnsignedInt(zcu), | |
| 738 | 754 | } })); |
| 739 | 755 | }, |
| 740 | 756 | .Optional => { |
| 741 | assert(ty.isPtrLikeOptional(mod)); | |
| 742 | const child_ty = ty.optionalChild(mod); | |
| 743 | const child_val = try readFromMemory(child_ty, mod, buffer, arena); | |
| 757 | assert(ty.isPtrLikeOptional(zcu)); | |
| 758 | const child_ty = ty.optionalChild(zcu); | |
| 759 | const child_val = try readFromMemory(child_ty, zcu, buffer, arena); | |
| 744 | 760 | return Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 745 | 761 | .ty = ty.toIntern(), |
| 746 | 762 | .val = switch (child_val.orderAgainstZero(pt)) { |
| ... | ... | @@ -768,11 +784,11 @@ pub fn readFromPackedMemory( |
| 768 | 784 | IllDefinedMemoryLayout, |
| 769 | 785 | OutOfMemory, |
| 770 | 786 | }!Value { |
| 771 | const mod = pt.zcu; | |
| 772 | const ip = &mod.intern_pool; | |
| 773 | const target = mod.getTarget(); | |
| 787 | const zcu = pt.zcu; | |
| 788 | const ip = &zcu.intern_pool; | |
| 789 | const target = zcu.getTarget(); | |
| 774 | 790 | const endian = target.cpu.arch.endian(); |
| 775 | switch (ty.zigTypeTag(mod)) { | |
| 791 | switch (ty.zigTypeTag(zcu)) { | |
| 776 | 792 | .Void => return Value.void, |
| 777 | 793 | .Bool => { |
| 778 | 794 | const byte = switch (endian) { |
| ... | ... | @@ -787,7 +803,7 @@ pub fn readFromPackedMemory( |
| 787 | 803 | }, |
| 788 | 804 | .Int => { |
| 789 | 805 | if (buffer.len == 0) return pt.intValue(ty, 0); |
| 790 | const int_info = ty.intInfo(mod); | |
| 806 | const int_info = ty.intInfo(zcu); | |
| 791 | 807 | const bits = int_info.bits; |
| 792 | 808 | if (bits == 0) return pt.intValue(ty, 0); |
| 793 | 809 | |
| ... | ... | @@ -800,7 +816,7 @@ pub fn readFromPackedMemory( |
| 800 | 816 | }; |
| 801 | 817 | |
| 802 | 818 | // Slow path, we have to construct a big-int |
| 803 | const abi_size: usize = @intCast(ty.abiSize(pt)); | |
| 819 | const abi_size: usize = @intCast(ty.abiSize(zcu)); | |
| 804 | 820 | const Limb = std.math.big.Limb; |
| 805 | 821 | const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb); |
| 806 | 822 | const limbs_buffer = try arena.alloc(Limb, limb_count); |
| ... | ... | @@ -810,7 +826,7 @@ pub fn readFromPackedMemory( |
| 810 | 826 | return pt.intValue_big(ty, bigint.toConst()); |
| 811 | 827 | }, |
| 812 | 828 | .Enum => { |
| 813 | const int_ty = ty.intTagType(mod); | |
| 829 | const int_ty = ty.intTagType(zcu); | |
| 814 | 830 | const int_val = try Value.readFromPackedMemory(int_ty, pt, buffer, bit_offset, arena); |
| 815 | 831 | return pt.getCoerced(int_val, ty); |
| 816 | 832 | }, |
| ... | ... | @@ -826,11 +842,11 @@ pub fn readFromPackedMemory( |
| 826 | 842 | }, |
| 827 | 843 | } })), |
| 828 | 844 | .Vector => { |
| 829 | const elem_ty = ty.childType(mod); | |
| 830 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(mod))); | |
| 845 | const elem_ty = ty.childType(zcu); | |
| 846 | const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(zcu))); | |
| 831 | 847 | |
| 832 | 848 | var bits: u16 = 0; |
| 833 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(pt)); | |
| 849 | const elem_bit_size: u16 = @intCast(elem_ty.bitSize(zcu)); | |
| 834 | 850 | for (elems, 0..) |_, i| { |
| 835 | 851 | // On big-endian systems, LLVM reverses the element order of vectors by default |
| 836 | 852 | const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i; |
| ... | ... | @@ -845,12 +861,12 @@ pub fn readFromPackedMemory( |
| 845 | 861 | .Struct => { |
| 846 | 862 | // Sema is supposed to have emitted a compile error already for Auto layout structs, |
| 847 | 863 | // and Extern is handled by non-packed readFromMemory. |
| 848 | const struct_type = mod.typeToPackedStruct(ty).?; | |
| 864 | const struct_type = zcu.typeToPackedStruct(ty).?; | |
| 849 | 865 | var bits: u16 = 0; |
| 850 | 866 | const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len); |
| 851 | 867 | for (field_vals, 0..) |*field_val, i| { |
| 852 | 868 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 853 | const field_bits: u16 = @intCast(field_ty.bitSize(pt)); | |
| 869 | const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); | |
| 854 | 870 | field_val.* = (try readFromPackedMemory(field_ty, pt, buffer, bit_offset + bits, arena)).toIntern(); |
| 855 | 871 | bits += field_bits; |
| 856 | 872 | } |
| ... | ... | @@ -859,7 +875,7 @@ pub fn readFromPackedMemory( |
| 859 | 875 | .storage = .{ .elems = field_vals }, |
| 860 | 876 | } })); |
| 861 | 877 | }, |
| 862 | .Union => switch (ty.containerLayout(mod)) { | |
| 878 | .Union => switch (ty.containerLayout(zcu)) { | |
| 863 | 879 | .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory |
| 864 | 880 | .@"packed" => { |
| 865 | 881 | const backing_ty = try ty.unionBackingType(pt); |
| ... | ... | @@ -872,21 +888,21 @@ pub fn readFromPackedMemory( |
| 872 | 888 | }, |
| 873 | 889 | }, |
| 874 | 890 | .Pointer => { |
| 875 | assert(!ty.isSlice(mod)); // No well defined layout. | |
| 891 | assert(!ty.isSlice(zcu)); // No well defined layout. | |
| 876 | 892 | const int_val = try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, arena); |
| 877 | 893 | return Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 878 | 894 | .ty = ty.toIntern(), |
| 879 | 895 | .base_addr = .int, |
| 880 | .byte_offset = int_val.toUnsignedInt(pt), | |
| 896 | .byte_offset = int_val.toUnsignedInt(zcu), | |
| 881 | 897 | } })); |
| 882 | 898 | }, |
| 883 | 899 | .Optional => { |
| 884 | assert(ty.isPtrLikeOptional(mod)); | |
| 885 | const child_ty = ty.optionalChild(mod); | |
| 900 | assert(ty.isPtrLikeOptional(zcu)); | |
| 901 | const child_ty = ty.optionalChild(zcu); | |
| 886 | 902 | const child_val = try readFromPackedMemory(child_ty, pt, buffer, bit_offset, arena); |
| 887 | 903 | return Value.fromInterned(try pt.intern(.{ .opt = .{ |
| 888 | 904 | .ty = ty.toIntern(), |
| 889 | .val = switch (child_val.orderAgainstZero(pt)) { | |
| 905 | .val = switch (child_val.orderAgainstZero(zcu)) { | |
| 890 | 906 | .lt => unreachable, |
| 891 | 907 | .eq => .none, |
| 892 | 908 | .gt => child_val.toIntern(), |
| ... | ... | @@ -898,8 +914,8 @@ pub fn readFromPackedMemory( |
| 898 | 914 | } |
| 899 | 915 | |
| 900 | 916 | /// Asserts that the value is a float or an integer. |
| 901 | pub fn toFloat(val: Value, comptime T: type, pt: Zcu.PerThread) T { | |
| 902 | return switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 917 | pub fn toFloat(val: Value, comptime T: type, zcu: *Zcu) T { | |
| 918 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 903 | 919 | .int => |int| switch (int.storage) { |
| 904 | 920 | .big_int => |big_int| @floatCast(bigIntToFloat(big_int.limbs, big_int.positive)), |
| 905 | 921 | inline .u64, .i64 => |x| { |
| ... | ... | @@ -908,8 +924,8 @@ pub fn toFloat(val: Value, comptime T: type, pt: Zcu.PerThread) T { |
| 908 | 924 | } |
| 909 | 925 | return @floatFromInt(x); |
| 910 | 926 | }, |
| 911 | .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0), | |
| 912 | .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(pt)), | |
| 927 | .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0), | |
| 928 | .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(zcu)), | |
| 913 | 929 | }, |
| 914 | 930 | .float => |float| switch (float.storage) { |
| 915 | 931 | inline else => |x| @floatCast(x), |
| ... | ... | @@ -937,30 +953,30 @@ fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 { |
| 937 | 953 | } |
| 938 | 954 | } |
| 939 | 955 | |
| 940 | pub fn clz(val: Value, ty: Type, pt: Zcu.PerThread) u64 { | |
| 956 | pub fn clz(val: Value, ty: Type, zcu: *Zcu) u64 { | |
| 941 | 957 | var bigint_buf: BigIntSpace = undefined; |
| 942 | const bigint = val.toBigInt(&bigint_buf, pt); | |
| 943 | return bigint.clz(ty.intInfo(pt.zcu).bits); | |
| 958 | const bigint = val.toBigInt(&bigint_buf, zcu); | |
| 959 | return bigint.clz(ty.intInfo(zcu).bits); | |
| 944 | 960 | } |
| 945 | 961 | |
| 946 | pub fn ctz(val: Value, ty: Type, pt: Zcu.PerThread) u64 { | |
| 962 | pub fn ctz(val: Value, ty: Type, zcu: *Zcu) u64 { | |
| 947 | 963 | var bigint_buf: BigIntSpace = undefined; |
| 948 | const bigint = val.toBigInt(&bigint_buf, pt); | |
| 949 | return bigint.ctz(ty.intInfo(pt.zcu).bits); | |
| 964 | const bigint = val.toBigInt(&bigint_buf, zcu); | |
| 965 | return bigint.ctz(ty.intInfo(zcu).bits); | |
| 950 | 966 | } |
| 951 | 967 | |
| 952 | pub fn popCount(val: Value, ty: Type, pt: Zcu.PerThread) u64 { | |
| 968 | pub fn popCount(val: Value, ty: Type, zcu: *Zcu) u64 { | |
| 953 | 969 | var bigint_buf: BigIntSpace = undefined; |
| 954 | const bigint = val.toBigInt(&bigint_buf, pt); | |
| 955 | return @intCast(bigint.popCount(ty.intInfo(pt.zcu).bits)); | |
| 970 | const bigint = val.toBigInt(&bigint_buf, zcu); | |
| 971 | return @intCast(bigint.popCount(ty.intInfo(zcu).bits)); | |
| 956 | 972 | } |
| 957 | 973 | |
| 958 | 974 | pub fn bitReverse(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value { |
| 959 | const mod = pt.zcu; | |
| 960 | const info = ty.intInfo(mod); | |
| 975 | const zcu = pt.zcu; | |
| 976 | const info = ty.intInfo(zcu); | |
| 961 | 977 | |
| 962 | 978 | var buffer: Value.BigIntSpace = undefined; |
| 963 | const operand_bigint = val.toBigInt(&buffer, pt); | |
| 979 | const operand_bigint = val.toBigInt(&buffer, zcu); | |
| 964 | 980 | |
| 965 | 981 | const limbs = try arena.alloc( |
| 966 | 982 | std.math.big.Limb, |
| ... | ... | @@ -973,14 +989,14 @@ pub fn bitReverse(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Va |
| 973 | 989 | } |
| 974 | 990 | |
| 975 | 991 | pub fn byteSwap(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Value { |
| 976 | const mod = pt.zcu; | |
| 977 | const info = ty.intInfo(mod); | |
| 992 | const zcu = pt.zcu; | |
| 993 | const info = ty.intInfo(zcu); | |
| 978 | 994 | |
| 979 | 995 | // Bit count must be evenly divisible by 8 |
| 980 | 996 | assert(info.bits % 8 == 0); |
| 981 | 997 | |
| 982 | 998 | var buffer: Value.BigIntSpace = undefined; |
| 983 | const operand_bigint = val.toBigInt(&buffer, pt); | |
| 999 | const operand_bigint = val.toBigInt(&buffer, zcu); | |
| 984 | 1000 | |
| 985 | 1001 | const limbs = try arena.alloc( |
| 986 | 1002 | std.math.big.Limb, |
| ... | ... | @@ -994,33 +1010,34 @@ pub fn byteSwap(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) !Valu |
| 994 | 1010 | |
| 995 | 1011 | /// Asserts the value is an integer and not undefined. |
| 996 | 1012 | /// Returns the number of bits the value requires to represent stored in twos complement form. |
| 997 | pub fn intBitCountTwosComp(self: Value, pt: Zcu.PerThread) usize { | |
| 1013 | pub fn intBitCountTwosComp(self: Value, zcu: *Zcu) usize { | |
| 998 | 1014 | var buffer: BigIntSpace = undefined; |
| 999 | const big_int = self.toBigInt(&buffer, pt); | |
| 1015 | const big_int = self.toBigInt(&buffer, zcu); | |
| 1000 | 1016 | return big_int.bitCountTwosComp(); |
| 1001 | 1017 | } |
| 1002 | 1018 | |
| 1003 | 1019 | /// Converts an integer or a float to a float. May result in a loss of information. |
| 1004 | 1020 | /// Caller can find out by equality checking the result against the operand. |
| 1005 | 1021 | pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value { |
| 1006 | const target = pt.zcu.getTarget(); | |
| 1007 | if (val.isUndef(pt.zcu)) return pt.undefValue(dest_ty); | |
| 1022 | const zcu = pt.zcu; | |
| 1023 | const target = zcu.getTarget(); | |
| 1024 | if (val.isUndef(zcu)) return pt.undefValue(dest_ty); | |
| 1008 | 1025 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| 1009 | 1026 | .ty = dest_ty.toIntern(), |
| 1010 | 1027 | .storage = switch (dest_ty.floatBits(target)) { |
| 1011 | 16 => .{ .f16 = val.toFloat(f16, pt) }, | |
| 1012 | 32 => .{ .f32 = val.toFloat(f32, pt) }, | |
| 1013 | 64 => .{ .f64 = val.toFloat(f64, pt) }, | |
| 1014 | 80 => .{ .f80 = val.toFloat(f80, pt) }, | |
| 1015 | 128 => .{ .f128 = val.toFloat(f128, pt) }, | |
| 1028 | 16 => .{ .f16 = val.toFloat(f16, zcu) }, | |
| 1029 | 32 => .{ .f32 = val.toFloat(f32, zcu) }, | |
| 1030 | 64 => .{ .f64 = val.toFloat(f64, zcu) }, | |
| 1031 | 80 => .{ .f80 = val.toFloat(f80, zcu) }, | |
| 1032 | 128 => .{ .f128 = val.toFloat(f128, zcu) }, | |
| 1016 | 1033 | else => unreachable, |
| 1017 | 1034 | }, |
| 1018 | 1035 | } })); |
| 1019 | 1036 | } |
| 1020 | 1037 | |
| 1021 | 1038 | /// Asserts the value is a float |
| 1022 | pub fn floatHasFraction(self: Value, mod: *const Module) bool { | |
| 1023 | return switch (mod.intern_pool.indexToKey(self.toIntern())) { | |
| 1039 | pub fn floatHasFraction(self: Value, zcu: *const Module) bool { | |
| 1040 | return switch (zcu.intern_pool.indexToKey(self.toIntern())) { | |
| 1024 | 1041 | .float => |float| switch (float.storage) { |
| 1025 | 1042 | inline else => |x| @rem(x, 1) != 0, |
| 1026 | 1043 | }, |
| ... | ... | @@ -1028,19 +1045,24 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool { |
| 1028 | 1045 | }; |
| 1029 | 1046 | } |
| 1030 | 1047 | |
| 1031 | pub fn orderAgainstZero(lhs: Value, pt: Zcu.PerThread) std.math.Order { | |
| 1032 | return orderAgainstZeroAdvanced(lhs, pt, .normal) catch unreachable; | |
| 1048 | pub fn orderAgainstZero(lhs: Value, zcu: *Zcu) std.math.Order { | |
| 1049 | return orderAgainstZeroInner(lhs, .normal, zcu, {}) catch unreachable; | |
| 1033 | 1050 | } |
| 1034 | 1051 | |
| 1035 | pub fn orderAgainstZeroAdvanced( | |
| 1052 | pub fn orderAgainstZeroSema(lhs: Value, pt: Zcu.PerThread) !std.math.Order { | |
| 1053 | return try orderAgainstZeroInner(lhs, .sema, pt.zcu, pt.tid); | |
| 1054 | } | |
| 1055 | ||
| 1056 | pub fn orderAgainstZeroInner( | |
| 1036 | 1057 | lhs: Value, |
| 1037 | pt: Zcu.PerThread, | |
| 1038 | 1058 | comptime strat: ResolveStrat, |
| 1059 | zcu: *Zcu, | |
| 1060 | tid: strat.Tid(), | |
| 1039 | 1061 | ) Module.CompileError!std.math.Order { |
| 1040 | 1062 | return switch (lhs.toIntern()) { |
| 1041 | 1063 | .bool_false => .eq, |
| 1042 | 1064 | .bool_true => .gt, |
| 1043 | else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) { | |
| 1065 | else => switch (zcu.intern_pool.indexToKey(lhs.toIntern())) { | |
| 1044 | 1066 | .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) { |
| 1045 | 1067 | .nav, .comptime_alloc, .comptime_field => .gt, |
| 1046 | 1068 | .int => .eq, |
| ... | ... | @@ -1050,16 +1072,17 @@ pub fn orderAgainstZeroAdvanced( |
| 1050 | 1072 | .big_int => |big_int| big_int.orderAgainstScalar(0), |
| 1051 | 1073 | inline .u64, .i64 => |x| std.math.order(x, 0), |
| 1052 | 1074 | .lazy_align => .gt, // alignment is never 0 |
| 1053 | .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced( | |
| 1054 | pt, | |
| 1075 | .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsInner( | |
| 1055 | 1076 | false, |
| 1056 | 1077 | strat.toLazy(), |
| 1078 | zcu, | |
| 1079 | tid, | |
| 1057 | 1080 | ) catch |err| switch (err) { |
| 1058 | 1081 | error.NeedLazy => unreachable, |
| 1059 | 1082 | else => |e| return e, |
| 1060 | 1083 | }) .gt else .eq, |
| 1061 | 1084 | }, |
| 1062 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(pt, strat), | |
| 1085 | .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroInner(strat, zcu, tid), | |
| 1063 | 1086 | .float => |float| switch (float.storage) { |
| 1064 | 1087 | inline else => |x| std.math.order(x, 0), |
| 1065 | 1088 | }, |
| ... | ... | @@ -1069,14 +1092,20 @@ pub fn orderAgainstZeroAdvanced( |
| 1069 | 1092 | } |
| 1070 | 1093 | |
| 1071 | 1094 | /// Asserts the value is comparable. |
| 1072 | pub fn order(lhs: Value, rhs: Value, pt: Zcu.PerThread) std.math.Order { | |
| 1073 | return orderAdvanced(lhs, rhs, pt, .normal) catch unreachable; | |
| 1095 | pub fn order(lhs: Value, rhs: Value, zcu: *Zcu) std.math.Order { | |
| 1096 | return orderAdvanced(lhs, rhs, .normal, zcu, {}) catch unreachable; | |
| 1074 | 1097 | } |
| 1075 | 1098 | |
| 1076 | 1099 | /// Asserts the value is comparable. |
| 1077 | pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, comptime strat: ResolveStrat) !std.math.Order { | |
| 1078 | const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(pt, strat); | |
| 1079 | const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(pt, strat); | |
| 1100 | pub fn orderAdvanced( | |
| 1101 | lhs: Value, | |
| 1102 | rhs: Value, | |
| 1103 | comptime strat: ResolveStrat, | |
| 1104 | zcu: *Zcu, | |
| 1105 | tid: strat.Tid(), | |
| 1106 | ) !std.math.Order { | |
| 1107 | const lhs_against_zero = try lhs.orderAgainstZeroInner(strat, zcu, tid); | |
| 1108 | const rhs_against_zero = try rhs.orderAgainstZeroInner(strat, zcu, tid); | |
| 1080 | 1109 | switch (lhs_against_zero) { |
| 1081 | 1110 | .lt => if (rhs_against_zero != .lt) return .lt, |
| 1082 | 1111 | .eq => return rhs_against_zero.invert(), |
| ... | ... | @@ -1088,34 +1117,39 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, pt: Zcu.PerThread, comptime strat: |
| 1088 | 1117 | .gt => {}, |
| 1089 | 1118 | } |
| 1090 | 1119 | |
| 1091 | if (lhs.isFloat(pt.zcu) or rhs.isFloat(pt.zcu)) { | |
| 1092 | const lhs_f128 = lhs.toFloat(f128, pt); | |
| 1093 | const rhs_f128 = rhs.toFloat(f128, pt); | |
| 1120 | if (lhs.isFloat(zcu) or rhs.isFloat(zcu)) { | |
| 1121 | const lhs_f128 = lhs.toFloat(f128, zcu); | |
| 1122 | const rhs_f128 = rhs.toFloat(f128, zcu); | |
| 1094 | 1123 | return std.math.order(lhs_f128, rhs_f128); |
| 1095 | 1124 | } |
| 1096 | 1125 | |
| 1097 | 1126 | var lhs_bigint_space: BigIntSpace = undefined; |
| 1098 | 1127 | var rhs_bigint_space: BigIntSpace = undefined; |
| 1099 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, pt, strat); | |
| 1100 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, pt, strat); | |
| 1128 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, strat, zcu, tid); | |
| 1129 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, strat, zcu, tid); | |
| 1101 | 1130 | return lhs_bigint.order(rhs_bigint); |
| 1102 | 1131 | } |
| 1103 | 1132 | |
| 1104 | 1133 | /// Asserts the value is comparable. Does not take a type parameter because it supports |
| 1105 | 1134 | /// comparisons between heterogeneous types. |
| 1106 | pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread) bool { | |
| 1107 | return compareHeteroAdvanced(lhs, op, rhs, pt, .normal) catch unreachable; | |
| 1135 | pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, zcu: *Zcu) bool { | |
| 1136 | return compareHeteroAdvanced(lhs, op, rhs, .normal, zcu, {}) catch unreachable; | |
| 1137 | } | |
| 1138 | ||
| 1139 | pub fn compareHeteroSema(lhs: Value, op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread) !bool { | |
| 1140 | return try compareHeteroAdvanced(lhs, op, rhs, .sema, pt.zcu, pt.tid); | |
| 1108 | 1141 | } |
| 1109 | 1142 | |
| 1110 | 1143 | pub fn compareHeteroAdvanced( |
| 1111 | 1144 | lhs: Value, |
| 1112 | 1145 | op: std.math.CompareOperator, |
| 1113 | 1146 | rhs: Value, |
| 1114 | pt: Zcu.PerThread, | |
| 1115 | 1147 | comptime strat: ResolveStrat, |
| 1148 | zcu: *Zcu, | |
| 1149 | tid: strat.Tid(), | |
| 1116 | 1150 | ) !bool { |
| 1117 | if (lhs.pointerNav(pt.zcu)) |lhs_nav| { | |
| 1118 | if (rhs.pointerNav(pt.zcu)) |rhs_nav| { | |
| 1151 | if (lhs.pointerNav(zcu)) |lhs_nav| { | |
| 1152 | if (rhs.pointerNav(zcu)) |rhs_nav| { | |
| 1119 | 1153 | switch (op) { |
| 1120 | 1154 | .eq => return lhs_nav == rhs_nav, |
| 1121 | 1155 | .neq => return lhs_nav != rhs_nav, |
| ... | ... | @@ -1128,32 +1162,32 @@ pub fn compareHeteroAdvanced( |
| 1128 | 1162 | else => {}, |
| 1129 | 1163 | } |
| 1130 | 1164 | } |
| 1131 | } else if (rhs.pointerNav(pt.zcu)) |_| { | |
| 1165 | } else if (rhs.pointerNav(zcu)) |_| { | |
| 1132 | 1166 | switch (op) { |
| 1133 | 1167 | .eq => return false, |
| 1134 | 1168 | .neq => return true, |
| 1135 | 1169 | else => {}, |
| 1136 | 1170 | } |
| 1137 | 1171 | } |
| 1138 | return (try orderAdvanced(lhs, rhs, pt, strat)).compare(op); | |
| 1172 | return (try orderAdvanced(lhs, rhs, strat, zcu, tid)).compare(op); | |
| 1139 | 1173 | } |
| 1140 | 1174 | |
| 1141 | 1175 | /// Asserts the values are comparable. Both operands have type `ty`. |
| 1142 | 1176 | /// For vectors, returns true if comparison is true for ALL elements. |
| 1143 | 1177 | pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, pt: Zcu.PerThread) !bool { |
| 1144 | const mod = pt.zcu; | |
| 1145 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 1146 | const scalar_ty = ty.scalarType(mod); | |
| 1147 | for (0..ty.vectorLen(mod)) |i| { | |
| 1178 | const zcu = pt.zcu; | |
| 1179 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 1180 | const scalar_ty = ty.scalarType(zcu); | |
| 1181 | for (0..ty.vectorLen(zcu)) |i| { | |
| 1148 | 1182 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1149 | 1183 | const rhs_elem = try rhs.elemValue(pt, i); |
| 1150 | if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, pt)) { | |
| 1184 | if (!compareScalar(lhs_elem, op, rhs_elem, scalar_ty, zcu)) { | |
| 1151 | 1185 | return false; |
| 1152 | 1186 | } |
| 1153 | 1187 | } |
| 1154 | 1188 | return true; |
| 1155 | 1189 | } |
| 1156 | return compareScalar(lhs, op, rhs, ty, pt); | |
| 1190 | return compareScalar(lhs, op, rhs, ty, zcu); | |
| 1157 | 1191 | } |
| 1158 | 1192 | |
| 1159 | 1193 | /// Asserts the values are comparable. Both operands have type `ty`. |
| ... | ... | @@ -1162,12 +1196,12 @@ pub fn compareScalar( |
| 1162 | 1196 | op: std.math.CompareOperator, |
| 1163 | 1197 | rhs: Value, |
| 1164 | 1198 | ty: Type, |
| 1165 | pt: Zcu.PerThread, | |
| 1199 | zcu: *Zcu, | |
| 1166 | 1200 | ) bool { |
| 1167 | 1201 | return switch (op) { |
| 1168 | .eq => lhs.eql(rhs, ty, pt.zcu), | |
| 1169 | .neq => !lhs.eql(rhs, ty, pt.zcu), | |
| 1170 | else => compareHetero(lhs, op, rhs, pt), | |
| 1202 | .eq => lhs.eql(rhs, ty, zcu), | |
| 1203 | .neq => !lhs.eql(rhs, ty, zcu), | |
| 1204 | else => compareHetero(lhs, op, rhs, zcu), | |
| 1171 | 1205 | }; |
| 1172 | 1206 | } |
| 1173 | 1207 | |
| ... | ... | @@ -1176,8 +1210,8 @@ pub fn compareScalar( |
| 1176 | 1210 | /// Returns `false` if the value or any vector element is undefined. |
| 1177 | 1211 | /// |
| 1178 | 1212 | /// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)` |
| 1179 | pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, pt: Zcu.PerThread) bool { | |
| 1180 | return compareAllWithZeroAdvancedExtra(lhs, op, pt, .normal) catch unreachable; | |
| 1213 | pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, zcu: *Zcu) bool { | |
| 1214 | return compareAllWithZeroAdvancedExtra(lhs, op, .normal, zcu, {}) catch unreachable; | |
| 1181 | 1215 | } |
| 1182 | 1216 | |
| 1183 | 1217 | pub fn compareAllWithZeroSema( |
| ... | ... | @@ -1185,47 +1219,47 @@ pub fn compareAllWithZeroSema( |
| 1185 | 1219 | op: std.math.CompareOperator, |
| 1186 | 1220 | pt: Zcu.PerThread, |
| 1187 | 1221 | ) Module.CompileError!bool { |
| 1188 | return compareAllWithZeroAdvancedExtra(lhs, op, pt, .sema); | |
| 1222 | return compareAllWithZeroAdvancedExtra(lhs, op, .sema, pt.zcu, pt.tid); | |
| 1189 | 1223 | } |
| 1190 | 1224 | |
| 1191 | 1225 | pub fn compareAllWithZeroAdvancedExtra( |
| 1192 | 1226 | lhs: Value, |
| 1193 | 1227 | op: std.math.CompareOperator, |
| 1194 | pt: Zcu.PerThread, | |
| 1195 | 1228 | comptime strat: ResolveStrat, |
| 1229 | zcu: *Zcu, | |
| 1230 | tid: strat.Tid(), | |
| 1196 | 1231 | ) Module.CompileError!bool { |
| 1197 | const mod = pt.zcu; | |
| 1198 | if (lhs.isInf(mod)) { | |
| 1232 | if (lhs.isInf(zcu)) { | |
| 1199 | 1233 | switch (op) { |
| 1200 | 1234 | .neq => return true, |
| 1201 | 1235 | .eq => return false, |
| 1202 | .gt, .gte => return !lhs.isNegativeInf(mod), | |
| 1203 | .lt, .lte => return lhs.isNegativeInf(mod), | |
| 1236 | .gt, .gte => return !lhs.isNegativeInf(zcu), | |
| 1237 | .lt, .lte => return lhs.isNegativeInf(zcu), | |
| 1204 | 1238 | } |
| 1205 | 1239 | } |
| 1206 | 1240 | |
| 1207 | switch (mod.intern_pool.indexToKey(lhs.toIntern())) { | |
| 1241 | switch (zcu.intern_pool.indexToKey(lhs.toIntern())) { | |
| 1208 | 1242 | .float => |float| switch (float.storage) { |
| 1209 | 1243 | inline else => |x| if (std.math.isNan(x)) return op == .neq, |
| 1210 | 1244 | }, |
| 1211 | 1245 | .aggregate => |aggregate| return switch (aggregate.storage) { |
| 1212 | .bytes => |bytes| for (bytes.toSlice(lhs.typeOf(mod).arrayLenIncludingSentinel(mod), &mod.intern_pool)) |byte| { | |
| 1246 | .bytes => |bytes| for (bytes.toSlice(lhs.typeOf(zcu).arrayLenIncludingSentinel(zcu), &zcu.intern_pool)) |byte| { | |
| 1213 | 1247 | if (!std.math.order(byte, 0).compare(op)) break false; |
| 1214 | 1248 | } else true, |
| 1215 | 1249 | .elems => |elems| for (elems) |elem| { |
| 1216 | if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat)) break false; | |
| 1250 | if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, strat, zcu, tid)) break false; | |
| 1217 | 1251 | } else true, |
| 1218 | .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, pt, strat), | |
| 1252 | .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, strat, zcu, tid), | |
| 1219 | 1253 | }, |
| 1220 | 1254 | .undef => return false, |
| 1221 | 1255 | else => {}, |
| 1222 | 1256 | } |
| 1223 | return (try orderAgainstZeroAdvanced(lhs, pt, strat)).compare(op); | |
| 1257 | return (try orderAgainstZeroInner(lhs, strat, zcu, tid)).compare(op); | |
| 1224 | 1258 | } |
| 1225 | 1259 | |
| 1226 | pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool { | |
| 1227 | assert(mod.intern_pool.typeOf(a.toIntern()) == ty.toIntern()); | |
| 1228 | assert(mod.intern_pool.typeOf(b.toIntern()) == ty.toIntern()); | |
| 1260 | pub fn eql(a: Value, b: Value, ty: Type, zcu: *Module) bool { | |
| 1261 | assert(zcu.intern_pool.typeOf(a.toIntern()) == ty.toIntern()); | |
| 1262 | assert(zcu.intern_pool.typeOf(b.toIntern()) == ty.toIntern()); | |
| 1229 | 1263 | return a.toIntern() == b.toIntern(); |
| 1230 | 1264 | } |
| 1231 | 1265 | |
| ... | ... | @@ -1260,8 +1294,8 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool { |
| 1260 | 1294 | /// Gets the `Nav` referenced by this pointer. If the pointer does not point |
| 1261 | 1295 | /// to a `Nav`, or if it points to some part of one (like a field or element), |
| 1262 | 1296 | /// returns null. |
| 1263 | pub fn pointerNav(val: Value, mod: *Module) ?InternPool.Nav.Index { | |
| 1264 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1297 | pub fn pointerNav(val: Value, zcu: *Zcu) ?InternPool.Nav.Index { | |
| 1298 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1265 | 1299 | // TODO: these 3 cases are weird; these aren't pointer values! |
| 1266 | 1300 | .variable => |v| v.owner_nav, |
| 1267 | 1301 | .@"extern" => |e| e.owner_nav, |
| ... | ... | @@ -1277,8 +1311,8 @@ pub fn pointerNav(val: Value, mod: *Module) ?InternPool.Nav.Index { |
| 1277 | 1311 | pub const slice_ptr_index = 0; |
| 1278 | 1312 | pub const slice_len_index = 1; |
| 1279 | 1313 | |
| 1280 | pub fn slicePtr(val: Value, mod: *Module) Value { | |
| 1281 | return Value.fromInterned(mod.intern_pool.slicePtr(val.toIntern())); | |
| 1314 | pub fn slicePtr(val: Value, zcu: *Module) Value { | |
| 1315 | return Value.fromInterned(zcu.intern_pool.slicePtr(val.toIntern())); | |
| 1282 | 1316 | } |
| 1283 | 1317 | |
| 1284 | 1318 | /// Gets the `len` field of a slice value as a `u64`. |
| ... | ... | @@ -1312,15 +1346,15 @@ pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Va |
| 1312 | 1346 | } |
| 1313 | 1347 | } |
| 1314 | 1348 | |
| 1315 | pub fn isLazyAlign(val: Value, mod: *Module) bool { | |
| 1316 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1349 | pub fn isLazyAlign(val: Value, zcu: *Module) bool { | |
| 1350 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1317 | 1351 | .int => |int| int.storage == .lazy_align, |
| 1318 | 1352 | else => false, |
| 1319 | 1353 | }; |
| 1320 | 1354 | } |
| 1321 | 1355 | |
| 1322 | pub fn isLazySize(val: Value, mod: *Module) bool { | |
| 1323 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1356 | pub fn isLazySize(val: Value, zcu: *Module) bool { | |
| 1357 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1324 | 1358 | .int => |int| int.storage == .lazy_size, |
| 1325 | 1359 | else => false, |
| 1326 | 1360 | }; |
| ... | ... | @@ -1377,15 +1411,15 @@ pub fn sliceArray( |
| 1377 | 1411 | } |
| 1378 | 1412 | |
| 1379 | 1413 | pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value { |
| 1380 | const mod = pt.zcu; | |
| 1381 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1414 | const zcu = pt.zcu; | |
| 1415 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1382 | 1416 | .undef => |ty| Value.fromInterned(try pt.intern(.{ |
| 1383 | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), | |
| 1417 | .undef = Type.fromInterned(ty).structFieldType(index, zcu).toIntern(), | |
| 1384 | 1418 | })), |
| 1385 | 1419 | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { |
| 1386 | 1420 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 1387 | 1421 | .ty = .u8_type, |
| 1388 | .storage = .{ .u64 = bytes.at(index, &mod.intern_pool) }, | |
| 1422 | .storage = .{ .u64 = bytes.at(index, &zcu.intern_pool) }, | |
| 1389 | 1423 | } }), |
| 1390 | 1424 | .elems => |elems| elems[index], |
| 1391 | 1425 | .repeated_elem => |elem| elem, |
| ... | ... | @@ -1396,40 +1430,40 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value { |
| 1396 | 1430 | }; |
| 1397 | 1431 | } |
| 1398 | 1432 | |
| 1399 | pub fn unionTag(val: Value, mod: *Module) ?Value { | |
| 1400 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1433 | pub fn unionTag(val: Value, zcu: *Module) ?Value { | |
| 1434 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1401 | 1435 | .undef, .enum_tag => val, |
| 1402 | 1436 | .un => |un| if (un.tag != .none) Value.fromInterned(un.tag) else return null, |
| 1403 | 1437 | else => unreachable, |
| 1404 | 1438 | }; |
| 1405 | 1439 | } |
| 1406 | 1440 | |
| 1407 | pub fn unionValue(val: Value, mod: *Module) Value { | |
| 1408 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1441 | pub fn unionValue(val: Value, zcu: *Module) Value { | |
| 1442 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1409 | 1443 | .un => |un| Value.fromInterned(un.val), |
| 1410 | 1444 | else => unreachable, |
| 1411 | 1445 | }; |
| 1412 | 1446 | } |
| 1413 | 1447 | |
| 1414 | pub fn isUndef(val: Value, mod: *Module) bool { | |
| 1415 | return mod.intern_pool.isUndef(val.toIntern()); | |
| 1448 | pub fn isUndef(val: Value, zcu: *Module) bool { | |
| 1449 | return zcu.intern_pool.isUndef(val.toIntern()); | |
| 1416 | 1450 | } |
| 1417 | 1451 | |
| 1418 | 1452 | /// TODO: check for cases such as array that is not marked undef but all the element |
| 1419 | 1453 | /// values are marked undef, or struct that is not marked undef but all fields are marked |
| 1420 | 1454 | /// undef, etc. |
| 1421 | pub fn isUndefDeep(val: Value, mod: *Module) bool { | |
| 1422 | return val.isUndef(mod); | |
| 1455 | pub fn isUndefDeep(val: Value, zcu: *Module) bool { | |
| 1456 | return val.isUndef(zcu); | |
| 1423 | 1457 | } |
| 1424 | 1458 | |
| 1425 | 1459 | /// Asserts the value is not undefined and not unreachable. |
| 1426 | 1460 | /// C pointers with an integer value of 0 are also considered null. |
| 1427 | pub fn isNull(val: Value, mod: *Module) bool { | |
| 1461 | pub fn isNull(val: Value, zcu: *Module) bool { | |
| 1428 | 1462 | return switch (val.toIntern()) { |
| 1429 | 1463 | .undef => unreachable, |
| 1430 | 1464 | .unreachable_value => unreachable, |
| 1431 | 1465 | .null_value => true, |
| 1432 | else => return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1466 | else => return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1433 | 1467 | .undef => unreachable, |
| 1434 | 1468 | .ptr => |ptr| switch (ptr.base_addr) { |
| 1435 | 1469 | .int => ptr.byte_offset == 0, |
| ... | ... | @@ -1442,8 +1476,8 @@ pub fn isNull(val: Value, mod: *Module) bool { |
| 1442 | 1476 | } |
| 1443 | 1477 | |
| 1444 | 1478 | /// Valid only for error (union) types. Asserts the value is not undefined and not unreachable. |
| 1445 | pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTerminatedString { | |
| 1446 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1479 | pub fn getErrorName(val: Value, zcu: *const Module) InternPool.OptionalNullTerminatedString { | |
| 1480 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1447 | 1481 | .err => |err| err.name.toOptional(), |
| 1448 | 1482 | .error_union => |error_union| switch (error_union.val) { |
| 1449 | 1483 | .err_name => |err_name| err_name.toOptional(), |
| ... | ... | @@ -1462,13 +1496,13 @@ pub fn getErrorInt(val: Value, zcu: *Zcu) Module.ErrorInt { |
| 1462 | 1496 | |
| 1463 | 1497 | /// Assumes the type is an error union. Returns true if and only if the value is |
| 1464 | 1498 | /// the error union payload, not an error. |
| 1465 | pub fn errorUnionIsPayload(val: Value, mod: *const Module) bool { | |
| 1466 | return mod.intern_pool.indexToKey(val.toIntern()).error_union.val == .payload; | |
| 1499 | pub fn errorUnionIsPayload(val: Value, zcu: *const Module) bool { | |
| 1500 | return zcu.intern_pool.indexToKey(val.toIntern()).error_union.val == .payload; | |
| 1467 | 1501 | } |
| 1468 | 1502 | |
| 1469 | 1503 | /// Value of the optional, null if optional has no payload. |
| 1470 | pub fn optionalValue(val: Value, mod: *const Module) ?Value { | |
| 1471 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1504 | pub fn optionalValue(val: Value, zcu: *const Module) ?Value { | |
| 1505 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1472 | 1506 | .opt => |opt| switch (opt.val) { |
| 1473 | 1507 | .none => null, |
| 1474 | 1508 | else => |payload| Value.fromInterned(payload), |
| ... | ... | @@ -1479,10 +1513,10 @@ pub fn optionalValue(val: Value, mod: *const Module) ?Value { |
| 1479 | 1513 | } |
| 1480 | 1514 | |
| 1481 | 1515 | /// Valid for all types. Asserts the value is not undefined. |
| 1482 | pub fn isFloat(self: Value, mod: *const Module) bool { | |
| 1516 | pub fn isFloat(self: Value, zcu: *const Module) bool { | |
| 1483 | 1517 | return switch (self.toIntern()) { |
| 1484 | 1518 | .undef => unreachable, |
| 1485 | else => switch (mod.intern_pool.indexToKey(self.toIntern())) { | |
| 1519 | else => switch (zcu.intern_pool.indexToKey(self.toIntern())) { | |
| 1486 | 1520 | .undef => unreachable, |
| 1487 | 1521 | .float => true, |
| 1488 | 1522 | else => false, |
| ... | ... | @@ -1490,8 +1524,8 @@ pub fn isFloat(self: Value, mod: *const Module) bool { |
| 1490 | 1524 | }; |
| 1491 | 1525 | } |
| 1492 | 1526 | |
| 1493 | pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module) !Value { | |
| 1494 | return floatFromIntAdvanced(val, arena, int_ty, float_ty, mod, .normal) catch |err| switch (err) { | |
| 1527 | pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, zcu: *Module) !Value { | |
| 1528 | return floatFromIntAdvanced(val, arena, int_ty, float_ty, zcu, .normal) catch |err| switch (err) { | |
| 1495 | 1529 | error.OutOfMemory => return error.OutOfMemory, |
| 1496 | 1530 | else => unreachable, |
| 1497 | 1531 | }; |
| ... | ... | @@ -1505,10 +1539,10 @@ pub fn floatFromIntAdvanced( |
| 1505 | 1539 | pt: Zcu.PerThread, |
| 1506 | 1540 | comptime strat: ResolveStrat, |
| 1507 | 1541 | ) !Value { |
| 1508 | const mod = pt.zcu; | |
| 1509 | if (int_ty.zigTypeTag(mod) == .Vector) { | |
| 1510 | const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod)); | |
| 1511 | const scalar_ty = float_ty.scalarType(mod); | |
| 1542 | const zcu = pt.zcu; | |
| 1543 | if (int_ty.zigTypeTag(zcu) == .Vector) { | |
| 1544 | const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(zcu)); | |
| 1545 | const scalar_ty = float_ty.scalarType(zcu); | |
| 1512 | 1546 | for (result_data, 0..) |*scalar, i| { |
| 1513 | 1547 | const elem_val = try val.elemValue(pt, i); |
| 1514 | 1548 | scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, pt, strat)).toIntern(); |
| ... | ... | @@ -1522,8 +1556,8 @@ pub fn floatFromIntAdvanced( |
| 1522 | 1556 | } |
| 1523 | 1557 | |
| 1524 | 1558 | pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Value { |
| 1525 | const mod = pt.zcu; | |
| 1526 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 1559 | const zcu = pt.zcu; | |
| 1560 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 1527 | 1561 | .undef => try pt.undefValue(float_ty), |
| 1528 | 1562 | .int => |int| switch (int.storage) { |
| 1529 | 1563 | .big_int => |big_int| { |
| ... | ... | @@ -1531,8 +1565,8 @@ pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, comptim |
| 1531 | 1565 | return pt.floatValue(float_ty, float); |
| 1532 | 1566 | }, |
| 1533 | 1567 | inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, pt), |
| 1534 | .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(pt, strat.toLazy())).scalar.toByteUnits() orelse 0, float_ty, pt), | |
| 1535 | .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(pt, strat.toLazy())).scalar, float_ty, pt), | |
| 1568 | .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentInner(strat.toLazy(), pt.zcu, pt.tid)).scalar.toByteUnits() orelse 0, float_ty, pt), | |
| 1569 | .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeInner(strat.toLazy(), pt.zcu, pt.tid)).scalar, float_ty, pt), | |
| 1536 | 1570 | }, |
| 1537 | 1571 | else => unreachable, |
| 1538 | 1572 | }; |
| ... | ... | @@ -1600,15 +1634,16 @@ pub fn intAddSatScalar( |
| 1600 | 1634 | arena: Allocator, |
| 1601 | 1635 | pt: Zcu.PerThread, |
| 1602 | 1636 | ) !Value { |
| 1603 | assert(!lhs.isUndef(pt.zcu)); | |
| 1604 | assert(!rhs.isUndef(pt.zcu)); | |
| 1637 | const zcu = pt.zcu; | |
| 1638 | assert(!lhs.isUndef(zcu)); | |
| 1639 | assert(!rhs.isUndef(zcu)); | |
| 1605 | 1640 | |
| 1606 | const info = ty.intInfo(pt.zcu); | |
| 1641 | const info = ty.intInfo(zcu); | |
| 1607 | 1642 | |
| 1608 | 1643 | var lhs_space: Value.BigIntSpace = undefined; |
| 1609 | 1644 | var rhs_space: Value.BigIntSpace = undefined; |
| 1610 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 1611 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 1645 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 1646 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 1612 | 1647 | const limbs = try arena.alloc( |
| 1613 | 1648 | std.math.big.Limb, |
| 1614 | 1649 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| ... | ... | @@ -1650,15 +1685,17 @@ pub fn intSubSatScalar( |
| 1650 | 1685 | arena: Allocator, |
| 1651 | 1686 | pt: Zcu.PerThread, |
| 1652 | 1687 | ) !Value { |
| 1653 | assert(!lhs.isUndef(pt.zcu)); | |
| 1654 | assert(!rhs.isUndef(pt.zcu)); | |
| 1688 | const zcu = pt.zcu; | |
| 1655 | 1689 | |
| 1656 | const info = ty.intInfo(pt.zcu); | |
| 1690 | assert(!lhs.isUndef(zcu)); | |
| 1691 | assert(!rhs.isUndef(zcu)); | |
| 1692 | ||
| 1693 | const info = ty.intInfo(zcu); | |
| 1657 | 1694 | |
| 1658 | 1695 | var lhs_space: Value.BigIntSpace = undefined; |
| 1659 | 1696 | var rhs_space: Value.BigIntSpace = undefined; |
| 1660 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 1661 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 1697 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 1698 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 1662 | 1699 | const limbs = try arena.alloc( |
| 1663 | 1700 | std.math.big.Limb, |
| 1664 | 1701 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| ... | ... | @@ -1675,12 +1712,12 @@ pub fn intMulWithOverflow( |
| 1675 | 1712 | arena: Allocator, |
| 1676 | 1713 | pt: Zcu.PerThread, |
| 1677 | 1714 | ) !OverflowArithmeticResult { |
| 1678 | const mod = pt.zcu; | |
| 1679 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 1680 | const vec_len = ty.vectorLen(mod); | |
| 1715 | const zcu = pt.zcu; | |
| 1716 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 1717 | const vec_len = ty.vectorLen(zcu); | |
| 1681 | 1718 | const overflowed_data = try arena.alloc(InternPool.Index, vec_len); |
| 1682 | 1719 | const result_data = try arena.alloc(InternPool.Index, vec_len); |
| 1683 | const scalar_ty = ty.scalarType(mod); | |
| 1720 | const scalar_ty = ty.scalarType(zcu); | |
| 1684 | 1721 | for (overflowed_data, result_data, 0..) |*of, *scalar, i| { |
| 1685 | 1722 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1686 | 1723 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -1709,10 +1746,10 @@ pub fn intMulWithOverflowScalar( |
| 1709 | 1746 | arena: Allocator, |
| 1710 | 1747 | pt: Zcu.PerThread, |
| 1711 | 1748 | ) !OverflowArithmeticResult { |
| 1712 | const mod = pt.zcu; | |
| 1713 | const info = ty.intInfo(mod); | |
| 1749 | const zcu = pt.zcu; | |
| 1750 | const info = ty.intInfo(zcu); | |
| 1714 | 1751 | |
| 1715 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) { | |
| 1752 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) { | |
| 1716 | 1753 | return .{ |
| 1717 | 1754 | .overflow_bit = try pt.undefValue(Type.u1), |
| 1718 | 1755 | .wrapped_result = try pt.undefValue(ty), |
| ... | ... | @@ -1721,8 +1758,8 @@ pub fn intMulWithOverflowScalar( |
| 1721 | 1758 | |
| 1722 | 1759 | var lhs_space: Value.BigIntSpace = undefined; |
| 1723 | 1760 | var rhs_space: Value.BigIntSpace = undefined; |
| 1724 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 1725 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 1761 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 1762 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 1726 | 1763 | const limbs = try arena.alloc( |
| 1727 | 1764 | std.math.big.Limb, |
| 1728 | 1765 | lhs_bigint.limbs.len + rhs_bigint.limbs.len, |
| ... | ... | @@ -1753,10 +1790,10 @@ pub fn numberMulWrap( |
| 1753 | 1790 | arena: Allocator, |
| 1754 | 1791 | pt: Zcu.PerThread, |
| 1755 | 1792 | ) !Value { |
| 1756 | const mod = pt.zcu; | |
| 1757 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 1758 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 1759 | const scalar_ty = ty.scalarType(mod); | |
| 1793 | const zcu = pt.zcu; | |
| 1794 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 1795 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 1796 | const scalar_ty = ty.scalarType(zcu); | |
| 1760 | 1797 | for (result_data, 0..) |*scalar, i| { |
| 1761 | 1798 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1762 | 1799 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -1778,10 +1815,10 @@ pub fn numberMulWrapScalar( |
| 1778 | 1815 | arena: Allocator, |
| 1779 | 1816 | pt: Zcu.PerThread, |
| 1780 | 1817 | ) !Value { |
| 1781 | const mod = pt.zcu; | |
| 1782 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.undef; | |
| 1818 | const zcu = pt.zcu; | |
| 1819 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return Value.undef; | |
| 1783 | 1820 | |
| 1784 | if (ty.zigTypeTag(mod) == .ComptimeInt) { | |
| 1821 | if (ty.zigTypeTag(zcu) == .ComptimeInt) { | |
| 1785 | 1822 | return intMul(lhs, rhs, ty, undefined, arena, pt); |
| 1786 | 1823 | } |
| 1787 | 1824 | |
| ... | ... | @@ -1825,15 +1862,17 @@ pub fn intMulSatScalar( |
| 1825 | 1862 | arena: Allocator, |
| 1826 | 1863 | pt: Zcu.PerThread, |
| 1827 | 1864 | ) !Value { |
| 1828 | assert(!lhs.isUndef(pt.zcu)); | |
| 1829 | assert(!rhs.isUndef(pt.zcu)); | |
| 1865 | const zcu = pt.zcu; | |
| 1866 | ||
| 1867 | assert(!lhs.isUndef(zcu)); | |
| 1868 | assert(!rhs.isUndef(zcu)); | |
| 1830 | 1869 | |
| 1831 | const info = ty.intInfo(pt.zcu); | |
| 1870 | const info = ty.intInfo(zcu); | |
| 1832 | 1871 | |
| 1833 | 1872 | var lhs_space: Value.BigIntSpace = undefined; |
| 1834 | 1873 | var rhs_space: Value.BigIntSpace = undefined; |
| 1835 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 1836 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 1874 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 1875 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 1837 | 1876 | const limbs = try arena.alloc( |
| 1838 | 1877 | std.math.big.Limb, |
| 1839 | 1878 | @max( |
| ... | ... | @@ -1853,24 +1892,24 @@ pub fn intMulSatScalar( |
| 1853 | 1892 | } |
| 1854 | 1893 | |
| 1855 | 1894 | /// Supports both floats and ints; handles undefined. |
| 1856 | pub fn numberMax(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value { | |
| 1857 | if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef; | |
| 1858 | if (lhs.isNan(pt.zcu)) return rhs; | |
| 1859 | if (rhs.isNan(pt.zcu)) return lhs; | |
| 1895 | pub fn numberMax(lhs: Value, rhs: Value, zcu: *Zcu) Value { | |
| 1896 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef; | |
| 1897 | if (lhs.isNan(zcu)) return rhs; | |
| 1898 | if (rhs.isNan(zcu)) return lhs; | |
| 1860 | 1899 | |
| 1861 | return switch (order(lhs, rhs, pt)) { | |
| 1900 | return switch (order(lhs, rhs, zcu)) { | |
| 1862 | 1901 | .lt => rhs, |
| 1863 | 1902 | .gt, .eq => lhs, |
| 1864 | 1903 | }; |
| 1865 | 1904 | } |
| 1866 | 1905 | |
| 1867 | 1906 | /// Supports both floats and ints; handles undefined. |
| 1868 | pub fn numberMin(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value { | |
| 1869 | if (lhs.isUndef(pt.zcu) or rhs.isUndef(pt.zcu)) return undef; | |
| 1870 | if (lhs.isNan(pt.zcu)) return rhs; | |
| 1871 | if (rhs.isNan(pt.zcu)) return lhs; | |
| 1907 | pub fn numberMin(lhs: Value, rhs: Value, zcu: *Zcu) Value { | |
| 1908 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef; | |
| 1909 | if (lhs.isNan(zcu)) return rhs; | |
| 1910 | if (rhs.isNan(zcu)) return lhs; | |
| 1872 | 1911 | |
| 1873 | return switch (order(lhs, rhs, pt)) { | |
| 1912 | return switch (order(lhs, rhs, zcu)) { | |
| 1874 | 1913 | .lt => lhs, |
| 1875 | 1914 | .gt, .eq => rhs, |
| 1876 | 1915 | }; |
| ... | ... | @@ -1878,10 +1917,10 @@ pub fn numberMin(lhs: Value, rhs: Value, pt: Zcu.PerThread) Value { |
| 1878 | 1917 | |
| 1879 | 1918 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1880 | 1919 | pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1881 | const mod = pt.zcu; | |
| 1882 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 1883 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 1884 | const scalar_ty = ty.scalarType(mod); | |
| 1920 | const zcu = pt.zcu; | |
| 1921 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 1922 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 1923 | const scalar_ty = ty.scalarType(zcu); | |
| 1885 | 1924 | for (result_data, 0..) |*scalar, i| { |
| 1886 | 1925 | const elem_val = try val.elemValue(pt, i); |
| 1887 | 1926 | scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, pt)).toIntern(); |
| ... | ... | @@ -1896,11 +1935,11 @@ pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Va |
| 1896 | 1935 | |
| 1897 | 1936 | /// operands must be integers; handles undefined. |
| 1898 | 1937 | pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1899 | const mod = pt.zcu; | |
| 1900 | if (val.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | |
| 1938 | const zcu = pt.zcu; | |
| 1939 | if (val.isUndef(zcu)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | |
| 1901 | 1940 | if (ty.toIntern() == .bool_type) return makeBool(!val.toBool()); |
| 1902 | 1941 | |
| 1903 | const info = ty.intInfo(mod); | |
| 1942 | const info = ty.intInfo(zcu); | |
| 1904 | 1943 | |
| 1905 | 1944 | if (info.bits == 0) { |
| 1906 | 1945 | return val; |
| ... | ... | @@ -1909,7 +1948,7 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThrea |
| 1909 | 1948 | // TODO is this a performance issue? maybe we should try the operation without |
| 1910 | 1949 | // resorting to BigInt first. |
| 1911 | 1950 | var val_space: Value.BigIntSpace = undefined; |
| 1912 | const val_bigint = val.toBigInt(&val_space, pt); | |
| 1951 | const val_bigint = val.toBigInt(&val_space, zcu); | |
| 1913 | 1952 | const limbs = try arena.alloc( |
| 1914 | 1953 | std.math.big.Limb, |
| 1915 | 1954 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| ... | ... | @@ -1922,10 +1961,10 @@ pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThrea |
| 1922 | 1961 | |
| 1923 | 1962 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1924 | 1963 | pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 1925 | const mod = pt.zcu; | |
| 1926 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 1927 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 1928 | const scalar_ty = ty.scalarType(mod); | |
| 1964 | const zcu = pt.zcu; | |
| 1965 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 1966 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 1967 | const scalar_ty = ty.scalarType(zcu); | |
| 1929 | 1968 | for (result_data, 0..) |*scalar, i| { |
| 1930 | 1969 | const lhs_elem = try lhs.elemValue(pt, i); |
| 1931 | 1970 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -1962,8 +2001,8 @@ pub fn bitwiseAndScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloc |
| 1962 | 2001 | // resorting to BigInt first. |
| 1963 | 2002 | var lhs_space: Value.BigIntSpace = undefined; |
| 1964 | 2003 | var rhs_space: Value.BigIntSpace = undefined; |
| 1965 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 1966 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2004 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2005 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 1967 | 2006 | const limbs = try arena.alloc( |
| 1968 | 2007 | std.math.big.Limb, |
| 1969 | 2008 | // + 1 for negatives |
| ... | ... | @@ -1995,10 +2034,10 @@ fn intValueAa(ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1995 | 2034 | |
| 1996 | 2035 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 1997 | 2036 | pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 1998 | const mod = pt.zcu; | |
| 1999 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2000 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 2001 | const scalar_ty = ty.scalarType(mod); | |
| 2037 | const zcu = pt.zcu; | |
| 2038 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2039 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2040 | const scalar_ty = ty.scalarType(zcu); | |
| 2002 | 2041 | for (result_data, 0..) |*scalar, i| { |
| 2003 | 2042 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2004 | 2043 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2014,21 +2053,21 @@ pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.P |
| 2014 | 2053 | |
| 2015 | 2054 | /// operands must be integers; handles undefined. |
| 2016 | 2055 | pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 2017 | const mod = pt.zcu; | |
| 2018 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | |
| 2056 | const zcu = pt.zcu; | |
| 2057 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | |
| 2019 | 2058 | if (ty.toIntern() == .bool_type) return makeBool(!(lhs.toBool() and rhs.toBool())); |
| 2020 | 2059 | |
| 2021 | 2060 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, pt); |
| 2022 | const all_ones = if (ty.isSignedInt(mod)) try pt.intValue(ty, -1) else try ty.maxIntScalar(pt, ty); | |
| 2061 | const all_ones = if (ty.isSignedInt(zcu)) try pt.intValue(ty, -1) else try ty.maxIntScalar(pt, ty); | |
| 2023 | 2062 | return bitwiseXor(anded, all_ones, ty, arena, pt); |
| 2024 | 2063 | } |
| 2025 | 2064 | |
| 2026 | 2065 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 2027 | 2066 | pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2028 | const mod = pt.zcu; | |
| 2029 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2030 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 2031 | const scalar_ty = ty.scalarType(mod); | |
| 2067 | const zcu = pt.zcu; | |
| 2068 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2069 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2070 | const scalar_ty = ty.scalarType(zcu); | |
| 2032 | 2071 | for (result_data, 0..) |*scalar, i| { |
| 2033 | 2072 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2034 | 2073 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2047,9 +2086,10 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca |
| 2047 | 2086 | // If one operand is defined, we turn the other into `0xAA` so the bitwise AND can |
| 2048 | 2087 | // still zero out some bits. |
| 2049 | 2088 | // TODO: ideally we'd still like tracking for the undef bits. Related: #19634. |
| 2089 | const zcu = pt.zcu; | |
| 2050 | 2090 | const lhs: Value, const rhs: Value = make_defined: { |
| 2051 | const lhs_undef = orig_lhs.isUndef(pt.zcu); | |
| 2052 | const rhs_undef = orig_rhs.isUndef(pt.zcu); | |
| 2091 | const lhs_undef = orig_lhs.isUndef(zcu); | |
| 2092 | const rhs_undef = orig_rhs.isUndef(zcu); | |
| 2053 | 2093 | break :make_defined switch ((@as(u2, @intFromBool(lhs_undef)) << 1) | @intFromBool(rhs_undef)) { |
| 2054 | 2094 | 0b00 => .{ orig_lhs, orig_rhs }, |
| 2055 | 2095 | 0b01 => .{ orig_lhs, try intValueAa(ty, arena, pt) }, |
| ... | ... | @@ -2064,8 +2104,8 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca |
| 2064 | 2104 | // resorting to BigInt first. |
| 2065 | 2105 | var lhs_space: Value.BigIntSpace = undefined; |
| 2066 | 2106 | var rhs_space: Value.BigIntSpace = undefined; |
| 2067 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2068 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2107 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2108 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 2069 | 2109 | const limbs = try arena.alloc( |
| 2070 | 2110 | std.math.big.Limb, |
| 2071 | 2111 | @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), |
| ... | ... | @@ -2077,10 +2117,10 @@ pub fn bitwiseOrScalar(orig_lhs: Value, orig_rhs: Value, ty: Type, arena: Alloca |
| 2077 | 2117 | |
| 2078 | 2118 | /// operands must be (vectors of) integers; handles undefined scalars. |
| 2079 | 2119 | pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2080 | const mod = pt.zcu; | |
| 2081 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2082 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 2083 | const scalar_ty = ty.scalarType(mod); | |
| 2120 | const zcu = pt.zcu; | |
| 2121 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2122 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2123 | const scalar_ty = ty.scalarType(zcu); | |
| 2084 | 2124 | for (result_data, 0..) |*scalar, i| { |
| 2085 | 2125 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2086 | 2126 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2096,16 +2136,16 @@ pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zc |
| 2096 | 2136 | |
| 2097 | 2137 | /// operands must be integers; handles undefined. |
| 2098 | 2138 | pub fn bitwiseXorScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 2099 | const mod = pt.zcu; | |
| 2100 | if (lhs.isUndef(mod) or rhs.isUndef(mod)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | |
| 2139 | const zcu = pt.zcu; | |
| 2140 | if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() })); | |
| 2101 | 2141 | if (ty.toIntern() == .bool_type) return makeBool(lhs.toBool() != rhs.toBool()); |
| 2102 | 2142 | |
| 2103 | 2143 | // TODO is this a performance issue? maybe we should try the operation without |
| 2104 | 2144 | // resorting to BigInt first. |
| 2105 | 2145 | var lhs_space: Value.BigIntSpace = undefined; |
| 2106 | 2146 | var rhs_space: Value.BigIntSpace = undefined; |
| 2107 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2108 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2147 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2148 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 2109 | 2149 | const limbs = try arena.alloc( |
| 2110 | 2150 | std.math.big.Limb, |
| 2111 | 2151 | // + 1 for negatives |
| ... | ... | @@ -2164,10 +2204,11 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2164 | 2204 | pub fn intDivScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2165 | 2205 | // TODO is this a performance issue? maybe we should try the operation without |
| 2166 | 2206 | // resorting to BigInt first. |
| 2207 | const zcu = pt.zcu; | |
| 2167 | 2208 | var lhs_space: Value.BigIntSpace = undefined; |
| 2168 | 2209 | var rhs_space: Value.BigIntSpace = undefined; |
| 2169 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2170 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2210 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2211 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 2171 | 2212 | const limbs_q = try allocator.alloc( |
| 2172 | 2213 | std.math.big.Limb, |
| 2173 | 2214 | lhs_bigint.limbs.len, |
| ... | ... | @@ -2212,10 +2253,11 @@ pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Z |
| 2212 | 2253 | pub fn intDivFloorScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2213 | 2254 | // TODO is this a performance issue? maybe we should try the operation without |
| 2214 | 2255 | // resorting to BigInt first. |
| 2256 | const zcu = pt.zcu; | |
| 2215 | 2257 | var lhs_space: Value.BigIntSpace = undefined; |
| 2216 | 2258 | var rhs_space: Value.BigIntSpace = undefined; |
| 2217 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2218 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2259 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2260 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 2219 | 2261 | const limbs_q = try allocator.alloc( |
| 2220 | 2262 | std.math.big.Limb, |
| 2221 | 2263 | lhs_bigint.limbs.len, |
| ... | ... | @@ -2254,10 +2296,11 @@ pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.Pe |
| 2254 | 2296 | pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2255 | 2297 | // TODO is this a performance issue? maybe we should try the operation without |
| 2256 | 2298 | // resorting to BigInt first. |
| 2299 | const zcu = pt.zcu; | |
| 2257 | 2300 | var lhs_space: Value.BigIntSpace = undefined; |
| 2258 | 2301 | var rhs_space: Value.BigIntSpace = undefined; |
| 2259 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2260 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2302 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2303 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 2261 | 2304 | const limbs_q = try allocator.alloc( |
| 2262 | 2305 | std.math.big.Limb, |
| 2263 | 2306 | lhs_bigint.limbs.len, |
| ... | ... | @@ -2277,8 +2320,8 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: |
| 2277 | 2320 | } |
| 2278 | 2321 | |
| 2279 | 2322 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. |
| 2280 | pub fn isNan(val: Value, mod: *const Module) bool { | |
| 2281 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 2323 | pub fn isNan(val: Value, zcu: *const Module) bool { | |
| 2324 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 2282 | 2325 | .float => |float| switch (float.storage) { |
| 2283 | 2326 | inline else => |x| std.math.isNan(x), |
| 2284 | 2327 | }, |
| ... | ... | @@ -2287,8 +2330,8 @@ pub fn isNan(val: Value, mod: *const Module) bool { |
| 2287 | 2330 | } |
| 2288 | 2331 | |
| 2289 | 2332 | /// Returns true if the value is a floating point type and is infinite. Returns false otherwise. |
| 2290 | pub fn isInf(val: Value, mod: *const Module) bool { | |
| 2291 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 2333 | pub fn isInf(val: Value, zcu: *const Module) bool { | |
| 2334 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 2292 | 2335 | .float => |float| switch (float.storage) { |
| 2293 | 2336 | inline else => |x| std.math.isInf(x), |
| 2294 | 2337 | }, |
| ... | ... | @@ -2296,8 +2339,8 @@ pub fn isInf(val: Value, mod: *const Module) bool { |
| 2296 | 2339 | }; |
| 2297 | 2340 | } |
| 2298 | 2341 | |
| 2299 | pub fn isNegativeInf(val: Value, mod: *const Module) bool { | |
| 2300 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | |
| 2342 | pub fn isNegativeInf(val: Value, zcu: *const Module) bool { | |
| 2343 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | |
| 2301 | 2344 | .float => |float| switch (float.storage) { |
| 2302 | 2345 | inline else => |x| std.math.isNegativeInf(x), |
| 2303 | 2346 | }, |
| ... | ... | @@ -2323,13 +2366,14 @@ pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: |
| 2323 | 2366 | } |
| 2324 | 2367 | |
| 2325 | 2368 | pub fn floatRemScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value { |
| 2369 | const zcu = pt.zcu; | |
| 2326 | 2370 | const target = pt.zcu.getTarget(); |
| 2327 | 2371 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2328 | 16 => .{ .f16 = @rem(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, | |
| 2329 | 32 => .{ .f32 = @rem(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, | |
| 2330 | 64 => .{ .f64 = @rem(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, | |
| 2331 | 80 => .{ .f80 = @rem(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, | |
| 2332 | 128 => .{ .f128 = @rem(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, | |
| 2372 | 16 => .{ .f16 = @rem(lhs.toFloat(f16, zcu), rhs.toFloat(f16, zcu)) }, | |
| 2373 | 32 => .{ .f32 = @rem(lhs.toFloat(f32, zcu), rhs.toFloat(f32, zcu)) }, | |
| 2374 | 64 => .{ .f64 = @rem(lhs.toFloat(f64, zcu), rhs.toFloat(f64, zcu)) }, | |
| 2375 | 80 => .{ .f80 = @rem(lhs.toFloat(f80, zcu), rhs.toFloat(f80, zcu)) }, | |
| 2376 | 128 => .{ .f128 = @rem(lhs.toFloat(f128, zcu), rhs.toFloat(f128, zcu)) }, | |
| 2333 | 2377 | else => unreachable, |
| 2334 | 2378 | }; |
| 2335 | 2379 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2356,13 +2400,14 @@ pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, pt: |
| 2356 | 2400 | } |
| 2357 | 2401 | |
| 2358 | 2402 | pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThread) !Value { |
| 2359 | const target = pt.zcu.getTarget(); | |
| 2403 | const zcu = pt.zcu; | |
| 2404 | const target = zcu.getTarget(); | |
| 2360 | 2405 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2361 | 16 => .{ .f16 = @mod(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, | |
| 2362 | 32 => .{ .f32 = @mod(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, | |
| 2363 | 64 => .{ .f64 = @mod(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, | |
| 2364 | 80 => .{ .f80 = @mod(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, | |
| 2365 | 128 => .{ .f128 = @mod(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, | |
| 2406 | 16 => .{ .f16 = @mod(lhs.toFloat(f16, zcu), rhs.toFloat(f16, zcu)) }, | |
| 2407 | 32 => .{ .f32 = @mod(lhs.toFloat(f32, zcu), rhs.toFloat(f32, zcu)) }, | |
| 2408 | 64 => .{ .f64 = @mod(lhs.toFloat(f64, zcu), rhs.toFloat(f64, zcu)) }, | |
| 2409 | 80 => .{ .f80 = @mod(lhs.toFloat(f80, zcu), rhs.toFloat(f80, zcu)) }, | |
| 2410 | 128 => .{ .f128 = @mod(lhs.toFloat(f128, zcu), rhs.toFloat(f128, zcu)) }, | |
| 2366 | 2411 | else => unreachable, |
| 2367 | 2412 | }; |
| 2368 | 2413 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2374,14 +2419,14 @@ pub fn floatModScalar(lhs: Value, rhs: Value, float_type: Type, pt: Zcu.PerThrea |
| 2374 | 2419 | /// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting |
| 2375 | 2420 | /// overflow_idx to the vector index the overflow was at (or 0 for a scalar). |
| 2376 | 2421 | pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2377 | const mod = pt.zcu; | |
| 2422 | const zcu = pt.zcu; | |
| 2378 | 2423 | var overflow: usize = undefined; |
| 2379 | 2424 | return intMulInner(lhs, rhs, ty, &overflow, allocator, pt) catch |err| switch (err) { |
| 2380 | 2425 | error.Overflow => { |
| 2381 | const is_vec = ty.isVector(mod); | |
| 2426 | const is_vec = ty.isVector(zcu); | |
| 2382 | 2427 | overflow_idx.* = if (is_vec) overflow else 0; |
| 2383 | 2428 | const safe_ty = if (is_vec) try pt.vectorType(.{ |
| 2384 | .len = ty.vectorLen(mod), | |
| 2429 | .len = ty.vectorLen(zcu), | |
| 2385 | 2430 | .child = .comptime_int_type, |
| 2386 | 2431 | }) else Type.comptime_int; |
| 2387 | 2432 | return intMulInner(lhs, rhs, safe_ty, undefined, allocator, pt) catch |err1| switch (err1) { |
| ... | ... | @@ -2394,10 +2439,10 @@ pub fn intMul(lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize, allocator |
| 2394 | 2439 | } |
| 2395 | 2440 | |
| 2396 | 2441 | fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2397 | const mod = pt.zcu; | |
| 2398 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2399 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 2400 | const scalar_ty = ty.scalarType(mod); | |
| 2442 | const zcu = pt.zcu; | |
| 2443 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2444 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2445 | const scalar_ty = ty.scalarType(zcu); | |
| 2401 | 2446 | for (result_data, 0..) |*scalar, i| { |
| 2402 | 2447 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2403 | 2448 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2419,17 +2464,18 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2419 | 2464 | } |
| 2420 | 2465 | |
| 2421 | 2466 | pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2467 | const zcu = pt.zcu; | |
| 2422 | 2468 | if (ty.toIntern() != .comptime_int_type) { |
| 2423 | 2469 | const res = try intMulWithOverflowScalar(lhs, rhs, ty, allocator, pt); |
| 2424 | if (res.overflow_bit.compareAllWithZero(.neq, pt)) return error.Overflow; | |
| 2470 | if (res.overflow_bit.compareAllWithZero(.neq, zcu)) return error.Overflow; | |
| 2425 | 2471 | return res.wrapped_result; |
| 2426 | 2472 | } |
| 2427 | 2473 | // TODO is this a performance issue? maybe we should try the operation without |
| 2428 | 2474 | // resorting to BigInt first. |
| 2429 | 2475 | var lhs_space: Value.BigIntSpace = undefined; |
| 2430 | 2476 | var rhs_space: Value.BigIntSpace = undefined; |
| 2431 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2432 | const rhs_bigint = rhs.toBigInt(&rhs_space, pt); | |
| 2477 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2478 | const rhs_bigint = rhs.toBigInt(&rhs_space, zcu); | |
| 2433 | 2479 | const limbs = try allocator.alloc( |
| 2434 | 2480 | std.math.big.Limb, |
| 2435 | 2481 | lhs_bigint.limbs.len + rhs_bigint.limbs.len, |
| ... | ... | @@ -2445,10 +2491,10 @@ pub fn intMulScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: |
| 2445 | 2491 | } |
| 2446 | 2492 | |
| 2447 | 2493 | pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, pt: Zcu.PerThread) !Value { |
| 2448 | const mod = pt.zcu; | |
| 2449 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2450 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 2451 | const scalar_ty = ty.scalarType(mod); | |
| 2494 | const zcu = pt.zcu; | |
| 2495 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2496 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2497 | const scalar_ty = ty.scalarType(zcu); | |
| 2452 | 2498 | for (result_data, 0..) |*scalar, i| { |
| 2453 | 2499 | const elem_val = try val.elemValue(pt, i); |
| 2454 | 2500 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, pt)).toIntern(); |
| ... | ... | @@ -2470,20 +2516,21 @@ pub fn intTruncBitsAsValue( |
| 2470 | 2516 | bits: Value, |
| 2471 | 2517 | pt: Zcu.PerThread, |
| 2472 | 2518 | ) !Value { |
| 2473 | if (ty.zigTypeTag(pt.zcu) == .Vector) { | |
| 2474 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(pt.zcu)); | |
| 2475 | const scalar_ty = ty.scalarType(pt.zcu); | |
| 2519 | const zcu = pt.zcu; | |
| 2520 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2521 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2522 | const scalar_ty = ty.scalarType(zcu); | |
| 2476 | 2523 | for (result_data, 0..) |*scalar, i| { |
| 2477 | 2524 | const elem_val = try val.elemValue(pt, i); |
| 2478 | 2525 | const bits_elem = try bits.elemValue(pt, i); |
| 2479 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(pt)), pt)).toIntern(); | |
| 2526 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @intCast(bits_elem.toUnsignedInt(zcu)), pt)).toIntern(); | |
| 2480 | 2527 | } |
| 2481 | 2528 | return Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 2482 | 2529 | .ty = ty.toIntern(), |
| 2483 | 2530 | .storage = .{ .elems = result_data }, |
| 2484 | 2531 | } })); |
| 2485 | 2532 | } |
| 2486 | return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(pt)), pt); | |
| 2533 | return intTruncScalar(val, ty, allocator, signedness, @intCast(bits.toUnsignedInt(zcu)), pt); | |
| 2487 | 2534 | } |
| 2488 | 2535 | |
| 2489 | 2536 | pub fn intTruncScalar( |
| ... | ... | @@ -2500,7 +2547,7 @@ pub fn intTruncScalar( |
| 2500 | 2547 | if (val.isUndef(zcu)) return pt.undefValue(ty); |
| 2501 | 2548 | |
| 2502 | 2549 | var val_space: Value.BigIntSpace = undefined; |
| 2503 | const val_bigint = val.toBigInt(&val_space, pt); | |
| 2550 | const val_bigint = val.toBigInt(&val_space, zcu); | |
| 2504 | 2551 | |
| 2505 | 2552 | const limbs = try allocator.alloc( |
| 2506 | 2553 | std.math.big.Limb, |
| ... | ... | @@ -2513,10 +2560,10 @@ pub fn intTruncScalar( |
| 2513 | 2560 | } |
| 2514 | 2561 | |
| 2515 | 2562 | pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2516 | const mod = pt.zcu; | |
| 2517 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2518 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 2519 | const scalar_ty = ty.scalarType(mod); | |
| 2563 | const zcu = pt.zcu; | |
| 2564 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2565 | const result_data = try allocator.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 2566 | const scalar_ty = ty.scalarType(zcu); | |
| 2520 | 2567 | for (result_data, 0..) |*scalar, i| { |
| 2521 | 2568 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2522 | 2569 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2533,9 +2580,10 @@ pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerTh |
| 2533 | 2580 | pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2534 | 2581 | // TODO is this a performance issue? maybe we should try the operation without |
| 2535 | 2582 | // resorting to BigInt first. |
| 2583 | const zcu = pt.zcu; | |
| 2536 | 2584 | var lhs_space: Value.BigIntSpace = undefined; |
| 2537 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2538 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); | |
| 2585 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2586 | const shift: usize = @intCast(rhs.toUnsignedInt(zcu)); | |
| 2539 | 2587 | const limbs = try allocator.alloc( |
| 2540 | 2588 | std.math.big.Limb, |
| 2541 | 2589 | lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, |
| ... | ... | @@ -2547,7 +2595,7 @@ pub fn shlScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu |
| 2547 | 2595 | }; |
| 2548 | 2596 | result_bigint.shiftLeft(lhs_bigint, shift); |
| 2549 | 2597 | if (ty.toIntern() != .comptime_int_type) { |
| 2550 | const int_info = ty.intInfo(pt.zcu); | |
| 2598 | const int_info = ty.intInfo(zcu); | |
| 2551 | 2599 | result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits); |
| 2552 | 2600 | } |
| 2553 | 2601 | |
| ... | ... | @@ -2594,10 +2642,11 @@ pub fn shlWithOverflowScalar( |
| 2594 | 2642 | allocator: Allocator, |
| 2595 | 2643 | pt: Zcu.PerThread, |
| 2596 | 2644 | ) !OverflowArithmeticResult { |
| 2597 | const info = ty.intInfo(pt.zcu); | |
| 2645 | const zcu = pt.zcu; | |
| 2646 | const info = ty.intInfo(zcu); | |
| 2598 | 2647 | var lhs_space: Value.BigIntSpace = undefined; |
| 2599 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2600 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); | |
| 2648 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2649 | const shift: usize = @intCast(rhs.toUnsignedInt(zcu)); | |
| 2601 | 2650 | const limbs = try allocator.alloc( |
| 2602 | 2651 | std.math.big.Limb, |
| 2603 | 2652 | lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, |
| ... | ... | @@ -2650,11 +2699,12 @@ pub fn shlSatScalar( |
| 2650 | 2699 | ) !Value { |
| 2651 | 2700 | // TODO is this a performance issue? maybe we should try the operation without |
| 2652 | 2701 | // resorting to BigInt first. |
| 2653 | const info = ty.intInfo(pt.zcu); | |
| 2702 | const zcu = pt.zcu; | |
| 2703 | const info = ty.intInfo(zcu); | |
| 2654 | 2704 | |
| 2655 | 2705 | var lhs_space: Value.BigIntSpace = undefined; |
| 2656 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2657 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); | |
| 2706 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2707 | const shift: usize = @intCast(rhs.toUnsignedInt(zcu)); | |
| 2658 | 2708 | const limbs = try arena.alloc( |
| 2659 | 2709 | std.math.big.Limb, |
| 2660 | 2710 | std.math.big.int.calcTwosCompLimbCount(info.bits) + 1, |
| ... | ... | @@ -2724,9 +2774,10 @@ pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerTh |
| 2724 | 2774 | pub fn shrScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, pt: Zcu.PerThread) !Value { |
| 2725 | 2775 | // TODO is this a performance issue? maybe we should try the operation without |
| 2726 | 2776 | // resorting to BigInt first. |
| 2777 | const zcu = pt.zcu; | |
| 2727 | 2778 | var lhs_space: Value.BigIntSpace = undefined; |
| 2728 | const lhs_bigint = lhs.toBigInt(&lhs_space, pt); | |
| 2729 | const shift: usize = @intCast(rhs.toUnsignedInt(pt)); | |
| 2779 | const lhs_bigint = lhs.toBigInt(&lhs_space, zcu); | |
| 2780 | const shift: usize = @intCast(rhs.toUnsignedInt(zcu)); | |
| 2730 | 2781 | |
| 2731 | 2782 | const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8)); |
| 2732 | 2783 | if (result_limbs == 0) { |
| ... | ... | @@ -2758,10 +2809,10 @@ pub fn floatNeg( |
| 2758 | 2809 | arena: Allocator, |
| 2759 | 2810 | pt: Zcu.PerThread, |
| 2760 | 2811 | ) !Value { |
| 2761 | const mod = pt.zcu; | |
| 2762 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 2763 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 2764 | const scalar_ty = float_type.scalarType(mod); | |
| 2812 | const zcu = pt.zcu; | |
| 2813 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 2814 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 2815 | const scalar_ty = float_type.scalarType(zcu); | |
| 2765 | 2816 | for (result_data, 0..) |*scalar, i| { |
| 2766 | 2817 | const elem_val = try val.elemValue(pt, i); |
| 2767 | 2818 | scalar.* = (try floatNegScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -2775,13 +2826,14 @@ pub fn floatNeg( |
| 2775 | 2826 | } |
| 2776 | 2827 | |
| 2777 | 2828 | pub fn floatNegScalar(val: Value, float_type: Type, pt: Zcu.PerThread) !Value { |
| 2778 | const target = pt.zcu.getTarget(); | |
| 2829 | const zcu = pt.zcu; | |
| 2830 | const target = zcu.getTarget(); | |
| 2779 | 2831 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2780 | 16 => .{ .f16 = -val.toFloat(f16, pt) }, | |
| 2781 | 32 => .{ .f32 = -val.toFloat(f32, pt) }, | |
| 2782 | 64 => .{ .f64 = -val.toFloat(f64, pt) }, | |
| 2783 | 80 => .{ .f80 = -val.toFloat(f80, pt) }, | |
| 2784 | 128 => .{ .f128 = -val.toFloat(f128, pt) }, | |
| 2832 | 16 => .{ .f16 = -val.toFloat(f16, zcu) }, | |
| 2833 | 32 => .{ .f32 = -val.toFloat(f32, zcu) }, | |
| 2834 | 64 => .{ .f64 = -val.toFloat(f64, zcu) }, | |
| 2835 | 80 => .{ .f80 = -val.toFloat(f80, zcu) }, | |
| 2836 | 128 => .{ .f128 = -val.toFloat(f128, zcu) }, | |
| 2785 | 2837 | else => unreachable, |
| 2786 | 2838 | }; |
| 2787 | 2839 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2797,10 +2849,10 @@ pub fn floatAdd( |
| 2797 | 2849 | arena: Allocator, |
| 2798 | 2850 | pt: Zcu.PerThread, |
| 2799 | 2851 | ) !Value { |
| 2800 | const mod = pt.zcu; | |
| 2801 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 2802 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 2803 | const scalar_ty = float_type.scalarType(mod); | |
| 2852 | const zcu = pt.zcu; | |
| 2853 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 2854 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 2855 | const scalar_ty = float_type.scalarType(zcu); | |
| 2804 | 2856 | for (result_data, 0..) |*scalar, i| { |
| 2805 | 2857 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2806 | 2858 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2820,14 +2872,14 @@ pub fn floatAddScalar( |
| 2820 | 2872 | float_type: Type, |
| 2821 | 2873 | pt: Zcu.PerThread, |
| 2822 | 2874 | ) !Value { |
| 2823 | const mod = pt.zcu; | |
| 2824 | const target = mod.getTarget(); | |
| 2875 | const zcu = pt.zcu; | |
| 2876 | const target = zcu.getTarget(); | |
| 2825 | 2877 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2826 | 16 => .{ .f16 = lhs.toFloat(f16, pt) + rhs.toFloat(f16, pt) }, | |
| 2827 | 32 => .{ .f32 = lhs.toFloat(f32, pt) + rhs.toFloat(f32, pt) }, | |
| 2828 | 64 => .{ .f64 = lhs.toFloat(f64, pt) + rhs.toFloat(f64, pt) }, | |
| 2829 | 80 => .{ .f80 = lhs.toFloat(f80, pt) + rhs.toFloat(f80, pt) }, | |
| 2830 | 128 => .{ .f128 = lhs.toFloat(f128, pt) + rhs.toFloat(f128, pt) }, | |
| 2878 | 16 => .{ .f16 = lhs.toFloat(f16, zcu) + rhs.toFloat(f16, zcu) }, | |
| 2879 | 32 => .{ .f32 = lhs.toFloat(f32, zcu) + rhs.toFloat(f32, zcu) }, | |
| 2880 | 64 => .{ .f64 = lhs.toFloat(f64, zcu) + rhs.toFloat(f64, zcu) }, | |
| 2881 | 80 => .{ .f80 = lhs.toFloat(f80, zcu) + rhs.toFloat(f80, zcu) }, | |
| 2882 | 128 => .{ .f128 = lhs.toFloat(f128, zcu) + rhs.toFloat(f128, zcu) }, | |
| 2831 | 2883 | else => unreachable, |
| 2832 | 2884 | }; |
| 2833 | 2885 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2843,10 +2895,10 @@ pub fn floatSub( |
| 2843 | 2895 | arena: Allocator, |
| 2844 | 2896 | pt: Zcu.PerThread, |
| 2845 | 2897 | ) !Value { |
| 2846 | const mod = pt.zcu; | |
| 2847 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 2848 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 2849 | const scalar_ty = float_type.scalarType(mod); | |
| 2898 | const zcu = pt.zcu; | |
| 2899 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 2900 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 2901 | const scalar_ty = float_type.scalarType(zcu); | |
| 2850 | 2902 | for (result_data, 0..) |*scalar, i| { |
| 2851 | 2903 | const lhs_elem = try lhs.elemValue(pt, i); |
| 2852 | 2904 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -2866,14 +2918,14 @@ pub fn floatSubScalar( |
| 2866 | 2918 | float_type: Type, |
| 2867 | 2919 | pt: Zcu.PerThread, |
| 2868 | 2920 | ) !Value { |
| 2869 | const mod = pt.zcu; | |
| 2870 | const target = mod.getTarget(); | |
| 2921 | const zcu = pt.zcu; | |
| 2922 | const target = zcu.getTarget(); | |
| 2871 | 2923 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2872 | 16 => .{ .f16 = lhs.toFloat(f16, pt) - rhs.toFloat(f16, pt) }, | |
| 2873 | 32 => .{ .f32 = lhs.toFloat(f32, pt) - rhs.toFloat(f32, pt) }, | |
| 2874 | 64 => .{ .f64 = lhs.toFloat(f64, pt) - rhs.toFloat(f64, pt) }, | |
| 2875 | 80 => .{ .f80 = lhs.toFloat(f80, pt) - rhs.toFloat(f80, pt) }, | |
| 2876 | 128 => .{ .f128 = lhs.toFloat(f128, pt) - rhs.toFloat(f128, pt) }, | |
| 2924 | 16 => .{ .f16 = lhs.toFloat(f16, zcu) - rhs.toFloat(f16, zcu) }, | |
| 2925 | 32 => .{ .f32 = lhs.toFloat(f32, zcu) - rhs.toFloat(f32, zcu) }, | |
| 2926 | 64 => .{ .f64 = lhs.toFloat(f64, zcu) - rhs.toFloat(f64, zcu) }, | |
| 2927 | 80 => .{ .f80 = lhs.toFloat(f80, zcu) - rhs.toFloat(f80, zcu) }, | |
| 2928 | 128 => .{ .f128 = lhs.toFloat(f128, zcu) - rhs.toFloat(f128, zcu) }, | |
| 2877 | 2929 | else => unreachable, |
| 2878 | 2930 | }; |
| 2879 | 2931 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2911,13 +2963,14 @@ pub fn floatDivScalar( |
| 2911 | 2963 | float_type: Type, |
| 2912 | 2964 | pt: Zcu.PerThread, |
| 2913 | 2965 | ) !Value { |
| 2914 | const target = pt.zcu.getTarget(); | |
| 2966 | const zcu = pt.zcu; | |
| 2967 | const target = zcu.getTarget(); | |
| 2915 | 2968 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2916 | 16 => .{ .f16 = lhs.toFloat(f16, pt) / rhs.toFloat(f16, pt) }, | |
| 2917 | 32 => .{ .f32 = lhs.toFloat(f32, pt) / rhs.toFloat(f32, pt) }, | |
| 2918 | 64 => .{ .f64 = lhs.toFloat(f64, pt) / rhs.toFloat(f64, pt) }, | |
| 2919 | 80 => .{ .f80 = lhs.toFloat(f80, pt) / rhs.toFloat(f80, pt) }, | |
| 2920 | 128 => .{ .f128 = lhs.toFloat(f128, pt) / rhs.toFloat(f128, pt) }, | |
| 2969 | 16 => .{ .f16 = lhs.toFloat(f16, zcu) / rhs.toFloat(f16, zcu) }, | |
| 2970 | 32 => .{ .f32 = lhs.toFloat(f32, zcu) / rhs.toFloat(f32, zcu) }, | |
| 2971 | 64 => .{ .f64 = lhs.toFloat(f64, zcu) / rhs.toFloat(f64, zcu) }, | |
| 2972 | 80 => .{ .f80 = lhs.toFloat(f80, zcu) / rhs.toFloat(f80, zcu) }, | |
| 2973 | 128 => .{ .f128 = lhs.toFloat(f128, zcu) / rhs.toFloat(f128, zcu) }, | |
| 2921 | 2974 | else => unreachable, |
| 2922 | 2975 | }; |
| 2923 | 2976 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2955,13 +3008,14 @@ pub fn floatDivFloorScalar( |
| 2955 | 3008 | float_type: Type, |
| 2956 | 3009 | pt: Zcu.PerThread, |
| 2957 | 3010 | ) !Value { |
| 2958 | const target = pt.zcu.getTarget(); | |
| 3011 | const zcu = pt.zcu; | |
| 3012 | const target = zcu.getTarget(); | |
| 2959 | 3013 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 2960 | 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, | |
| 2961 | 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, | |
| 2962 | 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, | |
| 2963 | 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, | |
| 2964 | 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, | |
| 3014 | 16 => .{ .f16 = @divFloor(lhs.toFloat(f16, zcu), rhs.toFloat(f16, zcu)) }, | |
| 3015 | 32 => .{ .f32 = @divFloor(lhs.toFloat(f32, zcu), rhs.toFloat(f32, zcu)) }, | |
| 3016 | 64 => .{ .f64 = @divFloor(lhs.toFloat(f64, zcu), rhs.toFloat(f64, zcu)) }, | |
| 3017 | 80 => .{ .f80 = @divFloor(lhs.toFloat(f80, zcu), rhs.toFloat(f80, zcu)) }, | |
| 3018 | 128 => .{ .f128 = @divFloor(lhs.toFloat(f128, zcu), rhs.toFloat(f128, zcu)) }, | |
| 2965 | 3019 | else => unreachable, |
| 2966 | 3020 | }; |
| 2967 | 3021 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -2999,13 +3053,14 @@ pub fn floatDivTruncScalar( |
| 2999 | 3053 | float_type: Type, |
| 3000 | 3054 | pt: Zcu.PerThread, |
| 3001 | 3055 | ) !Value { |
| 3002 | const target = pt.zcu.getTarget(); | |
| 3056 | const zcu = pt.zcu; | |
| 3057 | const target = zcu.getTarget(); | |
| 3003 | 3058 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3004 | 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, pt), rhs.toFloat(f16, pt)) }, | |
| 3005 | 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, pt), rhs.toFloat(f32, pt)) }, | |
| 3006 | 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, pt), rhs.toFloat(f64, pt)) }, | |
| 3007 | 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, pt), rhs.toFloat(f80, pt)) }, | |
| 3008 | 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, pt), rhs.toFloat(f128, pt)) }, | |
| 3059 | 16 => .{ .f16 = @divTrunc(lhs.toFloat(f16, zcu), rhs.toFloat(f16, zcu)) }, | |
| 3060 | 32 => .{ .f32 = @divTrunc(lhs.toFloat(f32, zcu), rhs.toFloat(f32, zcu)) }, | |
| 3061 | 64 => .{ .f64 = @divTrunc(lhs.toFloat(f64, zcu), rhs.toFloat(f64, zcu)) }, | |
| 3062 | 80 => .{ .f80 = @divTrunc(lhs.toFloat(f80, zcu), rhs.toFloat(f80, zcu)) }, | |
| 3063 | 128 => .{ .f128 = @divTrunc(lhs.toFloat(f128, zcu), rhs.toFloat(f128, zcu)) }, | |
| 3009 | 3064 | else => unreachable, |
| 3010 | 3065 | }; |
| 3011 | 3066 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3021,10 +3076,10 @@ pub fn floatMul( |
| 3021 | 3076 | arena: Allocator, |
| 3022 | 3077 | pt: Zcu.PerThread, |
| 3023 | 3078 | ) !Value { |
| 3024 | const mod = pt.zcu; | |
| 3025 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3026 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3027 | const scalar_ty = float_type.scalarType(mod); | |
| 3079 | const zcu = pt.zcu; | |
| 3080 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3081 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3082 | const scalar_ty = float_type.scalarType(zcu); | |
| 3028 | 3083 | for (result_data, 0..) |*scalar, i| { |
| 3029 | 3084 | const lhs_elem = try lhs.elemValue(pt, i); |
| 3030 | 3085 | const rhs_elem = try rhs.elemValue(pt, i); |
| ... | ... | @@ -3044,14 +3099,14 @@ pub fn floatMulScalar( |
| 3044 | 3099 | float_type: Type, |
| 3045 | 3100 | pt: Zcu.PerThread, |
| 3046 | 3101 | ) !Value { |
| 3047 | const mod = pt.zcu; | |
| 3048 | const target = mod.getTarget(); | |
| 3102 | const zcu = pt.zcu; | |
| 3103 | const target = zcu.getTarget(); | |
| 3049 | 3104 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3050 | 16 => .{ .f16 = lhs.toFloat(f16, pt) * rhs.toFloat(f16, pt) }, | |
| 3051 | 32 => .{ .f32 = lhs.toFloat(f32, pt) * rhs.toFloat(f32, pt) }, | |
| 3052 | 64 => .{ .f64 = lhs.toFloat(f64, pt) * rhs.toFloat(f64, pt) }, | |
| 3053 | 80 => .{ .f80 = lhs.toFloat(f80, pt) * rhs.toFloat(f80, pt) }, | |
| 3054 | 128 => .{ .f128 = lhs.toFloat(f128, pt) * rhs.toFloat(f128, pt) }, | |
| 3105 | 16 => .{ .f16 = lhs.toFloat(f16, zcu) * rhs.toFloat(f16, zcu) }, | |
| 3106 | 32 => .{ .f32 = lhs.toFloat(f32, zcu) * rhs.toFloat(f32, zcu) }, | |
| 3107 | 64 => .{ .f64 = lhs.toFloat(f64, zcu) * rhs.toFloat(f64, zcu) }, | |
| 3108 | 80 => .{ .f80 = lhs.toFloat(f80, zcu) * rhs.toFloat(f80, zcu) }, | |
| 3109 | 128 => .{ .f128 = lhs.toFloat(f128, zcu) * rhs.toFloat(f128, zcu) }, | |
| 3055 | 3110 | else => unreachable, |
| 3056 | 3111 | }; |
| 3057 | 3112 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3077,14 +3132,14 @@ pub fn sqrt(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) ! |
| 3077 | 3132 | } |
| 3078 | 3133 | |
| 3079 | 3134 | pub fn sqrtScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3080 | const mod = pt.zcu; | |
| 3081 | const target = mod.getTarget(); | |
| 3135 | const zcu = pt.zcu; | |
| 3136 | const target = zcu.getTarget(); | |
| 3082 | 3137 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3083 | 16 => .{ .f16 = @sqrt(val.toFloat(f16, pt)) }, | |
| 3084 | 32 => .{ .f32 = @sqrt(val.toFloat(f32, pt)) }, | |
| 3085 | 64 => .{ .f64 = @sqrt(val.toFloat(f64, pt)) }, | |
| 3086 | 80 => .{ .f80 = @sqrt(val.toFloat(f80, pt)) }, | |
| 3087 | 128 => .{ .f128 = @sqrt(val.toFloat(f128, pt)) }, | |
| 3138 | 16 => .{ .f16 = @sqrt(val.toFloat(f16, zcu)) }, | |
| 3139 | 32 => .{ .f32 = @sqrt(val.toFloat(f32, zcu)) }, | |
| 3140 | 64 => .{ .f64 = @sqrt(val.toFloat(f64, zcu)) }, | |
| 3141 | 80 => .{ .f80 = @sqrt(val.toFloat(f80, zcu)) }, | |
| 3142 | 128 => .{ .f128 = @sqrt(val.toFloat(f128, zcu)) }, | |
| 3088 | 3143 | else => unreachable, |
| 3089 | 3144 | }; |
| 3090 | 3145 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3094,10 +3149,10 @@ pub fn sqrtScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Err |
| 3094 | 3149 | } |
| 3095 | 3150 | |
| 3096 | 3151 | pub fn sin(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3097 | const mod = pt.zcu; | |
| 3098 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3099 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3100 | const scalar_ty = float_type.scalarType(mod); | |
| 3152 | const zcu = pt.zcu; | |
| 3153 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3154 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3155 | const scalar_ty = float_type.scalarType(zcu); | |
| 3101 | 3156 | for (result_data, 0..) |*scalar, i| { |
| 3102 | 3157 | const elem_val = try val.elemValue(pt, i); |
| 3103 | 3158 | scalar.* = (try sinScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3111,14 +3166,14 @@ pub fn sin(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !V |
| 3111 | 3166 | } |
| 3112 | 3167 | |
| 3113 | 3168 | pub fn sinScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3114 | const mod = pt.zcu; | |
| 3115 | const target = mod.getTarget(); | |
| 3169 | const zcu = pt.zcu; | |
| 3170 | const target = zcu.getTarget(); | |
| 3116 | 3171 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3117 | 16 => .{ .f16 = @sin(val.toFloat(f16, pt)) }, | |
| 3118 | 32 => .{ .f32 = @sin(val.toFloat(f32, pt)) }, | |
| 3119 | 64 => .{ .f64 = @sin(val.toFloat(f64, pt)) }, | |
| 3120 | 80 => .{ .f80 = @sin(val.toFloat(f80, pt)) }, | |
| 3121 | 128 => .{ .f128 = @sin(val.toFloat(f128, pt)) }, | |
| 3172 | 16 => .{ .f16 = @sin(val.toFloat(f16, zcu)) }, | |
| 3173 | 32 => .{ .f32 = @sin(val.toFloat(f32, zcu)) }, | |
| 3174 | 64 => .{ .f64 = @sin(val.toFloat(f64, zcu)) }, | |
| 3175 | 80 => .{ .f80 = @sin(val.toFloat(f80, zcu)) }, | |
| 3176 | 128 => .{ .f128 = @sin(val.toFloat(f128, zcu)) }, | |
| 3122 | 3177 | else => unreachable, |
| 3123 | 3178 | }; |
| 3124 | 3179 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3128,10 +3183,10 @@ pub fn sinScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Erro |
| 3128 | 3183 | } |
| 3129 | 3184 | |
| 3130 | 3185 | pub fn cos(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3131 | const mod = pt.zcu; | |
| 3132 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3133 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3134 | const scalar_ty = float_type.scalarType(mod); | |
| 3186 | const zcu = pt.zcu; | |
| 3187 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3188 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3189 | const scalar_ty = float_type.scalarType(zcu); | |
| 3135 | 3190 | for (result_data, 0..) |*scalar, i| { |
| 3136 | 3191 | const elem_val = try val.elemValue(pt, i); |
| 3137 | 3192 | scalar.* = (try cosScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3145,14 +3200,14 @@ pub fn cos(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !V |
| 3145 | 3200 | } |
| 3146 | 3201 | |
| 3147 | 3202 | pub fn cosScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3148 | const mod = pt.zcu; | |
| 3149 | const target = mod.getTarget(); | |
| 3203 | const zcu = pt.zcu; | |
| 3204 | const target = zcu.getTarget(); | |
| 3150 | 3205 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3151 | 16 => .{ .f16 = @cos(val.toFloat(f16, pt)) }, | |
| 3152 | 32 => .{ .f32 = @cos(val.toFloat(f32, pt)) }, | |
| 3153 | 64 => .{ .f64 = @cos(val.toFloat(f64, pt)) }, | |
| 3154 | 80 => .{ .f80 = @cos(val.toFloat(f80, pt)) }, | |
| 3155 | 128 => .{ .f128 = @cos(val.toFloat(f128, pt)) }, | |
| 3206 | 16 => .{ .f16 = @cos(val.toFloat(f16, zcu)) }, | |
| 3207 | 32 => .{ .f32 = @cos(val.toFloat(f32, zcu)) }, | |
| 3208 | 64 => .{ .f64 = @cos(val.toFloat(f64, zcu)) }, | |
| 3209 | 80 => .{ .f80 = @cos(val.toFloat(f80, zcu)) }, | |
| 3210 | 128 => .{ .f128 = @cos(val.toFloat(f128, zcu)) }, | |
| 3156 | 3211 | else => unreachable, |
| 3157 | 3212 | }; |
| 3158 | 3213 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3162,10 +3217,10 @@ pub fn cosScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Erro |
| 3162 | 3217 | } |
| 3163 | 3218 | |
| 3164 | 3219 | pub fn tan(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3165 | const mod = pt.zcu; | |
| 3166 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3167 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3168 | const scalar_ty = float_type.scalarType(mod); | |
| 3220 | const zcu = pt.zcu; | |
| 3221 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3222 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3223 | const scalar_ty = float_type.scalarType(zcu); | |
| 3169 | 3224 | for (result_data, 0..) |*scalar, i| { |
| 3170 | 3225 | const elem_val = try val.elemValue(pt, i); |
| 3171 | 3226 | scalar.* = (try tanScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3179,14 +3234,14 @@ pub fn tan(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !V |
| 3179 | 3234 | } |
| 3180 | 3235 | |
| 3181 | 3236 | pub fn tanScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3182 | const mod = pt.zcu; | |
| 3183 | const target = mod.getTarget(); | |
| 3237 | const zcu = pt.zcu; | |
| 3238 | const target = zcu.getTarget(); | |
| 3184 | 3239 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3185 | 16 => .{ .f16 = @tan(val.toFloat(f16, pt)) }, | |
| 3186 | 32 => .{ .f32 = @tan(val.toFloat(f32, pt)) }, | |
| 3187 | 64 => .{ .f64 = @tan(val.toFloat(f64, pt)) }, | |
| 3188 | 80 => .{ .f80 = @tan(val.toFloat(f80, pt)) }, | |
| 3189 | 128 => .{ .f128 = @tan(val.toFloat(f128, pt)) }, | |
| 3240 | 16 => .{ .f16 = @tan(val.toFloat(f16, zcu)) }, | |
| 3241 | 32 => .{ .f32 = @tan(val.toFloat(f32, zcu)) }, | |
| 3242 | 64 => .{ .f64 = @tan(val.toFloat(f64, zcu)) }, | |
| 3243 | 80 => .{ .f80 = @tan(val.toFloat(f80, zcu)) }, | |
| 3244 | 128 => .{ .f128 = @tan(val.toFloat(f128, zcu)) }, | |
| 3190 | 3245 | else => unreachable, |
| 3191 | 3246 | }; |
| 3192 | 3247 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3196,10 +3251,10 @@ pub fn tanScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Erro |
| 3196 | 3251 | } |
| 3197 | 3252 | |
| 3198 | 3253 | pub fn exp(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3199 | const mod = pt.zcu; | |
| 3200 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3201 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3202 | const scalar_ty = float_type.scalarType(mod); | |
| 3254 | const zcu = pt.zcu; | |
| 3255 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3256 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3257 | const scalar_ty = float_type.scalarType(zcu); | |
| 3203 | 3258 | for (result_data, 0..) |*scalar, i| { |
| 3204 | 3259 | const elem_val = try val.elemValue(pt, i); |
| 3205 | 3260 | scalar.* = (try expScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3213,14 +3268,14 @@ pub fn exp(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !V |
| 3213 | 3268 | } |
| 3214 | 3269 | |
| 3215 | 3270 | pub fn expScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3216 | const mod = pt.zcu; | |
| 3217 | const target = mod.getTarget(); | |
| 3271 | const zcu = pt.zcu; | |
| 3272 | const target = zcu.getTarget(); | |
| 3218 | 3273 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3219 | 16 => .{ .f16 = @exp(val.toFloat(f16, pt)) }, | |
| 3220 | 32 => .{ .f32 = @exp(val.toFloat(f32, pt)) }, | |
| 3221 | 64 => .{ .f64 = @exp(val.toFloat(f64, pt)) }, | |
| 3222 | 80 => .{ .f80 = @exp(val.toFloat(f80, pt)) }, | |
| 3223 | 128 => .{ .f128 = @exp(val.toFloat(f128, pt)) }, | |
| 3274 | 16 => .{ .f16 = @exp(val.toFloat(f16, zcu)) }, | |
| 3275 | 32 => .{ .f32 = @exp(val.toFloat(f32, zcu)) }, | |
| 3276 | 64 => .{ .f64 = @exp(val.toFloat(f64, zcu)) }, | |
| 3277 | 80 => .{ .f80 = @exp(val.toFloat(f80, zcu)) }, | |
| 3278 | 128 => .{ .f128 = @exp(val.toFloat(f128, zcu)) }, | |
| 3224 | 3279 | else => unreachable, |
| 3225 | 3280 | }; |
| 3226 | 3281 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3230,10 +3285,10 @@ pub fn expScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Erro |
| 3230 | 3285 | } |
| 3231 | 3286 | |
| 3232 | 3287 | pub fn exp2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3233 | const mod = pt.zcu; | |
| 3234 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3235 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3236 | const scalar_ty = float_type.scalarType(mod); | |
| 3288 | const zcu = pt.zcu; | |
| 3289 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3290 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3291 | const scalar_ty = float_type.scalarType(zcu); | |
| 3237 | 3292 | for (result_data, 0..) |*scalar, i| { |
| 3238 | 3293 | const elem_val = try val.elemValue(pt, i); |
| 3239 | 3294 | scalar.* = (try exp2Scalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3247,14 +3302,14 @@ pub fn exp2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) ! |
| 3247 | 3302 | } |
| 3248 | 3303 | |
| 3249 | 3304 | pub fn exp2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3250 | const mod = pt.zcu; | |
| 3251 | const target = mod.getTarget(); | |
| 3305 | const zcu = pt.zcu; | |
| 3306 | const target = zcu.getTarget(); | |
| 3252 | 3307 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3253 | 16 => .{ .f16 = @exp2(val.toFloat(f16, pt)) }, | |
| 3254 | 32 => .{ .f32 = @exp2(val.toFloat(f32, pt)) }, | |
| 3255 | 64 => .{ .f64 = @exp2(val.toFloat(f64, pt)) }, | |
| 3256 | 80 => .{ .f80 = @exp2(val.toFloat(f80, pt)) }, | |
| 3257 | 128 => .{ .f128 = @exp2(val.toFloat(f128, pt)) }, | |
| 3308 | 16 => .{ .f16 = @exp2(val.toFloat(f16, zcu)) }, | |
| 3309 | 32 => .{ .f32 = @exp2(val.toFloat(f32, zcu)) }, | |
| 3310 | 64 => .{ .f64 = @exp2(val.toFloat(f64, zcu)) }, | |
| 3311 | 80 => .{ .f80 = @exp2(val.toFloat(f80, zcu)) }, | |
| 3312 | 128 => .{ .f128 = @exp2(val.toFloat(f128, zcu)) }, | |
| 3258 | 3313 | else => unreachable, |
| 3259 | 3314 | }; |
| 3260 | 3315 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3264,10 +3319,10 @@ pub fn exp2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Err |
| 3264 | 3319 | } |
| 3265 | 3320 | |
| 3266 | 3321 | pub fn log(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3267 | const mod = pt.zcu; | |
| 3268 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3269 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3270 | const scalar_ty = float_type.scalarType(mod); | |
| 3322 | const zcu = pt.zcu; | |
| 3323 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3324 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3325 | const scalar_ty = float_type.scalarType(zcu); | |
| 3271 | 3326 | for (result_data, 0..) |*scalar, i| { |
| 3272 | 3327 | const elem_val = try val.elemValue(pt, i); |
| 3273 | 3328 | scalar.* = (try logScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3281,14 +3336,14 @@ pub fn log(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !V |
| 3281 | 3336 | } |
| 3282 | 3337 | |
| 3283 | 3338 | pub fn logScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3284 | const mod = pt.zcu; | |
| 3285 | const target = mod.getTarget(); | |
| 3339 | const zcu = pt.zcu; | |
| 3340 | const target = zcu.getTarget(); | |
| 3286 | 3341 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3287 | 16 => .{ .f16 = @log(val.toFloat(f16, pt)) }, | |
| 3288 | 32 => .{ .f32 = @log(val.toFloat(f32, pt)) }, | |
| 3289 | 64 => .{ .f64 = @log(val.toFloat(f64, pt)) }, | |
| 3290 | 80 => .{ .f80 = @log(val.toFloat(f80, pt)) }, | |
| 3291 | 128 => .{ .f128 = @log(val.toFloat(f128, pt)) }, | |
| 3342 | 16 => .{ .f16 = @log(val.toFloat(f16, zcu)) }, | |
| 3343 | 32 => .{ .f32 = @log(val.toFloat(f32, zcu)) }, | |
| 3344 | 64 => .{ .f64 = @log(val.toFloat(f64, zcu)) }, | |
| 3345 | 80 => .{ .f80 = @log(val.toFloat(f80, zcu)) }, | |
| 3346 | 128 => .{ .f128 = @log(val.toFloat(f128, zcu)) }, | |
| 3292 | 3347 | else => unreachable, |
| 3293 | 3348 | }; |
| 3294 | 3349 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3298,10 +3353,10 @@ pub fn logScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Erro |
| 3298 | 3353 | } |
| 3299 | 3354 | |
| 3300 | 3355 | pub fn log2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3301 | const mod = pt.zcu; | |
| 3302 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3303 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3304 | const scalar_ty = float_type.scalarType(mod); | |
| 3356 | const zcu = pt.zcu; | |
| 3357 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3358 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3359 | const scalar_ty = float_type.scalarType(zcu); | |
| 3305 | 3360 | for (result_data, 0..) |*scalar, i| { |
| 3306 | 3361 | const elem_val = try val.elemValue(pt, i); |
| 3307 | 3362 | scalar.* = (try log2Scalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3315,14 +3370,14 @@ pub fn log2(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) ! |
| 3315 | 3370 | } |
| 3316 | 3371 | |
| 3317 | 3372 | pub fn log2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3318 | const mod = pt.zcu; | |
| 3319 | const target = mod.getTarget(); | |
| 3373 | const zcu = pt.zcu; | |
| 3374 | const target = zcu.getTarget(); | |
| 3320 | 3375 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3321 | 16 => .{ .f16 = @log2(val.toFloat(f16, pt)) }, | |
| 3322 | 32 => .{ .f32 = @log2(val.toFloat(f32, pt)) }, | |
| 3323 | 64 => .{ .f64 = @log2(val.toFloat(f64, pt)) }, | |
| 3324 | 80 => .{ .f80 = @log2(val.toFloat(f80, pt)) }, | |
| 3325 | 128 => .{ .f128 = @log2(val.toFloat(f128, pt)) }, | |
| 3376 | 16 => .{ .f16 = @log2(val.toFloat(f16, zcu)) }, | |
| 3377 | 32 => .{ .f32 = @log2(val.toFloat(f32, zcu)) }, | |
| 3378 | 64 => .{ .f64 = @log2(val.toFloat(f64, zcu)) }, | |
| 3379 | 80 => .{ .f80 = @log2(val.toFloat(f80, zcu)) }, | |
| 3380 | 128 => .{ .f128 = @log2(val.toFloat(f128, zcu)) }, | |
| 3326 | 3381 | else => unreachable, |
| 3327 | 3382 | }; |
| 3328 | 3383 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3332,10 +3387,10 @@ pub fn log2Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Err |
| 3332 | 3387 | } |
| 3333 | 3388 | |
| 3334 | 3389 | pub fn log10(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3335 | const mod = pt.zcu; | |
| 3336 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3337 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3338 | const scalar_ty = float_type.scalarType(mod); | |
| 3390 | const zcu = pt.zcu; | |
| 3391 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3392 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3393 | const scalar_ty = float_type.scalarType(zcu); | |
| 3339 | 3394 | for (result_data, 0..) |*scalar, i| { |
| 3340 | 3395 | const elem_val = try val.elemValue(pt, i); |
| 3341 | 3396 | scalar.* = (try log10Scalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3349,14 +3404,14 @@ pub fn log10(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) |
| 3349 | 3404 | } |
| 3350 | 3405 | |
| 3351 | 3406 | pub fn log10Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3352 | const mod = pt.zcu; | |
| 3353 | const target = mod.getTarget(); | |
| 3407 | const zcu = pt.zcu; | |
| 3408 | const target = zcu.getTarget(); | |
| 3354 | 3409 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3355 | 16 => .{ .f16 = @log10(val.toFloat(f16, pt)) }, | |
| 3356 | 32 => .{ .f32 = @log10(val.toFloat(f32, pt)) }, | |
| 3357 | 64 => .{ .f64 = @log10(val.toFloat(f64, pt)) }, | |
| 3358 | 80 => .{ .f80 = @log10(val.toFloat(f80, pt)) }, | |
| 3359 | 128 => .{ .f128 = @log10(val.toFloat(f128, pt)) }, | |
| 3410 | 16 => .{ .f16 = @log10(val.toFloat(f16, zcu)) }, | |
| 3411 | 32 => .{ .f32 = @log10(val.toFloat(f32, zcu)) }, | |
| 3412 | 64 => .{ .f64 = @log10(val.toFloat(f64, zcu)) }, | |
| 3413 | 80 => .{ .f80 = @log10(val.toFloat(f80, zcu)) }, | |
| 3414 | 128 => .{ .f128 = @log10(val.toFloat(f128, zcu)) }, | |
| 3360 | 3415 | else => unreachable, |
| 3361 | 3416 | }; |
| 3362 | 3417 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3366,10 +3421,10 @@ pub fn log10Scalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Er |
| 3366 | 3421 | } |
| 3367 | 3422 | |
| 3368 | 3423 | pub fn abs(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3369 | const mod = pt.zcu; | |
| 3370 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 3371 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(mod)); | |
| 3372 | const scalar_ty = ty.scalarType(mod); | |
| 3424 | const zcu = pt.zcu; | |
| 3425 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 3426 | const result_data = try arena.alloc(InternPool.Index, ty.vectorLen(zcu)); | |
| 3427 | const scalar_ty = ty.scalarType(zcu); | |
| 3373 | 3428 | for (result_data, 0..) |*scalar, i| { |
| 3374 | 3429 | const elem_val = try val.elemValue(pt, i); |
| 3375 | 3430 | scalar.* = (try absScalar(elem_val, scalar_ty, pt, arena)).toIntern(); |
| ... | ... | @@ -3383,30 +3438,30 @@ pub fn abs(val: Value, ty: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3383 | 3438 | } |
| 3384 | 3439 | |
| 3385 | 3440 | pub fn absScalar(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) Allocator.Error!Value { |
| 3386 | const mod = pt.zcu; | |
| 3387 | switch (ty.zigTypeTag(mod)) { | |
| 3441 | const zcu = pt.zcu; | |
| 3442 | switch (ty.zigTypeTag(zcu)) { | |
| 3388 | 3443 | .Int => { |
| 3389 | 3444 | var buffer: Value.BigIntSpace = undefined; |
| 3390 | var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena); | |
| 3445 | var operand_bigint = try val.toBigInt(&buffer, zcu).toManaged(arena); | |
| 3391 | 3446 | operand_bigint.abs(); |
| 3392 | 3447 | |
| 3393 | 3448 | return pt.intValue_big(try ty.toUnsigned(pt), operand_bigint.toConst()); |
| 3394 | 3449 | }, |
| 3395 | 3450 | .ComptimeInt => { |
| 3396 | 3451 | var buffer: Value.BigIntSpace = undefined; |
| 3397 | var operand_bigint = try val.toBigInt(&buffer, pt).toManaged(arena); | |
| 3452 | var operand_bigint = try val.toBigInt(&buffer, zcu).toManaged(arena); | |
| 3398 | 3453 | operand_bigint.abs(); |
| 3399 | 3454 | |
| 3400 | 3455 | return pt.intValue_big(ty, operand_bigint.toConst()); |
| 3401 | 3456 | }, |
| 3402 | 3457 | .ComptimeFloat, .Float => { |
| 3403 | const target = mod.getTarget(); | |
| 3458 | const target = zcu.getTarget(); | |
| 3404 | 3459 | const storage: InternPool.Key.Float.Storage = switch (ty.floatBits(target)) { |
| 3405 | 16 => .{ .f16 = @abs(val.toFloat(f16, pt)) }, | |
| 3406 | 32 => .{ .f32 = @abs(val.toFloat(f32, pt)) }, | |
| 3407 | 64 => .{ .f64 = @abs(val.toFloat(f64, pt)) }, | |
| 3408 | 80 => .{ .f80 = @abs(val.toFloat(f80, pt)) }, | |
| 3409 | 128 => .{ .f128 = @abs(val.toFloat(f128, pt)) }, | |
| 3460 | 16 => .{ .f16 = @abs(val.toFloat(f16, zcu)) }, | |
| 3461 | 32 => .{ .f32 = @abs(val.toFloat(f32, zcu)) }, | |
| 3462 | 64 => .{ .f64 = @abs(val.toFloat(f64, zcu)) }, | |
| 3463 | 80 => .{ .f80 = @abs(val.toFloat(f80, zcu)) }, | |
| 3464 | 128 => .{ .f128 = @abs(val.toFloat(f128, zcu)) }, | |
| 3410 | 3465 | else => unreachable, |
| 3411 | 3466 | }; |
| 3412 | 3467 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3419,10 +3474,10 @@ pub fn absScalar(val: Value, ty: Type, pt: Zcu.PerThread, arena: Allocator) Allo |
| 3419 | 3474 | } |
| 3420 | 3475 | |
| 3421 | 3476 | pub fn floor(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3422 | const mod = pt.zcu; | |
| 3423 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3424 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3425 | const scalar_ty = float_type.scalarType(mod); | |
| 3477 | const zcu = pt.zcu; | |
| 3478 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3479 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3480 | const scalar_ty = float_type.scalarType(zcu); | |
| 3426 | 3481 | for (result_data, 0..) |*scalar, i| { |
| 3427 | 3482 | const elem_val = try val.elemValue(pt, i); |
| 3428 | 3483 | scalar.* = (try floorScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3436,14 +3491,14 @@ pub fn floor(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) |
| 3436 | 3491 | } |
| 3437 | 3492 | |
| 3438 | 3493 | pub fn floorScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3439 | const mod = pt.zcu; | |
| 3440 | const target = mod.getTarget(); | |
| 3494 | const zcu = pt.zcu; | |
| 3495 | const target = zcu.getTarget(); | |
| 3441 | 3496 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3442 | 16 => .{ .f16 = @floor(val.toFloat(f16, pt)) }, | |
| 3443 | 32 => .{ .f32 = @floor(val.toFloat(f32, pt)) }, | |
| 3444 | 64 => .{ .f64 = @floor(val.toFloat(f64, pt)) }, | |
| 3445 | 80 => .{ .f80 = @floor(val.toFloat(f80, pt)) }, | |
| 3446 | 128 => .{ .f128 = @floor(val.toFloat(f128, pt)) }, | |
| 3497 | 16 => .{ .f16 = @floor(val.toFloat(f16, zcu)) }, | |
| 3498 | 32 => .{ .f32 = @floor(val.toFloat(f32, zcu)) }, | |
| 3499 | 64 => .{ .f64 = @floor(val.toFloat(f64, zcu)) }, | |
| 3500 | 80 => .{ .f80 = @floor(val.toFloat(f80, zcu)) }, | |
| 3501 | 128 => .{ .f128 = @floor(val.toFloat(f128, zcu)) }, | |
| 3447 | 3502 | else => unreachable, |
| 3448 | 3503 | }; |
| 3449 | 3504 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3453,10 +3508,10 @@ pub fn floorScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Er |
| 3453 | 3508 | } |
| 3454 | 3509 | |
| 3455 | 3510 | pub fn ceil(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3456 | const mod = pt.zcu; | |
| 3457 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3458 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3459 | const scalar_ty = float_type.scalarType(mod); | |
| 3511 | const zcu = pt.zcu; | |
| 3512 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3513 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3514 | const scalar_ty = float_type.scalarType(zcu); | |
| 3460 | 3515 | for (result_data, 0..) |*scalar, i| { |
| 3461 | 3516 | const elem_val = try val.elemValue(pt, i); |
| 3462 | 3517 | scalar.* = (try ceilScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3470,14 +3525,14 @@ pub fn ceil(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) ! |
| 3470 | 3525 | } |
| 3471 | 3526 | |
| 3472 | 3527 | pub fn ceilScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3473 | const mod = pt.zcu; | |
| 3474 | const target = mod.getTarget(); | |
| 3528 | const zcu = pt.zcu; | |
| 3529 | const target = zcu.getTarget(); | |
| 3475 | 3530 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3476 | 16 => .{ .f16 = @ceil(val.toFloat(f16, pt)) }, | |
| 3477 | 32 => .{ .f32 = @ceil(val.toFloat(f32, pt)) }, | |
| 3478 | 64 => .{ .f64 = @ceil(val.toFloat(f64, pt)) }, | |
| 3479 | 80 => .{ .f80 = @ceil(val.toFloat(f80, pt)) }, | |
| 3480 | 128 => .{ .f128 = @ceil(val.toFloat(f128, pt)) }, | |
| 3531 | 16 => .{ .f16 = @ceil(val.toFloat(f16, zcu)) }, | |
| 3532 | 32 => .{ .f32 = @ceil(val.toFloat(f32, zcu)) }, | |
| 3533 | 64 => .{ .f64 = @ceil(val.toFloat(f64, zcu)) }, | |
| 3534 | 80 => .{ .f80 = @ceil(val.toFloat(f80, zcu)) }, | |
| 3535 | 128 => .{ .f128 = @ceil(val.toFloat(f128, zcu)) }, | |
| 3481 | 3536 | else => unreachable, |
| 3482 | 3537 | }; |
| 3483 | 3538 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3487,10 +3542,10 @@ pub fn ceilScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Err |
| 3487 | 3542 | } |
| 3488 | 3543 | |
| 3489 | 3544 | pub fn round(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3490 | const mod = pt.zcu; | |
| 3491 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3492 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3493 | const scalar_ty = float_type.scalarType(mod); | |
| 3545 | const zcu = pt.zcu; | |
| 3546 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3547 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3548 | const scalar_ty = float_type.scalarType(zcu); | |
| 3494 | 3549 | for (result_data, 0..) |*scalar, i| { |
| 3495 | 3550 | const elem_val = try val.elemValue(pt, i); |
| 3496 | 3551 | scalar.* = (try roundScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3504,14 +3559,14 @@ pub fn round(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) |
| 3504 | 3559 | } |
| 3505 | 3560 | |
| 3506 | 3561 | pub fn roundScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3507 | const mod = pt.zcu; | |
| 3508 | const target = mod.getTarget(); | |
| 3562 | const zcu = pt.zcu; | |
| 3563 | const target = zcu.getTarget(); | |
| 3509 | 3564 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3510 | 16 => .{ .f16 = @round(val.toFloat(f16, pt)) }, | |
| 3511 | 32 => .{ .f32 = @round(val.toFloat(f32, pt)) }, | |
| 3512 | 64 => .{ .f64 = @round(val.toFloat(f64, pt)) }, | |
| 3513 | 80 => .{ .f80 = @round(val.toFloat(f80, pt)) }, | |
| 3514 | 128 => .{ .f128 = @round(val.toFloat(f128, pt)) }, | |
| 3565 | 16 => .{ .f16 = @round(val.toFloat(f16, zcu)) }, | |
| 3566 | 32 => .{ .f32 = @round(val.toFloat(f32, zcu)) }, | |
| 3567 | 64 => .{ .f64 = @round(val.toFloat(f64, zcu)) }, | |
| 3568 | 80 => .{ .f80 = @round(val.toFloat(f80, zcu)) }, | |
| 3569 | 128 => .{ .f128 = @round(val.toFloat(f128, zcu)) }, | |
| 3515 | 3570 | else => unreachable, |
| 3516 | 3571 | }; |
| 3517 | 3572 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3521,10 +3576,10 @@ pub fn roundScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Er |
| 3521 | 3576 | } |
| 3522 | 3577 | |
| 3523 | 3578 | pub fn trunc(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) !Value { |
| 3524 | const mod = pt.zcu; | |
| 3525 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3526 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3527 | const scalar_ty = float_type.scalarType(mod); | |
| 3579 | const zcu = pt.zcu; | |
| 3580 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3581 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3582 | const scalar_ty = float_type.scalarType(zcu); | |
| 3528 | 3583 | for (result_data, 0..) |*scalar, i| { |
| 3529 | 3584 | const elem_val = try val.elemValue(pt, i); |
| 3530 | 3585 | scalar.* = (try truncScalar(elem_val, scalar_ty, pt)).toIntern(); |
| ... | ... | @@ -3538,14 +3593,14 @@ pub fn trunc(val: Value, float_type: Type, arena: Allocator, pt: Zcu.PerThread) |
| 3538 | 3593 | } |
| 3539 | 3594 | |
| 3540 | 3595 | pub fn truncScalar(val: Value, float_type: Type, pt: Zcu.PerThread) Allocator.Error!Value { |
| 3541 | const mod = pt.zcu; | |
| 3542 | const target = mod.getTarget(); | |
| 3596 | const zcu = pt.zcu; | |
| 3597 | const target = zcu.getTarget(); | |
| 3543 | 3598 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3544 | 16 => .{ .f16 = @trunc(val.toFloat(f16, pt)) }, | |
| 3545 | 32 => .{ .f32 = @trunc(val.toFloat(f32, pt)) }, | |
| 3546 | 64 => .{ .f64 = @trunc(val.toFloat(f64, pt)) }, | |
| 3547 | 80 => .{ .f80 = @trunc(val.toFloat(f80, pt)) }, | |
| 3548 | 128 => .{ .f128 = @trunc(val.toFloat(f128, pt)) }, | |
| 3599 | 16 => .{ .f16 = @trunc(val.toFloat(f16, zcu)) }, | |
| 3600 | 32 => .{ .f32 = @trunc(val.toFloat(f32, zcu)) }, | |
| 3601 | 64 => .{ .f64 = @trunc(val.toFloat(f64, zcu)) }, | |
| 3602 | 80 => .{ .f80 = @trunc(val.toFloat(f80, zcu)) }, | |
| 3603 | 128 => .{ .f128 = @trunc(val.toFloat(f128, zcu)) }, | |
| 3549 | 3604 | else => unreachable, |
| 3550 | 3605 | }; |
| 3551 | 3606 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3562,10 +3617,10 @@ pub fn mulAdd( |
| 3562 | 3617 | arena: Allocator, |
| 3563 | 3618 | pt: Zcu.PerThread, |
| 3564 | 3619 | ) !Value { |
| 3565 | const mod = pt.zcu; | |
| 3566 | if (float_type.zigTypeTag(mod) == .Vector) { | |
| 3567 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(mod)); | |
| 3568 | const scalar_ty = float_type.scalarType(mod); | |
| 3620 | const zcu = pt.zcu; | |
| 3621 | if (float_type.zigTypeTag(zcu) == .Vector) { | |
| 3622 | const result_data = try arena.alloc(InternPool.Index, float_type.vectorLen(zcu)); | |
| 3623 | const scalar_ty = float_type.scalarType(zcu); | |
| 3569 | 3624 | for (result_data, 0..) |*scalar, i| { |
| 3570 | 3625 | const mulend1_elem = try mulend1.elemValue(pt, i); |
| 3571 | 3626 | const mulend2_elem = try mulend2.elemValue(pt, i); |
| ... | ... | @@ -3587,14 +3642,14 @@ pub fn mulAddScalar( |
| 3587 | 3642 | addend: Value, |
| 3588 | 3643 | pt: Zcu.PerThread, |
| 3589 | 3644 | ) Allocator.Error!Value { |
| 3590 | const mod = pt.zcu; | |
| 3591 | const target = mod.getTarget(); | |
| 3645 | const zcu = pt.zcu; | |
| 3646 | const target = zcu.getTarget(); | |
| 3592 | 3647 | const storage: InternPool.Key.Float.Storage = switch (float_type.floatBits(target)) { |
| 3593 | 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, pt), mulend2.toFloat(f16, pt), addend.toFloat(f16, pt)) }, | |
| 3594 | 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, pt), mulend2.toFloat(f32, pt), addend.toFloat(f32, pt)) }, | |
| 3595 | 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, pt), mulend2.toFloat(f64, pt), addend.toFloat(f64, pt)) }, | |
| 3596 | 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, pt), mulend2.toFloat(f80, pt), addend.toFloat(f80, pt)) }, | |
| 3597 | 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, pt), mulend2.toFloat(f128, pt), addend.toFloat(f128, pt)) }, | |
| 3648 | 16 => .{ .f16 = @mulAdd(f16, mulend1.toFloat(f16, zcu), mulend2.toFloat(f16, zcu), addend.toFloat(f16, zcu)) }, | |
| 3649 | 32 => .{ .f32 = @mulAdd(f32, mulend1.toFloat(f32, zcu), mulend2.toFloat(f32, zcu), addend.toFloat(f32, zcu)) }, | |
| 3650 | 64 => .{ .f64 = @mulAdd(f64, mulend1.toFloat(f64, zcu), mulend2.toFloat(f64, zcu), addend.toFloat(f64, zcu)) }, | |
| 3651 | 80 => .{ .f80 = @mulAdd(f80, mulend1.toFloat(f80, zcu), mulend2.toFloat(f80, zcu), addend.toFloat(f80, zcu)) }, | |
| 3652 | 128 => .{ .f128 = @mulAdd(f128, mulend1.toFloat(f128, zcu), mulend2.toFloat(f128, zcu), addend.toFloat(f128, zcu)) }, | |
| 3598 | 3653 | else => unreachable, |
| 3599 | 3654 | }; |
| 3600 | 3655 | return Value.fromInterned(try pt.intern(.{ .float = .{ |
| ... | ... | @@ -3606,10 +3661,11 @@ pub fn mulAddScalar( |
| 3606 | 3661 | /// If the value is represented in-memory as a series of bytes that all |
| 3607 | 3662 | /// have the same value, return that byte value, otherwise null. |
| 3608 | 3663 | pub fn hasRepeatedByteRepr(val: Value, ty: Type, pt: Zcu.PerThread) !?u8 { |
| 3609 | const abi_size = std.math.cast(usize, ty.abiSize(pt)) orelse return null; | |
| 3664 | const zcu = pt.zcu; | |
| 3665 | const abi_size = std.math.cast(usize, ty.abiSize(zcu)) orelse return null; | |
| 3610 | 3666 | assert(abi_size >= 1); |
| 3611 | const byte_buffer = try pt.zcu.gpa.alloc(u8, abi_size); | |
| 3612 | defer pt.zcu.gpa.free(byte_buffer); | |
| 3667 | const byte_buffer = try zcu.gpa.alloc(u8, abi_size); | |
| 3668 | defer zcu.gpa.free(byte_buffer); | |
| 3613 | 3669 | |
| 3614 | 3670 | writeToMemory(val, ty, pt, byte_buffer) catch |err| switch (err) { |
| 3615 | 3671 | error.OutOfMemory => return error.OutOfMemory, |
| ... | ... | @@ -3756,13 +3812,13 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3756 | 3812 | .Struct => field: { |
| 3757 | 3813 | const field_ty = aggregate_ty.structFieldType(field_idx, zcu); |
| 3758 | 3814 | switch (aggregate_ty.containerLayout(zcu)) { |
| 3759 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) }, | |
| 3815 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), .sema, zcu, pt.tid) }, | |
| 3760 | 3816 | .@"extern" => { |
| 3761 | 3817 | // Well-defined layout, so just offset the pointer appropriately. |
| 3762 | const byte_off = aggregate_ty.structFieldOffset(field_idx, pt); | |
| 3818 | const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu); | |
| 3763 | 3819 | const field_align = a: { |
| 3764 | 3820 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { |
| 3765 | break :pa (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar; | |
| 3821 | break :pa try aggregate_ty.abiAlignmentSema(pt); | |
| 3766 | 3822 | } else parent_ptr_info.flags.alignment; |
| 3767 | 3823 | break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off))); |
| 3768 | 3824 | }; |
| ... | ... | @@ -3781,7 +3837,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3781 | 3837 | new.packed_offset = packed_offset; |
| 3782 | 3838 | new.child = field_ty.toIntern(); |
| 3783 | 3839 | if (new.flags.alignment == .none) { |
| 3784 | new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(pt, .sema)).scalar; | |
| 3840 | new.flags.alignment = try aggregate_ty.abiAlignmentSema(pt); | |
| 3785 | 3841 | } |
| 3786 | 3842 | break :info new; |
| 3787 | 3843 | }); |
| ... | ... | @@ -3807,7 +3863,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3807 | 3863 | const union_obj = zcu.typeToUnion(aggregate_ty).?; |
| 3808 | 3864 | const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]); |
| 3809 | 3865 | switch (aggregate_ty.containerLayout(zcu)) { |
| 3810 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), pt, .sema) }, | |
| 3866 | .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), .sema, zcu, pt.tid) }, | |
| 3811 | 3867 | .@"extern" => { |
| 3812 | 3868 | // Point to the same address. |
| 3813 | 3869 | const result_ty = try pt.ptrTypeSema(info: { |
| ... | ... | @@ -3820,17 +3876,17 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3820 | 3876 | .@"packed" => { |
| 3821 | 3877 | // If the field has an ABI size matching its bit size, then we can continue to use a |
| 3822 | 3878 | // non-bit pointer if the parent pointer is also a non-bit pointer. |
| 3823 | if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeAdvanced(pt, .sema)).scalar * 8 == try field_ty.bitSizeAdvanced(pt, .sema)) { | |
| 3879 | if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar * 8 == try field_ty.bitSizeSema(pt)) { | |
| 3824 | 3880 | // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely. |
| 3825 | 3881 | const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) { |
| 3826 | 3882 | .little => 0, |
| 3827 | .big => (try aggregate_ty.abiSizeAdvanced(pt, .sema)).scalar - (try field_ty.abiSizeAdvanced(pt, .sema)).scalar, | |
| 3883 | .big => (try aggregate_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar - (try field_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar, | |
| 3828 | 3884 | }; |
| 3829 | 3885 | const result_ty = try pt.ptrTypeSema(info: { |
| 3830 | 3886 | var new = parent_ptr_info; |
| 3831 | 3887 | new.child = field_ty.toIntern(); |
| 3832 | 3888 | new.flags.alignment = InternPool.Alignment.fromLog2Units( |
| 3833 | @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(pt, .sema)).toByteUnits().?), | |
| 3889 | @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentSema(pt)).toByteUnits().?), | |
| 3834 | 3890 | ); |
| 3835 | 3891 | break :info new; |
| 3836 | 3892 | }); |
| ... | ... | @@ -3841,7 +3897,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3841 | 3897 | var new = parent_ptr_info; |
| 3842 | 3898 | new.child = field_ty.toIntern(); |
| 3843 | 3899 | if (new.packed_offset.host_size == 0) { |
| 3844 | new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(pt, .sema)) + 7) / 8); | |
| 3900 | new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeSema(pt)) + 7) / 8); | |
| 3845 | 3901 | assert(new.packed_offset.bit_offset == 0); |
| 3846 | 3902 | } |
| 3847 | 3903 | break :info new; |
| ... | ... | @@ -3854,8 +3910,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3854 | 3910 | .Pointer => field_ty: { |
| 3855 | 3911 | assert(aggregate_ty.isSlice(zcu)); |
| 3856 | 3912 | break :field_ty switch (field_idx) { |
| 3857 | Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(pt) }, | |
| 3858 | Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(pt) }, | |
| 3913 | Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(zcu) }, | |
| 3914 | Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(zcu) }, | |
| 3859 | 3915 | else => unreachable, |
| 3860 | 3916 | }; |
| 3861 | 3917 | }, |
| ... | ... | @@ -3863,7 +3919,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3863 | 3919 | }; |
| 3864 | 3920 | |
| 3865 | 3921 | const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: { |
| 3866 | const ty_align = (try field_ty.abiAlignmentAdvanced(pt, .sema)).scalar; | |
| 3922 | const ty_align = (try field_ty.abiAlignmentInner(.sema, zcu, pt.tid)).scalar; | |
| 3867 | 3923 | const true_field_align = if (field_align == .none) ty_align else field_align; |
| 3868 | 3924 | const new_align = true_field_align.min(parent_ptr_info.flags.alignment); |
| 3869 | 3925 | if (new_align == ty_align) break :a .none; |
| ... | ... | @@ -3919,21 +3975,21 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value |
| 3919 | 3975 | |
| 3920 | 3976 | const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) { |
| 3921 | 3977 | .One => switch (elem_ty.zigTypeTag(zcu)) { |
| 3922 | .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(pt, .sema), 8) }, | |
| 3978 | .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeSema(pt), 8) }, | |
| 3923 | 3979 | .Array => strat: { |
| 3924 | 3980 | const arr_elem_ty = elem_ty.childType(zcu); |
| 3925 | if (try arr_elem_ty.comptimeOnlyAdvanced(pt, .sema)) { | |
| 3981 | if (try arr_elem_ty.comptimeOnlySema(pt)) { | |
| 3926 | 3982 | break :strat .{ .elem_ptr = arr_elem_ty }; |
| 3927 | 3983 | } |
| 3928 | break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(pt, .sema)).scalar }; | |
| 3984 | break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar }; | |
| 3929 | 3985 | }, |
| 3930 | 3986 | else => unreachable, |
| 3931 | 3987 | }, |
| 3932 | 3988 | |
| 3933 | .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(pt, .sema)) | |
| 3989 | .Many, .C => if (try elem_ty.comptimeOnlySema(pt)) | |
| 3934 | 3990 | .{ .elem_ptr = elem_ty } |
| 3935 | 3991 | else |
| 3936 | .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(pt, .sema)).scalar }, | |
| 3992 | .{ .offset = field_idx * (try elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar }, | |
| 3937 | 3993 | |
| 3938 | 3994 | .Slice => unreachable, |
| 3939 | 3995 | }; |
| ... | ... | @@ -4142,22 +4198,32 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4142 | 4198 | const base_ptr_ty = base_ptr.typeOf(zcu); |
| 4143 | 4199 | const agg_ty = base_ptr_ty.childType(zcu); |
| 4144 | 4200 | const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) { |
| 4145 | .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, if (have_sema) .sema else .normal) }, | |
| 4146 | .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), pt, if (have_sema) .sema else .normal) }, | |
| 4201 | .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced( | |
| 4202 | @intCast(field.index), | |
| 4203 | if (have_sema) .sema else .normal, | |
| 4204 | pt.zcu, | |
| 4205 | if (have_sema) pt.tid else {}, | |
| 4206 | ) }, | |
| 4207 | .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced( | |
| 4208 | @intCast(field.index), | |
| 4209 | if (have_sema) .sema else .normal, | |
| 4210 | pt.zcu, | |
| 4211 | if (have_sema) pt.tid else {}, | |
| 4212 | ) }, | |
| 4147 | 4213 | .Pointer => .{ switch (field.index) { |
| 4148 | 4214 | Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu), |
| 4149 | 4215 | Value.slice_len_index => Type.usize, |
| 4150 | 4216 | else => unreachable, |
| 4151 | }, Type.usize.abiAlignment(pt) }, | |
| 4217 | }, Type.usize.abiAlignment(zcu) }, | |
| 4152 | 4218 | else => unreachable, |
| 4153 | 4219 | }; |
| 4154 | const base_align = base_ptr_ty.ptrAlignment(pt); | |
| 4220 | const base_align = base_ptr_ty.ptrAlignment(zcu); | |
| 4155 | 4221 | const result_align = field_align.minStrict(base_align); |
| 4156 | 4222 | const result_ty = try pt.ptrType(.{ |
| 4157 | 4223 | .child = field_ty.toIntern(), |
| 4158 | 4224 | .flags = flags: { |
| 4159 | 4225 | var flags = base_ptr_ty.ptrInfo(zcu).flags; |
| 4160 | if (result_align == field_ty.abiAlignment(pt)) { | |
| 4226 | if (result_align == field_ty.abiAlignment(zcu)) { | |
| 4161 | 4227 | flags.alignment = .none; |
| 4162 | 4228 | } else { |
| 4163 | 4229 | flags.alignment = result_align; |
| ... | ... | @@ -4198,7 +4264,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4198 | 4264 | } |
| 4199 | 4265 | |
| 4200 | 4266 | const need_child = Type.fromInterned(ptr.ty).childType(zcu); |
| 4201 | if (need_child.comptimeOnly(pt)) { | |
| 4267 | if (need_child.comptimeOnly(zcu)) { | |
| 4202 | 4268 | // No refinement can happen - this pointer is presumably invalid. |
| 4203 | 4269 | // Just offset it. |
| 4204 | 4270 | const parent = try arena.create(PointerDeriveStep); |
| ... | ... | @@ -4209,7 +4275,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4209 | 4275 | .new_ptr_ty = Type.fromInterned(ptr.ty), |
| 4210 | 4276 | } }; |
| 4211 | 4277 | } |
| 4212 | const need_bytes = need_child.abiSize(pt); | |
| 4278 | const need_bytes = need_child.abiSize(zcu); | |
| 4213 | 4279 | |
| 4214 | 4280 | var cur_derive = base_derive; |
| 4215 | 4281 | var cur_offset = ptr.byte_offset; |
| ... | ... | @@ -4248,7 +4314,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4248 | 4314 | |
| 4249 | 4315 | .Array => { |
| 4250 | 4316 | const elem_ty = cur_ty.childType(zcu); |
| 4251 | const elem_size = elem_ty.abiSize(pt); | |
| 4317 | const elem_size = elem_ty.abiSize(zcu); | |
| 4252 | 4318 | const start_idx = cur_offset / elem_size; |
| 4253 | 4319 | const end_idx = (cur_offset + need_bytes + elem_size - 1) / elem_size; |
| 4254 | 4320 | if (end_idx == start_idx + 1) { |
| ... | ... | @@ -4279,11 +4345,11 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4279 | 4345 | .auto, .@"packed" => break, |
| 4280 | 4346 | .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| { |
| 4281 | 4347 | const field_ty = cur_ty.structFieldType(field_idx, zcu); |
| 4282 | const start_off = cur_ty.structFieldOffset(field_idx, pt); | |
| 4283 | const end_off = start_off + field_ty.abiSize(pt); | |
| 4348 | const start_off = cur_ty.structFieldOffset(field_idx, zcu); | |
| 4349 | const end_off = start_off + field_ty.abiSize(zcu); | |
| 4284 | 4350 | if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) { |
| 4285 | 4351 | const old_ptr_ty = try cur_derive.ptrType(pt); |
| 4286 | const parent_align = old_ptr_ty.ptrAlignment(pt); | |
| 4352 | const parent_align = old_ptr_ty.ptrAlignment(zcu); | |
| 4287 | 4353 | const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off))); |
| 4288 | 4354 | const parent = try arena.create(PointerDeriveStep); |
| 4289 | 4355 | parent.* = cur_derive; |
| ... | ... | @@ -4291,7 +4357,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4291 | 4357 | .child = field_ty.toIntern(), |
| 4292 | 4358 | .flags = flags: { |
| 4293 | 4359 | var flags = old_ptr_ty.ptrInfo(zcu).flags; |
| 4294 | if (field_align == field_ty.abiAlignment(pt)) { | |
| 4360 | if (field_align == field_ty.abiAlignment(zcu)) { | |
| 4295 | 4361 | flags.alignment = .none; |
| 4296 | 4362 | } else { |
| 4297 | 4363 | flags.alignment = field_align; |
| ... | ... | @@ -4325,13 +4391,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh |
| 4325 | 4391 | } }; |
| 4326 | 4392 | } |
| 4327 | 4393 | |
| 4328 | pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaError!Value { | |
| 4394 | pub fn resolveLazy( | |
| 4395 | val: Value, | |
| 4396 | arena: Allocator, | |
| 4397 | pt: Zcu.PerThread, | |
| 4398 | ) Zcu.SemaError!Value { | |
| 4329 | 4399 | switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 4330 | 4400 | .int => |int| switch (int.storage) { |
| 4331 | 4401 | .u64, .i64, .big_int => return val, |
| 4332 | 4402 | .lazy_align, .lazy_size => return pt.intValue( |
| 4333 | 4403 | Type.fromInterned(int.ty), |
| 4334 | (try val.getUnsignedIntAdvanced(pt, .sema)).?, | |
| 4404 | (try val.getUnsignedIntInner(.sema, pt.zcu, pt.tid)).?, | |
| 4335 | 4405 | ), |
| 4336 | 4406 | }, |
| 4337 | 4407 | .slice => |slice| { |
src/Zcu.zig+35-35| ... | ... | @@ -2109,9 +2109,9 @@ pub const CompileError = error{ |
| 2109 | 2109 | ComptimeBreak, |
| 2110 | 2110 | }; |
| 2111 | 2111 | |
| 2112 | pub fn init(mod: *Zcu, thread_count: usize) !void { | |
| 2113 | const gpa = mod.gpa; | |
| 2114 | try mod.intern_pool.init(gpa, thread_count); | |
| 2112 | pub fn init(zcu: *Zcu, thread_count: usize) !void { | |
| 2113 | const gpa = zcu.gpa; | |
| 2114 | try zcu.intern_pool.init(gpa, thread_count); | |
| 2115 | 2115 | } |
| 2116 | 2116 | |
| 2117 | 2117 | pub fn deinit(zcu: *Zcu) void { |
| ... | ... | @@ -2204,8 +2204,8 @@ pub fn namespacePtr(zcu: *Zcu, index: Namespace.Index) *Namespace { |
| 2204 | 2204 | return zcu.intern_pool.namespacePtr(index); |
| 2205 | 2205 | } |
| 2206 | 2206 | |
| 2207 | pub fn namespacePtrUnwrap(mod: *Zcu, index: Namespace.OptionalIndex) ?*Namespace { | |
| 2208 | return mod.namespacePtr(index.unwrap() orelse return null); | |
| 2207 | pub fn namespacePtrUnwrap(zcu: *Zcu, index: Namespace.OptionalIndex) ?*Namespace { | |
| 2208 | return zcu.namespacePtr(index.unwrap() orelse return null); | |
| 2209 | 2209 | } |
| 2210 | 2210 | |
| 2211 | 2211 | // TODO https://github.com/ziglang/zig/issues/8643 |
| ... | ... | @@ -2682,7 +2682,7 @@ pub fn mapOldZirToNew( |
| 2682 | 2682 | /// |
| 2683 | 2683 | /// The caller is responsible for ensuring the function decl itself is already |
| 2684 | 2684 | /// analyzed, and for ensuring it can exist at runtime (see |
| 2685 | /// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body | |
| 2685 | /// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body | |
| 2686 | 2686 | /// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`. |
| 2687 | 2687 | pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void { |
| 2688 | 2688 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -2846,16 +2846,16 @@ pub fn errorSetBits(mod: *Zcu) u16 { |
| 2846 | 2846 | } |
| 2847 | 2847 | |
| 2848 | 2848 | pub fn errNote( |
| 2849 | mod: *Zcu, | |
| 2849 | zcu: *Zcu, | |
| 2850 | 2850 | src_loc: LazySrcLoc, |
| 2851 | 2851 | parent: *ErrorMsg, |
| 2852 | 2852 | comptime format: []const u8, |
| 2853 | 2853 | args: anytype, |
| 2854 | 2854 | ) error{OutOfMemory}!void { |
| 2855 | const msg = try std.fmt.allocPrint(mod.gpa, format, args); | |
| 2856 | errdefer mod.gpa.free(msg); | |
| 2855 | const msg = try std.fmt.allocPrint(zcu.gpa, format, args); | |
| 2856 | errdefer zcu.gpa.free(msg); | |
| 2857 | 2857 | |
| 2858 | parent.notes = try mod.gpa.realloc(parent.notes, parent.notes.len + 1); | |
| 2858 | parent.notes = try zcu.gpa.realloc(parent.notes, parent.notes.len + 1); | |
| 2859 | 2859 | parent.notes[parent.notes.len - 1] = .{ |
| 2860 | 2860 | .src_loc = src_loc, |
| 2861 | 2861 | .msg = msg, |
| ... | ... | @@ -2876,14 +2876,14 @@ pub fn optimizeMode(zcu: *const Zcu) std.builtin.OptimizeMode { |
| 2876 | 2876 | return zcu.root_mod.optimize_mode; |
| 2877 | 2877 | } |
| 2878 | 2878 | |
| 2879 | fn lockAndClearFileCompileError(mod: *Zcu, file: *File) void { | |
| 2879 | fn lockAndClearFileCompileError(zcu: *Zcu, file: *File) void { | |
| 2880 | 2880 | switch (file.status) { |
| 2881 | 2881 | .success_zir, .retryable_failure => {}, |
| 2882 | 2882 | .never_loaded, .parse_failure, .astgen_failure => { |
| 2883 | mod.comp.mutex.lock(); | |
| 2884 | defer mod.comp.mutex.unlock(); | |
| 2885 | if (mod.failed_files.fetchSwapRemove(file)) |kv| { | |
| 2886 | if (kv.value) |msg| msg.destroy(mod.gpa); // Delete previous error message. | |
| 2883 | zcu.comp.mutex.lock(); | |
| 2884 | defer zcu.comp.mutex.unlock(); | |
| 2885 | if (zcu.failed_files.fetchSwapRemove(file)) |kv| { | |
| 2886 | if (kv.value) |msg| msg.destroy(zcu.gpa); // Delete previous error message. | |
| 2887 | 2887 | } |
| 2888 | 2888 | }, |
| 2889 | 2889 | } |
| ... | ... | @@ -2965,11 +2965,11 @@ pub const AtomicPtrAlignmentDiagnostics = struct { |
| 2965 | 2965 | // TODO this function does not take into account CPU features, which can affect |
| 2966 | 2966 | // this value. Audit this! |
| 2967 | 2967 | pub fn atomicPtrAlignment( |
| 2968 | mod: *Zcu, | |
| 2968 | zcu: *Zcu, | |
| 2969 | 2969 | ty: Type, |
| 2970 | 2970 | diags: *AtomicPtrAlignmentDiagnostics, |
| 2971 | 2971 | ) AtomicPtrAlignmentError!Alignment { |
| 2972 | const target = mod.getTarget(); | |
| 2972 | const target = zcu.getTarget(); | |
| 2973 | 2973 | const max_atomic_bits: u16 = switch (target.cpu.arch) { |
| 2974 | 2974 | .avr, |
| 2975 | 2975 | .msp430, |
| ... | ... | @@ -3039,8 +3039,8 @@ pub fn atomicPtrAlignment( |
| 3039 | 3039 | } |
| 3040 | 3040 | return .none; |
| 3041 | 3041 | } |
| 3042 | if (ty.isAbiInt(mod)) { | |
| 3043 | const bit_count = ty.intInfo(mod).bits; | |
| 3042 | if (ty.isAbiInt(zcu)) { | |
| 3043 | const bit_count = ty.intInfo(zcu).bits; | |
| 3044 | 3044 | if (bit_count > max_atomic_bits) { |
| 3045 | 3045 | diags.* = .{ |
| 3046 | 3046 | .bits = bit_count, |
| ... | ... | @@ -3050,7 +3050,7 @@ pub fn atomicPtrAlignment( |
| 3050 | 3050 | } |
| 3051 | 3051 | return .none; |
| 3052 | 3052 | } |
| 3053 | if (ty.isPtrAtRuntime(mod)) return .none; | |
| 3053 | if (ty.isPtrAtRuntime(zcu)) return .none; | |
| 3054 | 3054 | return error.BadType; |
| 3055 | 3055 | } |
| 3056 | 3056 | |
| ... | ... | @@ -3058,45 +3058,45 @@ pub fn atomicPtrAlignment( |
| 3058 | 3058 | /// * `@TypeOf(.{})` |
| 3059 | 3059 | /// * A struct which has no fields (`struct {}`). |
| 3060 | 3060 | /// * Not a struct. |
| 3061 | pub fn typeToStruct(mod: *Zcu, ty: Type) ?InternPool.LoadedStructType { | |
| 3061 | pub fn typeToStruct(zcu: *Zcu, ty: Type) ?InternPool.LoadedStructType { | |
| 3062 | 3062 | if (ty.ip_index == .none) return null; |
| 3063 | const ip = &mod.intern_pool; | |
| 3063 | const ip = &zcu.intern_pool; | |
| 3064 | 3064 | return switch (ip.indexToKey(ty.ip_index)) { |
| 3065 | 3065 | .struct_type => ip.loadStructType(ty.ip_index), |
| 3066 | 3066 | else => null, |
| 3067 | 3067 | }; |
| 3068 | 3068 | } |
| 3069 | 3069 | |
| 3070 | pub fn typeToPackedStruct(mod: *Zcu, ty: Type) ?InternPool.LoadedStructType { | |
| 3071 | const s = mod.typeToStruct(ty) orelse return null; | |
| 3070 | pub fn typeToPackedStruct(zcu: *Zcu, ty: Type) ?InternPool.LoadedStructType { | |
| 3071 | const s = zcu.typeToStruct(ty) orelse return null; | |
| 3072 | 3072 | if (s.layout != .@"packed") return null; |
| 3073 | 3073 | return s; |
| 3074 | 3074 | } |
| 3075 | 3075 | |
| 3076 | pub fn typeToUnion(mod: *Zcu, ty: Type) ?InternPool.LoadedUnionType { | |
| 3076 | pub fn typeToUnion(zcu: *const Zcu, ty: Type) ?InternPool.LoadedUnionType { | |
| 3077 | 3077 | if (ty.ip_index == .none) return null; |
| 3078 | const ip = &mod.intern_pool; | |
| 3078 | const ip = &zcu.intern_pool; | |
| 3079 | 3079 | return switch (ip.indexToKey(ty.ip_index)) { |
| 3080 | 3080 | .union_type => ip.loadUnionType(ty.ip_index), |
| 3081 | 3081 | else => null, |
| 3082 | 3082 | }; |
| 3083 | 3083 | } |
| 3084 | 3084 | |
| 3085 | pub fn typeToFunc(mod: *Zcu, ty: Type) ?InternPool.Key.FuncType { | |
| 3085 | pub fn typeToFunc(zcu: *const Zcu, ty: Type) ?InternPool.Key.FuncType { | |
| 3086 | 3086 | if (ty.ip_index == .none) return null; |
| 3087 | return mod.intern_pool.indexToFuncType(ty.toIntern()); | |
| 3087 | return zcu.intern_pool.indexToFuncType(ty.toIntern()); | |
| 3088 | 3088 | } |
| 3089 | 3089 | |
| 3090 | 3090 | pub fn iesFuncIndex(zcu: *const Zcu, ies_index: InternPool.Index) InternPool.Index { |
| 3091 | 3091 | return zcu.intern_pool.iesFuncIndex(ies_index); |
| 3092 | 3092 | } |
| 3093 | 3093 | |
| 3094 | pub fn funcInfo(mod: *Zcu, func_index: InternPool.Index) InternPool.Key.Func { | |
| 3095 | return mod.intern_pool.indexToKey(func_index).func; | |
| 3094 | pub fn funcInfo(zcu: *const Zcu, func_index: InternPool.Index) InternPool.Key.Func { | |
| 3095 | return zcu.intern_pool.indexToKey(func_index).func; | |
| 3096 | 3096 | } |
| 3097 | 3097 | |
| 3098 | pub fn toEnum(mod: *Zcu, comptime E: type, val: Value) E { | |
| 3099 | return mod.intern_pool.toEnum(E, val.toIntern()); | |
| 3098 | pub fn toEnum(zcu: *const Zcu, comptime E: type, val: Value) E { | |
| 3099 | return zcu.intern_pool.toEnum(E, val.toIntern()); | |
| 3100 | 3100 | } |
| 3101 | 3101 | |
| 3102 | 3102 | pub const UnionLayout = struct { |
| ... | ... | @@ -3121,8 +3121,8 @@ pub const UnionLayout = struct { |
| 3121 | 3121 | }; |
| 3122 | 3122 | |
| 3123 | 3123 | /// Returns the index of the active field, given the current tag value |
| 3124 | pub fn unionTagFieldIndex(mod: *Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { | |
| 3125 | const ip = &mod.intern_pool; | |
| 3124 | pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { | |
| 3125 | const ip = &zcu.intern_pool; | |
| 3126 | 3126 | if (enum_tag.toIntern() == .none) return null; |
| 3127 | 3127 | assert(ip.typeOf(enum_tag.toIntern()) == loaded_union.enum_tag_ty); |
| 3128 | 3128 | return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern()); |
| ... | ... | @@ -3348,7 +3348,7 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolve |
| 3348 | 3348 | return result; |
| 3349 | 3349 | } |
| 3350 | 3350 | |
| 3351 | pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File { | |
| 3351 | pub fn fileByIndex(zcu: *const Zcu, file_index: File.Index) *File { | |
| 3352 | 3352 | return zcu.intern_pool.filePtr(file_index); |
| 3353 | 3353 | } |
| 3354 | 3354 |
src/Zcu/PerThread.zig+27-135| ... | ... | @@ -2756,7 +2756,7 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error! |
| 2756 | 2756 | // pointee type needs to be resolved more, that needs to be done before calling |
| 2757 | 2757 | // this ptr() function. |
| 2758 | 2758 | if (info.flags.alignment != .none and |
| 2759 | info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt)) | |
| 2759 | info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt.zcu)) | |
| 2760 | 2760 | { |
| 2761 | 2761 | canon_info.flags.alignment = .none; |
| 2762 | 2762 | } |
| ... | ... | @@ -2766,7 +2766,7 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error! |
| 2766 | 2766 | // we change it to 0 here. If this causes an assertion trip, the pointee type |
| 2767 | 2767 | // needs to be resolved before calling this ptr() function. |
| 2768 | 2768 | .none => if (info.packed_offset.host_size != 0) { |
| 2769 | const elem_bit_size = Type.fromInterned(info.child).bitSize(pt); | |
| 2769 | const elem_bit_size = Type.fromInterned(info.child).bitSize(pt.zcu); | |
| 2770 | 2770 | assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8); |
| 2771 | 2771 | if (info.packed_offset.host_size * 8 == elem_bit_size) { |
| 2772 | 2772 | canon_info.packed_offset.host_size = 0; |
| ... | ... | @@ -2784,7 +2784,7 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error! |
| 2784 | 2784 | /// In general, prefer this function during semantic analysis. |
| 2785 | 2785 | pub fn ptrTypeSema(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Zcu.SemaError!Type { |
| 2786 | 2786 | if (info.flags.alignment != .none) { |
| 2787 | _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(pt, .sema); | |
| 2787 | _ = try Type.fromInterned(info.child).abiAlignmentSema(pt); | |
| 2788 | 2788 | } |
| 2789 | 2789 | return pt.ptrType(info); |
| 2790 | 2790 | } |
| ... | ... | @@ -2984,15 +2984,15 @@ pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type { |
| 2984 | 2984 | /// `max`. Asserts that neither value is undef. |
| 2985 | 2985 | /// TODO: if #3806 is implemented, this becomes trivial |
| 2986 | 2986 | pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type { |
| 2987 | const mod = pt.zcu; | |
| 2988 | assert(!min.isUndef(mod)); | |
| 2989 | assert(!max.isUndef(mod)); | |
| 2987 | const zcu = pt.zcu; | |
| 2988 | assert(!min.isUndef(zcu)); | |
| 2989 | assert(!max.isUndef(zcu)); | |
| 2990 | 2990 | |
| 2991 | 2991 | if (std.debug.runtime_safety) { |
| 2992 | assert(Value.order(min, max, pt).compare(.lte)); | |
| 2992 | assert(Value.order(min, max, zcu).compare(.lte)); | |
| 2993 | 2993 | } |
| 2994 | 2994 | |
| 2995 | const sign = min.orderAgainstZero(pt) == .lt; | |
| 2995 | const sign = min.orderAgainstZero(zcu) == .lt; | |
| 2996 | 2996 | |
| 2997 | 2997 | const min_val_bits = pt.intBitsForValue(min, sign); |
| 2998 | 2998 | const max_val_bits = pt.intBitsForValue(max, sign); |
| ... | ... | @@ -3032,120 +3032,30 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 { |
| 3032 | 3032 | return @as(u16, @intCast(big.bitCountTwosComp())); |
| 3033 | 3033 | }, |
| 3034 | 3034 | .lazy_align => |lazy_ty| { |
| 3035 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt).toByteUnits() orelse 0) + @intFromBool(sign); | |
| 3035 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt.zcu).toByteUnits() orelse 0) + @intFromBool(sign); | |
| 3036 | 3036 | }, |
| 3037 | 3037 | .lazy_size => |lazy_ty| { |
| 3038 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt)) + @intFromBool(sign); | |
| 3038 | return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt.zcu)) + @intFromBool(sign); | |
| 3039 | 3039 | }, |
| 3040 | 3040 | } |
| 3041 | 3041 | } |
| 3042 | 3042 | |
| 3043 | pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) Zcu.UnionLayout { | |
| 3044 | const mod = pt.zcu; | |
| 3045 | const ip = &mod.intern_pool; | |
| 3046 | assert(loaded_union.haveLayout(ip)); | |
| 3047 | var most_aligned_field: u32 = undefined; | |
| 3048 | var most_aligned_field_size: u64 = undefined; | |
| 3049 | var biggest_field: u32 = undefined; | |
| 3050 | var payload_size: u64 = 0; | |
| 3051 | var payload_align: InternPool.Alignment = .@"1"; | |
| 3052 | for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { | |
| 3053 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 3054 | ||
| 3055 | const explicit_align = loaded_union.fieldAlign(ip, field_index); | |
| 3056 | const field_align = if (explicit_align != .none) | |
| 3057 | explicit_align | |
| 3058 | else | |
| 3059 | Type.fromInterned(field_ty).abiAlignment(pt); | |
| 3060 | const field_size = Type.fromInterned(field_ty).abiSize(pt); | |
| 3061 | if (field_size > payload_size) { | |
| 3062 | payload_size = field_size; | |
| 3063 | biggest_field = @intCast(field_index); | |
| 3064 | } | |
| 3065 | if (field_align.compare(.gte, payload_align)) { | |
| 3066 | payload_align = field_align; | |
| 3067 | most_aligned_field = @intCast(field_index); | |
| 3068 | most_aligned_field_size = field_size; | |
| 3069 | } | |
| 3070 | } | |
| 3071 | const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag(); | |
| 3072 | if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) { | |
| 3073 | return .{ | |
| 3074 | .abi_size = payload_align.forward(payload_size), | |
| 3075 | .abi_align = payload_align, | |
| 3076 | .most_aligned_field = most_aligned_field, | |
| 3077 | .most_aligned_field_size = most_aligned_field_size, | |
| 3078 | .biggest_field = biggest_field, | |
| 3079 | .payload_size = payload_size, | |
| 3080 | .payload_align = payload_align, | |
| 3081 | .tag_align = .none, | |
| 3082 | .tag_size = 0, | |
| 3083 | .padding = 0, | |
| 3084 | }; | |
| 3085 | } | |
| 3086 | ||
| 3087 | const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt); | |
| 3088 | const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1"); | |
| 3089 | return .{ | |
| 3090 | .abi_size = loaded_union.sizeUnordered(ip), | |
| 3091 | .abi_align = tag_align.max(payload_align), | |
| 3092 | .most_aligned_field = most_aligned_field, | |
| 3093 | .most_aligned_field_size = most_aligned_field_size, | |
| 3094 | .biggest_field = biggest_field, | |
| 3095 | .payload_size = payload_size, | |
| 3096 | .payload_align = payload_align, | |
| 3097 | .tag_align = tag_align, | |
| 3098 | .tag_size = tag_size, | |
| 3099 | .padding = loaded_union.paddingUnordered(ip), | |
| 3100 | }; | |
| 3101 | } | |
| 3102 | ||
| 3103 | pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 { | |
| 3104 | return mod.getUnionLayout(loaded_union).abi_size; | |
| 3105 | } | |
| 3106 | ||
| 3107 | 3043 | /// Returns 0 if the union is represented with 0 bits at runtime. |
| 3108 | 3044 | pub fn unionAbiAlignment(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) InternPool.Alignment { |
| 3109 | const mod = pt.zcu; | |
| 3110 | const ip = &mod.intern_pool; | |
| 3045 | const zcu = pt.zcu; | |
| 3046 | const ip = &zcu.intern_pool; | |
| 3111 | 3047 | const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag(); |
| 3112 | 3048 | var max_align: InternPool.Alignment = .none; |
| 3113 | if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt); | |
| 3049 | if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(zcu); | |
| 3114 | 3050 | for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { |
| 3115 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | |
| 3051 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | |
| 3116 | 3052 | |
| 3117 | const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index)); | |
| 3053 | const field_align = zcu.unionFieldNormalAlignment(loaded_union, @intCast(field_index)); | |
| 3118 | 3054 | max_align = max_align.max(field_align); |
| 3119 | 3055 | } |
| 3120 | 3056 | return max_align; |
| 3121 | 3057 | } |
| 3122 | 3058 | |
| 3123 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | |
| 3124 | pub fn unionFieldNormalAlignment( | |
| 3125 | pt: Zcu.PerThread, | |
| 3126 | loaded_union: InternPool.LoadedUnionType, | |
| 3127 | field_index: u32, | |
| 3128 | ) InternPool.Alignment { | |
| 3129 | return pt.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable; | |
| 3130 | } | |
| 3131 | ||
| 3132 | /// Returns the field alignment of a non-packed union. Asserts the layout is not packed. | |
| 3133 | /// If `strat` is `.sema`, may perform type resolution. | |
| 3134 | pub fn unionFieldNormalAlignmentAdvanced( | |
| 3135 | pt: Zcu.PerThread, | |
| 3136 | loaded_union: InternPool.LoadedUnionType, | |
| 3137 | field_index: u32, | |
| 3138 | comptime strat: Type.ResolveStrat, | |
| 3139 | ) Zcu.SemaError!InternPool.Alignment { | |
| 3140 | const ip = &pt.zcu.intern_pool; | |
| 3141 | assert(loaded_union.flagsUnordered(ip).layout != .@"packed"); | |
| 3142 | const field_align = loaded_union.fieldAlign(ip, field_index); | |
| 3143 | if (field_align != .none) return field_align; | |
| 3144 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); | |
| 3145 | if (field_ty.isNoReturn(pt.zcu)) return .none; | |
| 3146 | return (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar; | |
| 3147 | } | |
| 3148 | ||
| 3149 | 3059 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. |
| 3150 | 3060 | pub fn structFieldAlignment( |
| 3151 | 3061 | pt: Zcu.PerThread, |
| ... | ... | @@ -3153,31 +3063,13 @@ pub fn structFieldAlignment( |
| 3153 | 3063 | field_ty: Type, |
| 3154 | 3064 | layout: std.builtin.Type.ContainerLayout, |
| 3155 | 3065 | ) InternPool.Alignment { |
| 3156 | return pt.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable; | |
| 3157 | } | |
| 3158 | ||
| 3159 | /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. | |
| 3160 | /// If `strat` is `.sema`, may perform type resolution. | |
| 3161 | pub fn structFieldAlignmentAdvanced( | |
| 3162 | pt: Zcu.PerThread, | |
| 3163 | explicit_alignment: InternPool.Alignment, | |
| 3164 | field_ty: Type, | |
| 3165 | layout: std.builtin.Type.ContainerLayout, | |
| 3166 | comptime strat: Type.ResolveStrat, | |
| 3167 | ) Zcu.SemaError!InternPool.Alignment { | |
| 3168 | assert(layout != .@"packed"); | |
| 3169 | if (explicit_alignment != .none) return explicit_alignment; | |
| 3170 | const ty_abi_align = (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar; | |
| 3171 | switch (layout) { | |
| 3172 | .@"packed" => unreachable, | |
| 3173 | .auto => if (pt.zcu.getTarget().ofmt != .c) return ty_abi_align, | |
| 3174 | .@"extern" => {}, | |
| 3175 | } | |
| 3176 | // extern | |
| 3177 | if (field_ty.isAbiInt(pt.zcu) and field_ty.intInfo(pt.zcu).bits >= 128) { | |
| 3178 | return ty_abi_align.maxStrict(.@"16"); | |
| 3179 | } | |
| 3180 | return ty_abi_align; | |
| 3066 | return field_ty.structFieldAlignmentAdvanced( | |
| 3067 | explicit_alignment, | |
| 3068 | layout, | |
| 3069 | .normal, | |
| 3070 | pt.zcu, | |
| 3071 | {}, | |
| 3072 | ) catch unreachable; | |
| 3181 | 3073 | } |
| 3182 | 3074 | |
| 3183 | 3075 | /// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets |
| ... | ... | @@ -3189,8 +3081,8 @@ pub fn structPackedFieldBitOffset( |
| 3189 | 3081 | struct_type: InternPool.LoadedStructType, |
| 3190 | 3082 | field_index: u32, |
| 3191 | 3083 | ) u16 { |
| 3192 | const mod = pt.zcu; | |
| 3193 | const ip = &mod.intern_pool; | |
| 3084 | const zcu = pt.zcu; | |
| 3085 | const ip = &zcu.intern_pool; | |
| 3194 | 3086 | assert(struct_type.layout == .@"packed"); |
| 3195 | 3087 | assert(struct_type.haveLayout(ip)); |
| 3196 | 3088 | var bit_sum: u64 = 0; |
| ... | ... | @@ -3199,7 +3091,7 @@ pub fn structPackedFieldBitOffset( |
| 3199 | 3091 | return @intCast(bit_sum); |
| 3200 | 3092 | } |
| 3201 | 3093 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 3202 | bit_sum += field_ty.bitSize(pt); | |
| 3094 | bit_sum += field_ty.bitSize(zcu); | |
| 3203 | 3095 | } |
| 3204 | 3096 | unreachable; // index out of bounds |
| 3205 | 3097 | } |
| ... | ... | @@ -3244,7 +3136,7 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator. |
| 3244 | 3136 | return pt.ptrType(.{ |
| 3245 | 3137 | .child = ty.toIntern(), |
| 3246 | 3138 | .flags = .{ |
| 3247 | .alignment = if (r.alignment == ty.abiAlignment(pt)) | |
| 3139 | .alignment = if (r.alignment == ty.abiAlignment(zcu)) | |
| 3248 | 3140 | .none |
| 3249 | 3141 | else |
| 3250 | 3142 | r.alignment, |
| ... | ... | @@ -3274,7 +3166,7 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo |
| 3274 | 3166 | const zcu = pt.zcu; |
| 3275 | 3167 | const r = zcu.intern_pool.getNav(nav_index).status.resolved; |
| 3276 | 3168 | if (r.alignment != .none) return r.alignment; |
| 3277 | return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(pt); | |
| 3169 | return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(zcu); | |
| 3278 | 3170 | } |
| 3279 | 3171 | |
| 3280 | 3172 | /// Given a container type requiring resolution, ensures that it is up-to-date. |
src/arch/aarch64/CodeGen.zig+261-260| ... | ... | @@ -467,8 +467,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 467 | 467 | |
| 468 | 468 | fn gen(self: *Self) !void { |
| 469 | 469 | const pt = self.pt; |
| 470 | const mod = pt.zcu; | |
| 471 | const cc = self.fn_type.fnCallingConvention(mod); | |
| 470 | const zcu = pt.zcu; | |
| 471 | const cc = self.fn_type.fnCallingConvention(zcu); | |
| 472 | 472 | if (cc != .Naked) { |
| 473 | 473 | // stp fp, lr, [sp, #-16]! |
| 474 | 474 | _ = try self.addInst(.{ |
| ... | ... | @@ -517,8 +517,8 @@ fn gen(self: *Self) !void { |
| 517 | 517 | |
| 518 | 518 | const ty = self.typeOfIndex(inst); |
| 519 | 519 | |
| 520 | const abi_size = @as(u32, @intCast(ty.abiSize(pt))); | |
| 521 | const abi_align = ty.abiAlignment(pt); | |
| 520 | const abi_size = @as(u32, @intCast(ty.abiSize(zcu))); | |
| 521 | const abi_align = ty.abiAlignment(zcu); | |
| 522 | 522 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 523 | 523 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 524 | 524 | |
| ... | ... | @@ -648,8 +648,8 @@ fn gen(self: *Self) !void { |
| 648 | 648 | |
| 649 | 649 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 650 | 650 | const pt = self.pt; |
| 651 | const mod = pt.zcu; | |
| 652 | const ip = &mod.intern_pool; | |
| 651 | const zcu = pt.zcu; | |
| 652 | const ip = &zcu.intern_pool; | |
| 653 | 653 | const air_tags = self.air.instructions.items(.tag); |
| 654 | 654 | |
| 655 | 655 | for (body) |inst| { |
| ... | ... | @@ -1016,31 +1016,31 @@ fn allocMem( |
| 1016 | 1016 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1017 | 1017 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1018 | 1018 | const pt = self.pt; |
| 1019 | const mod = pt.zcu; | |
| 1020 | const elem_ty = self.typeOfIndex(inst).childType(mod); | |
| 1019 | const zcu = pt.zcu; | |
| 1020 | const elem_ty = self.typeOfIndex(inst).childType(zcu); | |
| 1021 | 1021 | |
| 1022 | if (!elem_ty.hasRuntimeBits(pt)) { | |
| 1022 | if (!elem_ty.hasRuntimeBits(zcu)) { | |
| 1023 | 1023 | // return the stack offset 0. Stack offset 0 will be where all |
| 1024 | 1024 | // zero-sized stack allocations live as non-zero-sized |
| 1025 | 1025 | // allocations will always have an offset > 0. |
| 1026 | 1026 | return @as(u32, 0); |
| 1027 | 1027 | } |
| 1028 | 1028 | |
| 1029 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { | |
| 1029 | const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse { | |
| 1030 | 1030 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1031 | 1031 | }; |
| 1032 | 1032 | // TODO swap this for inst.ty.ptrAlign |
| 1033 | const abi_align = elem_ty.abiAlignment(pt); | |
| 1033 | const abi_align = elem_ty.abiAlignment(zcu); | |
| 1034 | 1034 | |
| 1035 | 1035 | return self.allocMem(abi_size, abi_align, inst); |
| 1036 | 1036 | } |
| 1037 | 1037 | |
| 1038 | 1038 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { |
| 1039 | 1039 | const pt = self.pt; |
| 1040 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { | |
| 1040 | const abi_size = math.cast(u32, elem_ty.abiSize(pt.zcu)) orelse { | |
| 1041 | 1041 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1042 | 1042 | }; |
| 1043 | const abi_align = elem_ty.abiAlignment(pt); | |
| 1043 | const abi_align = elem_ty.abiAlignment(pt.zcu); | |
| 1044 | 1044 | |
| 1045 | 1045 | if (reg_ok) { |
| 1046 | 1046 | // Make sure the type can fit in a register before we try to allocate one. |
| ... | ... | @@ -1128,13 +1128,13 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1128 | 1128 | |
| 1129 | 1129 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1130 | 1130 | const pt = self.pt; |
| 1131 | const mod = pt.zcu; | |
| 1131 | const zcu = pt.zcu; | |
| 1132 | 1132 | const result: MCValue = switch (self.ret_mcv) { |
| 1133 | 1133 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| 1134 | 1134 | .stack_offset => blk: { |
| 1135 | 1135 | // self.ret_mcv is an address to where this function |
| 1136 | 1136 | // should store its result into |
| 1137 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 1137 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 1138 | 1138 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 1139 | 1139 | |
| 1140 | 1140 | // addr_reg will contain the address of where to store the |
| ... | ... | @@ -1166,14 +1166,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1166 | 1166 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 1167 | 1167 | |
| 1168 | 1168 | const pt = self.pt; |
| 1169 | const mod = pt.zcu; | |
| 1169 | const zcu = pt.zcu; | |
| 1170 | 1170 | const operand = ty_op.operand; |
| 1171 | 1171 | const operand_mcv = try self.resolveInst(operand); |
| 1172 | 1172 | const operand_ty = self.typeOf(operand); |
| 1173 | const operand_info = operand_ty.intInfo(mod); | |
| 1173 | const operand_info = operand_ty.intInfo(zcu); | |
| 1174 | 1174 | |
| 1175 | 1175 | const dest_ty = self.typeOfIndex(inst); |
| 1176 | const dest_info = dest_ty.intInfo(mod); | |
| 1176 | const dest_info = dest_ty.intInfo(zcu); | |
| 1177 | 1177 | |
| 1178 | 1178 | const result: MCValue = result: { |
| 1179 | 1179 | const operand_lock: ?RegisterLock = switch (operand_mcv) { |
| ... | ... | @@ -1248,9 +1248,9 @@ fn trunc( |
| 1248 | 1248 | dest_ty: Type, |
| 1249 | 1249 | ) !MCValue { |
| 1250 | 1250 | const pt = self.pt; |
| 1251 | const mod = pt.zcu; | |
| 1252 | const info_a = operand_ty.intInfo(mod); | |
| 1253 | const info_b = dest_ty.intInfo(mod); | |
| 1251 | const zcu = pt.zcu; | |
| 1252 | const info_a = operand_ty.intInfo(zcu); | |
| 1253 | const info_b = dest_ty.intInfo(zcu); | |
| 1254 | 1254 | |
| 1255 | 1255 | if (info_b.bits <= 64) { |
| 1256 | 1256 | const operand_reg = switch (operand) { |
| ... | ... | @@ -1312,7 +1312,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 1312 | 1312 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1313 | 1313 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1314 | 1314 | const pt = self.pt; |
| 1315 | const mod = pt.zcu; | |
| 1315 | const zcu = pt.zcu; | |
| 1316 | 1316 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1317 | 1317 | const operand = try self.resolveInst(ty_op.operand); |
| 1318 | 1318 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -1321,7 +1321,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1321 | 1321 | .unreach => unreachable, |
| 1322 | 1322 | .compare_flags => |cond| break :result MCValue{ .compare_flags = cond.negate() }, |
| 1323 | 1323 | else => { |
| 1324 | switch (operand_ty.zigTypeTag(mod)) { | |
| 1324 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 1325 | 1325 | .Bool => { |
| 1326 | 1326 | // TODO convert this to mvn + and |
| 1327 | 1327 | const op_reg = switch (operand) { |
| ... | ... | @@ -1355,7 +1355,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1355 | 1355 | }, |
| 1356 | 1356 | .Vector => return self.fail("TODO bitwise not for vectors", .{}), |
| 1357 | 1357 | .Int => { |
| 1358 | const int_info = operand_ty.intInfo(mod); | |
| 1358 | const int_info = operand_ty.intInfo(zcu); | |
| 1359 | 1359 | if (int_info.bits <= 64) { |
| 1360 | 1360 | const op_reg = switch (operand) { |
| 1361 | 1361 | .register => |r| r, |
| ... | ... | @@ -1408,13 +1408,13 @@ fn minMax( |
| 1408 | 1408 | maybe_inst: ?Air.Inst.Index, |
| 1409 | 1409 | ) !MCValue { |
| 1410 | 1410 | const pt = self.pt; |
| 1411 | const mod = pt.zcu; | |
| 1412 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1411 | const zcu = pt.zcu; | |
| 1412 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1413 | 1413 | .Float => return self.fail("TODO ARM min/max on floats", .{}), |
| 1414 | 1414 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), |
| 1415 | 1415 | .Int => { |
| 1416 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 1417 | const int_info = lhs_ty.intInfo(mod); | |
| 1416 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 1417 | const int_info = lhs_ty.intInfo(zcu); | |
| 1418 | 1418 | if (int_info.bits <= 64) { |
| 1419 | 1419 | var lhs_reg: Register = undefined; |
| 1420 | 1420 | var rhs_reg: Register = undefined; |
| ... | ... | @@ -1899,13 +1899,13 @@ fn addSub( |
| 1899 | 1899 | maybe_inst: ?Air.Inst.Index, |
| 1900 | 1900 | ) InnerError!MCValue { |
| 1901 | 1901 | const pt = self.pt; |
| 1902 | const mod = pt.zcu; | |
| 1903 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1902 | const zcu = pt.zcu; | |
| 1903 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1904 | 1904 | .Float => return self.fail("TODO binary operations on floats", .{}), |
| 1905 | 1905 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 1906 | 1906 | .Int => { |
| 1907 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 1908 | const int_info = lhs_ty.intInfo(mod); | |
| 1907 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 1908 | const int_info = lhs_ty.intInfo(zcu); | |
| 1909 | 1909 | if (int_info.bits <= 64) { |
| 1910 | 1910 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); |
| 1911 | 1911 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| ... | ... | @@ -1961,12 +1961,12 @@ fn mul( |
| 1961 | 1961 | maybe_inst: ?Air.Inst.Index, |
| 1962 | 1962 | ) InnerError!MCValue { |
| 1963 | 1963 | const pt = self.pt; |
| 1964 | const mod = pt.zcu; | |
| 1965 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1964 | const zcu = pt.zcu; | |
| 1965 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1966 | 1966 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 1967 | 1967 | .Int => { |
| 1968 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 1969 | const int_info = lhs_ty.intInfo(mod); | |
| 1968 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 1969 | const int_info = lhs_ty.intInfo(zcu); | |
| 1970 | 1970 | if (int_info.bits <= 64) { |
| 1971 | 1971 | // TODO add optimisations for multiplication |
| 1972 | 1972 | // with immediates, for example a * 2 can be |
| ... | ... | @@ -1994,8 +1994,8 @@ fn divFloat( |
| 1994 | 1994 | _ = maybe_inst; |
| 1995 | 1995 | |
| 1996 | 1996 | const pt = self.pt; |
| 1997 | const mod = pt.zcu; | |
| 1998 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1997 | const zcu = pt.zcu; | |
| 1998 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1999 | 1999 | .Float => return self.fail("TODO div_float", .{}), |
| 2000 | 2000 | .Vector => return self.fail("TODO div_float on vectors", .{}), |
| 2001 | 2001 | else => unreachable, |
| ... | ... | @@ -2011,13 +2011,13 @@ fn divTrunc( |
| 2011 | 2011 | maybe_inst: ?Air.Inst.Index, |
| 2012 | 2012 | ) InnerError!MCValue { |
| 2013 | 2013 | const pt = self.pt; |
| 2014 | const mod = pt.zcu; | |
| 2015 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2014 | const zcu = pt.zcu; | |
| 2015 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2016 | 2016 | .Float => return self.fail("TODO div on floats", .{}), |
| 2017 | 2017 | .Vector => return self.fail("TODO div on vectors", .{}), |
| 2018 | 2018 | .Int => { |
| 2019 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2020 | const int_info = lhs_ty.intInfo(mod); | |
| 2019 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2020 | const int_info = lhs_ty.intInfo(zcu); | |
| 2021 | 2021 | if (int_info.bits <= 64) { |
| 2022 | 2022 | switch (int_info.signedness) { |
| 2023 | 2023 | .signed => { |
| ... | ... | @@ -2046,13 +2046,13 @@ fn divFloor( |
| 2046 | 2046 | maybe_inst: ?Air.Inst.Index, |
| 2047 | 2047 | ) InnerError!MCValue { |
| 2048 | 2048 | const pt = self.pt; |
| 2049 | const mod = pt.zcu; | |
| 2050 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2049 | const zcu = pt.zcu; | |
| 2050 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2051 | 2051 | .Float => return self.fail("TODO div on floats", .{}), |
| 2052 | 2052 | .Vector => return self.fail("TODO div on vectors", .{}), |
| 2053 | 2053 | .Int => { |
| 2054 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2055 | const int_info = lhs_ty.intInfo(mod); | |
| 2054 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2055 | const int_info = lhs_ty.intInfo(zcu); | |
| 2056 | 2056 | if (int_info.bits <= 64) { |
| 2057 | 2057 | switch (int_info.signedness) { |
| 2058 | 2058 | .signed => { |
| ... | ... | @@ -2080,13 +2080,13 @@ fn divExact( |
| 2080 | 2080 | maybe_inst: ?Air.Inst.Index, |
| 2081 | 2081 | ) InnerError!MCValue { |
| 2082 | 2082 | const pt = self.pt; |
| 2083 | const mod = pt.zcu; | |
| 2084 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2083 | const zcu = pt.zcu; | |
| 2084 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2085 | 2085 | .Float => return self.fail("TODO div on floats", .{}), |
| 2086 | 2086 | .Vector => return self.fail("TODO div on vectors", .{}), |
| 2087 | 2087 | .Int => { |
| 2088 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2089 | const int_info = lhs_ty.intInfo(mod); | |
| 2088 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2089 | const int_info = lhs_ty.intInfo(zcu); | |
| 2090 | 2090 | if (int_info.bits <= 64) { |
| 2091 | 2091 | switch (int_info.signedness) { |
| 2092 | 2092 | .signed => { |
| ... | ... | @@ -2117,13 +2117,13 @@ fn rem( |
| 2117 | 2117 | _ = maybe_inst; |
| 2118 | 2118 | |
| 2119 | 2119 | const pt = self.pt; |
| 2120 | const mod = pt.zcu; | |
| 2121 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2122 | .Float => return self.fail("TODO rem/mod on floats", .{}), | |
| 2123 | .Vector => return self.fail("TODO rem/mod on vectors", .{}), | |
| 2120 | const zcu = pt.zcu; | |
| 2121 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2122 | .Float => return self.fail("TODO rem/zcu on floats", .{}), | |
| 2123 | .Vector => return self.fail("TODO rem/zcu on vectors", .{}), | |
| 2124 | 2124 | .Int => { |
| 2125 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2126 | const int_info = lhs_ty.intInfo(mod); | |
| 2125 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2126 | const int_info = lhs_ty.intInfo(zcu); | |
| 2127 | 2127 | if (int_info.bits <= 64) { |
| 2128 | 2128 | var lhs_reg: Register = undefined; |
| 2129 | 2129 | var rhs_reg: Register = undefined; |
| ... | ... | @@ -2168,7 +2168,7 @@ fn rem( |
| 2168 | 2168 | |
| 2169 | 2169 | return MCValue{ .register = remainder_reg }; |
| 2170 | 2170 | } else { |
| 2171 | return self.fail("TODO rem/mod for integers with bits > 64", .{}); | |
| 2171 | return self.fail("TODO rem/zcu for integers with bits > 64", .{}); | |
| 2172 | 2172 | } |
| 2173 | 2173 | }, |
| 2174 | 2174 | else => unreachable, |
| ... | ... | @@ -2189,11 +2189,11 @@ fn modulo( |
| 2189 | 2189 | _ = maybe_inst; |
| 2190 | 2190 | |
| 2191 | 2191 | const pt = self.pt; |
| 2192 | const mod = pt.zcu; | |
| 2193 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2194 | .Float => return self.fail("TODO mod on floats", .{}), | |
| 2195 | .Vector => return self.fail("TODO mod on vectors", .{}), | |
| 2196 | .Int => return self.fail("TODO mod on ints", .{}), | |
| 2192 | const zcu = pt.zcu; | |
| 2193 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2194 | .Float => return self.fail("TODO zcu on floats", .{}), | |
| 2195 | .Vector => return self.fail("TODO zcu on vectors", .{}), | |
| 2196 | .Int => return self.fail("TODO zcu on ints", .{}), | |
| 2197 | 2197 | else => unreachable, |
| 2198 | 2198 | } |
| 2199 | 2199 | } |
| ... | ... | @@ -2208,11 +2208,11 @@ fn wrappingArithmetic( |
| 2208 | 2208 | maybe_inst: ?Air.Inst.Index, |
| 2209 | 2209 | ) InnerError!MCValue { |
| 2210 | 2210 | const pt = self.pt; |
| 2211 | const mod = pt.zcu; | |
| 2212 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2211 | const zcu = pt.zcu; | |
| 2212 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2213 | 2213 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2214 | 2214 | .Int => { |
| 2215 | const int_info = lhs_ty.intInfo(mod); | |
| 2215 | const int_info = lhs_ty.intInfo(zcu); | |
| 2216 | 2216 | if (int_info.bits <= 64) { |
| 2217 | 2217 | // Generate an add/sub/mul |
| 2218 | 2218 | const result: MCValue = switch (tag) { |
| ... | ... | @@ -2244,12 +2244,12 @@ fn bitwise( |
| 2244 | 2244 | maybe_inst: ?Air.Inst.Index, |
| 2245 | 2245 | ) InnerError!MCValue { |
| 2246 | 2246 | const pt = self.pt; |
| 2247 | const mod = pt.zcu; | |
| 2248 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2247 | const zcu = pt.zcu; | |
| 2248 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2249 | 2249 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2250 | 2250 | .Int => { |
| 2251 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2252 | const int_info = lhs_ty.intInfo(mod); | |
| 2251 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2252 | const int_info = lhs_ty.intInfo(zcu); | |
| 2253 | 2253 | if (int_info.bits <= 64) { |
| 2254 | 2254 | // TODO implement bitwise operations with immediates |
| 2255 | 2255 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| ... | ... | @@ -2280,11 +2280,11 @@ fn shiftExact( |
| 2280 | 2280 | _ = rhs_ty; |
| 2281 | 2281 | |
| 2282 | 2282 | const pt = self.pt; |
| 2283 | const mod = pt.zcu; | |
| 2284 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2283 | const zcu = pt.zcu; | |
| 2284 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2285 | 2285 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2286 | 2286 | .Int => { |
| 2287 | const int_info = lhs_ty.intInfo(mod); | |
| 2287 | const int_info = lhs_ty.intInfo(zcu); | |
| 2288 | 2288 | if (int_info.bits <= 64) { |
| 2289 | 2289 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| 2290 | 2290 | |
| ... | ... | @@ -2331,11 +2331,11 @@ fn shiftNormal( |
| 2331 | 2331 | maybe_inst: ?Air.Inst.Index, |
| 2332 | 2332 | ) InnerError!MCValue { |
| 2333 | 2333 | const pt = self.pt; |
| 2334 | const mod = pt.zcu; | |
| 2335 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2334 | const zcu = pt.zcu; | |
| 2335 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2336 | 2336 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2337 | 2337 | .Int => { |
| 2338 | const int_info = lhs_ty.intInfo(mod); | |
| 2338 | const int_info = lhs_ty.intInfo(zcu); | |
| 2339 | 2339 | if (int_info.bits <= 64) { |
| 2340 | 2340 | // Generate a shl_exact/shr_exact |
| 2341 | 2341 | const result: MCValue = switch (tag) { |
| ... | ... | @@ -2372,8 +2372,8 @@ fn booleanOp( |
| 2372 | 2372 | maybe_inst: ?Air.Inst.Index, |
| 2373 | 2373 | ) InnerError!MCValue { |
| 2374 | 2374 | const pt = self.pt; |
| 2375 | const mod = pt.zcu; | |
| 2376 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2375 | const zcu = pt.zcu; | |
| 2376 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2377 | 2377 | .Bool => { |
| 2378 | 2378 | assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema |
| 2379 | 2379 | assert((try rhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema |
| ... | ... | @@ -2400,17 +2400,17 @@ fn ptrArithmetic( |
| 2400 | 2400 | maybe_inst: ?Air.Inst.Index, |
| 2401 | 2401 | ) InnerError!MCValue { |
| 2402 | 2402 | const pt = self.pt; |
| 2403 | const mod = pt.zcu; | |
| 2404 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2403 | const zcu = pt.zcu; | |
| 2404 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2405 | 2405 | .Pointer => { |
| 2406 | assert(rhs_ty.eql(Type.usize, mod)); | |
| 2406 | assert(rhs_ty.eql(Type.usize, zcu)); | |
| 2407 | 2407 | |
| 2408 | 2408 | const ptr_ty = lhs_ty; |
| 2409 | const elem_ty = switch (ptr_ty.ptrSize(mod)) { | |
| 2410 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | |
| 2411 | else => ptr_ty.childType(mod), | |
| 2409 | const elem_ty = switch (ptr_ty.ptrSize(zcu)) { | |
| 2410 | .One => ptr_ty.childType(zcu).childType(zcu), // ptr to array, so get array element type | |
| 2411 | else => ptr_ty.childType(zcu), | |
| 2412 | 2412 | }; |
| 2413 | const elem_size = elem_ty.abiSize(pt); | |
| 2413 | const elem_size = elem_ty.abiSize(zcu); | |
| 2414 | 2414 | |
| 2415 | 2415 | const base_tag: Air.Inst.Tag = switch (tag) { |
| 2416 | 2416 | .ptr_add => .add, |
| ... | ... | @@ -2524,7 +2524,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2524 | 2524 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2525 | 2525 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2526 | 2526 | const pt = self.pt; |
| 2527 | const mod = pt.zcu; | |
| 2527 | const zcu = pt.zcu; | |
| 2528 | 2528 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2529 | 2529 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2530 | 2530 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -2532,15 +2532,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2532 | 2532 | const rhs_ty = self.typeOf(extra.rhs); |
| 2533 | 2533 | |
| 2534 | 2534 | const tuple_ty = self.typeOfIndex(inst); |
| 2535 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt))); | |
| 2536 | const tuple_align = tuple_ty.abiAlignment(pt); | |
| 2537 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt))); | |
| 2535 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(zcu))); | |
| 2536 | const tuple_align = tuple_ty.abiAlignment(zcu); | |
| 2537 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, zcu))); | |
| 2538 | 2538 | |
| 2539 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2539 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2540 | 2540 | .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}), |
| 2541 | 2541 | .Int => { |
| 2542 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2543 | const int_info = lhs_ty.intInfo(mod); | |
| 2542 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2543 | const int_info = lhs_ty.intInfo(zcu); | |
| 2544 | 2544 | switch (int_info.bits) { |
| 2545 | 2545 | 1...31, 33...63 => { |
| 2546 | 2546 | const stack_offset = try self.allocMem(tuple_size, tuple_align, inst); |
| ... | ... | @@ -2652,8 +2652,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2652 | 2652 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2653 | 2653 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2654 | 2654 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 2655 | const pt = self.pt; | |
| 2656 | const mod = pt.zcu; | |
| 2655 | const zcu = self.pt.zcu; | |
| 2657 | 2656 | const result: MCValue = result: { |
| 2658 | 2657 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2659 | 2658 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -2661,15 +2660,15 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2661 | 2660 | const rhs_ty = self.typeOf(extra.rhs); |
| 2662 | 2661 | |
| 2663 | 2662 | const tuple_ty = self.typeOfIndex(inst); |
| 2664 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt))); | |
| 2665 | const tuple_align = tuple_ty.abiAlignment(pt); | |
| 2666 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt))); | |
| 2663 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(zcu))); | |
| 2664 | const tuple_align = tuple_ty.abiAlignment(zcu); | |
| 2665 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, zcu))); | |
| 2667 | 2666 | |
| 2668 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2667 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2669 | 2668 | .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), |
| 2670 | 2669 | .Int => { |
| 2671 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2672 | const int_info = lhs_ty.intInfo(mod); | |
| 2670 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2671 | const int_info = lhs_ty.intInfo(zcu); | |
| 2673 | 2672 | if (int_info.bits <= 32) { |
| 2674 | 2673 | const stack_offset = try self.allocMem(tuple_size, tuple_align, inst); |
| 2675 | 2674 | |
| ... | ... | @@ -2878,7 +2877,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2878 | 2877 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2879 | 2878 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 2880 | 2879 | const pt = self.pt; |
| 2881 | const mod = pt.zcu; | |
| 2880 | const zcu = pt.zcu; | |
| 2882 | 2881 | const result: MCValue = result: { |
| 2883 | 2882 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2884 | 2883 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -2886,14 +2885,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2886 | 2885 | const rhs_ty = self.typeOf(extra.rhs); |
| 2887 | 2886 | |
| 2888 | 2887 | const tuple_ty = self.typeOfIndex(inst); |
| 2889 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(pt))); | |
| 2890 | const tuple_align = tuple_ty.abiAlignment(pt); | |
| 2891 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, pt))); | |
| 2888 | const tuple_size = @as(u32, @intCast(tuple_ty.abiSize(zcu))); | |
| 2889 | const tuple_align = tuple_ty.abiAlignment(zcu); | |
| 2890 | const overflow_bit_offset = @as(u32, @intCast(tuple_ty.structFieldOffset(1, zcu))); | |
| 2892 | 2891 | |
| 2893 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2892 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2894 | 2893 | .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), |
| 2895 | 2894 | .Int => { |
| 2896 | const int_info = lhs_ty.intInfo(mod); | |
| 2895 | const int_info = lhs_ty.intInfo(zcu); | |
| 2897 | 2896 | if (int_info.bits <= 64) { |
| 2898 | 2897 | const stack_offset = try self.allocMem(tuple_size, tuple_align, inst); |
| 2899 | 2898 | |
| ... | ... | @@ -3027,10 +3026,10 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3027 | 3026 | |
| 3028 | 3027 | fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue { |
| 3029 | 3028 | const pt = self.pt; |
| 3030 | const mod = pt.zcu; | |
| 3031 | const payload_ty = optional_ty.optionalChild(mod); | |
| 3032 | if (!payload_ty.hasRuntimeBits(pt)) return MCValue.none; | |
| 3033 | if (optional_ty.isPtrLikeOptional(mod)) { | |
| 3029 | const zcu = pt.zcu; | |
| 3030 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 3031 | if (!payload_ty.hasRuntimeBits(zcu)) return MCValue.none; | |
| 3032 | if (optional_ty.isPtrLikeOptional(zcu)) { | |
| 3034 | 3033 | // TODO should we reuse the operand here? |
| 3035 | 3034 | const raw_reg = try self.register_manager.allocReg(inst, gp); |
| 3036 | 3035 | const reg = self.registerAlias(raw_reg, payload_ty); |
| ... | ... | @@ -3072,17 +3071,17 @@ fn errUnionErr( |
| 3072 | 3071 | maybe_inst: ?Air.Inst.Index, |
| 3073 | 3072 | ) !MCValue { |
| 3074 | 3073 | const pt = self.pt; |
| 3075 | const mod = pt.zcu; | |
| 3076 | const err_ty = error_union_ty.errorUnionSet(mod); | |
| 3077 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 3078 | if (err_ty.errorSetIsEmpty(mod)) { | |
| 3074 | const zcu = pt.zcu; | |
| 3075 | const err_ty = error_union_ty.errorUnionSet(zcu); | |
| 3076 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 3077 | if (err_ty.errorSetIsEmpty(zcu)) { | |
| 3079 | 3078 | return MCValue{ .immediate = 0 }; |
| 3080 | 3079 | } |
| 3081 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3080 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3082 | 3081 | return try error_union_bind.resolveToMcv(self); |
| 3083 | 3082 | } |
| 3084 | 3083 | |
| 3085 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt)); | |
| 3084 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu)); | |
| 3086 | 3085 | switch (try error_union_bind.resolveToMcv(self)) { |
| 3087 | 3086 | .register => { |
| 3088 | 3087 | var operand_reg: Register = undefined; |
| ... | ... | @@ -3104,7 +3103,7 @@ fn errUnionErr( |
| 3104 | 3103 | ); |
| 3105 | 3104 | |
| 3106 | 3105 | const err_bit_offset = err_offset * 8; |
| 3107 | const err_bit_size = @as(u32, @intCast(err_ty.abiSize(pt))) * 8; | |
| 3106 | const err_bit_size = @as(u32, @intCast(err_ty.abiSize(zcu))) * 8; | |
| 3108 | 3107 | |
| 3109 | 3108 | _ = try self.addInst(.{ |
| 3110 | 3109 | .tag = .ubfx, // errors are unsigned integers |
| ... | ... | @@ -3153,17 +3152,17 @@ fn errUnionPayload( |
| 3153 | 3152 | maybe_inst: ?Air.Inst.Index, |
| 3154 | 3153 | ) !MCValue { |
| 3155 | 3154 | const pt = self.pt; |
| 3156 | const mod = pt.zcu; | |
| 3157 | const err_ty = error_union_ty.errorUnionSet(mod); | |
| 3158 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 3159 | if (err_ty.errorSetIsEmpty(mod)) { | |
| 3155 | const zcu = pt.zcu; | |
| 3156 | const err_ty = error_union_ty.errorUnionSet(zcu); | |
| 3157 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 3158 | if (err_ty.errorSetIsEmpty(zcu)) { | |
| 3160 | 3159 | return try error_union_bind.resolveToMcv(self); |
| 3161 | 3160 | } |
| 3162 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3161 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3163 | 3162 | return MCValue.none; |
| 3164 | 3163 | } |
| 3165 | 3164 | |
| 3166 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))); | |
| 3165 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))); | |
| 3167 | 3166 | switch (try error_union_bind.resolveToMcv(self)) { |
| 3168 | 3167 | .register => { |
| 3169 | 3168 | var operand_reg: Register = undefined; |
| ... | ... | @@ -3185,10 +3184,10 @@ fn errUnionPayload( |
| 3185 | 3184 | ); |
| 3186 | 3185 | |
| 3187 | 3186 | const payload_bit_offset = payload_offset * 8; |
| 3188 | const payload_bit_size = @as(u32, @intCast(payload_ty.abiSize(pt))) * 8; | |
| 3187 | const payload_bit_size = @as(u32, @intCast(payload_ty.abiSize(zcu))) * 8; | |
| 3189 | 3188 | |
| 3190 | 3189 | _ = try self.addInst(.{ |
| 3191 | .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, | |
| 3190 | .tag = if (payload_ty.isSignedInt(zcu)) Mir.Inst.Tag.sbfx else .ubfx, | |
| 3192 | 3191 | .data = .{ |
| 3193 | 3192 | .rr_lsb_width = .{ |
| 3194 | 3193 | // Set both registers to the X variant to get the full width |
| ... | ... | @@ -3266,7 +3265,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 3266 | 3265 | |
| 3267 | 3266 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3268 | 3267 | const pt = self.pt; |
| 3269 | const mod = pt.zcu; | |
| 3268 | const zcu = pt.zcu; | |
| 3270 | 3269 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3271 | 3270 | |
| 3272 | 3271 | if (self.liveness.isUnused(inst)) { |
| ... | ... | @@ -3275,7 +3274,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3275 | 3274 | |
| 3276 | 3275 | const result: MCValue = result: { |
| 3277 | 3276 | const payload_ty = self.typeOf(ty_op.operand); |
| 3278 | if (!payload_ty.hasRuntimeBits(pt)) { | |
| 3277 | if (!payload_ty.hasRuntimeBits(zcu)) { | |
| 3279 | 3278 | break :result MCValue{ .immediate = 1 }; |
| 3280 | 3279 | } |
| 3281 | 3280 | |
| ... | ... | @@ -3287,7 +3286,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3287 | 3286 | }; |
| 3288 | 3287 | defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); |
| 3289 | 3288 | |
| 3290 | if (optional_ty.isPtrLikeOptional(mod)) { | |
| 3289 | if (optional_ty.isPtrLikeOptional(zcu)) { | |
| 3291 | 3290 | // TODO should we check if we can reuse the operand? |
| 3292 | 3291 | const raw_reg = try self.register_manager.allocReg(inst, gp); |
| 3293 | 3292 | const reg = self.registerAlias(raw_reg, payload_ty); |
| ... | ... | @@ -3295,9 +3294,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3295 | 3294 | break :result MCValue{ .register = reg }; |
| 3296 | 3295 | } |
| 3297 | 3296 | |
| 3298 | const optional_abi_size: u32 = @intCast(optional_ty.abiSize(pt)); | |
| 3299 | const optional_abi_align = optional_ty.abiAlignment(pt); | |
| 3300 | const offset: u32 = @intCast(payload_ty.abiSize(pt)); | |
| 3297 | const optional_abi_size: u32 = @intCast(optional_ty.abiSize(zcu)); | |
| 3298 | const optional_abi_align = optional_ty.abiAlignment(zcu); | |
| 3299 | const offset: u32 = @intCast(payload_ty.abiSize(zcu)); | |
| 3301 | 3300 | |
| 3302 | 3301 | const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst); |
| 3303 | 3302 | try self.genSetStack(payload_ty, stack_offset, operand); |
| ... | ... | @@ -3312,20 +3311,20 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3312 | 3311 | /// T to E!T |
| 3313 | 3312 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3314 | 3313 | const pt = self.pt; |
| 3315 | const mod = pt.zcu; | |
| 3314 | const zcu = pt.zcu; | |
| 3316 | 3315 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3317 | 3316 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3318 | 3317 | const error_union_ty = ty_op.ty.toType(); |
| 3319 | const error_ty = error_union_ty.errorUnionSet(mod); | |
| 3320 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 3318 | const error_ty = error_union_ty.errorUnionSet(zcu); | |
| 3319 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 3321 | 3320 | const operand = try self.resolveInst(ty_op.operand); |
| 3322 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; | |
| 3321 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result operand; | |
| 3323 | 3322 | |
| 3324 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(pt))); | |
| 3325 | const abi_align = error_union_ty.abiAlignment(pt); | |
| 3323 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(zcu))); | |
| 3324 | const abi_align = error_union_ty.abiAlignment(zcu); | |
| 3326 | 3325 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 3327 | const payload_off = errUnionPayloadOffset(payload_ty, pt); | |
| 3328 | const err_off = errUnionErrorOffset(payload_ty, pt); | |
| 3326 | const payload_off = errUnionPayloadOffset(payload_ty, zcu); | |
| 3327 | const err_off = errUnionErrorOffset(payload_ty, zcu); | |
| 3329 | 3328 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand); |
| 3330 | 3329 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 }); |
| 3331 | 3330 | |
| ... | ... | @@ -3339,18 +3338,18 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 3339 | 3338 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3340 | 3339 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3341 | 3340 | const pt = self.pt; |
| 3342 | const mod = pt.zcu; | |
| 3341 | const zcu = pt.zcu; | |
| 3343 | 3342 | const error_union_ty = ty_op.ty.toType(); |
| 3344 | const error_ty = error_union_ty.errorUnionSet(mod); | |
| 3345 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 3343 | const error_ty = error_union_ty.errorUnionSet(zcu); | |
| 3344 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 3346 | 3345 | const operand = try self.resolveInst(ty_op.operand); |
| 3347 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; | |
| 3346 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result operand; | |
| 3348 | 3347 | |
| 3349 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(pt))); | |
| 3350 | const abi_align = error_union_ty.abiAlignment(pt); | |
| 3348 | const abi_size = @as(u32, @intCast(error_union_ty.abiSize(zcu))); | |
| 3349 | const abi_align = error_union_ty.abiAlignment(zcu); | |
| 3351 | 3350 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 3352 | const payload_off = errUnionPayloadOffset(payload_ty, pt); | |
| 3353 | const err_off = errUnionErrorOffset(payload_ty, pt); | |
| 3351 | const payload_off = errUnionPayloadOffset(payload_ty, zcu); | |
| 3352 | const err_off = errUnionErrorOffset(payload_ty, zcu); | |
| 3354 | 3353 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand); |
| 3355 | 3354 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef); |
| 3356 | 3355 | |
| ... | ... | @@ -3443,11 +3442,11 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3443 | 3442 | |
| 3444 | 3443 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3445 | 3444 | const pt = self.pt; |
| 3446 | const mod = pt.zcu; | |
| 3445 | const zcu = pt.zcu; | |
| 3447 | 3446 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3448 | 3447 | const slice_ty = self.typeOf(bin_op.lhs); |
| 3449 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 3450 | const ptr_ty = slice_ty.slicePtrFieldType(mod); | |
| 3448 | const result: MCValue = if (!slice_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) .dead else result: { | |
| 3449 | const ptr_ty = slice_ty.slicePtrFieldType(zcu); | |
| 3451 | 3450 | |
| 3452 | 3451 | const slice_mcv = try self.resolveInst(bin_op.lhs); |
| 3453 | 3452 | const base_mcv = slicePtr(slice_mcv); |
| ... | ... | @@ -3468,9 +3467,9 @@ fn ptrElemVal( |
| 3468 | 3467 | maybe_inst: ?Air.Inst.Index, |
| 3469 | 3468 | ) !MCValue { |
| 3470 | 3469 | const pt = self.pt; |
| 3471 | const mod = pt.zcu; | |
| 3472 | const elem_ty = ptr_ty.childType(mod); | |
| 3473 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(pt))); | |
| 3470 | const zcu = pt.zcu; | |
| 3471 | const elem_ty = ptr_ty.childType(zcu); | |
| 3472 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(zcu))); | |
| 3474 | 3473 | |
| 3475 | 3474 | // TODO optimize for elem_sizes of 1, 2, 4, 8 |
| 3476 | 3475 | switch (elem_size) { |
| ... | ... | @@ -3511,10 +3510,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3511 | 3510 | |
| 3512 | 3511 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3513 | 3512 | const pt = self.pt; |
| 3514 | const mod = pt.zcu; | |
| 3513 | const zcu = pt.zcu; | |
| 3515 | 3514 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3516 | 3515 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3517 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 3516 | const result: MCValue = if (!ptr_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) .dead else result: { | |
| 3518 | 3517 | const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs }; |
| 3519 | 3518 | const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs }; |
| 3520 | 3519 | |
| ... | ... | @@ -3635,9 +3634,9 @@ fn reuseOperand( |
| 3635 | 3634 | |
| 3636 | 3635 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 3637 | 3636 | const pt = self.pt; |
| 3638 | const mod = pt.zcu; | |
| 3639 | const elem_ty = ptr_ty.childType(mod); | |
| 3640 | const elem_size = elem_ty.abiSize(pt); | |
| 3637 | const zcu = pt.zcu; | |
| 3638 | const elem_ty = ptr_ty.childType(zcu); | |
| 3639 | const elem_size = elem_ty.abiSize(zcu); | |
| 3641 | 3640 | |
| 3642 | 3641 | switch (ptr) { |
| 3643 | 3642 | .none => unreachable, |
| ... | ... | @@ -3884,16 +3883,16 @@ fn genInlineMemsetCode( |
| 3884 | 3883 | |
| 3885 | 3884 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3886 | 3885 | const pt = self.pt; |
| 3887 | const mod = pt.zcu; | |
| 3886 | const zcu = pt.zcu; | |
| 3888 | 3887 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3889 | 3888 | const elem_ty = self.typeOfIndex(inst); |
| 3890 | const elem_size = elem_ty.abiSize(pt); | |
| 3889 | const elem_size = elem_ty.abiSize(zcu); | |
| 3891 | 3890 | const result: MCValue = result: { |
| 3892 | if (!elem_ty.hasRuntimeBits(pt)) | |
| 3891 | if (!elem_ty.hasRuntimeBits(zcu)) | |
| 3893 | 3892 | break :result MCValue.none; |
| 3894 | 3893 | |
| 3895 | 3894 | const ptr = try self.resolveInst(ty_op.operand); |
| 3896 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 3895 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(zcu); | |
| 3897 | 3896 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 3898 | 3897 | break :result MCValue.dead; |
| 3899 | 3898 | |
| ... | ... | @@ -3916,12 +3915,12 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3916 | 3915 | |
| 3917 | 3916 | fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3918 | 3917 | const pt = self.pt; |
| 3919 | const mod = pt.zcu; | |
| 3920 | const abi_size = ty.abiSize(pt); | |
| 3918 | const zcu = pt.zcu; | |
| 3919 | const abi_size = ty.abiSize(zcu); | |
| 3921 | 3920 | |
| 3922 | 3921 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3923 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate, | |
| 3924 | 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_immediate else .ldrh_immediate, | |
| 3922 | 1 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate, | |
| 3923 | 2 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsh_immediate else .ldrh_immediate, | |
| 3925 | 3924 | 4 => .ldr_immediate, |
| 3926 | 3925 | 8 => .ldr_immediate, |
| 3927 | 3926 | 3, 5, 6, 7 => return self.fail("TODO: genLdrRegister for more abi_sizes", .{}), |
| ... | ... | @@ -3940,7 +3939,7 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3940 | 3939 | |
| 3941 | 3940 | fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3942 | 3941 | const pt = self.pt; |
| 3943 | const abi_size = ty.abiSize(pt); | |
| 3942 | const abi_size = ty.abiSize(pt.zcu); | |
| 3944 | 3943 | |
| 3945 | 3944 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3946 | 3945 | 1 => .strb_immediate, |
| ... | ... | @@ -3963,7 +3962,7 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3963 | 3962 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 3964 | 3963 | const pt = self.pt; |
| 3965 | 3964 | log.debug("store: storing {} to {}", .{ value, ptr }); |
| 3966 | const abi_size = value_ty.abiSize(pt); | |
| 3965 | const abi_size = value_ty.abiSize(pt.zcu); | |
| 3967 | 3966 | |
| 3968 | 3967 | switch (ptr) { |
| 3969 | 3968 | .none => unreachable, |
| ... | ... | @@ -4116,11 +4115,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 4116 | 4115 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 4117 | 4116 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 4118 | 4117 | const pt = self.pt; |
| 4119 | const mod = pt.zcu; | |
| 4118 | const zcu = pt.zcu; | |
| 4120 | 4119 | const mcv = try self.resolveInst(operand); |
| 4121 | 4120 | const ptr_ty = self.typeOf(operand); |
| 4122 | const struct_ty = ptr_ty.childType(mod); | |
| 4123 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); | |
| 4121 | const struct_ty = ptr_ty.childType(zcu); | |
| 4122 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu))); | |
| 4124 | 4123 | switch (mcv) { |
| 4125 | 4124 | .ptr_stack_offset => |off| { |
| 4126 | 4125 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
| ... | ... | @@ -4142,11 +4141,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4142 | 4141 | const index = extra.field_index; |
| 4143 | 4142 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4144 | 4143 | const pt = self.pt; |
| 4145 | const mod = pt.zcu; | |
| 4144 | const zcu = pt.zcu; | |
| 4146 | 4145 | const mcv = try self.resolveInst(operand); |
| 4147 | 4146 | const struct_ty = self.typeOf(operand); |
| 4148 | const struct_field_ty = struct_ty.structFieldType(index, mod); | |
| 4149 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); | |
| 4147 | const struct_field_ty = struct_ty.structFieldType(index, zcu); | |
| 4148 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu))); | |
| 4150 | 4149 | |
| 4151 | 4150 | switch (mcv) { |
| 4152 | 4151 | .dead, .unreach => unreachable, |
| ... | ... | @@ -4193,13 +4192,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4193 | 4192 | |
| 4194 | 4193 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4195 | 4194 | const pt = self.pt; |
| 4196 | const mod = pt.zcu; | |
| 4195 | const zcu = pt.zcu; | |
| 4197 | 4196 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4198 | 4197 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 4199 | 4198 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4200 | 4199 | const field_ptr = try self.resolveInst(extra.field_ptr); |
| 4201 | const struct_ty = ty_pl.ty.toType().childType(mod); | |
| 4202 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, pt))); | |
| 4200 | const struct_ty = ty_pl.ty.toType().childType(zcu); | |
| 4201 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, zcu))); | |
| 4203 | 4202 | switch (field_ptr) { |
| 4204 | 4203 | .ptr_stack_offset => |off| { |
| 4205 | 4204 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; |
| ... | ... | @@ -4274,12 +4273,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4274 | 4273 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len])); |
| 4275 | 4274 | const ty = self.typeOf(callee); |
| 4276 | 4275 | const pt = self.pt; |
| 4277 | const mod = pt.zcu; | |
| 4278 | const ip = &mod.intern_pool; | |
| 4276 | const zcu = pt.zcu; | |
| 4277 | const ip = &zcu.intern_pool; | |
| 4279 | 4278 | |
| 4280 | const fn_ty = switch (ty.zigTypeTag(mod)) { | |
| 4279 | const fn_ty = switch (ty.zigTypeTag(zcu)) { | |
| 4281 | 4280 | .Fn => ty, |
| 4282 | .Pointer => ty.childType(mod), | |
| 4281 | .Pointer => ty.childType(zcu), | |
| 4283 | 4282 | else => unreachable, |
| 4284 | 4283 | }; |
| 4285 | 4284 | |
| ... | ... | @@ -4298,9 +4297,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4298 | 4297 | |
| 4299 | 4298 | if (info.return_value == .stack_offset) { |
| 4300 | 4299 | log.debug("airCall: return by reference", .{}); |
| 4301 | const ret_ty = fn_ty.fnReturnType(mod); | |
| 4302 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 4303 | const ret_abi_align = ret_ty.abiAlignment(pt); | |
| 4300 | const ret_ty = fn_ty.fnReturnType(zcu); | |
| 4301 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 4302 | const ret_abi_align = ret_ty.abiAlignment(zcu); | |
| 4304 | 4303 | const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); |
| 4305 | 4304 | |
| 4306 | 4305 | const ret_ptr_reg = self.registerAlias(.x0, Type.usize); |
| ... | ... | @@ -4387,7 +4386,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4387 | 4386 | }, |
| 4388 | 4387 | else => return self.fail("TODO implement calling bitcasted functions", .{}), |
| 4389 | 4388 | } else { |
| 4390 | assert(ty.zigTypeTag(mod) == .Pointer); | |
| 4389 | assert(ty.zigTypeTag(zcu) == .Pointer); | |
| 4391 | 4390 | const mcv = try self.resolveInst(callee); |
| 4392 | 4391 | try self.genSetReg(ty, .x30, mcv); |
| 4393 | 4392 | |
| ... | ... | @@ -4426,15 +4425,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4426 | 4425 | |
| 4427 | 4426 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4428 | 4427 | const pt = self.pt; |
| 4429 | const mod = pt.zcu; | |
| 4428 | const zcu = pt.zcu; | |
| 4430 | 4429 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4431 | 4430 | const operand = try self.resolveInst(un_op); |
| 4432 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 4431 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 4433 | 4432 | |
| 4434 | 4433 | switch (self.ret_mcv) { |
| 4435 | 4434 | .none => {}, |
| 4436 | 4435 | .immediate => { |
| 4437 | assert(ret_ty.isError(mod)); | |
| 4436 | assert(ret_ty.isError(zcu)); | |
| 4438 | 4437 | }, |
| 4439 | 4438 | .register => |reg| { |
| 4440 | 4439 | // Return result by value |
| ... | ... | @@ -4459,11 +4458,11 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4459 | 4458 | |
| 4460 | 4459 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4461 | 4460 | const pt = self.pt; |
| 4462 | const mod = pt.zcu; | |
| 4461 | const zcu = pt.zcu; | |
| 4463 | 4462 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4464 | 4463 | const ptr = try self.resolveInst(un_op); |
| 4465 | 4464 | const ptr_ty = self.typeOf(un_op); |
| 4466 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 4465 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 4467 | 4466 | |
| 4468 | 4467 | switch (self.ret_mcv) { |
| 4469 | 4468 | .none => {}, |
| ... | ... | @@ -4483,8 +4482,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4483 | 4482 | // location. |
| 4484 | 4483 | const op_inst = un_op.toIndex().?; |
| 4485 | 4484 | if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) { |
| 4486 | const abi_size = @as(u32, @intCast(ret_ty.abiSize(pt))); | |
| 4487 | const abi_align = ret_ty.abiAlignment(pt); | |
| 4485 | const abi_size = @as(u32, @intCast(ret_ty.abiSize(zcu))); | |
| 4486 | const abi_align = ret_ty.abiAlignment(zcu); | |
| 4488 | 4487 | |
| 4489 | 4488 | const offset = try self.allocMem(abi_size, abi_align, null); |
| 4490 | 4489 | |
| ... | ... | @@ -4520,20 +4519,20 @@ fn cmp( |
| 4520 | 4519 | op: math.CompareOperator, |
| 4521 | 4520 | ) !MCValue { |
| 4522 | 4521 | const pt = self.pt; |
| 4523 | const mod = pt.zcu; | |
| 4524 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { | |
| 4522 | const zcu = pt.zcu; | |
| 4523 | const int_ty = switch (lhs_ty.zigTypeTag(zcu)) { | |
| 4525 | 4524 | .Optional => blk: { |
| 4526 | const payload_ty = lhs_ty.optionalChild(mod); | |
| 4527 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4525 | const payload_ty = lhs_ty.optionalChild(zcu); | |
| 4526 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4528 | 4527 | break :blk Type.u1; |
| 4529 | } else if (lhs_ty.isPtrLikeOptional(mod)) { | |
| 4528 | } else if (lhs_ty.isPtrLikeOptional(zcu)) { | |
| 4530 | 4529 | break :blk Type.usize; |
| 4531 | 4530 | } else { |
| 4532 | 4531 | return self.fail("TODO ARM cmp non-pointer optionals", .{}); |
| 4533 | 4532 | } |
| 4534 | 4533 | }, |
| 4535 | 4534 | .Float => return self.fail("TODO ARM cmp floats", .{}), |
| 4536 | .Enum => lhs_ty.intTagType(mod), | |
| 4535 | .Enum => lhs_ty.intTagType(zcu), | |
| 4537 | 4536 | .Int => lhs_ty, |
| 4538 | 4537 | .Bool => Type.u1, |
| 4539 | 4538 | .Pointer => Type.usize, |
| ... | ... | @@ -4541,7 +4540,7 @@ fn cmp( |
| 4541 | 4540 | else => unreachable, |
| 4542 | 4541 | }; |
| 4543 | 4542 | |
| 4544 | const int_info = int_ty.intInfo(mod); | |
| 4543 | const int_info = int_ty.intInfo(zcu); | |
| 4545 | 4544 | if (int_info.bits <= 64) { |
| 4546 | 4545 | try self.spillCompareFlagsIfOccupied(); |
| 4547 | 4546 | |
| ... | ... | @@ -4628,10 +4627,10 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4628 | 4627 | |
| 4629 | 4628 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4630 | 4629 | const pt = self.pt; |
| 4631 | const mod = pt.zcu; | |
| 4630 | const zcu = pt.zcu; | |
| 4632 | 4631 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4633 | 4632 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 4634 | const func = mod.funcInfo(extra.data.func); | |
| 4633 | const func = zcu.funcInfo(extra.data.func); | |
| 4635 | 4634 | // TODO emit debug info for function change |
| 4636 | 4635 | _ = func; |
| 4637 | 4636 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); |
| ... | ... | @@ -4834,13 +4833,13 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4834 | 4833 | |
| 4835 | 4834 | fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { |
| 4836 | 4835 | const pt = self.pt; |
| 4837 | const mod = pt.zcu; | |
| 4838 | const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: { | |
| 4839 | const payload_ty = operand_ty.optionalChild(mod); | |
| 4840 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 4836 | const zcu = pt.zcu; | |
| 4837 | const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(zcu)) blk: { | |
| 4838 | const payload_ty = operand_ty.optionalChild(zcu); | |
| 4839 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 4841 | 4840 | break :blk .{ .ty = operand_ty, .bind = operand_bind }; |
| 4842 | 4841 | |
| 4843 | const offset = @as(u32, @intCast(payload_ty.abiSize(pt))); | |
| 4842 | const offset = @as(u32, @intCast(payload_ty.abiSize(zcu))); | |
| 4844 | 4843 | const operand_mcv = try operand_bind.resolveToMcv(self); |
| 4845 | 4844 | const new_mcv: MCValue = switch (operand_mcv) { |
| 4846 | 4845 | .register => |source_reg| new: { |
| ... | ... | @@ -4853,7 +4852,7 @@ fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { |
| 4853 | 4852 | try self.genSetReg(payload_ty, dest_reg, operand_mcv); |
| 4854 | 4853 | } else { |
| 4855 | 4854 | _ = try self.addInst(.{ |
| 4856 | .tag = if (payload_ty.isSignedInt(mod)) | |
| 4855 | .tag = if (payload_ty.isSignedInt(zcu)) | |
| 4857 | 4856 | Mir.Inst.Tag.asr_immediate |
| 4858 | 4857 | else |
| 4859 | 4858 | Mir.Inst.Tag.lsr_immediate, |
| ... | ... | @@ -4891,10 +4890,10 @@ fn isErr( |
| 4891 | 4890 | error_union_ty: Type, |
| 4892 | 4891 | ) !MCValue { |
| 4893 | 4892 | const pt = self.pt; |
| 4894 | const mod = pt.zcu; | |
| 4895 | const error_type = error_union_ty.errorUnionSet(mod); | |
| 4893 | const zcu = pt.zcu; | |
| 4894 | const error_type = error_union_ty.errorUnionSet(zcu); | |
| 4896 | 4895 | |
| 4897 | if (error_type.errorSetIsEmpty(mod)) { | |
| 4896 | if (error_type.errorSetIsEmpty(zcu)) { | |
| 4898 | 4897 | return MCValue{ .immediate = 0 }; // always false |
| 4899 | 4898 | } |
| 4900 | 4899 | |
| ... | ... | @@ -4934,12 +4933,12 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4934 | 4933 | |
| 4935 | 4934 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4936 | 4935 | const pt = self.pt; |
| 4937 | const mod = pt.zcu; | |
| 4936 | const zcu = pt.zcu; | |
| 4938 | 4937 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4939 | 4938 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4940 | 4939 | const operand_ptr = try self.resolveInst(un_op); |
| 4941 | 4940 | const ptr_ty = self.typeOf(un_op); |
| 4942 | const elem_ty = ptr_ty.childType(mod); | |
| 4941 | const elem_ty = ptr_ty.childType(zcu); | |
| 4943 | 4942 | |
| 4944 | 4943 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 4945 | 4944 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -4962,12 +4961,12 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4962 | 4961 | |
| 4963 | 4962 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4964 | 4963 | const pt = self.pt; |
| 4965 | const mod = pt.zcu; | |
| 4964 | const zcu = pt.zcu; | |
| 4966 | 4965 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4967 | 4966 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4968 | 4967 | const operand_ptr = try self.resolveInst(un_op); |
| 4969 | 4968 | const ptr_ty = self.typeOf(un_op); |
| 4970 | const elem_ty = ptr_ty.childType(mod); | |
| 4969 | const elem_ty = ptr_ty.childType(zcu); | |
| 4971 | 4970 | |
| 4972 | 4971 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 4973 | 4972 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -4990,12 +4989,12 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4990 | 4989 | |
| 4991 | 4990 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4992 | 4991 | const pt = self.pt; |
| 4993 | const mod = pt.zcu; | |
| 4992 | const zcu = pt.zcu; | |
| 4994 | 4993 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4995 | 4994 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4996 | 4995 | const operand_ptr = try self.resolveInst(un_op); |
| 4997 | 4996 | const ptr_ty = self.typeOf(un_op); |
| 4998 | const elem_ty = ptr_ty.childType(mod); | |
| 4997 | const elem_ty = ptr_ty.childType(zcu); | |
| 4999 | 4998 | |
| 5000 | 4999 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 5001 | 5000 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -5018,12 +5017,12 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5018 | 5017 | |
| 5019 | 5018 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5020 | 5019 | const pt = self.pt; |
| 5021 | const mod = pt.zcu; | |
| 5020 | const zcu = pt.zcu; | |
| 5022 | 5021 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5023 | 5022 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5024 | 5023 | const operand_ptr = try self.resolveInst(un_op); |
| 5025 | 5024 | const ptr_ty = self.typeOf(un_op); |
| 5026 | const elem_ty = ptr_ty.childType(mod); | |
| 5025 | const elem_ty = ptr_ty.childType(zcu); | |
| 5027 | 5026 | |
| 5028 | 5027 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 5029 | 5028 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -5240,9 +5239,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 5240 | 5239 | |
| 5241 | 5240 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 5242 | 5241 | const pt = self.pt; |
| 5242 | const zcu = pt.zcu; | |
| 5243 | 5243 | const block_data = self.blocks.getPtr(block).?; |
| 5244 | 5244 | |
| 5245 | if (self.typeOf(operand).hasRuntimeBits(pt)) { | |
| 5245 | if (self.typeOf(operand).hasRuntimeBits(zcu)) { | |
| 5246 | 5246 | const operand_mcv = try self.resolveInst(operand); |
| 5247 | 5247 | const block_mcv = block_data.mcv; |
| 5248 | 5248 | if (block_mcv == .none) { |
| ... | ... | @@ -5417,8 +5417,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5417 | 5417 | |
| 5418 | 5418 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5419 | 5419 | const pt = self.pt; |
| 5420 | const mod = pt.zcu; | |
| 5421 | const abi_size = @as(u32, @intCast(ty.abiSize(pt))); | |
| 5420 | const zcu = pt.zcu; | |
| 5421 | const abi_size = @as(u32, @intCast(ty.abiSize(zcu))); | |
| 5422 | 5422 | switch (mcv) { |
| 5423 | 5423 | .dead => unreachable, |
| 5424 | 5424 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -5473,11 +5473,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5473 | 5473 | const reg_lock = self.register_manager.lockReg(rwo.reg); |
| 5474 | 5474 | defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg); |
| 5475 | 5475 | |
| 5476 | const wrapped_ty = ty.structFieldType(0, mod); | |
| 5476 | const wrapped_ty = ty.structFieldType(0, zcu); | |
| 5477 | 5477 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg }); |
| 5478 | 5478 | |
| 5479 | const overflow_bit_ty = ty.structFieldType(1, mod); | |
| 5480 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, pt))); | |
| 5479 | const overflow_bit_ty = ty.structFieldType(1, zcu); | |
| 5480 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu))); | |
| 5481 | 5481 | const raw_cond_reg = try self.register_manager.allocReg(null, gp); |
| 5482 | 5482 | const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty); |
| 5483 | 5483 | |
| ... | ... | @@ -5589,7 +5589,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5589 | 5589 | |
| 5590 | 5590 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 5591 | 5591 | const pt = self.pt; |
| 5592 | const mod = pt.zcu; | |
| 5592 | const zcu = pt.zcu; | |
| 5593 | 5593 | switch (mcv) { |
| 5594 | 5594 | .dead => unreachable, |
| 5595 | 5595 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -5701,13 +5701,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5701 | 5701 | try self.genLdrRegister(reg, reg.toX(), ty); |
| 5702 | 5702 | }, |
| 5703 | 5703 | .stack_offset => |off| { |
| 5704 | const abi_size = ty.abiSize(pt); | |
| 5704 | const abi_size = ty.abiSize(zcu); | |
| 5705 | 5705 | |
| 5706 | 5706 | switch (abi_size) { |
| 5707 | 5707 | 1, 2, 4, 8 => { |
| 5708 | 5708 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 5709 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack else .ldrb_stack, | |
| 5710 | 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack else .ldrh_stack, | |
| 5709 | 1 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsb_stack else .ldrb_stack, | |
| 5710 | 2 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsh_stack else .ldrh_stack, | |
| 5711 | 5711 | 4, 8 => .ldr_stack, |
| 5712 | 5712 | else => unreachable, // unexpected abi size |
| 5713 | 5713 | }; |
| ... | ... | @@ -5725,13 +5725,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5725 | 5725 | } |
| 5726 | 5726 | }, |
| 5727 | 5727 | .stack_argument_offset => |off| { |
| 5728 | const abi_size = ty.abiSize(pt); | |
| 5728 | const abi_size = ty.abiSize(zcu); | |
| 5729 | 5729 | |
| 5730 | 5730 | switch (abi_size) { |
| 5731 | 5731 | 1, 2, 4, 8 => { |
| 5732 | 5732 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 5733 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument, | |
| 5734 | 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument, | |
| 5733 | 1 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument, | |
| 5734 | 2 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument, | |
| 5735 | 5735 | 4, 8 => .ldr_stack_argument, |
| 5736 | 5736 | else => unreachable, // unexpected abi size |
| 5737 | 5737 | }; |
| ... | ... | @@ -5753,7 +5753,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5753 | 5753 | |
| 5754 | 5754 | fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5755 | 5755 | const pt = self.pt; |
| 5756 | const abi_size = @as(u32, @intCast(ty.abiSize(pt))); | |
| 5756 | const zcu = pt.zcu; | |
| 5757 | const abi_size = @as(u32, @intCast(ty.abiSize(zcu))); | |
| 5757 | 5758 | switch (mcv) { |
| 5758 | 5759 | .dead => unreachable, |
| 5759 | 5760 | .none, .unreach => return, |
| ... | ... | @@ -5761,7 +5762,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 5761 | 5762 | if (!self.wantSafety()) |
| 5762 | 5763 | return; // The already existing value will do just fine. |
| 5763 | 5764 | // TODO Upgrade this to a memset call when we have that available. |
| 5764 | switch (ty.abiSize(pt)) { | |
| 5765 | switch (ty.abiSize(pt.zcu)) { | |
| 5765 | 5766 | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }), |
| 5766 | 5767 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), |
| 5767 | 5768 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), |
| ... | ... | @@ -5953,13 +5954,13 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 5953 | 5954 | |
| 5954 | 5955 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 5955 | 5956 | const pt = self.pt; |
| 5956 | const mod = pt.zcu; | |
| 5957 | const zcu = pt.zcu; | |
| 5957 | 5958 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5958 | 5959 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5959 | 5960 | const ptr_ty = self.typeOf(ty_op.operand); |
| 5960 | 5961 | const ptr = try self.resolveInst(ty_op.operand); |
| 5961 | const array_ty = ptr_ty.childType(mod); | |
| 5962 | const array_len = @as(u32, @intCast(array_ty.arrayLen(mod))); | |
| 5962 | const array_ty = ptr_ty.childType(zcu); | |
| 5963 | const array_len = @as(u32, @intCast(array_ty.arrayLen(zcu))); | |
| 5963 | 5964 | const ptr_bytes = 8; |
| 5964 | 5965 | const stack_offset = try self.allocMem(ptr_bytes * 2, .@"8", inst); |
| 5965 | 5966 | try self.genSetStack(ptr_ty, stack_offset, ptr); |
| ... | ... | @@ -6074,9 +6075,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 6074 | 6075 | |
| 6075 | 6076 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 6076 | 6077 | const pt = self.pt; |
| 6077 | const mod = pt.zcu; | |
| 6078 | const zcu = pt.zcu; | |
| 6078 | 6079 | const vector_ty = self.typeOfIndex(inst); |
| 6079 | const len = vector_ty.vectorLen(mod); | |
| 6080 | const len = vector_ty.vectorLen(zcu); | |
| 6080 | 6081 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6081 | 6082 | const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len])); |
| 6082 | 6083 | const result: MCValue = res: { |
| ... | ... | @@ -6125,8 +6126,8 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 6125 | 6126 | const result: MCValue = result: { |
| 6126 | 6127 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; |
| 6127 | 6128 | const error_union_ty = self.typeOf(pl_op.operand); |
| 6128 | const error_union_size = @as(u32, @intCast(error_union_ty.abiSize(pt))); | |
| 6129 | const error_union_align = error_union_ty.abiAlignment(pt); | |
| 6129 | const error_union_size = @as(u32, @intCast(error_union_ty.abiSize(pt.zcu))); | |
| 6130 | const error_union_align = error_union_ty.abiAlignment(pt.zcu); | |
| 6130 | 6131 | |
| 6131 | 6132 | // The error union will die in the body. However, we need the |
| 6132 | 6133 | // error union after the body in order to extract the payload |
| ... | ... | @@ -6156,11 +6157,11 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6156 | 6157 | |
| 6157 | 6158 | fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6158 | 6159 | const pt = self.pt; |
| 6159 | const mod = pt.zcu; | |
| 6160 | const zcu = pt.zcu; | |
| 6160 | 6161 | |
| 6161 | 6162 | // If the type has no codegen bits, no need to store it. |
| 6162 | 6163 | const inst_ty = self.typeOf(inst); |
| 6163 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod)) | |
| 6164 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !inst_ty.isError(zcu)) | |
| 6164 | 6165 | return MCValue{ .none = {} }; |
| 6165 | 6166 | |
| 6166 | 6167 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?); |
| ... | ... | @@ -6220,9 +6221,9 @@ const CallMCValues = struct { |
| 6220 | 6221 | /// Caller must call `CallMCValues.deinit`. |
| 6221 | 6222 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6222 | 6223 | const pt = self.pt; |
| 6223 | const mod = pt.zcu; | |
| 6224 | const ip = &mod.intern_pool; | |
| 6225 | const fn_info = mod.typeToFunc(fn_ty).?; | |
| 6224 | const zcu = pt.zcu; | |
| 6225 | const ip = &zcu.intern_pool; | |
| 6226 | const fn_info = zcu.typeToFunc(fn_ty).?; | |
| 6226 | 6227 | const cc = fn_info.cc; |
| 6227 | 6228 | var result: CallMCValues = .{ |
| 6228 | 6229 | .args = try self.gpa.alloc(MCValue, fn_info.param_types.len), |
| ... | ... | @@ -6233,7 +6234,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6233 | 6234 | }; |
| 6234 | 6235 | errdefer self.gpa.free(result.args); |
| 6235 | 6236 | |
| 6236 | const ret_ty = fn_ty.fnReturnType(mod); | |
| 6237 | const ret_ty = fn_ty.fnReturnType(zcu); | |
| 6237 | 6238 | |
| 6238 | 6239 | switch (cc) { |
| 6239 | 6240 | .Naked => { |
| ... | ... | @@ -6248,14 +6249,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6248 | 6249 | var ncrn: usize = 0; // Next Core Register Number |
| 6249 | 6250 | var nsaa: u32 = 0; // Next stacked argument address |
| 6250 | 6251 | |
| 6251 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 6252 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 6252 | 6253 | result.return_value = .{ .unreach = {} }; |
| 6253 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { | |
| 6254 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { | |
| 6254 | 6255 | result.return_value = .{ .none = {} }; |
| 6255 | 6256 | } else { |
| 6256 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 6257 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 6257 | 6258 | if (ret_ty_size == 0) { |
| 6258 | assert(ret_ty.isError(mod)); | |
| 6259 | assert(ret_ty.isError(zcu)); | |
| 6259 | 6260 | result.return_value = .{ .immediate = 0 }; |
| 6260 | 6261 | } else if (ret_ty_size <= 8) { |
| 6261 | 6262 | result.return_value = .{ .register = self.registerAlias(c_abi_int_return_regs[0], ret_ty) }; |
| ... | ... | @@ -6265,7 +6266,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6265 | 6266 | } |
| 6266 | 6267 | |
| 6267 | 6268 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6268 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))); | |
| 6269 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(zcu))); | |
| 6269 | 6270 | if (param_size == 0) { |
| 6270 | 6271 | result_arg.* = .{ .none = {} }; |
| 6271 | 6272 | continue; |
| ... | ... | @@ -6273,7 +6274,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6273 | 6274 | |
| 6274 | 6275 | // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned |
| 6275 | 6276 | // values to spread across odd-numbered registers. |
| 6276 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"16" and !self.target.isDarwin()) { | |
| 6277 | if (Type.fromInterned(ty).abiAlignment(zcu) == .@"16" and !self.target.isDarwin()) { | |
| 6277 | 6278 | // Round up NCRN to the next even number |
| 6278 | 6279 | ncrn += ncrn % 2; |
| 6279 | 6280 | } |
| ... | ... | @@ -6291,7 +6292,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6291 | 6292 | ncrn = 8; |
| 6292 | 6293 | // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided |
| 6293 | 6294 | // that the entire stack space consumed by the arguments is 8-byte aligned. |
| 6294 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") { | |
| 6295 | if (Type.fromInterned(ty).abiAlignment(zcu) == .@"8") { | |
| 6295 | 6296 | if (nsaa % 8 != 0) { |
| 6296 | 6297 | nsaa += 8 - (nsaa % 8); |
| 6297 | 6298 | } |
| ... | ... | @@ -6306,14 +6307,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6306 | 6307 | result.stack_align = 16; |
| 6307 | 6308 | }, |
| 6308 | 6309 | .Unspecified => { |
| 6309 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 6310 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 6310 | 6311 | result.return_value = .{ .unreach = {} }; |
| 6311 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { | |
| 6312 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { | |
| 6312 | 6313 | result.return_value = .{ .none = {} }; |
| 6313 | 6314 | } else { |
| 6314 | const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(pt))); | |
| 6315 | const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(zcu))); | |
| 6315 | 6316 | if (ret_ty_size == 0) { |
| 6316 | assert(ret_ty.isError(mod)); | |
| 6317 | assert(ret_ty.isError(zcu)); | |
| 6317 | 6318 | result.return_value = .{ .immediate = 0 }; |
| 6318 | 6319 | } else if (ret_ty_size <= 8) { |
| 6319 | 6320 | result.return_value = .{ .register = self.registerAlias(.x0, ret_ty) }; |
| ... | ... | @@ -6330,9 +6331,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6330 | 6331 | var stack_offset: u32 = 0; |
| 6331 | 6332 | |
| 6332 | 6333 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6333 | if (Type.fromInterned(ty).abiSize(pt) > 0) { | |
| 6334 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt)); | |
| 6335 | const param_alignment = Type.fromInterned(ty).abiAlignment(pt); | |
| 6334 | if (Type.fromInterned(ty).abiSize(zcu) > 0) { | |
| 6335 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(zcu)); | |
| 6336 | const param_alignment = Type.fromInterned(ty).abiAlignment(zcu); | |
| 6336 | 6337 | |
| 6337 | 6338 | stack_offset = @intCast(param_alignment.forward(stack_offset)); |
| 6338 | 6339 | result_arg.* = .{ .stack_argument_offset = stack_offset }; |
| ... | ... | @@ -6383,7 +6384,7 @@ fn parseRegName(name: []const u8) ?Register { |
| 6383 | 6384 | } |
| 6384 | 6385 | |
| 6385 | 6386 | fn registerAlias(self: *Self, reg: Register, ty: Type) Register { |
| 6386 | const abi_size = ty.abiSize(self.pt); | |
| 6387 | const abi_size = ty.abiSize(self.pt.zcu); | |
| 6387 | 6388 | |
| 6388 | 6389 | switch (reg.class()) { |
| 6389 | 6390 | .general_purpose => { |
src/arch/aarch64/abi.zig+12-12| ... | ... | @@ -15,44 +15,44 @@ pub const Class = union(enum) { |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | 17 | /// For `float_array` the second element will be the amount of floats. |
| 18 | pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { | |
| 19 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 18 | pub fn classifyType(ty: Type, zcu: *Zcu) Class { | |
| 19 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 20 | 20 | |
| 21 | 21 | var maybe_float_bits: ?u16 = null; |
| 22 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 22 | switch (ty.zigTypeTag(zcu)) { | |
| 23 | 23 | .Struct => { |
| 24 | if (ty.containerLayout(pt.zcu) == .@"packed") return .byval; | |
| 25 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); | |
| 24 | if (ty.containerLayout(zcu) == .@"packed") return .byval; | |
| 25 | const float_count = countFloats(ty, zcu, &maybe_float_bits); | |
| 26 | 26 | if (float_count <= sret_float_count) return .{ .float_array = float_count }; |
| 27 | 27 | |
| 28 | const bit_size = ty.bitSize(pt); | |
| 28 | const bit_size = ty.bitSize(zcu); | |
| 29 | 29 | if (bit_size > 128) return .memory; |
| 30 | 30 | if (bit_size > 64) return .double_integer; |
| 31 | 31 | return .integer; |
| 32 | 32 | }, |
| 33 | 33 | .Union => { |
| 34 | if (ty.containerLayout(pt.zcu) == .@"packed") return .byval; | |
| 35 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); | |
| 34 | if (ty.containerLayout(zcu) == .@"packed") return .byval; | |
| 35 | const float_count = countFloats(ty, zcu, &maybe_float_bits); | |
| 36 | 36 | if (float_count <= sret_float_count) return .{ .float_array = float_count }; |
| 37 | 37 | |
| 38 | const bit_size = ty.bitSize(pt); | |
| 38 | const bit_size = ty.bitSize(zcu); | |
| 39 | 39 | if (bit_size > 128) return .memory; |
| 40 | 40 | if (bit_size > 64) return .double_integer; |
| 41 | 41 | return .integer; |
| 42 | 42 | }, |
| 43 | 43 | .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval, |
| 44 | 44 | .Vector => { |
| 45 | const bit_size = ty.bitSize(pt); | |
| 45 | const bit_size = ty.bitSize(zcu); | |
| 46 | 46 | // TODO is this controlled by a cpu feature? |
| 47 | 47 | if (bit_size > 128) return .memory; |
| 48 | 48 | return .byval; |
| 49 | 49 | }, |
| 50 | 50 | .Optional => { |
| 51 | std.debug.assert(ty.isPtrLikeOptional(pt.zcu)); | |
| 51 | std.debug.assert(ty.isPtrLikeOptional(zcu)); | |
| 52 | 52 | return .byval; |
| 53 | 53 | }, |
| 54 | 54 | .Pointer => { |
| 55 | std.debug.assert(!ty.isSlice(pt.zcu)); | |
| 55 | std.debug.assert(!ty.isSlice(zcu)); | |
| 56 | 56 | return .byval; |
| 57 | 57 | }, |
| 58 | 58 | .ErrorUnion, |
src/arch/arm/CodeGen.zig+252-252| ... | ... | @@ -474,8 +474,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 474 | 474 | |
| 475 | 475 | fn gen(self: *Self) !void { |
| 476 | 476 | const pt = self.pt; |
| 477 | const mod = pt.zcu; | |
| 478 | const cc = self.fn_type.fnCallingConvention(mod); | |
| 477 | const zcu = pt.zcu; | |
| 478 | const cc = self.fn_type.fnCallingConvention(zcu); | |
| 479 | 479 | if (cc != .Naked) { |
| 480 | 480 | // push {fp, lr} |
| 481 | 481 | const push_reloc = try self.addNop(); |
| ... | ... | @@ -518,8 +518,8 @@ fn gen(self: *Self) !void { |
| 518 | 518 | |
| 519 | 519 | const ty = self.typeOfIndex(inst); |
| 520 | 520 | |
| 521 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 522 | const abi_align = ty.abiAlignment(pt); | |
| 521 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 522 | const abi_align = ty.abiAlignment(zcu); | |
| 523 | 523 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 524 | 524 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 525 | 525 | |
| ... | ... | @@ -635,8 +635,8 @@ fn gen(self: *Self) !void { |
| 635 | 635 | |
| 636 | 636 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 637 | 637 | const pt = self.pt; |
| 638 | const mod = pt.zcu; | |
| 639 | const ip = &mod.intern_pool; | |
| 638 | const zcu = pt.zcu; | |
| 639 | const ip = &zcu.intern_pool; | |
| 640 | 640 | const air_tags = self.air.instructions.items(.tag); |
| 641 | 641 | |
| 642 | 642 | for (body) |inst| { |
| ... | ... | @@ -999,10 +999,10 @@ fn allocMem( |
| 999 | 999 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1000 | 1000 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1001 | 1001 | const pt = self.pt; |
| 1002 | const mod = pt.zcu; | |
| 1003 | const elem_ty = self.typeOfIndex(inst).childType(mod); | |
| 1002 | const zcu = pt.zcu; | |
| 1003 | const elem_ty = self.typeOfIndex(inst).childType(zcu); | |
| 1004 | 1004 | |
| 1005 | if (!elem_ty.hasRuntimeBits(pt)) { | |
| 1005 | if (!elem_ty.hasRuntimeBits(zcu)) { | |
| 1006 | 1006 | // As this stack item will never be dereferenced at runtime, |
| 1007 | 1007 | // return the stack offset 0. Stack offset 0 will be where all |
| 1008 | 1008 | // zero-sized stack allocations live as non-zero-sized |
| ... | ... | @@ -1010,21 +1010,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1010 | 1010 | return 0; |
| 1011 | 1011 | } |
| 1012 | 1012 | |
| 1013 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { | |
| 1013 | const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse { | |
| 1014 | 1014 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1015 | 1015 | }; |
| 1016 | 1016 | // TODO swap this for inst.ty.ptrAlign |
| 1017 | const abi_align = elem_ty.abiAlignment(pt); | |
| 1017 | const abi_align = elem_ty.abiAlignment(zcu); | |
| 1018 | 1018 | |
| 1019 | 1019 | return self.allocMem(abi_size, abi_align, inst); |
| 1020 | 1020 | } |
| 1021 | 1021 | |
| 1022 | 1022 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { |
| 1023 | 1023 | const pt = self.pt; |
| 1024 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { | |
| 1024 | const abi_size = math.cast(u32, elem_ty.abiSize(pt.zcu)) orelse { | |
| 1025 | 1025 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 1026 | 1026 | }; |
| 1027 | const abi_align = elem_ty.abiAlignment(pt); | |
| 1027 | const abi_align = elem_ty.abiAlignment(pt.zcu); | |
| 1028 | 1028 | |
| 1029 | 1029 | if (reg_ok) { |
| 1030 | 1030 | // Make sure the type can fit in a register before we try to allocate one. |
| ... | ... | @@ -1108,13 +1108,13 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1108 | 1108 | |
| 1109 | 1109 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1110 | 1110 | const pt = self.pt; |
| 1111 | const mod = pt.zcu; | |
| 1111 | const zcu = pt.zcu; | |
| 1112 | 1112 | const result: MCValue = switch (self.ret_mcv) { |
| 1113 | 1113 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| 1114 | 1114 | .stack_offset => blk: { |
| 1115 | 1115 | // self.ret_mcv is an address to where this function |
| 1116 | 1116 | // should store its result into |
| 1117 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 1117 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 1118 | 1118 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 1119 | 1119 | |
| 1120 | 1120 | // addr_reg will contain the address of where to store the |
| ... | ... | @@ -1142,7 +1142,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 1142 | 1142 | |
| 1143 | 1143 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1144 | 1144 | const pt = self.pt; |
| 1145 | const mod = pt.zcu; | |
| 1145 | const zcu = pt.zcu; | |
| 1146 | 1146 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1147 | 1147 | if (self.liveness.isUnused(inst)) |
| 1148 | 1148 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -1151,10 +1151,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1151 | 1151 | const operand_ty = self.typeOf(ty_op.operand); |
| 1152 | 1152 | const dest_ty = self.typeOfIndex(inst); |
| 1153 | 1153 | |
| 1154 | const operand_abi_size = operand_ty.abiSize(pt); | |
| 1155 | const dest_abi_size = dest_ty.abiSize(pt); | |
| 1156 | const info_a = operand_ty.intInfo(mod); | |
| 1157 | const info_b = dest_ty.intInfo(mod); | |
| 1154 | const operand_abi_size = operand_ty.abiSize(zcu); | |
| 1155 | const dest_abi_size = dest_ty.abiSize(zcu); | |
| 1156 | const info_a = operand_ty.intInfo(zcu); | |
| 1157 | const info_b = dest_ty.intInfo(zcu); | |
| 1158 | 1158 | |
| 1159 | 1159 | const dst_mcv: MCValue = blk: { |
| 1160 | 1160 | if (info_a.bits == info_b.bits) { |
| ... | ... | @@ -1209,9 +1209,9 @@ fn trunc( |
| 1209 | 1209 | dest_ty: Type, |
| 1210 | 1210 | ) !MCValue { |
| 1211 | 1211 | const pt = self.pt; |
| 1212 | const mod = pt.zcu; | |
| 1213 | const info_a = operand_ty.intInfo(mod); | |
| 1214 | const info_b = dest_ty.intInfo(mod); | |
| 1212 | const zcu = pt.zcu; | |
| 1213 | const info_a = operand_ty.intInfo(zcu); | |
| 1214 | const info_b = dest_ty.intInfo(zcu); | |
| 1215 | 1215 | |
| 1216 | 1216 | if (info_b.bits <= 32) { |
| 1217 | 1217 | if (info_a.bits > 32) { |
| ... | ... | @@ -1274,7 +1274,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 1274 | 1274 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1275 | 1275 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1276 | 1276 | const pt = self.pt; |
| 1277 | const mod = pt.zcu; | |
| 1277 | const zcu = pt.zcu; | |
| 1278 | 1278 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1279 | 1279 | const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand }; |
| 1280 | 1280 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -1283,7 +1283,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1283 | 1283 | .unreach => unreachable, |
| 1284 | 1284 | .cpsr_flags => |cond| break :result MCValue{ .cpsr_flags = cond.negate() }, |
| 1285 | 1285 | else => { |
| 1286 | switch (operand_ty.zigTypeTag(mod)) { | |
| 1286 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 1287 | 1287 | .Bool => { |
| 1288 | 1288 | var op_reg: Register = undefined; |
| 1289 | 1289 | var dest_reg: Register = undefined; |
| ... | ... | @@ -1316,7 +1316,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1316 | 1316 | }, |
| 1317 | 1317 | .Vector => return self.fail("TODO bitwise not for vectors", .{}), |
| 1318 | 1318 | .Int => { |
| 1319 | const int_info = operand_ty.intInfo(mod); | |
| 1319 | const int_info = operand_ty.intInfo(zcu); | |
| 1320 | 1320 | if (int_info.bits <= 32) { |
| 1321 | 1321 | var op_reg: Register = undefined; |
| 1322 | 1322 | var dest_reg: Register = undefined; |
| ... | ... | @@ -1371,13 +1371,13 @@ fn minMax( |
| 1371 | 1371 | maybe_inst: ?Air.Inst.Index, |
| 1372 | 1372 | ) !MCValue { |
| 1373 | 1373 | const pt = self.pt; |
| 1374 | const mod = pt.zcu; | |
| 1375 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1374 | const zcu = pt.zcu; | |
| 1375 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1376 | 1376 | .Float => return self.fail("TODO ARM min/max on floats", .{}), |
| 1377 | 1377 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), |
| 1378 | 1378 | .Int => { |
| 1379 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 1380 | const int_info = lhs_ty.intInfo(mod); | |
| 1379 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 1380 | const int_info = lhs_ty.intInfo(zcu); | |
| 1381 | 1381 | if (int_info.bits <= 32) { |
| 1382 | 1382 | var lhs_reg: Register = undefined; |
| 1383 | 1383 | var rhs_reg: Register = undefined; |
| ... | ... | @@ -1581,7 +1581,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1581 | 1581 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1582 | 1582 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1583 | 1583 | const pt = self.pt; |
| 1584 | const mod = pt.zcu; | |
| 1584 | const zcu = pt.zcu; | |
| 1585 | 1585 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1586 | 1586 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 1587 | 1587 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -1589,15 +1589,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1589 | 1589 | const rhs_ty = self.typeOf(extra.rhs); |
| 1590 | 1590 | |
| 1591 | 1591 | const tuple_ty = self.typeOfIndex(inst); |
| 1592 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt)); | |
| 1593 | const tuple_align = tuple_ty.abiAlignment(pt); | |
| 1594 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt)); | |
| 1592 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(zcu)); | |
| 1593 | const tuple_align = tuple_ty.abiAlignment(zcu); | |
| 1594 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | |
| 1595 | 1595 | |
| 1596 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1596 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1597 | 1597 | .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}), |
| 1598 | 1598 | .Int => { |
| 1599 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 1600 | const int_info = lhs_ty.intInfo(mod); | |
| 1599 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 1600 | const int_info = lhs_ty.intInfo(zcu); | |
| 1601 | 1601 | if (int_info.bits < 32) { |
| 1602 | 1602 | const stack_offset = try self.allocMem(tuple_size, tuple_align, inst); |
| 1603 | 1603 | |
| ... | ... | @@ -1695,7 +1695,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1695 | 1695 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1696 | 1696 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 1697 | 1697 | const pt = self.pt; |
| 1698 | const mod = pt.zcu; | |
| 1698 | const zcu = pt.zcu; | |
| 1699 | 1699 | const result: MCValue = result: { |
| 1700 | 1700 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 1701 | 1701 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -1703,15 +1703,15 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1703 | 1703 | const rhs_ty = self.typeOf(extra.rhs); |
| 1704 | 1704 | |
| 1705 | 1705 | const tuple_ty = self.typeOfIndex(inst); |
| 1706 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt)); | |
| 1707 | const tuple_align = tuple_ty.abiAlignment(pt); | |
| 1708 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt)); | |
| 1706 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(zcu)); | |
| 1707 | const tuple_align = tuple_ty.abiAlignment(zcu); | |
| 1708 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | |
| 1709 | 1709 | |
| 1710 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1710 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1711 | 1711 | .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}), |
| 1712 | 1712 | .Int => { |
| 1713 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 1714 | const int_info = lhs_ty.intInfo(mod); | |
| 1713 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 1714 | const int_info = lhs_ty.intInfo(zcu); | |
| 1715 | 1715 | if (int_info.bits <= 16) { |
| 1716 | 1716 | const stack_offset = try self.allocMem(tuple_size, tuple_align, inst); |
| 1717 | 1717 | |
| ... | ... | @@ -1860,20 +1860,20 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1860 | 1860 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1861 | 1861 | if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none }); |
| 1862 | 1862 | const pt = self.pt; |
| 1863 | const mod = pt.zcu; | |
| 1863 | const zcu = pt.zcu; | |
| 1864 | 1864 | const result: MCValue = result: { |
| 1865 | 1865 | const lhs_ty = self.typeOf(extra.lhs); |
| 1866 | 1866 | const rhs_ty = self.typeOf(extra.rhs); |
| 1867 | 1867 | |
| 1868 | 1868 | const tuple_ty = self.typeOfIndex(inst); |
| 1869 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt)); | |
| 1870 | const tuple_align = tuple_ty.abiAlignment(pt); | |
| 1871 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt)); | |
| 1869 | const tuple_size: u32 = @intCast(tuple_ty.abiSize(zcu)); | |
| 1870 | const tuple_align = tuple_ty.abiAlignment(zcu); | |
| 1871 | const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | |
| 1872 | 1872 | |
| 1873 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 1873 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1874 | 1874 | .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}), |
| 1875 | 1875 | .Int => { |
| 1876 | const int_info = lhs_ty.intInfo(mod); | |
| 1876 | const int_info = lhs_ty.intInfo(zcu); | |
| 1877 | 1877 | if (int_info.bits <= 32) { |
| 1878 | 1878 | const stack_offset = try self.allocMem(tuple_size, tuple_align, inst); |
| 1879 | 1879 | |
| ... | ... | @@ -2020,7 +2020,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2020 | 2020 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2021 | 2021 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2022 | 2022 | const optional_ty = self.typeOfIndex(inst); |
| 2023 | const abi_size: u32 = @intCast(optional_ty.abiSize(pt)); | |
| 2023 | const abi_size: u32 = @intCast(optional_ty.abiSize(pt.zcu)); | |
| 2024 | 2024 | |
| 2025 | 2025 | // Optional with a zero-bit payload type is just a boolean true |
| 2026 | 2026 | if (abi_size == 1) { |
| ... | ... | @@ -2040,17 +2040,17 @@ fn errUnionErr( |
| 2040 | 2040 | maybe_inst: ?Air.Inst.Index, |
| 2041 | 2041 | ) !MCValue { |
| 2042 | 2042 | const pt = self.pt; |
| 2043 | const mod = pt.zcu; | |
| 2044 | const err_ty = error_union_ty.errorUnionSet(mod); | |
| 2045 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2046 | if (err_ty.errorSetIsEmpty(mod)) { | |
| 2043 | const zcu = pt.zcu; | |
| 2044 | const err_ty = error_union_ty.errorUnionSet(zcu); | |
| 2045 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2046 | if (err_ty.errorSetIsEmpty(zcu)) { | |
| 2047 | 2047 | return MCValue{ .immediate = 0 }; |
| 2048 | 2048 | } |
| 2049 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2049 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2050 | 2050 | return try error_union_bind.resolveToMcv(self); |
| 2051 | 2051 | } |
| 2052 | 2052 | |
| 2053 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt)); | |
| 2053 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu)); | |
| 2054 | 2054 | switch (try error_union_bind.resolveToMcv(self)) { |
| 2055 | 2055 | .register => { |
| 2056 | 2056 | var operand_reg: Register = undefined; |
| ... | ... | @@ -2072,7 +2072,7 @@ fn errUnionErr( |
| 2072 | 2072 | ); |
| 2073 | 2073 | |
| 2074 | 2074 | const err_bit_offset = err_offset * 8; |
| 2075 | const err_bit_size: u32 = @intCast(err_ty.abiSize(pt) * 8); | |
| 2075 | const err_bit_size: u32 = @intCast(err_ty.abiSize(zcu) * 8); | |
| 2076 | 2076 | |
| 2077 | 2077 | _ = try self.addInst(.{ |
| 2078 | 2078 | .tag = .ubfx, // errors are unsigned integers |
| ... | ... | @@ -2118,17 +2118,17 @@ fn errUnionPayload( |
| 2118 | 2118 | maybe_inst: ?Air.Inst.Index, |
| 2119 | 2119 | ) !MCValue { |
| 2120 | 2120 | const pt = self.pt; |
| 2121 | const mod = pt.zcu; | |
| 2122 | const err_ty = error_union_ty.errorUnionSet(mod); | |
| 2123 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2124 | if (err_ty.errorSetIsEmpty(mod)) { | |
| 2121 | const zcu = pt.zcu; | |
| 2122 | const err_ty = error_union_ty.errorUnionSet(zcu); | |
| 2123 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2124 | if (err_ty.errorSetIsEmpty(zcu)) { | |
| 2125 | 2125 | return try error_union_bind.resolveToMcv(self); |
| 2126 | 2126 | } |
| 2127 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2127 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2128 | 2128 | return MCValue.none; |
| 2129 | 2129 | } |
| 2130 | 2130 | |
| 2131 | const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, pt)); | |
| 2131 | const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu)); | |
| 2132 | 2132 | switch (try error_union_bind.resolveToMcv(self)) { |
| 2133 | 2133 | .register => { |
| 2134 | 2134 | var operand_reg: Register = undefined; |
| ... | ... | @@ -2150,10 +2150,10 @@ fn errUnionPayload( |
| 2150 | 2150 | ); |
| 2151 | 2151 | |
| 2152 | 2152 | const payload_bit_offset = payload_offset * 8; |
| 2153 | const payload_bit_size: u32 = @intCast(payload_ty.abiSize(pt) * 8); | |
| 2153 | const payload_bit_size: u32 = @intCast(payload_ty.abiSize(zcu) * 8); | |
| 2154 | 2154 | |
| 2155 | 2155 | _ = try self.addInst(.{ |
| 2156 | .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, | |
| 2156 | .tag = if (payload_ty.isSignedInt(zcu)) Mir.Inst.Tag.sbfx else .ubfx, | |
| 2157 | 2157 | .data = .{ .rr_lsb_width = .{ |
| 2158 | 2158 | .rd = dest_reg, |
| 2159 | 2159 | .rn = operand_reg, |
| ... | ... | @@ -2229,20 +2229,20 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 2229 | 2229 | /// T to E!T |
| 2230 | 2230 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2231 | 2231 | const pt = self.pt; |
| 2232 | const mod = pt.zcu; | |
| 2232 | const zcu = pt.zcu; | |
| 2233 | 2233 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2234 | 2234 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2235 | 2235 | const error_union_ty = ty_op.ty.toType(); |
| 2236 | const error_ty = error_union_ty.errorUnionSet(mod); | |
| 2237 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2236 | const error_ty = error_union_ty.errorUnionSet(zcu); | |
| 2237 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2238 | 2238 | const operand = try self.resolveInst(ty_op.operand); |
| 2239 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; | |
| 2239 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result operand; | |
| 2240 | 2240 | |
| 2241 | const abi_size: u32 = @intCast(error_union_ty.abiSize(pt)); | |
| 2242 | const abi_align = error_union_ty.abiAlignment(pt); | |
| 2241 | const abi_size: u32 = @intCast(error_union_ty.abiSize(zcu)); | |
| 2242 | const abi_align = error_union_ty.abiAlignment(zcu); | |
| 2243 | 2243 | const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst)); |
| 2244 | const payload_off = errUnionPayloadOffset(payload_ty, pt); | |
| 2245 | const err_off = errUnionErrorOffset(payload_ty, pt); | |
| 2244 | const payload_off = errUnionPayloadOffset(payload_ty, zcu); | |
| 2245 | const err_off = errUnionErrorOffset(payload_ty, zcu); | |
| 2246 | 2246 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand); |
| 2247 | 2247 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 }); |
| 2248 | 2248 | |
| ... | ... | @@ -2254,20 +2254,20 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2254 | 2254 | /// E to E!T |
| 2255 | 2255 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2256 | 2256 | const pt = self.pt; |
| 2257 | const mod = pt.zcu; | |
| 2257 | const zcu = pt.zcu; | |
| 2258 | 2258 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2259 | 2259 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2260 | 2260 | const error_union_ty = ty_op.ty.toType(); |
| 2261 | const error_ty = error_union_ty.errorUnionSet(mod); | |
| 2262 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2261 | const error_ty = error_union_ty.errorUnionSet(zcu); | |
| 2262 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2263 | 2263 | const operand = try self.resolveInst(ty_op.operand); |
| 2264 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand; | |
| 2264 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result operand; | |
| 2265 | 2265 | |
| 2266 | const abi_size: u32 = @intCast(error_union_ty.abiSize(pt)); | |
| 2267 | const abi_align = error_union_ty.abiAlignment(pt); | |
| 2266 | const abi_size: u32 = @intCast(error_union_ty.abiSize(zcu)); | |
| 2267 | const abi_align = error_union_ty.abiAlignment(zcu); | |
| 2268 | 2268 | const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst)); |
| 2269 | const payload_off = errUnionPayloadOffset(payload_ty, pt); | |
| 2270 | const err_off = errUnionErrorOffset(payload_ty, pt); | |
| 2269 | const payload_off = errUnionPayloadOffset(payload_ty, zcu); | |
| 2270 | const err_off = errUnionErrorOffset(payload_ty, zcu); | |
| 2271 | 2271 | try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand); |
| 2272 | 2272 | try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef); |
| 2273 | 2273 | |
| ... | ... | @@ -2372,9 +2372,9 @@ fn ptrElemVal( |
| 2372 | 2372 | maybe_inst: ?Air.Inst.Index, |
| 2373 | 2373 | ) !MCValue { |
| 2374 | 2374 | const pt = self.pt; |
| 2375 | const mod = pt.zcu; | |
| 2376 | const elem_ty = ptr_ty.childType(mod); | |
| 2377 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 2375 | const zcu = pt.zcu; | |
| 2376 | const elem_ty = ptr_ty.childType(zcu); | |
| 2377 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 2378 | 2378 | |
| 2379 | 2379 | switch (elem_size) { |
| 2380 | 2380 | 1, 4 => { |
| ... | ... | @@ -2432,11 +2432,11 @@ fn ptrElemVal( |
| 2432 | 2432 | |
| 2433 | 2433 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2434 | 2434 | const pt = self.pt; |
| 2435 | const mod = pt.zcu; | |
| 2435 | const zcu = pt.zcu; | |
| 2436 | 2436 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2437 | 2437 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2438 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 2439 | const ptr_ty = slice_ty.slicePtrFieldType(mod); | |
| 2438 | const result: MCValue = if (!slice_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) .dead else result: { | |
| 2439 | const ptr_ty = slice_ty.slicePtrFieldType(zcu); | |
| 2440 | 2440 | |
| 2441 | 2441 | const slice_mcv = try self.resolveInst(bin_op.lhs); |
| 2442 | 2442 | const base_mcv = slicePtr(slice_mcv); |
| ... | ... | @@ -2476,8 +2476,8 @@ fn arrayElemVal( |
| 2476 | 2476 | maybe_inst: ?Air.Inst.Index, |
| 2477 | 2477 | ) InnerError!MCValue { |
| 2478 | 2478 | const pt = self.pt; |
| 2479 | const mod = pt.zcu; | |
| 2480 | const elem_ty = array_ty.childType(mod); | |
| 2479 | const zcu = pt.zcu; | |
| 2480 | const elem_ty = array_ty.childType(zcu); | |
| 2481 | 2481 | |
| 2482 | 2482 | const mcv = try array_bind.resolveToMcv(self); |
| 2483 | 2483 | switch (mcv) { |
| ... | ... | @@ -2533,10 +2533,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2533 | 2533 | |
| 2534 | 2534 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2535 | 2535 | const pt = self.pt; |
| 2536 | const mod = pt.zcu; | |
| 2536 | const zcu = pt.zcu; | |
| 2537 | 2537 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2538 | 2538 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 2539 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 2539 | const result: MCValue = if (!ptr_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) .dead else result: { | |
| 2540 | 2540 | const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs }; |
| 2541 | 2541 | const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs }; |
| 2542 | 2542 | |
| ... | ... | @@ -2668,9 +2668,9 @@ fn reuseOperand( |
| 2668 | 2668 | |
| 2669 | 2669 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 2670 | 2670 | const pt = self.pt; |
| 2671 | const mod = pt.zcu; | |
| 2672 | const elem_ty = ptr_ty.childType(mod); | |
| 2673 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 2671 | const zcu = pt.zcu; | |
| 2672 | const elem_ty = ptr_ty.childType(zcu); | |
| 2673 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 2674 | 2674 | |
| 2675 | 2675 | switch (ptr) { |
| 2676 | 2676 | .none => unreachable, |
| ... | ... | @@ -2746,20 +2746,20 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2746 | 2746 | |
| 2747 | 2747 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2748 | 2748 | const pt = self.pt; |
| 2749 | const mod = pt.zcu; | |
| 2749 | const zcu = pt.zcu; | |
| 2750 | 2750 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2751 | 2751 | const elem_ty = self.typeOfIndex(inst); |
| 2752 | 2752 | const result: MCValue = result: { |
| 2753 | if (!elem_ty.hasRuntimeBits(pt)) | |
| 2753 | if (!elem_ty.hasRuntimeBits(zcu)) | |
| 2754 | 2754 | break :result MCValue.none; |
| 2755 | 2755 | |
| 2756 | 2756 | const ptr = try self.resolveInst(ty_op.operand); |
| 2757 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 2757 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(zcu); | |
| 2758 | 2758 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 2759 | 2759 | break :result MCValue.dead; |
| 2760 | 2760 | |
| 2761 | 2761 | const dest_mcv: MCValue = blk: { |
| 2762 | const ptr_fits_dest = elem_ty.abiSize(pt) <= 4; | |
| 2762 | const ptr_fits_dest = elem_ty.abiSize(zcu) <= 4; | |
| 2763 | 2763 | if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) { |
| 2764 | 2764 | // The MCValue that holds the pointer can be re-used as the value. |
| 2765 | 2765 | break :blk ptr; |
| ... | ... | @@ -2776,7 +2776,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2776 | 2776 | |
| 2777 | 2777 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 2778 | 2778 | const pt = self.pt; |
| 2779 | const elem_size: u32 = @intCast(value_ty.abiSize(pt)); | |
| 2779 | const elem_size: u32 = @intCast(value_ty.abiSize(pt.zcu)); | |
| 2780 | 2780 | |
| 2781 | 2781 | switch (ptr) { |
| 2782 | 2782 | .none => unreachable, |
| ... | ... | @@ -2896,11 +2896,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 2896 | 2896 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 2897 | 2897 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 2898 | 2898 | const pt = self.pt; |
| 2899 | const mod = pt.zcu; | |
| 2899 | const zcu = pt.zcu; | |
| 2900 | 2900 | const mcv = try self.resolveInst(operand); |
| 2901 | 2901 | const ptr_ty = self.typeOf(operand); |
| 2902 | const struct_ty = ptr_ty.childType(mod); | |
| 2903 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt)); | |
| 2902 | const struct_ty = ptr_ty.childType(zcu); | |
| 2903 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, zcu)); | |
| 2904 | 2904 | switch (mcv) { |
| 2905 | 2905 | .ptr_stack_offset => |off| { |
| 2906 | 2906 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
| ... | ... | @@ -2921,12 +2921,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2921 | 2921 | const operand = extra.struct_operand; |
| 2922 | 2922 | const index = extra.field_index; |
| 2923 | 2923 | const pt = self.pt; |
| 2924 | const mod = pt.zcu; | |
| 2924 | const zcu = pt.zcu; | |
| 2925 | 2925 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2926 | 2926 | const mcv = try self.resolveInst(operand); |
| 2927 | 2927 | const struct_ty = self.typeOf(operand); |
| 2928 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt)); | |
| 2929 | const struct_field_ty = struct_ty.structFieldType(index, mod); | |
| 2928 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, zcu)); | |
| 2929 | const struct_field_ty = struct_ty.structFieldType(index, zcu); | |
| 2930 | 2930 | |
| 2931 | 2931 | switch (mcv) { |
| 2932 | 2932 | .dead, .unreach => unreachable, |
| ... | ... | @@ -2989,10 +2989,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2989 | 2989 | ); |
| 2990 | 2990 | |
| 2991 | 2991 | const field_bit_offset = struct_field_offset * 8; |
| 2992 | const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(pt) * 8); | |
| 2992 | const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(zcu) * 8); | |
| 2993 | 2993 | |
| 2994 | 2994 | _ = try self.addInst(.{ |
| 2995 | .tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx, | |
| 2995 | .tag = if (struct_field_ty.isSignedInt(zcu)) Mir.Inst.Tag.sbfx else .ubfx, | |
| 2996 | 2996 | .data = .{ .rr_lsb_width = .{ |
| 2997 | 2997 | .rd = dest_reg, |
| 2998 | 2998 | .rn = operand_reg, |
| ... | ... | @@ -3012,18 +3012,18 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3012 | 3012 | |
| 3013 | 3013 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3014 | 3014 | const pt = self.pt; |
| 3015 | const mod = pt.zcu; | |
| 3015 | const zcu = pt.zcu; | |
| 3016 | 3016 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3017 | 3017 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 3018 | 3018 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3019 | 3019 | const field_ptr = try self.resolveInst(extra.field_ptr); |
| 3020 | const struct_ty = ty_pl.ty.toType().childType(mod); | |
| 3020 | const struct_ty = ty_pl.ty.toType().childType(zcu); | |
| 3021 | 3021 | |
| 3022 | if (struct_ty.zigTypeTag(mod) == .Union) { | |
| 3022 | if (struct_ty.zigTypeTag(zcu) == .Union) { | |
| 3023 | 3023 | return self.fail("TODO implement @fieldParentPtr codegen for unions", .{}); |
| 3024 | 3024 | } |
| 3025 | 3025 | |
| 3026 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, pt)); | |
| 3026 | const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, zcu)); | |
| 3027 | 3027 | switch (field_ptr) { |
| 3028 | 3028 | .ptr_stack_offset => |off| { |
| 3029 | 3029 | break :result MCValue{ .ptr_stack_offset = off + struct_field_offset }; |
| ... | ... | @@ -3407,13 +3407,13 @@ fn addSub( |
| 3407 | 3407 | maybe_inst: ?Air.Inst.Index, |
| 3408 | 3408 | ) InnerError!MCValue { |
| 3409 | 3409 | const pt = self.pt; |
| 3410 | const mod = pt.zcu; | |
| 3411 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3410 | const zcu = pt.zcu; | |
| 3411 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3412 | 3412 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3413 | 3413 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3414 | 3414 | .Int => { |
| 3415 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 3416 | const int_info = lhs_ty.intInfo(mod); | |
| 3415 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 3416 | const int_info = lhs_ty.intInfo(zcu); | |
| 3417 | 3417 | if (int_info.bits <= 32) { |
| 3418 | 3418 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); |
| 3419 | 3419 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| ... | ... | @@ -3464,13 +3464,13 @@ fn mul( |
| 3464 | 3464 | maybe_inst: ?Air.Inst.Index, |
| 3465 | 3465 | ) InnerError!MCValue { |
| 3466 | 3466 | const pt = self.pt; |
| 3467 | const mod = pt.zcu; | |
| 3468 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3467 | const zcu = pt.zcu; | |
| 3468 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3469 | 3469 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3470 | 3470 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3471 | 3471 | .Int => { |
| 3472 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 3473 | const int_info = lhs_ty.intInfo(mod); | |
| 3472 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 3473 | const int_info = lhs_ty.intInfo(zcu); | |
| 3474 | 3474 | if (int_info.bits <= 32) { |
| 3475 | 3475 | // TODO add optimisations for multiplication |
| 3476 | 3476 | // with immediates, for example a * 2 can be |
| ... | ... | @@ -3498,8 +3498,8 @@ fn divFloat( |
| 3498 | 3498 | _ = maybe_inst; |
| 3499 | 3499 | |
| 3500 | 3500 | const pt = self.pt; |
| 3501 | const mod = pt.zcu; | |
| 3502 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3501 | const zcu = pt.zcu; | |
| 3502 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3503 | 3503 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3504 | 3504 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3505 | 3505 | else => unreachable, |
| ... | ... | @@ -3515,13 +3515,13 @@ fn divTrunc( |
| 3515 | 3515 | maybe_inst: ?Air.Inst.Index, |
| 3516 | 3516 | ) InnerError!MCValue { |
| 3517 | 3517 | const pt = self.pt; |
| 3518 | const mod = pt.zcu; | |
| 3519 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3518 | const zcu = pt.zcu; | |
| 3519 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3520 | 3520 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3521 | 3521 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3522 | 3522 | .Int => { |
| 3523 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 3524 | const int_info = lhs_ty.intInfo(mod); | |
| 3523 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 3524 | const int_info = lhs_ty.intInfo(zcu); | |
| 3525 | 3525 | if (int_info.bits <= 32) { |
| 3526 | 3526 | switch (int_info.signedness) { |
| 3527 | 3527 | .signed => { |
| ... | ... | @@ -3559,13 +3559,13 @@ fn divFloor( |
| 3559 | 3559 | maybe_inst: ?Air.Inst.Index, |
| 3560 | 3560 | ) InnerError!MCValue { |
| 3561 | 3561 | const pt = self.pt; |
| 3562 | const mod = pt.zcu; | |
| 3563 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3562 | const zcu = pt.zcu; | |
| 3563 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3564 | 3564 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3565 | 3565 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3566 | 3566 | .Int => { |
| 3567 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 3568 | const int_info = lhs_ty.intInfo(mod); | |
| 3567 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 3568 | const int_info = lhs_ty.intInfo(zcu); | |
| 3569 | 3569 | if (int_info.bits <= 32) { |
| 3570 | 3570 | switch (int_info.signedness) { |
| 3571 | 3571 | .signed => { |
| ... | ... | @@ -3608,8 +3608,8 @@ fn divExact( |
| 3608 | 3608 | _ = maybe_inst; |
| 3609 | 3609 | |
| 3610 | 3610 | const pt = self.pt; |
| 3611 | const mod = pt.zcu; | |
| 3612 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3611 | const zcu = pt.zcu; | |
| 3612 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3613 | 3613 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3614 | 3614 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3615 | 3615 | .Int => return self.fail("TODO ARM div_exact", .{}), |
| ... | ... | @@ -3626,17 +3626,17 @@ fn rem( |
| 3626 | 3626 | maybe_inst: ?Air.Inst.Index, |
| 3627 | 3627 | ) InnerError!MCValue { |
| 3628 | 3628 | const pt = self.pt; |
| 3629 | const mod = pt.zcu; | |
| 3630 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3629 | const zcu = pt.zcu; | |
| 3630 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3631 | 3631 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3632 | 3632 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3633 | 3633 | .Int => { |
| 3634 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 3635 | const int_info = lhs_ty.intInfo(mod); | |
| 3634 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 3635 | const int_info = lhs_ty.intInfo(zcu); | |
| 3636 | 3636 | if (int_info.bits <= 32) { |
| 3637 | 3637 | switch (int_info.signedness) { |
| 3638 | 3638 | .signed => { |
| 3639 | return self.fail("TODO ARM signed integer mod", .{}); | |
| 3639 | return self.fail("TODO ARM signed integer zcu", .{}); | |
| 3640 | 3640 | }, |
| 3641 | 3641 | .unsigned => { |
| 3642 | 3642 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| ... | ... | @@ -3667,10 +3667,10 @@ fn rem( |
| 3667 | 3667 | |
| 3668 | 3668 | return MCValue{ .register = dest_reg }; |
| 3669 | 3669 | } else { |
| 3670 | return self.fail("TODO ARM integer mod by constants", .{}); | |
| 3670 | return self.fail("TODO ARM integer zcu by constants", .{}); | |
| 3671 | 3671 | } |
| 3672 | 3672 | } else { |
| 3673 | return self.fail("TODO ARM integer mod", .{}); | |
| 3673 | return self.fail("TODO ARM integer zcu", .{}); | |
| 3674 | 3674 | } |
| 3675 | 3675 | }, |
| 3676 | 3676 | } |
| ... | ... | @@ -3696,11 +3696,11 @@ fn modulo( |
| 3696 | 3696 | _ = maybe_inst; |
| 3697 | 3697 | |
| 3698 | 3698 | const pt = self.pt; |
| 3699 | const mod = pt.zcu; | |
| 3700 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3699 | const zcu = pt.zcu; | |
| 3700 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3701 | 3701 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3702 | 3702 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3703 | .Int => return self.fail("TODO ARM mod", .{}), | |
| 3703 | .Int => return self.fail("TODO ARM zcu", .{}), | |
| 3704 | 3704 | else => unreachable, |
| 3705 | 3705 | } |
| 3706 | 3706 | } |
| ... | ... | @@ -3715,11 +3715,11 @@ fn wrappingArithmetic( |
| 3715 | 3715 | maybe_inst: ?Air.Inst.Index, |
| 3716 | 3716 | ) InnerError!MCValue { |
| 3717 | 3717 | const pt = self.pt; |
| 3718 | const mod = pt.zcu; | |
| 3719 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3718 | const zcu = pt.zcu; | |
| 3719 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3720 | 3720 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3721 | 3721 | .Int => { |
| 3722 | const int_info = lhs_ty.intInfo(mod); | |
| 3722 | const int_info = lhs_ty.intInfo(zcu); | |
| 3723 | 3723 | if (int_info.bits <= 32) { |
| 3724 | 3724 | // Generate an add/sub/mul |
| 3725 | 3725 | const result: MCValue = switch (tag) { |
| ... | ... | @@ -3754,12 +3754,12 @@ fn bitwise( |
| 3754 | 3754 | maybe_inst: ?Air.Inst.Index, |
| 3755 | 3755 | ) InnerError!MCValue { |
| 3756 | 3756 | const pt = self.pt; |
| 3757 | const mod = pt.zcu; | |
| 3758 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3757 | const zcu = pt.zcu; | |
| 3758 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3759 | 3759 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3760 | 3760 | .Int => { |
| 3761 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 3762 | const int_info = lhs_ty.intInfo(mod); | |
| 3761 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 3762 | const int_info = lhs_ty.intInfo(zcu); | |
| 3763 | 3763 | if (int_info.bits <= 32) { |
| 3764 | 3764 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); |
| 3765 | 3765 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| ... | ... | @@ -3800,17 +3800,17 @@ fn shiftExact( |
| 3800 | 3800 | maybe_inst: ?Air.Inst.Index, |
| 3801 | 3801 | ) InnerError!MCValue { |
| 3802 | 3802 | const pt = self.pt; |
| 3803 | const mod = pt.zcu; | |
| 3804 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3803 | const zcu = pt.zcu; | |
| 3804 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3805 | 3805 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3806 | 3806 | .Int => { |
| 3807 | const int_info = lhs_ty.intInfo(mod); | |
| 3807 | const int_info = lhs_ty.intInfo(zcu); | |
| 3808 | 3808 | if (int_info.bits <= 32) { |
| 3809 | 3809 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| 3810 | 3810 | |
| 3811 | 3811 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 3812 | 3812 | .shl_exact => .lsl, |
| 3813 | .shr_exact => switch (lhs_ty.intInfo(mod).signedness) { | |
| 3813 | .shr_exact => switch (lhs_ty.intInfo(zcu).signedness) { | |
| 3814 | 3814 | .signed => Mir.Inst.Tag.asr, |
| 3815 | 3815 | .unsigned => Mir.Inst.Tag.lsr, |
| 3816 | 3816 | }, |
| ... | ... | @@ -3840,11 +3840,11 @@ fn shiftNormal( |
| 3840 | 3840 | maybe_inst: ?Air.Inst.Index, |
| 3841 | 3841 | ) InnerError!MCValue { |
| 3842 | 3842 | const pt = self.pt; |
| 3843 | const mod = pt.zcu; | |
| 3844 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3843 | const zcu = pt.zcu; | |
| 3844 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3845 | 3845 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3846 | 3846 | .Int => { |
| 3847 | const int_info = lhs_ty.intInfo(mod); | |
| 3847 | const int_info = lhs_ty.intInfo(zcu); | |
| 3848 | 3848 | if (int_info.bits <= 32) { |
| 3849 | 3849 | // Generate a shl_exact/shr_exact |
| 3850 | 3850 | const result: MCValue = switch (tag) { |
| ... | ... | @@ -3884,8 +3884,8 @@ fn booleanOp( |
| 3884 | 3884 | maybe_inst: ?Air.Inst.Index, |
| 3885 | 3885 | ) InnerError!MCValue { |
| 3886 | 3886 | const pt = self.pt; |
| 3887 | const mod = pt.zcu; | |
| 3888 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3887 | const zcu = pt.zcu; | |
| 3888 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3889 | 3889 | .Bool => { |
| 3890 | 3890 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); |
| 3891 | 3891 | const rhs_immediate = try rhs_bind.resolveToImmediate(self); |
| ... | ... | @@ -3919,17 +3919,17 @@ fn ptrArithmetic( |
| 3919 | 3919 | maybe_inst: ?Air.Inst.Index, |
| 3920 | 3920 | ) InnerError!MCValue { |
| 3921 | 3921 | const pt = self.pt; |
| 3922 | const mod = pt.zcu; | |
| 3923 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3922 | const zcu = pt.zcu; | |
| 3923 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3924 | 3924 | .Pointer => { |
| 3925 | assert(rhs_ty.eql(Type.usize, mod)); | |
| 3925 | assert(rhs_ty.eql(Type.usize, zcu)); | |
| 3926 | 3926 | |
| 3927 | 3927 | const ptr_ty = lhs_ty; |
| 3928 | const elem_ty = switch (ptr_ty.ptrSize(mod)) { | |
| 3929 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | |
| 3930 | else => ptr_ty.childType(mod), | |
| 3928 | const elem_ty = switch (ptr_ty.ptrSize(zcu)) { | |
| 3929 | .One => ptr_ty.childType(zcu).childType(zcu), // ptr to array, so get array element type | |
| 3930 | else => ptr_ty.childType(zcu), | |
| 3931 | 3931 | }; |
| 3932 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 3932 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 3933 | 3933 | |
| 3934 | 3934 | const base_tag: Air.Inst.Tag = switch (tag) { |
| 3935 | 3935 | .ptr_add => .add, |
| ... | ... | @@ -3957,12 +3957,12 @@ fn ptrArithmetic( |
| 3957 | 3957 | |
| 3958 | 3958 | fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3959 | 3959 | const pt = self.pt; |
| 3960 | const mod = pt.zcu; | |
| 3961 | const abi_size = ty.abiSize(pt); | |
| 3960 | const zcu = pt.zcu; | |
| 3961 | const abi_size = ty.abiSize(zcu); | |
| 3962 | 3962 | |
| 3963 | 3963 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3964 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb, | |
| 3965 | 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh else .ldrh, | |
| 3964 | 1 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsb else .ldrb, | |
| 3965 | 2 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsh else .ldrh, | |
| 3966 | 3966 | 3, 4 => .ldr, |
| 3967 | 3967 | else => unreachable, |
| 3968 | 3968 | }; |
| ... | ... | @@ -3979,7 +3979,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) |
| 3979 | 3979 | } }; |
| 3980 | 3980 | |
| 3981 | 3981 | const data: Mir.Inst.Data = switch (abi_size) { |
| 3982 | 1 => if (ty.isSignedInt(mod)) rr_extra_offset else rr_offset, | |
| 3982 | 1 => if (ty.isSignedInt(zcu)) rr_extra_offset else rr_offset, | |
| 3983 | 3983 | 2 => rr_extra_offset, |
| 3984 | 3984 | 3, 4 => rr_offset, |
| 3985 | 3985 | else => unreachable, |
| ... | ... | @@ -3993,7 +3993,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) |
| 3993 | 3993 | |
| 3994 | 3994 | fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void { |
| 3995 | 3995 | const pt = self.pt; |
| 3996 | const abi_size = ty.abiSize(pt); | |
| 3996 | const abi_size = ty.abiSize(pt.zcu); | |
| 3997 | 3997 | |
| 3998 | 3998 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 3999 | 3999 | 1 => .strb, |
| ... | ... | @@ -4253,12 +4253,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4253 | 4253 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 4254 | 4254 | const ty = self.typeOf(callee); |
| 4255 | 4255 | const pt = self.pt; |
| 4256 | const mod = pt.zcu; | |
| 4257 | const ip = &mod.intern_pool; | |
| 4256 | const zcu = pt.zcu; | |
| 4257 | const ip = &zcu.intern_pool; | |
| 4258 | 4258 | |
| 4259 | const fn_ty = switch (ty.zigTypeTag(mod)) { | |
| 4259 | const fn_ty = switch (ty.zigTypeTag(zcu)) { | |
| 4260 | 4260 | .Fn => ty, |
| 4261 | .Pointer => ty.childType(mod), | |
| 4261 | .Pointer => ty.childType(zcu), | |
| 4262 | 4262 | else => unreachable, |
| 4263 | 4263 | }; |
| 4264 | 4264 | |
| ... | ... | @@ -4283,9 +4283,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4283 | 4283 | // untouched by the parameter passing code |
| 4284 | 4284 | const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: { |
| 4285 | 4285 | log.debug("airCall: return by reference", .{}); |
| 4286 | const ret_ty = fn_ty.fnReturnType(mod); | |
| 4287 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 4288 | const ret_abi_align = ret_ty.abiAlignment(pt); | |
| 4286 | const ret_ty = fn_ty.fnReturnType(zcu); | |
| 4287 | const ret_abi_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 4288 | const ret_abi_align = ret_ty.abiAlignment(zcu); | |
| 4289 | 4289 | const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); |
| 4290 | 4290 | |
| 4291 | 4291 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| ... | ... | @@ -4335,7 +4335,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4335 | 4335 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 4336 | 4336 | }, |
| 4337 | 4337 | } else { |
| 4338 | assert(ty.zigTypeTag(mod) == .Pointer); | |
| 4338 | assert(ty.zigTypeTag(zcu) == .Pointer); | |
| 4339 | 4339 | const mcv = try self.resolveInst(callee); |
| 4340 | 4340 | |
| 4341 | 4341 | try self.genSetReg(Type.usize, .lr, mcv); |
| ... | ... | @@ -4370,7 +4370,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4370 | 4370 | if (RegisterManager.indexOfRegIntoTracked(reg) == null) { |
| 4371 | 4371 | // Save function return value into a tracked register |
| 4372 | 4372 | log.debug("airCall: copying {} as it is not tracked", .{reg}); |
| 4373 | const new_reg = try self.copyToTmpRegister(fn_ty.fnReturnType(mod), info.return_value); | |
| 4373 | const new_reg = try self.copyToTmpRegister(fn_ty.fnReturnType(zcu), info.return_value); | |
| 4374 | 4374 | break :result MCValue{ .register = new_reg }; |
| 4375 | 4375 | } |
| 4376 | 4376 | }, |
| ... | ... | @@ -4395,15 +4395,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4395 | 4395 | |
| 4396 | 4396 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4397 | 4397 | const pt = self.pt; |
| 4398 | const mod = pt.zcu; | |
| 4398 | const zcu = pt.zcu; | |
| 4399 | 4399 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4400 | 4400 | const operand = try self.resolveInst(un_op); |
| 4401 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 4401 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 4402 | 4402 | |
| 4403 | 4403 | switch (self.ret_mcv) { |
| 4404 | 4404 | .none => {}, |
| 4405 | 4405 | .immediate => { |
| 4406 | assert(ret_ty.isError(mod)); | |
| 4406 | assert(ret_ty.isError(zcu)); | |
| 4407 | 4407 | }, |
| 4408 | 4408 | .register => |reg| { |
| 4409 | 4409 | // Return result by value |
| ... | ... | @@ -4428,11 +4428,11 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4428 | 4428 | |
| 4429 | 4429 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4430 | 4430 | const pt = self.pt; |
| 4431 | const mod = pt.zcu; | |
| 4431 | const zcu = pt.zcu; | |
| 4432 | 4432 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4433 | 4433 | const ptr = try self.resolveInst(un_op); |
| 4434 | 4434 | const ptr_ty = self.typeOf(un_op); |
| 4435 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 4435 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 4436 | 4436 | |
| 4437 | 4437 | switch (self.ret_mcv) { |
| 4438 | 4438 | .none => {}, |
| ... | ... | @@ -4452,8 +4452,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4452 | 4452 | // location. |
| 4453 | 4453 | const op_inst = un_op.toIndex().?; |
| 4454 | 4454 | if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) { |
| 4455 | const abi_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 4456 | const abi_align = ret_ty.abiAlignment(pt); | |
| 4455 | const abi_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 4456 | const abi_align = ret_ty.abiAlignment(zcu); | |
| 4457 | 4457 | |
| 4458 | 4458 | const offset = try self.allocMem(abi_size, abi_align, null); |
| 4459 | 4459 | |
| ... | ... | @@ -4490,20 +4490,20 @@ fn cmp( |
| 4490 | 4490 | op: math.CompareOperator, |
| 4491 | 4491 | ) !MCValue { |
| 4492 | 4492 | const pt = self.pt; |
| 4493 | const mod = pt.zcu; | |
| 4494 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { | |
| 4493 | const zcu = pt.zcu; | |
| 4494 | const int_ty = switch (lhs_ty.zigTypeTag(zcu)) { | |
| 4495 | 4495 | .Optional => blk: { |
| 4496 | const payload_ty = lhs_ty.optionalChild(mod); | |
| 4497 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4496 | const payload_ty = lhs_ty.optionalChild(zcu); | |
| 4497 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4498 | 4498 | break :blk Type.u1; |
| 4499 | } else if (lhs_ty.isPtrLikeOptional(mod)) { | |
| 4499 | } else if (lhs_ty.isPtrLikeOptional(zcu)) { | |
| 4500 | 4500 | break :blk Type.usize; |
| 4501 | 4501 | } else { |
| 4502 | 4502 | return self.fail("TODO ARM cmp non-pointer optionals", .{}); |
| 4503 | 4503 | } |
| 4504 | 4504 | }, |
| 4505 | 4505 | .Float => return self.fail("TODO ARM cmp floats", .{}), |
| 4506 | .Enum => lhs_ty.intTagType(mod), | |
| 4506 | .Enum => lhs_ty.intTagType(zcu), | |
| 4507 | 4507 | .Int => lhs_ty, |
| 4508 | 4508 | .Bool => Type.u1, |
| 4509 | 4509 | .Pointer => Type.usize, |
| ... | ... | @@ -4511,7 +4511,7 @@ fn cmp( |
| 4511 | 4511 | else => unreachable, |
| 4512 | 4512 | }; |
| 4513 | 4513 | |
| 4514 | const int_info = int_ty.intInfo(mod); | |
| 4514 | const int_info = int_ty.intInfo(zcu); | |
| 4515 | 4515 | if (int_info.bits <= 32) { |
| 4516 | 4516 | try self.spillCompareFlagsIfOccupied(); |
| 4517 | 4517 | |
| ... | ... | @@ -4597,10 +4597,10 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4597 | 4597 | |
| 4598 | 4598 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4599 | 4599 | const pt = self.pt; |
| 4600 | const mod = pt.zcu; | |
| 4600 | const zcu = pt.zcu; | |
| 4601 | 4601 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4602 | 4602 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 4603 | const func = mod.funcInfo(extra.data.func); | |
| 4603 | const func = zcu.funcInfo(extra.data.func); | |
| 4604 | 4604 | // TODO emit debug info for function change |
| 4605 | 4605 | _ = func; |
| 4606 | 4606 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); |
| ... | ... | @@ -4810,9 +4810,9 @@ fn isNull( |
| 4810 | 4810 | operand_ty: Type, |
| 4811 | 4811 | ) !MCValue { |
| 4812 | 4812 | const pt = self.pt; |
| 4813 | const mod = pt.zcu; | |
| 4814 | if (operand_ty.isPtrLikeOptional(mod)) { | |
| 4815 | assert(operand_ty.abiSize(pt) == 4); | |
| 4813 | const zcu = pt.zcu; | |
| 4814 | if (operand_ty.isPtrLikeOptional(zcu)) { | |
| 4815 | assert(operand_ty.abiSize(zcu) == 4); | |
| 4816 | 4816 | |
| 4817 | 4817 | const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } }; |
| 4818 | 4818 | return self.cmp(operand_bind, imm_bind, Type.usize, .eq); |
| ... | ... | @@ -4845,12 +4845,12 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4845 | 4845 | |
| 4846 | 4846 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4847 | 4847 | const pt = self.pt; |
| 4848 | const mod = pt.zcu; | |
| 4848 | const zcu = pt.zcu; | |
| 4849 | 4849 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4850 | 4850 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4851 | 4851 | const operand_ptr = try self.resolveInst(un_op); |
| 4852 | 4852 | const ptr_ty = self.typeOf(un_op); |
| 4853 | const elem_ty = ptr_ty.childType(mod); | |
| 4853 | const elem_ty = ptr_ty.childType(zcu); | |
| 4854 | 4854 | |
| 4855 | 4855 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 4856 | 4856 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -4873,12 +4873,12 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4873 | 4873 | |
| 4874 | 4874 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4875 | 4875 | const pt = self.pt; |
| 4876 | const mod = pt.zcu; | |
| 4876 | const zcu = pt.zcu; | |
| 4877 | 4877 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4878 | 4878 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4879 | 4879 | const operand_ptr = try self.resolveInst(un_op); |
| 4880 | 4880 | const ptr_ty = self.typeOf(un_op); |
| 4881 | const elem_ty = ptr_ty.childType(mod); | |
| 4881 | const elem_ty = ptr_ty.childType(zcu); | |
| 4882 | 4882 | |
| 4883 | 4883 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 4884 | 4884 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -4894,10 +4894,10 @@ fn isErr( |
| 4894 | 4894 | error_union_ty: Type, |
| 4895 | 4895 | ) !MCValue { |
| 4896 | 4896 | const pt = self.pt; |
| 4897 | const mod = pt.zcu; | |
| 4898 | const error_type = error_union_ty.errorUnionSet(mod); | |
| 4897 | const zcu = pt.zcu; | |
| 4898 | const error_type = error_union_ty.errorUnionSet(zcu); | |
| 4899 | 4899 | |
| 4900 | if (error_type.errorSetIsEmpty(mod)) { | |
| 4900 | if (error_type.errorSetIsEmpty(zcu)) { | |
| 4901 | 4901 | return MCValue{ .immediate = 0 }; // always false |
| 4902 | 4902 | } |
| 4903 | 4903 | |
| ... | ... | @@ -4937,12 +4937,12 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4937 | 4937 | |
| 4938 | 4938 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4939 | 4939 | const pt = self.pt; |
| 4940 | const mod = pt.zcu; | |
| 4940 | const zcu = pt.zcu; | |
| 4941 | 4941 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4942 | 4942 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4943 | 4943 | const operand_ptr = try self.resolveInst(un_op); |
| 4944 | 4944 | const ptr_ty = self.typeOf(un_op); |
| 4945 | const elem_ty = ptr_ty.childType(mod); | |
| 4945 | const elem_ty = ptr_ty.childType(zcu); | |
| 4946 | 4946 | |
| 4947 | 4947 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 4948 | 4948 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -4965,12 +4965,12 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4965 | 4965 | |
| 4966 | 4966 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4967 | 4967 | const pt = self.pt; |
| 4968 | const mod = pt.zcu; | |
| 4968 | const zcu = pt.zcu; | |
| 4969 | 4969 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4970 | 4970 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4971 | 4971 | const operand_ptr = try self.resolveInst(un_op); |
| 4972 | 4972 | const ptr_ty = self.typeOf(un_op); |
| 4973 | const elem_ty = ptr_ty.childType(mod); | |
| 4973 | const elem_ty = ptr_ty.childType(zcu); | |
| 4974 | 4974 | |
| 4975 | 4975 | const operand = try self.allocRegOrMem(elem_ty, true, null); |
| 4976 | 4976 | try self.load(operand, operand_ptr, ptr_ty); |
| ... | ... | @@ -5184,10 +5184,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 5184 | 5184 | } |
| 5185 | 5185 | |
| 5186 | 5186 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 5187 | const pt = self.pt; | |
| 5187 | const zcu = self.pt.zcu; | |
| 5188 | 5188 | const block_data = self.blocks.getPtr(block).?; |
| 5189 | 5189 | |
| 5190 | if (self.typeOf(operand).hasRuntimeBits(pt)) { | |
| 5190 | if (self.typeOf(operand).hasRuntimeBits(zcu)) { | |
| 5191 | 5191 | const operand_mcv = try self.resolveInst(operand); |
| 5192 | 5192 | const block_mcv = block_data.mcv; |
| 5193 | 5193 | if (block_mcv == .none) { |
| ... | ... | @@ -5356,8 +5356,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5356 | 5356 | |
| 5357 | 5357 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5358 | 5358 | const pt = self.pt; |
| 5359 | const mod = pt.zcu; | |
| 5360 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 5359 | const zcu = pt.zcu; | |
| 5360 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 5361 | 5361 | switch (mcv) { |
| 5362 | 5362 | .dead => unreachable, |
| 5363 | 5363 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -5434,11 +5434,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5434 | 5434 | const reg_lock = self.register_manager.lockReg(reg); |
| 5435 | 5435 | defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg); |
| 5436 | 5436 | |
| 5437 | const wrapped_ty = ty.structFieldType(0, mod); | |
| 5437 | const wrapped_ty = ty.structFieldType(0, zcu); | |
| 5438 | 5438 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg }); |
| 5439 | 5439 | |
| 5440 | const overflow_bit_ty = ty.structFieldType(1, mod); | |
| 5441 | const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, pt)); | |
| 5440 | const overflow_bit_ty = ty.structFieldType(1, zcu); | |
| 5441 | const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, zcu)); | |
| 5442 | 5442 | const cond_reg = try self.register_manager.allocReg(null, gp); |
| 5443 | 5443 | |
| 5444 | 5444 | // C flag: movcs reg, #1 |
| ... | ... | @@ -5519,7 +5519,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5519 | 5519 | |
| 5520 | 5520 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 5521 | 5521 | const pt = self.pt; |
| 5522 | const mod = pt.zcu; | |
| 5522 | const zcu = pt.zcu; | |
| 5523 | 5523 | switch (mcv) { |
| 5524 | 5524 | .dead => unreachable, |
| 5525 | 5525 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -5694,17 +5694,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5694 | 5694 | }, |
| 5695 | 5695 | .stack_offset => |off| { |
| 5696 | 5696 | // TODO: maybe addressing from sp instead of fp |
| 5697 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 5697 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 5698 | 5698 | |
| 5699 | 5699 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 5700 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb, | |
| 5701 | 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh else .ldrh, | |
| 5700 | 1 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsb else .ldrb, | |
| 5701 | 2 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsh else .ldrh, | |
| 5702 | 5702 | 3, 4 => .ldr, |
| 5703 | 5703 | else => unreachable, |
| 5704 | 5704 | }; |
| 5705 | 5705 | |
| 5706 | 5706 | const extra_offset = switch (abi_size) { |
| 5707 | 1 => ty.isSignedInt(mod), | |
| 5707 | 1 => ty.isSignedInt(zcu), | |
| 5708 | 5708 | 2 => true, |
| 5709 | 5709 | 3, 4 => false, |
| 5710 | 5710 | else => unreachable, |
| ... | ... | @@ -5745,11 +5745,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5745 | 5745 | } |
| 5746 | 5746 | }, |
| 5747 | 5747 | .stack_argument_offset => |off| { |
| 5748 | const abi_size = ty.abiSize(pt); | |
| 5748 | const abi_size = ty.abiSize(zcu); | |
| 5749 | 5749 | |
| 5750 | 5750 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| 5751 | 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument, | |
| 5752 | 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument, | |
| 5751 | 1 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument, | |
| 5752 | 2 => if (ty.isSignedInt(zcu)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument, | |
| 5753 | 5753 | 3, 4 => .ldr_stack_argument, |
| 5754 | 5754 | else => unreachable, |
| 5755 | 5755 | }; |
| ... | ... | @@ -5767,7 +5767,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5767 | 5767 | |
| 5768 | 5768 | fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 5769 | 5769 | const pt = self.pt; |
| 5770 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 5770 | const abi_size: u32 = @intCast(ty.abiSize(pt.zcu)); | |
| 5771 | 5771 | switch (mcv) { |
| 5772 | 5772 | .dead => unreachable, |
| 5773 | 5773 | .none, .unreach => return, |
| ... | ... | @@ -5923,13 +5923,13 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 5923 | 5923 | |
| 5924 | 5924 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 5925 | 5925 | const pt = self.pt; |
| 5926 | const mod = pt.zcu; | |
| 5926 | const zcu = pt.zcu; | |
| 5927 | 5927 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5928 | 5928 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5929 | 5929 | const ptr_ty = self.typeOf(ty_op.operand); |
| 5930 | 5930 | const ptr = try self.resolveInst(ty_op.operand); |
| 5931 | const array_ty = ptr_ty.childType(mod); | |
| 5932 | const array_len: u32 = @intCast(array_ty.arrayLen(mod)); | |
| 5931 | const array_ty = ptr_ty.childType(zcu); | |
| 5932 | const array_len: u32 = @intCast(array_ty.arrayLen(zcu)); | |
| 5933 | 5933 | |
| 5934 | 5934 | const stack_offset = try self.allocMem(8, .@"8", inst); |
| 5935 | 5935 | try self.genSetStack(ptr_ty, stack_offset, ptr); |
| ... | ... | @@ -6043,9 +6043,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 6043 | 6043 | |
| 6044 | 6044 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 6045 | 6045 | const pt = self.pt; |
| 6046 | const mod = pt.zcu; | |
| 6046 | const zcu = pt.zcu; | |
| 6047 | 6047 | const vector_ty = self.typeOfIndex(inst); |
| 6048 | const len = vector_ty.vectorLen(mod); | |
| 6048 | const len = vector_ty.vectorLen(zcu); | |
| 6049 | 6049 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6050 | 6050 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]); |
| 6051 | 6051 | const result: MCValue = res: { |
| ... | ... | @@ -6095,8 +6095,8 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 6095 | 6095 | const result: MCValue = result: { |
| 6096 | 6096 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; |
| 6097 | 6097 | const error_union_ty = self.typeOf(pl_op.operand); |
| 6098 | const error_union_size: u32 = @intCast(error_union_ty.abiSize(pt)); | |
| 6099 | const error_union_align = error_union_ty.abiAlignment(pt); | |
| 6098 | const error_union_size: u32 = @intCast(error_union_ty.abiSize(pt.zcu)); | |
| 6099 | const error_union_align = error_union_ty.abiAlignment(pt.zcu); | |
| 6100 | 6100 | |
| 6101 | 6101 | // The error union will die in the body. However, we need the |
| 6102 | 6102 | // error union after the body in order to extract the payload |
| ... | ... | @@ -6126,11 +6126,11 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6126 | 6126 | |
| 6127 | 6127 | fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6128 | 6128 | const pt = self.pt; |
| 6129 | const mod = pt.zcu; | |
| 6129 | const zcu = pt.zcu; | |
| 6130 | 6130 | |
| 6131 | 6131 | // If the type has no codegen bits, no need to store it. |
| 6132 | 6132 | const inst_ty = self.typeOf(inst); |
| 6133 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod)) | |
| 6133 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !inst_ty.isError(zcu)) | |
| 6134 | 6134 | return MCValue{ .none = {} }; |
| 6135 | 6135 | |
| 6136 | 6136 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?); |
| ... | ... | @@ -6189,9 +6189,9 @@ const CallMCValues = struct { |
| 6189 | 6189 | /// Caller must call `CallMCValues.deinit`. |
| 6190 | 6190 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6191 | 6191 | const pt = self.pt; |
| 6192 | const mod = pt.zcu; | |
| 6193 | const ip = &mod.intern_pool; | |
| 6194 | const fn_info = mod.typeToFunc(fn_ty).?; | |
| 6192 | const zcu = pt.zcu; | |
| 6193 | const ip = &zcu.intern_pool; | |
| 6194 | const fn_info = zcu.typeToFunc(fn_ty).?; | |
| 6195 | 6195 | const cc = fn_info.cc; |
| 6196 | 6196 | var result: CallMCValues = .{ |
| 6197 | 6197 | .args = try self.gpa.alloc(MCValue, fn_info.param_types.len), |
| ... | ... | @@ -6202,7 +6202,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6202 | 6202 | }; |
| 6203 | 6203 | errdefer self.gpa.free(result.args); |
| 6204 | 6204 | |
| 6205 | const ret_ty = fn_ty.fnReturnType(mod); | |
| 6205 | const ret_ty = fn_ty.fnReturnType(zcu); | |
| 6206 | 6206 | |
| 6207 | 6207 | switch (cc) { |
| 6208 | 6208 | .Naked => { |
| ... | ... | @@ -6217,12 +6217,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6217 | 6217 | var ncrn: usize = 0; // Next Core Register Number |
| 6218 | 6218 | var nsaa: u32 = 0; // Next stacked argument address |
| 6219 | 6219 | |
| 6220 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 6220 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 6221 | 6221 | result.return_value = .{ .unreach = {} }; |
| 6222 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 6222 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 6223 | 6223 | result.return_value = .{ .none = {} }; |
| 6224 | 6224 | } else { |
| 6225 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 6225 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 6226 | 6226 | // TODO handle cases where multiple registers are used |
| 6227 | 6227 | if (ret_ty_size <= 4) { |
| 6228 | 6228 | result.return_value = .{ .register = c_abi_int_return_regs[0] }; |
| ... | ... | @@ -6237,10 +6237,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6237 | 6237 | } |
| 6238 | 6238 | |
| 6239 | 6239 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6240 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") | |
| 6240 | if (Type.fromInterned(ty).abiAlignment(zcu) == .@"8") | |
| 6241 | 6241 | ncrn = std.mem.alignForward(usize, ncrn, 2); |
| 6242 | 6242 | |
| 6243 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt)); | |
| 6243 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(zcu)); | |
| 6244 | 6244 | if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) { |
| 6245 | 6245 | if (param_size <= 4) { |
| 6246 | 6246 | result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] }; |
| ... | ... | @@ -6252,7 +6252,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6252 | 6252 | return self.fail("TODO MCValues split between registers and stack", .{}); |
| 6253 | 6253 | } else { |
| 6254 | 6254 | ncrn = 4; |
| 6255 | if (Type.fromInterned(ty).abiAlignment(pt) == .@"8") | |
| 6255 | if (Type.fromInterned(ty).abiAlignment(zcu) == .@"8") | |
| 6256 | 6256 | nsaa = std.mem.alignForward(u32, nsaa, 8); |
| 6257 | 6257 | |
| 6258 | 6258 | result_arg.* = .{ .stack_argument_offset = nsaa }; |
| ... | ... | @@ -6264,14 +6264,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6264 | 6264 | result.stack_align = 8; |
| 6265 | 6265 | }, |
| 6266 | 6266 | .Unspecified => { |
| 6267 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 6267 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 6268 | 6268 | result.return_value = .{ .unreach = {} }; |
| 6269 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { | |
| 6269 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { | |
| 6270 | 6270 | result.return_value = .{ .none = {} }; |
| 6271 | 6271 | } else { |
| 6272 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 6272 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 6273 | 6273 | if (ret_ty_size == 0) { |
| 6274 | assert(ret_ty.isError(mod)); | |
| 6274 | assert(ret_ty.isError(zcu)); | |
| 6275 | 6275 | result.return_value = .{ .immediate = 0 }; |
| 6276 | 6276 | } else if (ret_ty_size <= 4) { |
| 6277 | 6277 | result.return_value = .{ .register = .r0 }; |
| ... | ... | @@ -6287,9 +6287,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6287 | 6287 | var stack_offset: u32 = 0; |
| 6288 | 6288 | |
| 6289 | 6289 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 6290 | if (Type.fromInterned(ty).abiSize(pt) > 0) { | |
| 6291 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt)); | |
| 6292 | const param_alignment = Type.fromInterned(ty).abiAlignment(pt); | |
| 6290 | if (Type.fromInterned(ty).abiSize(zcu) > 0) { | |
| 6291 | const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(zcu)); | |
| 6292 | const param_alignment = Type.fromInterned(ty).abiAlignment(zcu); | |
| 6293 | 6293 | |
| 6294 | 6294 | stack_offset = @intCast(param_alignment.forward(stack_offset)); |
| 6295 | 6295 | result_arg.* = .{ .stack_argument_offset = stack_offset }; |
src/arch/arm/abi.zig+21-21| ... | ... | @@ -24,29 +24,29 @@ pub const Class = union(enum) { |
| 24 | 24 | |
| 25 | 25 | pub const Context = enum { ret, arg }; |
| 26 | 26 | |
| 27 | pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class { | |
| 28 | assert(ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 27 | pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { | |
| 28 | assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 29 | 29 | |
| 30 | 30 | var maybe_float_bits: ?u16 = null; |
| 31 | 31 | const max_byval_size = 512; |
| 32 | const ip = &pt.zcu.intern_pool; | |
| 33 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 32 | const ip = &zcu.intern_pool; | |
| 33 | switch (ty.zigTypeTag(zcu)) { | |
| 34 | 34 | .Struct => { |
| 35 | const bit_size = ty.bitSize(pt); | |
| 36 | if (ty.containerLayout(pt.zcu) == .@"packed") { | |
| 35 | const bit_size = ty.bitSize(zcu); | |
| 36 | if (ty.containerLayout(zcu) == .@"packed") { | |
| 37 | 37 | if (bit_size > 64) return .memory; |
| 38 | 38 | return .byval; |
| 39 | 39 | } |
| 40 | 40 | if (bit_size > max_byval_size) return .memory; |
| 41 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); | |
| 41 | const float_count = countFloats(ty, zcu, &maybe_float_bits); | |
| 42 | 42 | if (float_count <= byval_float_count) return .byval; |
| 43 | 43 | |
| 44 | const fields = ty.structFieldCount(pt.zcu); | |
| 44 | const fields = ty.structFieldCount(zcu); | |
| 45 | 45 | var i: u32 = 0; |
| 46 | 46 | while (i < fields) : (i += 1) { |
| 47 | const field_ty = ty.structFieldType(i, pt.zcu); | |
| 48 | const field_alignment = ty.structFieldAlign(i, pt); | |
| 49 | const field_size = field_ty.bitSize(pt); | |
| 47 | const field_ty = ty.structFieldType(i, zcu); | |
| 48 | const field_alignment = ty.structFieldAlign(i, zcu); | |
| 49 | const field_size = field_ty.bitSize(zcu); | |
| 50 | 50 | if (field_size > 32 or field_alignment.compare(.gt, .@"32")) { |
| 51 | 51 | return Class.arrSize(bit_size, 64); |
| 52 | 52 | } |
| ... | ... | @@ -54,19 +54,19 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class { |
| 54 | 54 | return Class.arrSize(bit_size, 32); |
| 55 | 55 | }, |
| 56 | 56 | .Union => { |
| 57 | const bit_size = ty.bitSize(pt); | |
| 58 | const union_obj = pt.zcu.typeToUnion(ty).?; | |
| 57 | const bit_size = ty.bitSize(zcu); | |
| 58 | const union_obj = zcu.typeToUnion(ty).?; | |
| 59 | 59 | if (union_obj.flagsUnordered(ip).layout == .@"packed") { |
| 60 | 60 | if (bit_size > 64) return .memory; |
| 61 | 61 | return .byval; |
| 62 | 62 | } |
| 63 | 63 | if (bit_size > max_byval_size) return .memory; |
| 64 | const float_count = countFloats(ty, pt.zcu, &maybe_float_bits); | |
| 64 | const float_count = countFloats(ty, zcu, &maybe_float_bits); | |
| 65 | 65 | if (float_count <= byval_float_count) return .byval; |
| 66 | 66 | |
| 67 | 67 | for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| { |
| 68 | if (Type.fromInterned(field_ty).bitSize(pt) > 32 or | |
| 69 | pt.unionFieldNormalAlignment(union_obj, @intCast(field_index)).compare(.gt, .@"32")) | |
| 68 | if (Type.fromInterned(field_ty).bitSize(zcu) > 32 or | |
| 69 | Type.unionFieldNormalAlignment(union_obj, @intCast(field_index), zcu).compare(.gt, .@"32")) | |
| 70 | 70 | { |
| 71 | 71 | return Class.arrSize(bit_size, 64); |
| 72 | 72 | } |
| ... | ... | @@ -77,28 +77,28 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class { |
| 77 | 77 | .Int => { |
| 78 | 78 | // TODO this is incorrect for _BitInt(128) but implementing |
| 79 | 79 | // this correctly makes implementing compiler-rt impossible. |
| 80 | // const bit_size = ty.bitSize(pt); | |
| 80 | // const bit_size = ty.bitSize(zcu); | |
| 81 | 81 | // if (bit_size > 64) return .memory; |
| 82 | 82 | return .byval; |
| 83 | 83 | }, |
| 84 | 84 | .Enum, .ErrorSet => { |
| 85 | const bit_size = ty.bitSize(pt); | |
| 85 | const bit_size = ty.bitSize(zcu); | |
| 86 | 86 | if (bit_size > 64) return .memory; |
| 87 | 87 | return .byval; |
| 88 | 88 | }, |
| 89 | 89 | .Vector => { |
| 90 | const bit_size = ty.bitSize(pt); | |
| 90 | const bit_size = ty.bitSize(zcu); | |
| 91 | 91 | // TODO is this controlled by a cpu feature? |
| 92 | 92 | if (ctx == .ret and bit_size > 128) return .memory; |
| 93 | 93 | if (bit_size > 512) return .memory; |
| 94 | 94 | return .byval; |
| 95 | 95 | }, |
| 96 | 96 | .Optional => { |
| 97 | assert(ty.isPtrLikeOptional(pt.zcu)); | |
| 97 | assert(ty.isPtrLikeOptional(zcu)); | |
| 98 | 98 | return .byval; |
| 99 | 99 | }, |
| 100 | 100 | .Pointer => { |
| 101 | assert(!ty.isSlice(pt.zcu)); | |
| 101 | assert(!ty.isSlice(zcu)); | |
| 102 | 102 | return .byval; |
| 103 | 103 | }, |
| 104 | 104 | .ErrorUnion, |
src/arch/riscv64/CodeGen.zig+165-158| ... | ... | @@ -591,14 +591,14 @@ const FrameAlloc = struct { |
| 591 | 591 | .ref_count = 0, |
| 592 | 592 | }; |
| 593 | 593 | } |
| 594 | fn initType(ty: Type, pt: Zcu.PerThread) FrameAlloc { | |
| 594 | fn initType(ty: Type, zcu: *Zcu) FrameAlloc { | |
| 595 | 595 | return init(.{ |
| 596 | .size = ty.abiSize(pt), | |
| 597 | .alignment = ty.abiAlignment(pt), | |
| 596 | .size = ty.abiSize(zcu), | |
| 597 | .alignment = ty.abiAlignment(zcu), | |
| 598 | 598 | }); |
| 599 | 599 | } |
| 600 | fn initSpill(ty: Type, pt: Zcu.PerThread) FrameAlloc { | |
| 601 | const abi_size = ty.abiSize(pt); | |
| 600 | fn initSpill(ty: Type, zcu: *Zcu) FrameAlloc { | |
| 601 | const abi_size = ty.abiSize(zcu); | |
| 602 | 602 | const spill_size = if (abi_size < 8) |
| 603 | 603 | math.ceilPowerOfTwoAssert(u64, abi_size) |
| 604 | 604 | else |
| ... | ... | @@ -606,7 +606,7 @@ const FrameAlloc = struct { |
| 606 | 606 | return init(.{ |
| 607 | 607 | .size = spill_size, |
| 608 | 608 | .pad = @intCast(spill_size - abi_size), |
| 609 | .alignment = ty.abiAlignment(pt).maxStrict( | |
| 609 | .alignment = ty.abiAlignment(zcu).maxStrict( | |
| 610 | 610 | Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), |
| 611 | 611 | ), |
| 612 | 612 | }); |
| ... | ... | @@ -835,11 +835,11 @@ pub fn generate( |
| 835 | 835 | function.args = call_info.args; |
| 836 | 836 | function.ret_mcv = call_info.return_value; |
| 837 | 837 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ |
| 838 | .size = Type.u64.abiSize(pt), | |
| 839 | .alignment = Type.u64.abiAlignment(pt).min(call_info.stack_align), | |
| 838 | .size = Type.u64.abiSize(zcu), | |
| 839 | .alignment = Type.u64.abiAlignment(zcu).min(call_info.stack_align), | |
| 840 | 840 | })); |
| 841 | 841 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ |
| 842 | .size = Type.u64.abiSize(pt), | |
| 842 | .size = Type.u64.abiSize(zcu), | |
| 843 | 843 | .alignment = Alignment.min( |
| 844 | 844 | call_info.stack_align, |
| 845 | 845 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), |
| ... | ... | @@ -851,7 +851,7 @@ pub fn generate( |
| 851 | 851 | })); |
| 852 | 852 | function.frame_allocs.set(@intFromEnum(FrameIndex.spill_frame), FrameAlloc.init(.{ |
| 853 | 853 | .size = 0, |
| 854 | .alignment = Type.u64.abiAlignment(pt), | |
| 854 | .alignment = Type.u64.abiAlignment(zcu), | |
| 855 | 855 | })); |
| 856 | 856 | |
| 857 | 857 | function.gen() catch |err| switch (err) { |
| ... | ... | @@ -1245,7 +1245,7 @@ fn gen(func: *Func) !void { |
| 1245 | 1245 | // The address where to store the return value for the caller is in a |
| 1246 | 1246 | // register which the callee is free to clobber. Therefore, we purposely |
| 1247 | 1247 | // spill it to stack immediately. |
| 1248 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(Type.u64, pt)); | |
| 1248 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(Type.u64, zcu)); | |
| 1249 | 1249 | try func.genSetMem( |
| 1250 | 1250 | .{ .frame = frame_index }, |
| 1251 | 1251 | 0, |
| ... | ... | @@ -1379,9 +1379,9 @@ fn gen(func: *Func) !void { |
| 1379 | 1379 | |
| 1380 | 1380 | fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1381 | 1381 | const pt = func.pt; |
| 1382 | const mod = pt.zcu; | |
| 1383 | const ip = &mod.intern_pool; | |
| 1384 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(mod)) { | |
| 1382 | const zcu = pt.zcu; | |
| 1383 | const ip = &zcu.intern_pool; | |
| 1384 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) { | |
| 1385 | 1385 | .Enum => { |
| 1386 | 1386 | const enum_ty = Type.fromInterned(lazy_sym.ty); |
| 1387 | 1387 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); |
| ... | ... | @@ -1390,7 +1390,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1390 | 1390 | const ret_reg = param_regs[0]; |
| 1391 | 1391 | const enum_mcv: MCValue = .{ .register = param_regs[1] }; |
| 1392 | 1392 | |
| 1393 | const exitlude_jump_relocs = try func.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(mod)); | |
| 1393 | const exitlude_jump_relocs = try func.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(zcu)); | |
| 1394 | 1394 | defer func.gpa.free(exitlude_jump_relocs); |
| 1395 | 1395 | |
| 1396 | 1396 | const data_reg, const data_lock = try func.allocReg(.int); |
| ... | ... | @@ -1410,7 +1410,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1410 | 1410 | defer func.register_manager.unlockReg(cmp_lock); |
| 1411 | 1411 | |
| 1412 | 1412 | var data_off: i32 = 0; |
| 1413 | const tag_names = enum_ty.enumFields(mod); | |
| 1413 | const tag_names = enum_ty.enumFields(zcu); | |
| 1414 | 1414 | for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| { |
| 1415 | 1415 | const tag_name_len = tag_names.get(ip)[tag_index].length(ip); |
| 1416 | 1416 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| ... | ... | @@ -1944,32 +1944,32 @@ fn memSize(func: *Func, ty: Type) Memory.Size { |
| 1944 | 1944 | const zcu = pt.zcu; |
| 1945 | 1945 | return switch (ty.zigTypeTag(zcu)) { |
| 1946 | 1946 | .Float => Memory.Size.fromBitSize(ty.floatBits(func.target.*)), |
| 1947 | else => Memory.Size.fromByteSize(ty.abiSize(pt)), | |
| 1947 | else => Memory.Size.fromByteSize(ty.abiSize(zcu)), | |
| 1948 | 1948 | }; |
| 1949 | 1949 | } |
| 1950 | 1950 | |
| 1951 | 1951 | fn splitType(func: *Func, ty: Type) ![2]Type { |
| 1952 | const pt = func.pt; | |
| 1953 | const classes = mem.sliceTo(&abi.classifySystem(ty, pt), .none); | |
| 1952 | const zcu = func.pt.zcu; | |
| 1953 | const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none); | |
| 1954 | 1954 | var parts: [2]Type = undefined; |
| 1955 | 1955 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { |
| 1956 | 1956 | part.* = switch (class) { |
| 1957 | 1957 | .integer => switch (part_i) { |
| 1958 | 1958 | 0 => Type.u64, |
| 1959 | 1959 | 1 => part: { |
| 1960 | const elem_size = ty.abiAlignment(pt).minStrict(.@"8").toByteUnits().?; | |
| 1961 | const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8)); | |
| 1962 | break :part switch (@divExact(ty.abiSize(pt) - 8, elem_size)) { | |
| 1960 | const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?; | |
| 1961 | const elem_ty = try func.pt.intType(.unsigned, @intCast(elem_size * 8)); | |
| 1962 | break :part switch (@divExact(ty.abiSize(zcu) - 8, elem_size)) { | |
| 1963 | 1963 | 1 => elem_ty, |
| 1964 | else => |len| try pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), | |
| 1964 | else => |len| try func.pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), | |
| 1965 | 1965 | }; |
| 1966 | 1966 | }, |
| 1967 | 1967 | else => unreachable, |
| 1968 | 1968 | }, |
| 1969 | 1969 | else => return func.fail("TODO: splitType class {}", .{class}), |
| 1970 | 1970 | }; |
| 1971 | } else if (parts[0].abiSize(pt) + parts[1].abiSize(pt) == ty.abiSize(pt)) return parts; | |
| 1972 | return func.fail("TODO implement splitType for {}", .{ty.fmt(pt)}); | |
| 1971 | } else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts; | |
| 1972 | return func.fail("TODO implement splitType for {}", .{ty.fmt(func.pt)}); | |
| 1973 | 1973 | } |
| 1974 | 1974 | |
| 1975 | 1975 | /// Truncates the value in the register in place. |
| ... | ... | @@ -1979,7 +1979,7 @@ fn truncateRegister(func: *Func, ty: Type, reg: Register) !void { |
| 1979 | 1979 | const zcu = pt.zcu; |
| 1980 | 1980 | const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ |
| 1981 | 1981 | .signedness = .unsigned, |
| 1982 | .bits = @intCast(ty.bitSize(pt)), | |
| 1982 | .bits = @intCast(ty.bitSize(zcu)), | |
| 1983 | 1983 | }; |
| 1984 | 1984 | assert(reg.class() == .int); |
| 1985 | 1985 | |
| ... | ... | @@ -2081,10 +2081,10 @@ fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex { |
| 2081 | 2081 | const ptr_ty = func.typeOfIndex(inst); |
| 2082 | 2082 | const val_ty = ptr_ty.childType(zcu); |
| 2083 | 2083 | return func.allocFrameIndex(FrameAlloc.init(.{ |
| 2084 | .size = math.cast(u32, val_ty.abiSize(pt)) orelse { | |
| 2084 | .size = math.cast(u32, val_ty.abiSize(zcu)) orelse { | |
| 2085 | 2085 | return func.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)}); |
| 2086 | 2086 | }, |
| 2087 | .alignment = ptr_ty.ptrAlignment(pt).max(.@"1"), | |
| 2087 | .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"), | |
| 2088 | 2088 | })); |
| 2089 | 2089 | } |
| 2090 | 2090 | |
| ... | ... | @@ -2118,7 +2118,7 @@ fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool |
| 2118 | 2118 | const pt = func.pt; |
| 2119 | 2119 | const zcu = pt.zcu; |
| 2120 | 2120 | |
| 2121 | const bit_size = elem_ty.bitSize(pt); | |
| 2121 | const bit_size = elem_ty.bitSize(zcu); | |
| 2122 | 2122 | const min_size: u64 = switch (elem_ty.zigTypeTag(zcu)) { |
| 2123 | 2123 | .Float => if (func.hasFeature(.d)) 64 else 32, |
| 2124 | 2124 | .Vector => 256, // TODO: calculate it from avl * vsew |
| ... | ... | @@ -2133,7 +2133,7 @@ fn allocRegOrMem(func: *Func, elem_ty: Type, inst: ?Air.Inst.Index, reg_ok: bool |
| 2133 | 2133 | return func.fail("did you forget to extend vector registers before allocating", .{}); |
| 2134 | 2134 | } |
| 2135 | 2135 | |
| 2136 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(elem_ty, pt)); | |
| 2136 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(elem_ty, zcu)); | |
| 2137 | 2137 | return .{ .load_frame = .{ .index = frame_index } }; |
| 2138 | 2138 | } |
| 2139 | 2139 | |
| ... | ... | @@ -2368,7 +2368,7 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void { |
| 2368 | 2368 | }); |
| 2369 | 2369 | }, |
| 2370 | 2370 | .Int => { |
| 2371 | const size = ty.bitSize(pt); | |
| 2371 | const size = ty.bitSize(zcu); | |
| 2372 | 2372 | if (!math.isPowerOfTwo(size)) |
| 2373 | 2373 | return func.fail("TODO: airNot non-pow 2 int size", .{}); |
| 2374 | 2374 | |
| ... | ... | @@ -2399,11 +2399,12 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void { |
| 2399 | 2399 | |
| 2400 | 2400 | fn airSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 2401 | 2401 | const pt = func.pt; |
| 2402 | const zcu = pt.zcu; | |
| 2402 | 2403 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2403 | 2404 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2404 | 2405 | |
| 2405 | 2406 | const slice_ty = func.typeOfIndex(inst); |
| 2406 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); | |
| 2407 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | |
| 2407 | 2408 | |
| 2408 | 2409 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 2409 | 2410 | try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }); |
| ... | ... | @@ -2411,7 +2412,7 @@ fn airSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 2411 | 2412 | const len_ty = func.typeOf(bin_op.rhs); |
| 2412 | 2413 | try func.genSetMem( |
| 2413 | 2414 | .{ .frame = frame_index }, |
| 2414 | @intCast(ptr_ty.abiSize(pt)), | |
| 2415 | @intCast(ptr_ty.abiSize(zcu)), | |
| 2415 | 2416 | len_ty, |
| 2416 | 2417 | .{ .air_ref = bin_op.rhs }, |
| 2417 | 2418 | ); |
| ... | ... | @@ -2428,8 +2429,8 @@ fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 2428 | 2429 | |
| 2429 | 2430 | const dst_ty = func.typeOfIndex(inst); |
| 2430 | 2431 | if (dst_ty.isAbiInt(zcu)) { |
| 2431 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 2432 | const bit_size: u32 = @intCast(dst_ty.bitSize(pt)); | |
| 2432 | const abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 2433 | const bit_size: u32 = @intCast(dst_ty.bitSize(zcu)); | |
| 2433 | 2434 | if (abi_size * 8 > bit_size) { |
| 2434 | 2435 | const dst_lock = switch (dst_mcv) { |
| 2435 | 2436 | .register => |dst_reg| func.register_manager.lockRegAssumeUnused(dst_reg), |
| ... | ... | @@ -2443,7 +2444,7 @@ fn airBinOp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 2443 | 2444 | const tmp_reg, const tmp_lock = try func.allocReg(.int); |
| 2444 | 2445 | defer func.register_manager.unlockReg(tmp_lock); |
| 2445 | 2446 | |
| 2446 | const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(pt) - 1) % 64 + 1)); | |
| 2447 | const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(zcu) - 1) % 64 + 1)); | |
| 2447 | 2448 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 2448 | 2449 | try func.genSetReg(hi_ty, tmp_reg, hi_mcv); |
| 2449 | 2450 | try func.truncateRegister(dst_ty, tmp_reg); |
| ... | ... | @@ -2464,6 +2465,7 @@ fn binOp( |
| 2464 | 2465 | ) !MCValue { |
| 2465 | 2466 | _ = maybe_inst; |
| 2466 | 2467 | const pt = func.pt; |
| 2468 | const zcu = pt.zcu; | |
| 2467 | 2469 | const lhs_ty = func.typeOf(lhs_air); |
| 2468 | 2470 | const rhs_ty = func.typeOf(rhs_air); |
| 2469 | 2471 | |
| ... | ... | @@ -2480,9 +2482,9 @@ fn binOp( |
| 2480 | 2482 | } |
| 2481 | 2483 | |
| 2482 | 2484 | // don't have support for certain sizes of addition |
| 2483 | switch (lhs_ty.zigTypeTag(pt.zcu)) { | |
| 2485 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2484 | 2486 | .Vector => {}, // works differently and fails in a different place |
| 2485 | else => if (lhs_ty.bitSize(pt) > 64) return func.fail("TODO: binOp >= 64 bits", .{}), | |
| 2487 | else => if (lhs_ty.bitSize(zcu) > 64) return func.fail("TODO: binOp >= 64 bits", .{}), | |
| 2486 | 2488 | } |
| 2487 | 2489 | |
| 2488 | 2490 | const lhs_mcv = try func.resolveInst(lhs_air); |
| ... | ... | @@ -2533,7 +2535,7 @@ fn genBinOp( |
| 2533 | 2535 | ) !void { |
| 2534 | 2536 | const pt = func.pt; |
| 2535 | 2537 | const zcu = pt.zcu; |
| 2536 | const bit_size = lhs_ty.bitSize(pt); | |
| 2538 | const bit_size = lhs_ty.bitSize(zcu); | |
| 2537 | 2539 | |
| 2538 | 2540 | const is_unsigned = lhs_ty.isUnsignedInt(zcu); |
| 2539 | 2541 | |
| ... | ... | @@ -2646,7 +2648,7 @@ fn genBinOp( |
| 2646 | 2648 | }, |
| 2647 | 2649 | .Vector => { |
| 2648 | 2650 | const num_elem = lhs_ty.vectorLen(zcu); |
| 2649 | const elem_size = lhs_ty.childType(zcu).bitSize(pt); | |
| 2651 | const elem_size = lhs_ty.childType(zcu).bitSize(zcu); | |
| 2650 | 2652 | |
| 2651 | 2653 | const child_ty = lhs_ty.childType(zcu); |
| 2652 | 2654 | |
| ... | ... | @@ -2753,7 +2755,7 @@ fn genBinOp( |
| 2753 | 2755 | defer func.register_manager.unlockReg(tmp_lock); |
| 2754 | 2756 | |
| 2755 | 2757 | // RISC-V has no immediate mul, so we copy the size to a temporary register |
| 2756 | const elem_size = lhs_ty.elemType2(zcu).abiSize(pt); | |
| 2758 | const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu); | |
| 2757 | 2759 | const elem_size_reg = try func.copyToTmpRegister(Type.u64, .{ .immediate = elem_size }); |
| 2758 | 2760 | |
| 2759 | 2761 | try func.genBinOp( |
| ... | ... | @@ -2990,7 +2992,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 2990 | 2992 | |
| 2991 | 2993 | try func.genSetMem( |
| 2992 | 2994 | .{ .frame = offset.index }, |
| 2993 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), | |
| 2995 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | |
| 2994 | 2996 | lhs_ty, |
| 2995 | 2997 | add_result, |
| 2996 | 2998 | ); |
| ... | ... | @@ -3016,7 +3018,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3016 | 3018 | |
| 3017 | 3019 | try func.genSetMem( |
| 3018 | 3020 | .{ .frame = offset.index }, |
| 3019 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), | |
| 3021 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | |
| 3020 | 3022 | Type.u1, |
| 3021 | 3023 | .{ .register = overflow_reg }, |
| 3022 | 3024 | ); |
| ... | ... | @@ -3053,7 +3055,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3053 | 3055 | |
| 3054 | 3056 | try func.genSetMem( |
| 3055 | 3057 | .{ .frame = offset.index }, |
| 3056 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), | |
| 3058 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | |
| 3057 | 3059 | lhs_ty, |
| 3058 | 3060 | add_result, |
| 3059 | 3061 | ); |
| ... | ... | @@ -3079,7 +3081,7 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3079 | 3081 | |
| 3080 | 3082 | try func.genSetMem( |
| 3081 | 3083 | .{ .frame = offset.index }, |
| 3082 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), | |
| 3084 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | |
| 3083 | 3085 | Type.u1, |
| 3084 | 3086 | .{ .register = overflow_reg }, |
| 3085 | 3087 | ); |
| ... | ... | @@ -3126,7 +3128,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3126 | 3128 | |
| 3127 | 3129 | try func.genSetMem( |
| 3128 | 3130 | .{ .frame = offset.index }, |
| 3129 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), | |
| 3131 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | |
| 3130 | 3132 | lhs_ty, |
| 3131 | 3133 | .{ .register = dest_reg }, |
| 3132 | 3134 | ); |
| ... | ... | @@ -3155,7 +3157,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3155 | 3157 | |
| 3156 | 3158 | try func.genSetMem( |
| 3157 | 3159 | .{ .frame = offset.index }, |
| 3158 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), | |
| 3160 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | |
| 3159 | 3161 | Type.u1, |
| 3160 | 3162 | .{ .register = overflow_reg }, |
| 3161 | 3163 | ); |
| ... | ... | @@ -3203,7 +3205,7 @@ fn airSubWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3203 | 3205 | |
| 3204 | 3206 | try func.genSetMem( |
| 3205 | 3207 | .{ .frame = offset.index }, |
| 3206 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), | |
| 3208 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | |
| 3207 | 3209 | Type.u1, |
| 3208 | 3210 | .{ .register = overflow_reg }, |
| 3209 | 3211 | ); |
| ... | ... | @@ -3236,8 +3238,8 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void { |
| 3236 | 3238 | // genSetReg needs to support register_offset src_mcv for this to be true. |
| 3237 | 3239 | const result_mcv = try func.allocRegOrMem(tuple_ty, inst, false); |
| 3238 | 3240 | |
| 3239 | const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, pt)); | |
| 3240 | const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, pt)); | |
| 3241 | const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); | |
| 3242 | const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | |
| 3241 | 3243 | |
| 3242 | 3244 | const dest_reg, const dest_lock = try func.allocReg(.int); |
| 3243 | 3245 | defer func.register_manager.unlockReg(dest_lock); |
| ... | ... | @@ -3320,11 +3322,11 @@ fn airShlSat(func: *Func, inst: Air.Inst.Index) !void { |
| 3320 | 3322 | } |
| 3321 | 3323 | |
| 3322 | 3324 | fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void { |
| 3323 | const pt = func.pt; | |
| 3325 | const zcu = func.pt.zcu; | |
| 3324 | 3326 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3325 | 3327 | const result: MCValue = result: { |
| 3326 | 3328 | const pl_ty = func.typeOfIndex(inst); |
| 3327 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 3329 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 3328 | 3330 | |
| 3329 | 3331 | const opt_mcv = try func.resolveInst(ty_op.operand); |
| 3330 | 3332 | if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { |
| ... | ... | @@ -3368,11 +3370,11 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void { |
| 3368 | 3370 | break :result .{ .immediate = 0 }; |
| 3369 | 3371 | } |
| 3370 | 3372 | |
| 3371 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3373 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3372 | 3374 | break :result operand; |
| 3373 | 3375 | } |
| 3374 | 3376 | |
| 3375 | const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, pt)); | |
| 3377 | const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu)); | |
| 3376 | 3378 | |
| 3377 | 3379 | switch (operand) { |
| 3378 | 3380 | .register => |reg| { |
| ... | ... | @@ -3421,9 +3423,9 @@ fn genUnwrapErrUnionPayloadMir( |
| 3421 | 3423 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 3422 | 3424 | |
| 3423 | 3425 | const result: MCValue = result: { |
| 3424 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 3426 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 3425 | 3427 | |
| 3426 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, pt)); | |
| 3428 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu)); | |
| 3427 | 3429 | switch (err_union) { |
| 3428 | 3430 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ |
| 3429 | 3431 | .index = frame_addr.index, |
| ... | ... | @@ -3497,7 +3499,7 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { |
| 3497 | 3499 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3498 | 3500 | const result: MCValue = result: { |
| 3499 | 3501 | const pl_ty = func.typeOf(ty_op.operand); |
| 3500 | if (!pl_ty.hasRuntimeBits(pt)) break :result .{ .immediate = 1 }; | |
| 3502 | if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 }; | |
| 3501 | 3503 | |
| 3502 | 3504 | const opt_ty = func.typeOfIndex(inst); |
| 3503 | 3505 | const pl_mcv = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -3514,7 +3516,7 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { |
| 3514 | 3516 | try func.genCopy(pl_ty, opt_mcv, pl_mcv); |
| 3515 | 3517 | |
| 3516 | 3518 | if (!same_repr) { |
| 3517 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt)); | |
| 3519 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); | |
| 3518 | 3520 | switch (opt_mcv) { |
| 3519 | 3521 | .load_frame => |frame_addr| { |
| 3520 | 3522 | try func.genCopy(pl_ty, opt_mcv, pl_mcv); |
| ... | ... | @@ -3545,11 +3547,11 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void { |
| 3545 | 3547 | const operand = try func.resolveInst(ty_op.operand); |
| 3546 | 3548 | |
| 3547 | 3549 | const result: MCValue = result: { |
| 3548 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .{ .immediate = 0 }; | |
| 3550 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 }; | |
| 3549 | 3551 | |
| 3550 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); | |
| 3551 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); | |
| 3552 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 3552 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | |
| 3553 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | |
| 3554 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 3553 | 3555 | try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand); |
| 3554 | 3556 | try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }); |
| 3555 | 3557 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| ... | ... | @@ -3569,11 +3571,11 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void { |
| 3569 | 3571 | const err_ty = eu_ty.errorUnionSet(zcu); |
| 3570 | 3572 | |
| 3571 | 3573 | const result: MCValue = result: { |
| 3572 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result try func.resolveInst(ty_op.operand); | |
| 3574 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try func.resolveInst(ty_op.operand); | |
| 3573 | 3575 | |
| 3574 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); | |
| 3575 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); | |
| 3576 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 3576 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | |
| 3577 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | |
| 3578 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 3577 | 3579 | try func.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .{ .undef = null }); |
| 3578 | 3580 | const operand = try func.resolveInst(ty_op.operand); |
| 3579 | 3581 | try func.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand); |
| ... | ... | @@ -3717,7 +3719,7 @@ fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3717 | 3719 | |
| 3718 | 3720 | const result: MCValue = result: { |
| 3719 | 3721 | const elem_ty = func.typeOfIndex(inst); |
| 3720 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 3722 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 3721 | 3723 | |
| 3722 | 3724 | const slice_ty = func.typeOf(bin_op.lhs); |
| 3723 | 3725 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu); |
| ... | ... | @@ -3748,7 +3750,7 @@ fn genSliceElemPtr(func: *Func, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 3748 | 3750 | defer if (slice_mcv_lock) |lock| func.register_manager.unlockReg(lock); |
| 3749 | 3751 | |
| 3750 | 3752 | const elem_ty = slice_ty.childType(zcu); |
| 3751 | const elem_size = elem_ty.abiSize(pt); | |
| 3753 | const elem_size = elem_ty.abiSize(zcu); | |
| 3752 | 3754 | |
| 3753 | 3755 | const index_ty = func.typeOf(rhs); |
| 3754 | 3756 | const index_mcv = try func.resolveInst(rhs); |
| ... | ... | @@ -3792,14 +3794,14 @@ fn airArrayElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3792 | 3794 | const index_ty = func.typeOf(bin_op.rhs); |
| 3793 | 3795 | |
| 3794 | 3796 | const elem_ty = array_ty.childType(zcu); |
| 3795 | const elem_abi_size = elem_ty.abiSize(pt); | |
| 3797 | const elem_abi_size = elem_ty.abiSize(zcu); | |
| 3796 | 3798 | |
| 3797 | 3799 | const addr_reg, const addr_reg_lock = try func.allocReg(.int); |
| 3798 | 3800 | defer func.register_manager.unlockReg(addr_reg_lock); |
| 3799 | 3801 | |
| 3800 | 3802 | switch (array_mcv) { |
| 3801 | 3803 | .register => { |
| 3802 | const frame_index = try func.allocFrameIndex(FrameAlloc.initType(array_ty, pt)); | |
| 3804 | const frame_index = try func.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | |
| 3803 | 3805 | try func.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); |
| 3804 | 3806 | try func.genSetReg(Type.u64, addr_reg, .{ .lea_frame = .{ .index = frame_index } }); |
| 3805 | 3807 | }, |
| ... | ... | @@ -3870,7 +3872,7 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void { |
| 3870 | 3872 | |
| 3871 | 3873 | const result: MCValue = if (!is_volatile and func.liveness.isUnused(inst)) .unreach else result: { |
| 3872 | 3874 | const elem_ty = base_ptr_ty.elemType2(zcu); |
| 3873 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 3875 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 3874 | 3876 | |
| 3875 | 3877 | const base_ptr_mcv = try func.resolveInst(bin_op.lhs); |
| 3876 | 3878 | const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) { |
| ... | ... | @@ -3970,11 +3972,12 @@ fn airSetUnionTag(func: *Func, inst: Air.Inst.Index) !void { |
| 3970 | 3972 | |
| 3971 | 3973 | fn airGetUnionTag(func: *Func, inst: Air.Inst.Index) !void { |
| 3972 | 3974 | const pt = func.pt; |
| 3975 | const zcu = pt.zcu; | |
| 3973 | 3976 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3974 | 3977 | |
| 3975 | 3978 | const tag_ty = func.typeOfIndex(inst); |
| 3976 | 3979 | const union_ty = func.typeOf(ty_op.operand); |
| 3977 | const layout = union_ty.unionGetLayout(pt); | |
| 3980 | const layout = union_ty.unionGetLayout(zcu); | |
| 3978 | 3981 | |
| 3979 | 3982 | if (layout.tag_size == 0) { |
| 3980 | 3983 | return func.finishAir(inst, .none, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -3985,7 +3988,7 @@ fn airGetUnionTag(func: *Func, inst: Air.Inst.Index) !void { |
| 3985 | 3988 | const frame_mcv = try func.allocRegOrMem(union_ty, null, false); |
| 3986 | 3989 | try func.genCopy(union_ty, frame_mcv, operand); |
| 3987 | 3990 | |
| 3988 | const tag_abi_size = tag_ty.abiSize(pt); | |
| 3991 | const tag_abi_size = tag_ty.abiSize(zcu); | |
| 3989 | 3992 | const result_reg, const result_lock = try func.allocReg(.int); |
| 3990 | 3993 | defer func.register_manager.unlockReg(result_lock); |
| 3991 | 3994 | |
| ... | ... | @@ -4034,7 +4037,7 @@ fn airClz(func: *Func, inst: Air.Inst.Index) !void { |
| 4034 | 4037 | else |
| 4035 | 4038 | (try func.allocRegOrMem(func.typeOfIndex(inst), inst, true)).register; |
| 4036 | 4039 | |
| 4037 | const bit_size = ty.bitSize(func.pt); | |
| 4040 | const bit_size = ty.bitSize(func.pt.zcu); | |
| 4038 | 4041 | if (!math.isPowerOfTwo(bit_size)) try func.truncateRegister(ty, src_reg); |
| 4039 | 4042 | |
| 4040 | 4043 | if (bit_size > 64) { |
| ... | ... | @@ -4081,6 +4084,7 @@ fn airPopcount(func: *Func, inst: Air.Inst.Index) !void { |
| 4081 | 4084 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4082 | 4085 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 4083 | 4086 | const pt = func.pt; |
| 4087 | const zcu = pt.zcu; | |
| 4084 | 4088 | |
| 4085 | 4089 | const operand = try func.resolveInst(ty_op.operand); |
| 4086 | 4090 | const src_ty = func.typeOf(ty_op.operand); |
| ... | ... | @@ -4090,7 +4094,7 @@ fn airPopcount(func: *Func, inst: Air.Inst.Index) !void { |
| 4090 | 4094 | const dst_reg, const dst_lock = try func.allocReg(.int); |
| 4091 | 4095 | defer func.register_manager.unlockReg(dst_lock); |
| 4092 | 4096 | |
| 4093 | const bit_size = src_ty.bitSize(pt); | |
| 4097 | const bit_size = src_ty.bitSize(zcu); | |
| 4094 | 4098 | switch (bit_size) { |
| 4095 | 4099 | 32, 64 => {}, |
| 4096 | 4100 | 1...31, 33...63 => try func.truncateRegister(src_ty, operand_reg), |
| ... | ... | @@ -4283,12 +4287,13 @@ fn airBitReverse(func: *Func, inst: Air.Inst.Index) !void { |
| 4283 | 4287 | |
| 4284 | 4288 | fn airUnaryMath(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 4285 | 4289 | const pt = func.pt; |
| 4290 | const zcu = pt.zcu; | |
| 4286 | 4291 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4287 | 4292 | const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { |
| 4288 | 4293 | const ty = func.typeOf(un_op); |
| 4289 | 4294 | |
| 4290 | 4295 | const operand = try func.resolveInst(un_op); |
| 4291 | const operand_bit_size = ty.bitSize(pt); | |
| 4296 | const operand_bit_size = ty.bitSize(zcu); | |
| 4292 | 4297 | |
| 4293 | 4298 | if (!math.isPowerOfTwo(operand_bit_size)) |
| 4294 | 4299 | return func.fail("TODO: airUnaryMath non-pow 2", .{}); |
| ... | ... | @@ -4300,7 +4305,7 @@ fn airUnaryMath(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 4300 | 4305 | const dst_reg, const dst_lock = try func.allocReg(dst_class); |
| 4301 | 4306 | defer func.register_manager.unlockReg(dst_lock); |
| 4302 | 4307 | |
| 4303 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 4308 | switch (ty.zigTypeTag(zcu)) { | |
| 4304 | 4309 | .Float => { |
| 4305 | 4310 | assert(dst_class == .float); |
| 4306 | 4311 | |
| ... | ... | @@ -4397,7 +4402,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 4397 | 4402 | const elem_ty = func.typeOfIndex(inst); |
| 4398 | 4403 | |
| 4399 | 4404 | const result: MCValue = result: { |
| 4400 | if (!elem_ty.hasRuntimeBits(pt)) | |
| 4405 | if (!elem_ty.hasRuntimeBits(zcu)) | |
| 4401 | 4406 | break :result .none; |
| 4402 | 4407 | |
| 4403 | 4408 | const ptr = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4405,7 +4410,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 4405 | 4410 | if (func.liveness.isUnused(inst) and !is_volatile) |
| 4406 | 4411 | break :result .unreach; |
| 4407 | 4412 | |
| 4408 | const elem_size = elem_ty.abiSize(pt); | |
| 4413 | const elem_size = elem_ty.abiSize(zcu); | |
| 4409 | 4414 | |
| 4410 | 4415 | const dst_mcv: MCValue = blk: { |
| 4411 | 4416 | // The MCValue that holds the pointer can be re-used as the value. |
| ... | ... | @@ -4544,7 +4549,7 @@ fn structFieldPtr(func: *Func, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 4544 | 4549 | const container_ty = ptr_container_ty.childType(zcu); |
| 4545 | 4550 | |
| 4546 | 4551 | const field_offset: i32 = switch (container_ty.containerLayout(zcu)) { |
| 4547 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, pt)), | |
| 4552 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, zcu)), | |
| 4548 | 4553 | .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(zcu).packed_offset.bit_offset) + |
| 4549 | 4554 | (if (zcu.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, index) else 0) - |
| 4550 | 4555 | ptr_field_ty.ptrInfo(zcu).packed_offset.bit_offset, 8), |
| ... | ... | @@ -4572,10 +4577,10 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 4572 | 4577 | const src_mcv = try func.resolveInst(operand); |
| 4573 | 4578 | const struct_ty = func.typeOf(operand); |
| 4574 | 4579 | const field_ty = struct_ty.structFieldType(index, zcu); |
| 4575 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 4580 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 4576 | 4581 | |
| 4577 | 4582 | const field_off: u32 = switch (struct_ty.containerLayout(zcu)) { |
| 4578 | .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, pt) * 8), | |
| 4583 | .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8), | |
| 4579 | 4584 | .@"packed" => if (zcu.typeToStruct(struct_ty)) |struct_type| |
| 4580 | 4585 | pt.structPackedFieldBitOffset(struct_type, index) |
| 4581 | 4586 | else |
| ... | ... | @@ -4615,11 +4620,11 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 4615 | 4620 | break :result if (field_off == 0) dst_mcv else try func.copyToNewRegister(inst, dst_mcv); |
| 4616 | 4621 | }, |
| 4617 | 4622 | .load_frame => { |
| 4618 | const field_abi_size: u32 = @intCast(field_ty.abiSize(pt)); | |
| 4623 | const field_abi_size: u32 = @intCast(field_ty.abiSize(zcu)); | |
| 4619 | 4624 | if (field_off % 8 == 0) { |
| 4620 | 4625 | const field_byte_off = @divExact(field_off, 8); |
| 4621 | 4626 | const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref(); |
| 4622 | const field_bit_size = field_ty.bitSize(pt); | |
| 4627 | const field_bit_size = field_ty.bitSize(zcu); | |
| 4623 | 4628 | |
| 4624 | 4629 | if (field_abi_size <= 8) { |
| 4625 | 4630 | const int_ty = try pt.intType( |
| ... | ... | @@ -4635,7 +4640,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void { |
| 4635 | 4640 | break :result try func.copyToNewRegister(inst, dst_mcv); |
| 4636 | 4641 | } |
| 4637 | 4642 | |
| 4638 | const container_abi_size: u32 = @intCast(struct_ty.abiSize(pt)); | |
| 4643 | const container_abi_size: u32 = @intCast(struct_ty.abiSize(zcu)); | |
| 4639 | 4644 | const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and |
| 4640 | 4645 | func.reuseOperand(inst, operand, 0, src_mcv)) |
| 4641 | 4646 | off_mcv |
| ... | ... | @@ -4880,7 +4885,7 @@ fn genCall( |
| 4880 | 4885 | try reg_locks.appendSlice(&func.register_manager.lockRegs(2, regs)); |
| 4881 | 4886 | }, |
| 4882 | 4887 | .indirect => |reg_off| { |
| 4883 | frame_index.* = try func.allocFrameIndex(FrameAlloc.initType(arg_ty, pt)); | |
| 4888 | frame_index.* = try func.allocFrameIndex(FrameAlloc.initType(arg_ty, zcu)); | |
| 4884 | 4889 | try func.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg); |
| 4885 | 4890 | try func.register_manager.getReg(reg_off.reg, null); |
| 4886 | 4891 | try reg_locks.append(func.register_manager.lockReg(reg_off.reg)); |
| ... | ... | @@ -4893,7 +4898,7 @@ fn genCall( |
| 4893 | 4898 | .none, .unreach => {}, |
| 4894 | 4899 | .indirect => |reg_off| { |
| 4895 | 4900 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 4896 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(ret_ty, pt)); | |
| 4901 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(ret_ty, zcu)); | |
| 4897 | 4902 | try func.genSetReg(Type.u64, reg_off.reg, .{ |
| 4898 | 4903 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 4899 | 4904 | }); |
| ... | ... | @@ -5013,7 +5018,7 @@ fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 5013 | 5018 | .register_pair, |
| 5014 | 5019 | => { |
| 5015 | 5020 | if (ret_ty.isVector(zcu)) { |
| 5016 | const bit_size = ret_ty.totalVectorBits(pt); | |
| 5021 | const bit_size = ret_ty.totalVectorBits(zcu); | |
| 5017 | 5022 | |
| 5018 | 5023 | // set the vtype to hold the entire vector's contents in a single element |
| 5019 | 5024 | try func.setVl(.zero, 0, .{ |
| ... | ... | @@ -5113,7 +5118,7 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 5113 | 5118 | .ErrorSet => Type.anyerror, |
| 5114 | 5119 | .Optional => blk: { |
| 5115 | 5120 | const payload_ty = lhs_ty.optionalChild(zcu); |
| 5116 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5121 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5117 | 5122 | break :blk Type.u1; |
| 5118 | 5123 | } else if (lhs_ty.isPtrLikeOptional(zcu)) { |
| 5119 | 5124 | break :blk Type.u64; |
| ... | ... | @@ -5289,7 +5294,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 5289 | 5294 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) |
| 5290 | 5295 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } |
| 5291 | 5296 | else |
| 5292 | .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool }; | |
| 5297 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; | |
| 5293 | 5298 | |
| 5294 | 5299 | const return_mcv = try func.allocRegOrMem(func.typeOfIndex(inst), inst, true); |
| 5295 | 5300 | assert(return_mcv == .register); // should not be larger 8 bytes |
| ... | ... | @@ -5472,11 +5477,10 @@ fn airIsErrPtr(func: *Func, inst: Air.Inst.Index) !void { |
| 5472 | 5477 | /// Result is in the return register. |
| 5473 | 5478 | fn isErr(func: *Func, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { |
| 5474 | 5479 | _ = maybe_inst; |
| 5475 | const pt = func.pt; | |
| 5476 | const zcu = pt.zcu; | |
| 5480 | const zcu = func.pt.zcu; | |
| 5477 | 5481 | const err_ty = eu_ty.errorUnionSet(zcu); |
| 5478 | 5482 | if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false |
| 5479 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), pt)); | |
| 5483 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), zcu)); | |
| 5480 | 5484 | |
| 5481 | 5485 | const return_reg, const return_lock = try func.allocReg(.int); |
| 5482 | 5486 | defer func.register_manager.unlockReg(return_lock); |
| ... | ... | @@ -5769,12 +5773,12 @@ fn performReloc(func: *Func, inst: Mir.Inst.Index) void { |
| 5769 | 5773 | } |
| 5770 | 5774 | |
| 5771 | 5775 | fn airBr(func: *Func, inst: Air.Inst.Index) !void { |
| 5772 | const pt = func.pt; | |
| 5776 | const zcu = func.pt.zcu; | |
| 5773 | 5777 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 5774 | 5778 | |
| 5775 | 5779 | const block_ty = func.typeOfIndex(br.block_inst); |
| 5776 | 5780 | const block_unused = |
| 5777 | !block_ty.hasRuntimeBitsIgnoreComptime(pt) or func.liveness.isUnused(br.block_inst); | |
| 5781 | !block_ty.hasRuntimeBitsIgnoreComptime(zcu) or func.liveness.isUnused(br.block_inst); | |
| 5778 | 5782 | const block_tracking = func.inst_tracking.getPtr(br.block_inst).?; |
| 5779 | 5783 | const block_data = func.blocks.getPtr(br.block_inst).?; |
| 5780 | 5784 | const first_br = block_data.relocs.items.len == 0; |
| ... | ... | @@ -6354,6 +6358,8 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { |
| 6354 | 6358 | return std.debug.panic("tried to genCopy immutable: {s}", .{@tagName(dst_mcv)}); |
| 6355 | 6359 | } |
| 6356 | 6360 | |
| 6361 | const zcu = func.pt.zcu; | |
| 6362 | ||
| 6357 | 6363 | switch (dst_mcv) { |
| 6358 | 6364 | .register => |reg| return func.genSetReg(ty, reg, src_mcv), |
| 6359 | 6365 | .register_offset => |dst_reg_off| try func.genSetReg(ty, dst_reg_off.reg, switch (src_mcv) { |
| ... | ... | @@ -6425,7 +6431,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { |
| 6425 | 6431 | } }, |
| 6426 | 6432 | else => unreachable, |
| 6427 | 6433 | }); |
| 6428 | part_disp += @intCast(dst_ty.abiSize(func.pt)); | |
| 6434 | part_disp += @intCast(dst_ty.abiSize(zcu)); | |
| 6429 | 6435 | } |
| 6430 | 6436 | }, |
| 6431 | 6437 | else => return std.debug.panic("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }), |
| ... | ... | @@ -6622,7 +6628,7 @@ fn genInlineMemset( |
| 6622 | 6628 | fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void { |
| 6623 | 6629 | const pt = func.pt; |
| 6624 | 6630 | const zcu = pt.zcu; |
| 6625 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 6631 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 6626 | 6632 | |
| 6627 | 6633 | const max_size: u32 = switch (reg.class()) { |
| 6628 | 6634 | .int => 64, |
| ... | ... | @@ -6729,7 +6735,7 @@ fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError! |
| 6729 | 6735 | // size to the total size of the vector, and vmv.x.s will work then |
| 6730 | 6736 | if (src_reg.class() == .vector) { |
| 6731 | 6737 | try func.setVl(.zero, 0, .{ |
| 6732 | .vsew = switch (ty.totalVectorBits(pt)) { | |
| 6738 | .vsew = switch (ty.totalVectorBits(zcu)) { | |
| 6733 | 6739 | 8 => .@"8", |
| 6734 | 6740 | 16 => .@"16", |
| 6735 | 6741 | 32 => .@"32", |
| ... | ... | @@ -6848,7 +6854,7 @@ fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError! |
| 6848 | 6854 | // and load from it. |
| 6849 | 6855 | const len = ty.vectorLen(zcu); |
| 6850 | 6856 | const elem_ty = ty.childType(zcu); |
| 6851 | const elem_size = elem_ty.abiSize(pt); | |
| 6857 | const elem_size = elem_ty.abiSize(zcu); | |
| 6852 | 6858 | |
| 6853 | 6859 | try func.setVl(.zero, len, .{ |
| 6854 | 6860 | .vsew = switch (elem_size) { |
| ... | ... | @@ -6945,7 +6951,7 @@ fn genSetMem( |
| 6945 | 6951 | const pt = func.pt; |
| 6946 | 6952 | const zcu = pt.zcu; |
| 6947 | 6953 | |
| 6948 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 6954 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 6949 | 6955 | const dst_ptr_mcv: MCValue = switch (base) { |
| 6950 | 6956 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| 6951 | 6957 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, |
| ... | ... | @@ -6995,7 +7001,7 @@ fn genSetMem( |
| 6995 | 7001 | const addr_reg = try func.copyToTmpRegister(Type.u64, dst_ptr_mcv); |
| 6996 | 7002 | |
| 6997 | 7003 | const num_elem = ty.vectorLen(zcu); |
| 6998 | const elem_size = ty.childType(zcu).bitSize(pt); | |
| 7004 | const elem_size = ty.childType(zcu).bitSize(zcu); | |
| 6999 | 7005 | |
| 7000 | 7006 | try func.setVl(.zero, num_elem, .{ |
| 7001 | 7007 | .vsew = switch (elem_size) { |
| ... | ... | @@ -7083,7 +7089,7 @@ fn genSetMem( |
| 7083 | 7089 | var part_disp: i32 = disp; |
| 7084 | 7090 | for (try func.splitType(ty), src_regs) |src_ty, src_reg| { |
| 7085 | 7091 | try func.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }); |
| 7086 | part_disp += @intCast(src_ty.abiSize(pt)); | |
| 7092 | part_disp += @intCast(src_ty.abiSize(zcu)); | |
| 7087 | 7093 | } |
| 7088 | 7094 | }, |
| 7089 | 7095 | .immediate => { |
| ... | ... | @@ -7128,10 +7134,10 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { |
| 7128 | 7134 | const src_lock = if (src_mcv.getReg()) |reg| func.register_manager.lockReg(reg) else null; |
| 7129 | 7135 | defer if (src_lock) |lock| func.register_manager.unlockReg(lock); |
| 7130 | 7136 | |
| 7131 | const dst_mcv = if (dst_ty.abiSize(pt) <= src_ty.abiSize(pt) and src_mcv != .register_pair and | |
| 7137 | const dst_mcv = if (dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and src_mcv != .register_pair and | |
| 7132 | 7138 | func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { |
| 7133 | 7139 | const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true); |
| 7134 | try func.genCopy(switch (math.order(dst_ty.abiSize(pt), src_ty.abiSize(pt))) { | |
| 7140 | try func.genCopy(switch (math.order(dst_ty.abiSize(zcu), src_ty.abiSize(zcu))) { | |
| 7135 | 7141 | .lt => dst_ty, |
| 7136 | 7142 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, |
| 7137 | 7143 | .gt => src_ty, |
| ... | ... | @@ -7142,8 +7148,8 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { |
| 7142 | 7148 | if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and |
| 7143 | 7149 | dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv; |
| 7144 | 7150 | |
| 7145 | const abi_size = dst_ty.abiSize(pt); | |
| 7146 | const bit_size = dst_ty.bitSize(pt); | |
| 7151 | const abi_size = dst_ty.abiSize(zcu); | |
| 7152 | const bit_size = dst_ty.bitSize(zcu); | |
| 7147 | 7153 | if (abi_size * 8 <= bit_size) break :result dst_mcv; |
| 7148 | 7154 | |
| 7149 | 7155 | return func.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(pt), dst_ty.fmt(pt) }); |
| ... | ... | @@ -7162,11 +7168,11 @@ fn airArrayToSlice(func: *Func, inst: Air.Inst.Index) !void { |
| 7162 | 7168 | const array_ty = ptr_ty.childType(zcu); |
| 7163 | 7169 | const array_len = array_ty.arrayLen(zcu); |
| 7164 | 7170 | |
| 7165 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); | |
| 7171 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | |
| 7166 | 7172 | try func.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr); |
| 7167 | 7173 | try func.genSetMem( |
| 7168 | 7174 | .{ .frame = frame_index }, |
| 7169 | @intCast(ptr_ty.abiSize(pt)), | |
| 7175 | @intCast(ptr_ty.abiSize(zcu)), | |
| 7170 | 7176 | Type.u64, |
| 7171 | 7177 | .{ .immediate = array_len }, |
| 7172 | 7178 | ); |
| ... | ... | @@ -7190,21 +7196,21 @@ fn airFloatFromInt(func: *Func, inst: Air.Inst.Index) !void { |
| 7190 | 7196 | defer if (src_lock) |lock| func.register_manager.unlockReg(lock); |
| 7191 | 7197 | |
| 7192 | 7198 | const is_unsigned = dst_ty.isUnsignedInt(zcu); |
| 7193 | const src_bits = src_ty.bitSize(pt); | |
| 7194 | const dst_bits = dst_ty.bitSize(pt); | |
| 7199 | const src_bits = src_ty.bitSize(zcu); | |
| 7200 | const dst_bits = dst_ty.bitSize(zcu); | |
| 7195 | 7201 | |
| 7196 | 7202 | switch (src_bits) { |
| 7197 | 7203 | 32, 64 => {}, |
| 7198 | 7204 | else => try func.truncateRegister(src_ty, src_reg), |
| 7199 | 7205 | } |
| 7200 | 7206 | |
| 7201 | const int_mod: Mir.FcvtOp = switch (src_bits) { | |
| 7207 | const int_zcu: Mir.FcvtOp = switch (src_bits) { | |
| 7202 | 7208 | 8, 16, 32 => if (is_unsigned) .wu else .w, |
| 7203 | 7209 | 64 => if (is_unsigned) .lu else .l, |
| 7204 | 7210 | else => return func.fail("TODO: airFloatFromInt src size: {d}", .{src_bits}), |
| 7205 | 7211 | }; |
| 7206 | 7212 | |
| 7207 | const float_mod: enum { s, d } = switch (dst_bits) { | |
| 7213 | const float_zcu: enum { s, d } = switch (dst_bits) { | |
| 7208 | 7214 | 32 => .s, |
| 7209 | 7215 | 64 => .d, |
| 7210 | 7216 | else => return func.fail("TODO: airFloatFromInt dst size {d}", .{dst_bits}), |
| ... | ... | @@ -7214,14 +7220,14 @@ fn airFloatFromInt(func: *Func, inst: Air.Inst.Index) !void { |
| 7214 | 7220 | defer func.register_manager.unlockReg(dst_lock); |
| 7215 | 7221 | |
| 7216 | 7222 | _ = try func.addInst(.{ |
| 7217 | .tag = switch (float_mod) { | |
| 7218 | .s => switch (int_mod) { | |
| 7223 | .tag = switch (float_zcu) { | |
| 7224 | .s => switch (int_zcu) { | |
| 7219 | 7225 | .l => .fcvtsl, |
| 7220 | 7226 | .lu => .fcvtslu, |
| 7221 | 7227 | .w => .fcvtsw, |
| 7222 | 7228 | .wu => .fcvtswu, |
| 7223 | 7229 | }, |
| 7224 | .d => switch (int_mod) { | |
| 7230 | .d => switch (int_zcu) { | |
| 7225 | 7231 | .l => .fcvtdl, |
| 7226 | 7232 | .lu => .fcvtdlu, |
| 7227 | 7233 | .w => .fcvtdw, |
| ... | ... | @@ -7250,16 +7256,16 @@ fn airIntFromFloat(func: *Func, inst: Air.Inst.Index) !void { |
| 7250 | 7256 | const dst_ty = ty_op.ty.toType(); |
| 7251 | 7257 | |
| 7252 | 7258 | const is_unsigned = dst_ty.isUnsignedInt(zcu); |
| 7253 | const src_bits = src_ty.bitSize(pt); | |
| 7254 | const dst_bits = dst_ty.bitSize(pt); | |
| 7259 | const src_bits = src_ty.bitSize(zcu); | |
| 7260 | const dst_bits = dst_ty.bitSize(zcu); | |
| 7255 | 7261 | |
| 7256 | const float_mod: enum { s, d } = switch (src_bits) { | |
| 7262 | const float_zcu: enum { s, d } = switch (src_bits) { | |
| 7257 | 7263 | 32 => .s, |
| 7258 | 7264 | 64 => .d, |
| 7259 | 7265 | else => return func.fail("TODO: airIntFromFloat src size {d}", .{src_bits}), |
| 7260 | 7266 | }; |
| 7261 | 7267 | |
| 7262 | const int_mod: Mir.FcvtOp = switch (dst_bits) { | |
| 7268 | const int_zcu: Mir.FcvtOp = switch (dst_bits) { | |
| 7263 | 7269 | 32 => if (is_unsigned) .wu else .w, |
| 7264 | 7270 | 8, 16, 64 => if (is_unsigned) .lu else .l, |
| 7265 | 7271 | else => return func.fail("TODO: airIntFromFloat dst size: {d}", .{dst_bits}), |
| ... | ... | @@ -7272,14 +7278,14 @@ fn airIntFromFloat(func: *Func, inst: Air.Inst.Index) !void { |
| 7272 | 7278 | defer func.register_manager.unlockReg(dst_lock); |
| 7273 | 7279 | |
| 7274 | 7280 | _ = try func.addInst(.{ |
| 7275 | .tag = switch (float_mod) { | |
| 7276 | .s => switch (int_mod) { | |
| 7281 | .tag = switch (float_zcu) { | |
| 7282 | .s => switch (int_zcu) { | |
| 7277 | 7283 | .l => .fcvtls, |
| 7278 | 7284 | .lu => .fcvtlus, |
| 7279 | 7285 | .w => .fcvtws, |
| 7280 | 7286 | .wu => .fcvtwus, |
| 7281 | 7287 | }, |
| 7282 | .d => switch (int_mod) { | |
| 7288 | .d => switch (int_zcu) { | |
| 7283 | 7289 | .l => .fcvtld, |
| 7284 | 7290 | .lu => .fcvtlud, |
| 7285 | 7291 | .w => .fcvtwd, |
| ... | ... | @@ -7301,12 +7307,13 @@ fn airCmpxchg(func: *Func, inst: Air.Inst.Index, strength: enum { weak, strong } |
| 7301 | 7307 | _ = strength; // TODO: do something with this |
| 7302 | 7308 | |
| 7303 | 7309 | const pt = func.pt; |
| 7310 | const zcu = pt.zcu; | |
| 7304 | 7311 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7305 | 7312 | const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 7306 | 7313 | |
| 7307 | 7314 | const ptr_ty = func.typeOf(extra.ptr); |
| 7308 | 7315 | const val_ty = func.typeOf(extra.expected_value); |
| 7309 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); | |
| 7316 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt.zcu)); | |
| 7310 | 7317 | |
| 7311 | 7318 | switch (val_abi_size) { |
| 7312 | 7319 | 1, 2, 4, 8 => {}, |
| ... | ... | @@ -7364,7 +7371,7 @@ fn airCmpxchg(func: *Func, inst: Air.Inst.Index, strength: enum { weak, strong } |
| 7364 | 7371 | defer func.register_manager.unlockReg(fallthrough_lock); |
| 7365 | 7372 | |
| 7366 | 7373 | const jump_back = try func.addInst(.{ |
| 7367 | .tag = if (val_ty.bitSize(pt) <= 32) .lrw else .lrd, | |
| 7374 | .tag = if (val_ty.bitSize(zcu) <= 32) .lrw else .lrd, | |
| 7368 | 7375 | .data = .{ .amo = .{ |
| 7369 | 7376 | .aq = lr_order.aq, |
| 7370 | 7377 | .rl = lr_order.rl, |
| ... | ... | @@ -7385,7 +7392,7 @@ fn airCmpxchg(func: *Func, inst: Air.Inst.Index, strength: enum { weak, strong } |
| 7385 | 7392 | }); |
| 7386 | 7393 | |
| 7387 | 7394 | _ = try func.addInst(.{ |
| 7388 | .tag = if (val_ty.bitSize(pt) <= 32) .scw else .scd, | |
| 7395 | .tag = if (val_ty.bitSize(zcu) <= 32) .scw else .scd, | |
| 7389 | 7396 | .data = .{ .amo = .{ |
| 7390 | 7397 | .aq = sc_order.aq, |
| 7391 | 7398 | .rl = sc_order.rl, |
| ... | ... | @@ -7449,7 +7456,7 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void { |
| 7449 | 7456 | const ptr_mcv = try func.resolveInst(pl_op.operand); |
| 7450 | 7457 | |
| 7451 | 7458 | const val_ty = func.typeOf(extra.operand); |
| 7452 | const val_size = val_ty.abiSize(pt); | |
| 7459 | const val_size = val_ty.abiSize(zcu); | |
| 7453 | 7460 | const val_mcv = try func.resolveInst(extra.operand); |
| 7454 | 7461 | |
| 7455 | 7462 | if (!math.isPowerOfTwo(val_size)) |
| ... | ... | @@ -7488,7 +7495,7 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void { |
| 7488 | 7495 | |
| 7489 | 7496 | switch (method) { |
| 7490 | 7497 | .amo => { |
| 7491 | const is_d = val_ty.abiSize(pt) == 8; | |
| 7498 | const is_d = val_ty.abiSize(zcu) == 8; | |
| 7492 | 7499 | const is_un = val_ty.isUnsignedInt(zcu); |
| 7493 | 7500 | |
| 7494 | 7501 | const mnem: Mnemonic = switch (op) { |
| ... | ... | @@ -7587,7 +7594,7 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void { |
| 7587 | 7594 | const elem_ty = ptr_ty.childType(zcu); |
| 7588 | 7595 | const ptr_mcv = try func.resolveInst(atomic_load.ptr); |
| 7589 | 7596 | |
| 7590 | const bit_size = elem_ty.bitSize(pt); | |
| 7597 | const bit_size = elem_ty.bitSize(zcu); | |
| 7591 | 7598 | if (bit_size > 64) return func.fail("TODO: airAtomicStore > 64 bits", .{}); |
| 7592 | 7599 | |
| 7593 | 7600 | const result_mcv = try func.allocRegOrMem(elem_ty, inst, true); |
| ... | ... | @@ -7634,7 +7641,7 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr |
| 7634 | 7641 | const val_ty = func.typeOf(bin_op.rhs); |
| 7635 | 7642 | const val_mcv = try func.resolveInst(bin_op.rhs); |
| 7636 | 7643 | |
| 7637 | const bit_size = val_ty.bitSize(func.pt); | |
| 7644 | const bit_size = val_ty.bitSize(func.pt.zcu); | |
| 7638 | 7645 | if (bit_size > 64) return func.fail("TODO: airAtomicStore > 64 bits", .{}); |
| 7639 | 7646 | |
| 7640 | 7647 | switch (order) { |
| ... | ... | @@ -7679,7 +7686,7 @@ fn airMemset(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 7679 | 7686 | }; |
| 7680 | 7687 | defer if (src_val_lock) |lock| func.register_manager.unlockReg(lock); |
| 7681 | 7688 | |
| 7682 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(pt)); | |
| 7689 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); | |
| 7683 | 7690 | |
| 7684 | 7691 | if (elem_abi_size == 1) { |
| 7685 | 7692 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { |
| ... | ... | @@ -7751,7 +7758,7 @@ fn airMemcpy(func: *Func, inst: Air.Inst.Index) !void { |
| 7751 | 7758 | const len_reg, const len_lock = try func.allocReg(.int); |
| 7752 | 7759 | defer func.register_manager.unlockReg(len_lock); |
| 7753 | 7760 | |
| 7754 | const elem_size = dst_ty.childType(zcu).abiSize(pt); | |
| 7761 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); | |
| 7755 | 7762 | try func.genBinOp( |
| 7756 | 7763 | .mul, |
| 7757 | 7764 | .{ .immediate = elem_size }, |
| ... | ... | @@ -7764,7 +7771,7 @@ fn airMemcpy(func: *Func, inst: Air.Inst.Index) !void { |
| 7764 | 7771 | }, |
| 7765 | 7772 | .One => len: { |
| 7766 | 7773 | const array_ty = dst_ty.childType(zcu); |
| 7767 | break :len .{ .immediate = array_ty.arrayLen(zcu) * array_ty.childType(zcu).abiSize(pt) }; | |
| 7774 | break :len .{ .immediate = array_ty.arrayLen(zcu) * array_ty.childType(zcu).abiSize(zcu) }; | |
| 7768 | 7775 | }, |
| 7769 | 7776 | else => |size| return func.fail("TODO: airMemcpy size {s}", .{@tagName(size)}), |
| 7770 | 7777 | }; |
| ... | ... | @@ -7862,13 +7869,13 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 7862 | 7869 | const result: MCValue = result: { |
| 7863 | 7870 | switch (result_ty.zigTypeTag(zcu)) { |
| 7864 | 7871 | .Struct => { |
| 7865 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); | |
| 7872 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | |
| 7866 | 7873 | if (result_ty.containerLayout(zcu) == .@"packed") { |
| 7867 | 7874 | const struct_obj = zcu.typeToStruct(result_ty).?; |
| 7868 | 7875 | try func.genInlineMemset( |
| 7869 | 7876 | .{ .lea_frame = .{ .index = frame_index } }, |
| 7870 | 7877 | .{ .immediate = 0 }, |
| 7871 | .{ .immediate = result_ty.abiSize(pt) }, | |
| 7878 | .{ .immediate = result_ty.abiSize(zcu) }, | |
| 7872 | 7879 | ); |
| 7873 | 7880 | |
| 7874 | 7881 | for (elements, 0..) |elem, elem_i_usize| { |
| ... | ... | @@ -7876,7 +7883,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 7876 | 7883 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 7877 | 7884 | |
| 7878 | 7885 | const elem_ty = result_ty.structFieldType(elem_i, zcu); |
| 7879 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(pt)); | |
| 7886 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu)); | |
| 7880 | 7887 | if (elem_bit_size > 64) { |
| 7881 | 7888 | return func.fail( |
| 7882 | 7889 | "TODO airAggregateInit implement packed structs with large fields", |
| ... | ... | @@ -7884,7 +7891,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 7884 | 7891 | ); |
| 7885 | 7892 | } |
| 7886 | 7893 | |
| 7887 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 7894 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 7888 | 7895 | const elem_abi_bits = elem_abi_size * 8; |
| 7889 | 7896 | const elem_off = pt.structPackedFieldBitOffset(struct_obj, elem_i); |
| 7890 | 7897 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); |
| ... | ... | @@ -7910,7 +7917,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 7910 | 7917 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 7911 | 7918 | |
| 7912 | 7919 | const elem_ty = result_ty.structFieldType(elem_i, zcu); |
| 7913 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, pt)); | |
| 7920 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu)); | |
| 7914 | 7921 | const elem_mcv = try func.resolveInst(elem); |
| 7915 | 7922 | try func.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv); |
| 7916 | 7923 | } |
| ... | ... | @@ -7918,8 +7925,8 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 7918 | 7925 | }, |
| 7919 | 7926 | .Array => { |
| 7920 | 7927 | const elem_ty = result_ty.childType(zcu); |
| 7921 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); | |
| 7922 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 7928 | const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | |
| 7929 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 7923 | 7930 | |
| 7924 | 7931 | for (elements, 0..) |elem, elem_i| { |
| 7925 | 7932 | const elem_mcv = try func.resolveInst(elem); |
| ... | ... | @@ -7979,10 +7986,11 @@ fn airMulAdd(func: *Func, inst: Air.Inst.Index) !void { |
| 7979 | 7986 | |
| 7980 | 7987 | fn resolveInst(func: *Func, ref: Air.Inst.Ref) InnerError!MCValue { |
| 7981 | 7988 | const pt = func.pt; |
| 7989 | const zcu = pt.zcu; | |
| 7982 | 7990 | |
| 7983 | 7991 | // If the type has no codegen bits, no need to store it. |
| 7984 | 7992 | const inst_ty = func.typeOf(ref); |
| 7985 | if (!inst_ty.hasRuntimeBits(pt)) | |
| 7993 | if (!inst_ty.hasRuntimeBits(zcu)) | |
| 7986 | 7994 | return .none; |
| 7987 | 7995 | |
| 7988 | 7996 | const mcv = if (ref.toIndex()) |inst| mcv: { |
| ... | ... | @@ -8100,14 +8108,14 @@ fn resolveCallingConventionValues( |
| 8100 | 8108 | // Return values |
| 8101 | 8109 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { |
| 8102 | 8110 | result.return_value = InstTracking.init(.unreach); |
| 8103 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 8111 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 8104 | 8112 | result.return_value = InstTracking.init(.none); |
| 8105 | 8113 | } else { |
| 8106 | 8114 | var ret_tracking: [2]InstTracking = undefined; |
| 8107 | 8115 | var ret_tracking_i: usize = 0; |
| 8108 | 8116 | var ret_float_reg_i: usize = 0; |
| 8109 | 8117 | |
| 8110 | const classes = mem.sliceTo(&abi.classifySystem(ret_ty, pt), .none); | |
| 8118 | const classes = mem.sliceTo(&abi.classifySystem(ret_ty, zcu), .none); | |
| 8111 | 8119 | |
| 8112 | 8120 | for (classes) |class| switch (class) { |
| 8113 | 8121 | .integer => { |
| ... | ... | @@ -8151,7 +8159,7 @@ fn resolveCallingConventionValues( |
| 8151 | 8159 | var param_float_reg_i: usize = 0; |
| 8152 | 8160 | |
| 8153 | 8161 | for (param_types, result.args) |ty, *arg| { |
| 8154 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 8162 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 8155 | 8163 | assert(cc == .Unspecified); |
| 8156 | 8164 | arg.* = .none; |
| 8157 | 8165 | continue; |
| ... | ... | @@ -8160,7 +8168,7 @@ fn resolveCallingConventionValues( |
| 8160 | 8168 | var arg_mcv: [2]MCValue = undefined; |
| 8161 | 8169 | var arg_mcv_i: usize = 0; |
| 8162 | 8170 | |
| 8163 | const classes = mem.sliceTo(&abi.classifySystem(ty, pt), .none); | |
| 8171 | const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none); | |
| 8164 | 8172 | |
| 8165 | 8173 | for (classes) |class| switch (class) { |
| 8166 | 8174 | .integer => { |
| ... | ... | @@ -8244,8 +8252,7 @@ fn typeOf(func: *Func, inst: Air.Inst.Ref) Type { |
| 8244 | 8252 | } |
| 8245 | 8253 | |
| 8246 | 8254 | fn typeOfIndex(func: *Func, inst: Air.Inst.Index) Type { |
| 8247 | const pt = func.pt; | |
| 8248 | const zcu = pt.zcu; | |
| 8255 | const zcu = func.pt.zcu; | |
| 8249 | 8256 | return func.air.typeOfIndex(inst, &zcu.intern_pool); |
| 8250 | 8257 | } |
| 8251 | 8258 | |
| ... | ... | @@ -8253,23 +8260,23 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool { |
| 8253 | 8260 | return Target.riscv.featureSetHas(func.target.cpu.features, feature); |
| 8254 | 8261 | } |
| 8255 | 8262 | |
| 8256 | pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { | |
| 8257 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; | |
| 8258 | const payload_align = payload_ty.abiAlignment(pt); | |
| 8259 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 8260 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 8263 | pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 { | |
| 8264 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0; | |
| 8265 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 8266 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 8267 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 8261 | 8268 | return 0; |
| 8262 | 8269 | } else { |
| 8263 | return payload_align.forward(Type.anyerror.abiSize(pt)); | |
| 8270 | return payload_align.forward(Type.anyerror.abiSize(zcu)); | |
| 8264 | 8271 | } |
| 8265 | 8272 | } |
| 8266 | 8273 | |
| 8267 | pub fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { | |
| 8268 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; | |
| 8269 | const payload_align = payload_ty.abiAlignment(pt); | |
| 8270 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 8271 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 8272 | return error_align.forward(payload_ty.abiSize(pt)); | |
| 8274 | pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 { | |
| 8275 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0; | |
| 8276 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 8277 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 8278 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 8279 | return error_align.forward(payload_ty.abiSize(zcu)); | |
| 8273 | 8280 | } else { |
| 8274 | 8281 | return 0; |
| 8275 | 8282 | } |
src/arch/riscv64/Lower.zig+4-3| ... | ... | @@ -49,6 +49,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct { |
| 49 | 49 | relocs: []const Reloc, |
| 50 | 50 | } { |
| 51 | 51 | const pt = lower.pt; |
| 52 | const zcu = pt.zcu; | |
| 52 | 53 | |
| 53 | 54 | lower.result_insts = undefined; |
| 54 | 55 | lower.result_relocs = undefined; |
| ... | ... | @@ -308,11 +309,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct { |
| 308 | 309 | |
| 309 | 310 | const class = rs1.class(); |
| 310 | 311 | const ty = compare.ty; |
| 311 | const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(pt)) catch { | |
| 312 | return lower.fail("pseudo_compare size {}", .{ty.bitSize(pt)}); | |
| 312 | const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(zcu)) catch { | |
| 313 | return lower.fail("pseudo_compare size {}", .{ty.bitSize(zcu)}); | |
| 313 | 314 | }; |
| 314 | 315 | |
| 315 | const is_unsigned = ty.isUnsignedInt(pt.zcu); | |
| 316 | const is_unsigned = ty.isUnsignedInt(zcu); | |
| 316 | 317 | const less_than: Mnemonic = if (is_unsigned) .sltu else .slt; |
| 317 | 318 | |
| 318 | 319 | switch (class) { |
src/arch/riscv64/abi.zig+27-28| ... | ... | @@ -9,15 +9,15 @@ const assert = std.debug.assert; |
| 9 | 9 | |
| 10 | 10 | pub const Class = enum { memory, byval, integer, double_integer, fields }; |
| 11 | 11 | |
| 12 | pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { | |
| 13 | const target = pt.zcu.getTarget(); | |
| 14 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 12 | pub fn classifyType(ty: Type, zcu: *Zcu) Class { | |
| 13 | const target = zcu.getTarget(); | |
| 14 | std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 15 | 15 | |
| 16 | 16 | const max_byval_size = target.ptrBitWidth() * 2; |
| 17 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 17 | switch (ty.zigTypeTag(zcu)) { | |
| 18 | 18 | .Struct => { |
| 19 | const bit_size = ty.bitSize(pt); | |
| 20 | if (ty.containerLayout(pt.zcu) == .@"packed") { | |
| 19 | const bit_size = ty.bitSize(zcu); | |
| 20 | if (ty.containerLayout(zcu) == .@"packed") { | |
| 21 | 21 | if (bit_size > max_byval_size) return .memory; |
| 22 | 22 | return .byval; |
| 23 | 23 | } |
| ... | ... | @@ -25,12 +25,12 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { |
| 25 | 25 | if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: { |
| 26 | 26 | var any_fp = false; |
| 27 | 27 | var field_count: usize = 0; |
| 28 | for (0..ty.structFieldCount(pt.zcu)) |field_index| { | |
| 29 | const field_ty = ty.structFieldType(field_index, pt.zcu); | |
| 30 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 28 | for (0..ty.structFieldCount(zcu)) |field_index| { | |
| 29 | const field_ty = ty.structFieldType(field_index, zcu); | |
| 30 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 31 | 31 | if (field_ty.isRuntimeFloat()) |
| 32 | 32 | any_fp = true |
| 33 | else if (!field_ty.isAbiInt(pt.zcu)) | |
| 33 | else if (!field_ty.isAbiInt(zcu)) | |
| 34 | 34 | break :fields; |
| 35 | 35 | field_count += 1; |
| 36 | 36 | if (field_count > 2) break :fields; |
| ... | ... | @@ -45,8 +45,8 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { |
| 45 | 45 | return .integer; |
| 46 | 46 | }, |
| 47 | 47 | .Union => { |
| 48 | const bit_size = ty.bitSize(pt); | |
| 49 | if (ty.containerLayout(pt.zcu) == .@"packed") { | |
| 48 | const bit_size = ty.bitSize(zcu); | |
| 49 | if (ty.containerLayout(zcu) == .@"packed") { | |
| 50 | 50 | if (bit_size > max_byval_size) return .memory; |
| 51 | 51 | return .byval; |
| 52 | 52 | } |
| ... | ... | @@ -58,21 +58,21 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) Class { |
| 58 | 58 | .Bool => return .integer, |
| 59 | 59 | .Float => return .byval, |
| 60 | 60 | .Int, .Enum, .ErrorSet => { |
| 61 | const bit_size = ty.bitSize(pt); | |
| 61 | const bit_size = ty.bitSize(zcu); | |
| 62 | 62 | if (bit_size > max_byval_size) return .memory; |
| 63 | 63 | return .byval; |
| 64 | 64 | }, |
| 65 | 65 | .Vector => { |
| 66 | const bit_size = ty.bitSize(pt); | |
| 66 | const bit_size = ty.bitSize(zcu); | |
| 67 | 67 | if (bit_size > max_byval_size) return .memory; |
| 68 | 68 | return .integer; |
| 69 | 69 | }, |
| 70 | 70 | .Optional => { |
| 71 | std.debug.assert(ty.isPtrLikeOptional(pt.zcu)); | |
| 71 | std.debug.assert(ty.isPtrLikeOptional(zcu)); | |
| 72 | 72 | return .byval; |
| 73 | 73 | }, |
| 74 | 74 | .Pointer => { |
| 75 | std.debug.assert(!ty.isSlice(pt.zcu)); | |
| 75 | std.debug.assert(!ty.isSlice(zcu)); | |
| 76 | 76 | return .byval; |
| 77 | 77 | }, |
| 78 | 78 | .ErrorUnion, |
| ... | ... | @@ -97,19 +97,18 @@ pub const SystemClass = enum { integer, float, memory, none }; |
| 97 | 97 | |
| 98 | 98 | /// There are a maximum of 8 possible return slots. Returned values are in |
| 99 | 99 | /// the beginning of the array; unused slots are filled with .none. |
| 100 | pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { | |
| 101 | const zcu = pt.zcu; | |
| 100 | pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | |
| 102 | 101 | var result = [1]SystemClass{.none} ** 8; |
| 103 | 102 | const memory_class = [_]SystemClass{ |
| 104 | 103 | .memory, .none, .none, .none, |
| 105 | 104 | .none, .none, .none, .none, |
| 106 | 105 | }; |
| 107 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 106 | switch (ty.zigTypeTag(zcu)) { | |
| 108 | 107 | .Bool, .Void, .NoReturn => { |
| 109 | 108 | result[0] = .integer; |
| 110 | 109 | return result; |
| 111 | 110 | }, |
| 112 | .Pointer => switch (ty.ptrSize(pt.zcu)) { | |
| 111 | .Pointer => switch (ty.ptrSize(zcu)) { | |
| 113 | 112 | .Slice => { |
| 114 | 113 | result[0] = .integer; |
| 115 | 114 | result[1] = .integer; |
| ... | ... | @@ -121,14 +120,14 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { |
| 121 | 120 | }, |
| 122 | 121 | }, |
| 123 | 122 | .Optional => { |
| 124 | if (ty.isPtrLikeOptional(pt.zcu)) { | |
| 123 | if (ty.isPtrLikeOptional(zcu)) { | |
| 125 | 124 | result[0] = .integer; |
| 126 | 125 | return result; |
| 127 | 126 | } |
| 128 | 127 | return memory_class; |
| 129 | 128 | }, |
| 130 | 129 | .Int, .Enum, .ErrorSet => { |
| 131 | const int_bits = ty.intInfo(pt.zcu).bits; | |
| 130 | const int_bits = ty.intInfo(zcu).bits; | |
| 132 | 131 | if (int_bits <= 64) { |
| 133 | 132 | result[0] = .integer; |
| 134 | 133 | return result; |
| ... | ... | @@ -153,8 +152,8 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { |
| 153 | 152 | unreachable; // support split float args |
| 154 | 153 | }, |
| 155 | 154 | .ErrorUnion => { |
| 156 | const payload_ty = ty.errorUnionPayload(pt.zcu); | |
| 157 | const payload_bits = payload_ty.bitSize(pt); | |
| 155 | const payload_ty = ty.errorUnionPayload(zcu); | |
| 156 | const payload_bits = payload_ty.bitSize(zcu); | |
| 158 | 157 | |
| 159 | 158 | // the error union itself |
| 160 | 159 | result[0] = .integer; |
| ... | ... | @@ -165,8 +164,8 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { |
| 165 | 164 | return memory_class; |
| 166 | 165 | }, |
| 167 | 166 | .Struct, .Union => { |
| 168 | const layout = ty.containerLayout(pt.zcu); | |
| 169 | const ty_size = ty.abiSize(pt); | |
| 167 | const layout = ty.containerLayout(zcu); | |
| 168 | const ty_size = ty.abiSize(zcu); | |
| 170 | 169 | |
| 171 | 170 | if (layout == .@"packed") { |
| 172 | 171 | assert(ty_size <= 16); |
| ... | ... | @@ -178,7 +177,7 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { |
| 178 | 177 | return memory_class; |
| 179 | 178 | }, |
| 180 | 179 | .Array => { |
| 181 | const ty_size = ty.abiSize(pt); | |
| 180 | const ty_size = ty.abiSize(zcu); | |
| 182 | 181 | if (ty_size <= 8) { |
| 183 | 182 | result[0] = .integer; |
| 184 | 183 | return result; |
| ... | ... | @@ -192,7 +191,7 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass { |
| 192 | 191 | }, |
| 193 | 192 | .Vector => { |
| 194 | 193 | // we pass vectors through integer registers if they are small enough to fit. |
| 195 | const vec_bits = ty.totalVectorBits(pt); | |
| 194 | const vec_bits = ty.totalVectorBits(zcu); | |
| 196 | 195 | if (vec_bits <= 64) { |
| 197 | 196 | result[0] = .integer; |
| 198 | 197 | return result; |
src/arch/sparc64/CodeGen.zig+99-96| ... | ... | @@ -1012,6 +1012,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 1012 | 1012 | |
| 1013 | 1013 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1014 | 1014 | const pt = self.pt; |
| 1015 | const zcu = pt.zcu; | |
| 1015 | 1016 | const arg_index = self.arg_index; |
| 1016 | 1017 | self.arg_index += 1; |
| 1017 | 1018 | |
| ... | ... | @@ -1021,7 +1022,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1021 | 1022 | const mcv = blk: { |
| 1022 | 1023 | switch (arg) { |
| 1023 | 1024 | .stack_offset => |off| { |
| 1024 | const abi_size = math.cast(u32, ty.abiSize(pt)) orelse { | |
| 1025 | const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse { | |
| 1025 | 1026 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)}); |
| 1026 | 1027 | }; |
| 1027 | 1028 | const offset = off + abi_size; |
| ... | ... | @@ -1211,7 +1212,7 @@ fn airBreakpoint(self: *Self) !void { |
| 1211 | 1212 | |
| 1212 | 1213 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 1213 | 1214 | const pt = self.pt; |
| 1214 | const mod = pt.zcu; | |
| 1215 | const zcu = pt.zcu; | |
| 1215 | 1216 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1216 | 1217 | |
| 1217 | 1218 | // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you. |
| ... | ... | @@ -1227,14 +1228,14 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 1227 | 1228 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1228 | 1229 | const operand = try self.resolveInst(ty_op.operand); |
| 1229 | 1230 | const operand_ty = self.typeOf(ty_op.operand); |
| 1230 | switch (operand_ty.zigTypeTag(mod)) { | |
| 1231 | switch (operand_ty.zigTypeTag(zcu)) { | |
| 1231 | 1232 | .Vector => return self.fail("TODO byteswap for vectors", .{}), |
| 1232 | 1233 | .Int => { |
| 1233 | const int_info = operand_ty.intInfo(mod); | |
| 1234 | const int_info = operand_ty.intInfo(zcu); | |
| 1234 | 1235 | if (int_info.bits == 8) break :result operand; |
| 1235 | 1236 | |
| 1236 | 1237 | const abi_size = int_info.bits >> 3; |
| 1237 | const abi_align = operand_ty.abiAlignment(pt); | |
| 1238 | const abi_align = operand_ty.abiAlignment(zcu); | |
| 1238 | 1239 | const opposite_endian_asi = switch (self.target.cpu.arch.endian()) { |
| 1239 | 1240 | Endian.big => ASI.asi_primary_little, |
| 1240 | 1241 | Endian.little => ASI.asi_primary, |
| ... | ... | @@ -1409,24 +1410,24 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 1409 | 1410 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1410 | 1411 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 1411 | 1412 | const pt = self.pt; |
| 1412 | const mod = pt.zcu; | |
| 1413 | const zcu = pt.zcu; | |
| 1413 | 1414 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1414 | 1415 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1415 | 1416 | const rhs = try self.resolveInst(bin_op.rhs); |
| 1416 | 1417 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 1417 | 1418 | |
| 1418 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { | |
| 1419 | const int_ty = switch (lhs_ty.zigTypeTag(zcu)) { | |
| 1419 | 1420 | .Vector => unreachable, // Handled by cmp_vector. |
| 1420 | .Enum => lhs_ty.intTagType(mod), | |
| 1421 | .Enum => lhs_ty.intTagType(zcu), | |
| 1421 | 1422 | .Int => lhs_ty, |
| 1422 | 1423 | .Bool => Type.u1, |
| 1423 | 1424 | .Pointer => Type.usize, |
| 1424 | 1425 | .ErrorSet => Type.u16, |
| 1425 | 1426 | .Optional => blk: { |
| 1426 | const payload_ty = lhs_ty.optionalChild(mod); | |
| 1427 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1427 | const payload_ty = lhs_ty.optionalChild(zcu); | |
| 1428 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1428 | 1429 | break :blk Type.u1; |
| 1429 | } else if (lhs_ty.isPtrLikeOptional(mod)) { | |
| 1430 | } else if (lhs_ty.isPtrLikeOptional(zcu)) { | |
| 1430 | 1431 | break :blk Type.usize; |
| 1431 | 1432 | } else { |
| 1432 | 1433 | return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{}); |
| ... | ... | @@ -1436,7 +1437,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1436 | 1437 | else => unreachable, |
| 1437 | 1438 | }; |
| 1438 | 1439 | |
| 1439 | const int_info = int_ty.intInfo(mod); | |
| 1440 | const int_info = int_ty.intInfo(zcu); | |
| 1440 | 1441 | if (int_info.bits <= 64) { |
| 1441 | 1442 | _ = try self.binOp(.cmp_eq, lhs, rhs, int_ty, int_ty, BinOpMetadata{ |
| 1442 | 1443 | .lhs = bin_op.lhs, |
| ... | ... | @@ -1797,16 +1798,16 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 1797 | 1798 | |
| 1798 | 1799 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1799 | 1800 | const pt = self.pt; |
| 1800 | const mod = pt.zcu; | |
| 1801 | const zcu = pt.zcu; | |
| 1801 | 1802 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1802 | 1803 | const elem_ty = self.typeOfIndex(inst); |
| 1803 | const elem_size = elem_ty.abiSize(pt); | |
| 1804 | const elem_size = elem_ty.abiSize(zcu); | |
| 1804 | 1805 | const result: MCValue = result: { |
| 1805 | if (!elem_ty.hasRuntimeBits(pt)) | |
| 1806 | if (!elem_ty.hasRuntimeBits(zcu)) | |
| 1806 | 1807 | break :result MCValue.none; |
| 1807 | 1808 | |
| 1808 | 1809 | const ptr = try self.resolveInst(ty_op.operand); |
| 1809 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 1810 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(zcu); | |
| 1810 | 1811 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 1811 | 1812 | break :result MCValue.dead; |
| 1812 | 1813 | |
| ... | ... | @@ -2428,7 +2429,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 2428 | 2429 | |
| 2429 | 2430 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2430 | 2431 | const pt = self.pt; |
| 2431 | const mod = pt.zcu; | |
| 2432 | const zcu = pt.zcu; | |
| 2432 | 2433 | const is_volatile = false; // TODO |
| 2433 | 2434 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2434 | 2435 | |
| ... | ... | @@ -2438,10 +2439,10 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2438 | 2439 | const index_mcv = try self.resolveInst(bin_op.rhs); |
| 2439 | 2440 | |
| 2440 | 2441 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2441 | const elem_ty = slice_ty.childType(mod); | |
| 2442 | const elem_size = elem_ty.abiSize(pt); | |
| 2442 | const elem_ty = slice_ty.childType(zcu); | |
| 2443 | const elem_size = elem_ty.abiSize(zcu); | |
| 2443 | 2444 | |
| 2444 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | |
| 2445 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu); | |
| 2445 | 2446 | |
| 2446 | 2447 | const index_lock: ?RegisterLock = if (index_mcv == .register) |
| 2447 | 2448 | self.register_manager.lockRegAssumeUnused(index_mcv.register) |
| ... | ... | @@ -2553,10 +2554,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2553 | 2554 | const operand = extra.struct_operand; |
| 2554 | 2555 | const index = extra.field_index; |
| 2555 | 2556 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2556 | const pt = self.pt; | |
| 2557 | const zcu = self.pt.zcu; | |
| 2557 | 2558 | const mcv = try self.resolveInst(operand); |
| 2558 | 2559 | const struct_ty = self.typeOf(operand); |
| 2559 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); | |
| 2560 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu))); | |
| 2560 | 2561 | |
| 2561 | 2562 | switch (mcv) { |
| 2562 | 2563 | .dead, .unreach => unreachable, |
| ... | ... | @@ -2687,13 +2688,13 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 2687 | 2688 | |
| 2688 | 2689 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2689 | 2690 | const pt = self.pt; |
| 2690 | const mod = pt.zcu; | |
| 2691 | const zcu = pt.zcu; | |
| 2691 | 2692 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2692 | 2693 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2693 | 2694 | const error_union_ty = self.typeOf(ty_op.operand); |
| 2694 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2695 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2695 | 2696 | const mcv = try self.resolveInst(ty_op.operand); |
| 2696 | if (!payload_ty.hasRuntimeBits(pt)) break :result mcv; | |
| 2697 | if (!payload_ty.hasRuntimeBits(zcu)) break :result mcv; | |
| 2697 | 2698 | |
| 2698 | 2699 | return self.fail("TODO implement unwrap error union error for non-empty payloads", .{}); |
| 2699 | 2700 | }; |
| ... | ... | @@ -2702,12 +2703,12 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2702 | 2703 | |
| 2703 | 2704 | fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2704 | 2705 | const pt = self.pt; |
| 2705 | const mod = pt.zcu; | |
| 2706 | const zcu = pt.zcu; | |
| 2706 | 2707 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2707 | 2708 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2708 | 2709 | const error_union_ty = self.typeOf(ty_op.operand); |
| 2709 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2710 | if (!payload_ty.hasRuntimeBits(pt)) break :result MCValue.none; | |
| 2710 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2711 | if (!payload_ty.hasRuntimeBits(zcu)) break :result MCValue.none; | |
| 2711 | 2712 | |
| 2712 | 2713 | return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{}); |
| 2713 | 2714 | }; |
| ... | ... | @@ -2717,13 +2718,13 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2717 | 2718 | /// E to E!T |
| 2718 | 2719 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2719 | 2720 | const pt = self.pt; |
| 2720 | const mod = pt.zcu; | |
| 2721 | const zcu = pt.zcu; | |
| 2721 | 2722 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2722 | 2723 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2723 | 2724 | const error_union_ty = ty_op.ty.toType(); |
| 2724 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 2725 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 2725 | 2726 | const mcv = try self.resolveInst(ty_op.operand); |
| 2726 | if (!payload_ty.hasRuntimeBits(pt)) break :result mcv; | |
| 2727 | if (!payload_ty.hasRuntimeBits(zcu)) break :result mcv; | |
| 2727 | 2728 | |
| 2728 | 2729 | return self.fail("TODO implement wrap errunion error for non-empty payloads", .{}); |
| 2729 | 2730 | }; |
| ... | ... | @@ -2744,7 +2745,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2744 | 2745 | const optional_ty = self.typeOfIndex(inst); |
| 2745 | 2746 | |
| 2746 | 2747 | // Optional with a zero-bit payload type is just a boolean true |
| 2747 | if (optional_ty.abiSize(pt) == 1) | |
| 2748 | if (optional_ty.abiSize(pt.zcu) == 1) | |
| 2748 | 2749 | break :result MCValue{ .immediate = 1 }; |
| 2749 | 2750 | |
| 2750 | 2751 | return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch}); |
| ... | ... | @@ -2779,10 +2780,10 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme |
| 2779 | 2780 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 2780 | 2781 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2781 | 2782 | const pt = self.pt; |
| 2782 | const mod = pt.zcu; | |
| 2783 | const elem_ty = self.typeOfIndex(inst).childType(mod); | |
| 2783 | const zcu = pt.zcu; | |
| 2784 | const elem_ty = self.typeOfIndex(inst).childType(zcu); | |
| 2784 | 2785 | |
| 2785 | if (!elem_ty.hasRuntimeBits(pt)) { | |
| 2786 | if (!elem_ty.hasRuntimeBits(zcu)) { | |
| 2786 | 2787 | // As this stack item will never be dereferenced at runtime, |
| 2787 | 2788 | // return the stack offset 0. Stack offset 0 will be where all |
| 2788 | 2789 | // zero-sized stack allocations live as non-zero-sized |
| ... | ... | @@ -2790,21 +2791,22 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2790 | 2791 | return @as(u32, 0); |
| 2791 | 2792 | } |
| 2792 | 2793 | |
| 2793 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { | |
| 2794 | const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse { | |
| 2794 | 2795 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 2795 | 2796 | }; |
| 2796 | 2797 | // TODO swap this for inst.ty.ptrAlign |
| 2797 | const abi_align = elem_ty.abiAlignment(pt); | |
| 2798 | const abi_align = elem_ty.abiAlignment(zcu); | |
| 2798 | 2799 | return self.allocMem(inst, abi_size, abi_align); |
| 2799 | 2800 | } |
| 2800 | 2801 | |
| 2801 | 2802 | fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 2802 | 2803 | const pt = self.pt; |
| 2804 | const zcu = pt.zcu; | |
| 2803 | 2805 | const elem_ty = self.typeOfIndex(inst); |
| 2804 | const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse { | |
| 2806 | const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse { | |
| 2805 | 2807 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)}); |
| 2806 | 2808 | }; |
| 2807 | const abi_align = elem_ty.abiAlignment(pt); | |
| 2809 | const abi_align = elem_ty.abiAlignment(zcu); | |
| 2808 | 2810 | self.stack_align = self.stack_align.max(abi_align); |
| 2809 | 2811 | |
| 2810 | 2812 | if (reg_ok) { |
| ... | ... | @@ -2847,7 +2849,7 @@ fn binOp( |
| 2847 | 2849 | metadata: ?BinOpMetadata, |
| 2848 | 2850 | ) InnerError!MCValue { |
| 2849 | 2851 | const pt = self.pt; |
| 2850 | const mod = pt.zcu; | |
| 2852 | const zcu = pt.zcu; | |
| 2851 | 2853 | switch (tag) { |
| 2852 | 2854 | .add, |
| 2853 | 2855 | .sub, |
| ... | ... | @@ -2857,12 +2859,12 @@ fn binOp( |
| 2857 | 2859 | .xor, |
| 2858 | 2860 | .cmp_eq, |
| 2859 | 2861 | => { |
| 2860 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2862 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2861 | 2863 | .Float => return self.fail("TODO binary operations on floats", .{}), |
| 2862 | 2864 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2863 | 2865 | .Int => { |
| 2864 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2865 | const int_info = lhs_ty.intInfo(mod); | |
| 2866 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2867 | const int_info = lhs_ty.intInfo(zcu); | |
| 2866 | 2868 | if (int_info.bits <= 64) { |
| 2867 | 2869 | // Only say yes if the operation is |
| 2868 | 2870 | // commutative, i.e. we can swap both of the |
| ... | ... | @@ -2931,10 +2933,10 @@ fn binOp( |
| 2931 | 2933 | const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata); |
| 2932 | 2934 | |
| 2933 | 2935 | // Truncate if necessary |
| 2934 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2936 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2935 | 2937 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2936 | 2938 | .Int => { |
| 2937 | const int_info = lhs_ty.intInfo(mod); | |
| 2939 | const int_info = lhs_ty.intInfo(zcu); | |
| 2938 | 2940 | if (int_info.bits <= 64) { |
| 2939 | 2941 | const result_reg = result.register; |
| 2940 | 2942 | try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits); |
| ... | ... | @@ -2948,11 +2950,11 @@ fn binOp( |
| 2948 | 2950 | }, |
| 2949 | 2951 | |
| 2950 | 2952 | .div_trunc => { |
| 2951 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2953 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2952 | 2954 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2953 | 2955 | .Int => { |
| 2954 | assert(lhs_ty.eql(rhs_ty, mod)); | |
| 2955 | const int_info = lhs_ty.intInfo(mod); | |
| 2956 | assert(lhs_ty.eql(rhs_ty, zcu)); | |
| 2957 | const int_info = lhs_ty.intInfo(zcu); | |
| 2956 | 2958 | if (int_info.bits <= 64) { |
| 2957 | 2959 | const rhs_immediate_ok = switch (tag) { |
| 2958 | 2960 | .div_trunc => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12), |
| ... | ... | @@ -2981,14 +2983,14 @@ fn binOp( |
| 2981 | 2983 | }, |
| 2982 | 2984 | |
| 2983 | 2985 | .ptr_add => { |
| 2984 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 2986 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 2985 | 2987 | .Pointer => { |
| 2986 | 2988 | const ptr_ty = lhs_ty; |
| 2987 | const elem_ty = switch (ptr_ty.ptrSize(mod)) { | |
| 2988 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | |
| 2989 | else => ptr_ty.childType(mod), | |
| 2989 | const elem_ty = switch (ptr_ty.ptrSize(zcu)) { | |
| 2990 | .One => ptr_ty.childType(zcu).childType(zcu), // ptr to array, so get array element type | |
| 2991 | else => ptr_ty.childType(zcu), | |
| 2990 | 2992 | }; |
| 2991 | const elem_size = elem_ty.abiSize(pt); | |
| 2993 | const elem_size = elem_ty.abiSize(zcu); | |
| 2992 | 2994 | |
| 2993 | 2995 | if (elem_size == 1) { |
| 2994 | 2996 | const base_tag: Mir.Inst.Tag = switch (tag) { |
| ... | ... | @@ -3013,7 +3015,7 @@ fn binOp( |
| 3013 | 3015 | .bool_and, |
| 3014 | 3016 | .bool_or, |
| 3015 | 3017 | => { |
| 3016 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3018 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3017 | 3019 | .Bool => { |
| 3018 | 3020 | assert(lhs != .immediate); // should have been handled by Sema |
| 3019 | 3021 | assert(rhs != .immediate); // should have been handled by Sema |
| ... | ... | @@ -3043,10 +3045,10 @@ fn binOp( |
| 3043 | 3045 | const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata); |
| 3044 | 3046 | |
| 3045 | 3047 | // Truncate if necessary |
| 3046 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3048 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3047 | 3049 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 3048 | 3050 | .Int => { |
| 3049 | const int_info = lhs_ty.intInfo(mod); | |
| 3051 | const int_info = lhs_ty.intInfo(zcu); | |
| 3050 | 3052 | if (int_info.bits <= 64) { |
| 3051 | 3053 | // 32 and 64 bit operands doesn't need truncating |
| 3052 | 3054 | if (int_info.bits == 32 or int_info.bits == 64) return result; |
| ... | ... | @@ -3065,10 +3067,10 @@ fn binOp( |
| 3065 | 3067 | .shl_exact, |
| 3066 | 3068 | .shr_exact, |
| 3067 | 3069 | => { |
| 3068 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 3070 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 3069 | 3071 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 3070 | 3072 | .Int => { |
| 3071 | const int_info = lhs_ty.intInfo(mod); | |
| 3073 | const int_info = lhs_ty.intInfo(zcu); | |
| 3072 | 3074 | if (int_info.bits <= 64) { |
| 3073 | 3075 | const rhs_immediate_ok = rhs == .immediate; |
| 3074 | 3076 | |
| ... | ... | @@ -3388,8 +3390,8 @@ fn binOpRegister( |
| 3388 | 3390 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 3389 | 3391 | const block_data = self.blocks.getPtr(block).?; |
| 3390 | 3392 | |
| 3391 | const pt = self.pt; | |
| 3392 | if (self.typeOf(operand).hasRuntimeBits(pt)) { | |
| 3393 | const zcu = self.pt.zcu; | |
| 3394 | if (self.typeOf(operand).hasRuntimeBits(zcu)) { | |
| 3393 | 3395 | const operand_mcv = try self.resolveInst(operand); |
| 3394 | 3396 | const block_mcv = block_data.mcv; |
| 3395 | 3397 | if (block_mcv == .none) { |
| ... | ... | @@ -3509,17 +3511,17 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void { |
| 3509 | 3511 | /// Given an error union, returns the payload |
| 3510 | 3512 | fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { |
| 3511 | 3513 | const pt = self.pt; |
| 3512 | const mod = pt.zcu; | |
| 3513 | const err_ty = error_union_ty.errorUnionSet(mod); | |
| 3514 | const payload_ty = error_union_ty.errorUnionPayload(mod); | |
| 3515 | if (err_ty.errorSetIsEmpty(mod)) { | |
| 3514 | const zcu = pt.zcu; | |
| 3515 | const err_ty = error_union_ty.errorUnionSet(zcu); | |
| 3516 | const payload_ty = error_union_ty.errorUnionPayload(zcu); | |
| 3517 | if (err_ty.errorSetIsEmpty(zcu)) { | |
| 3516 | 3518 | return error_union_mcv; |
| 3517 | 3519 | } |
| 3518 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3520 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3519 | 3521 | return MCValue.none; |
| 3520 | 3522 | } |
| 3521 | 3523 | |
| 3522 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))); | |
| 3524 | const payload_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))); | |
| 3523 | 3525 | switch (error_union_mcv) { |
| 3524 | 3526 | .register => return self.fail("TODO errUnionPayload for registers", .{}), |
| 3525 | 3527 | .stack_offset => |off| { |
| ... | ... | @@ -3731,6 +3733,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg |
| 3731 | 3733 | |
| 3732 | 3734 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 3733 | 3735 | const pt = self.pt; |
| 3736 | const zcu = pt.zcu; | |
| 3734 | 3737 | switch (mcv) { |
| 3735 | 3738 | .dead => unreachable, |
| 3736 | 3739 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -3929,21 +3932,21 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3929 | 3932 | // The value is in memory at a hard-coded address. |
| 3930 | 3933 | // If the type is a pointer, it means the pointer address is at this memory location. |
| 3931 | 3934 | try self.genSetReg(ty, reg, .{ .immediate = addr }); |
| 3932 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(pt)); | |
| 3935 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(zcu)); | |
| 3933 | 3936 | }, |
| 3934 | 3937 | .stack_offset => |off| { |
| 3935 | 3938 | const real_offset = realStackOffset(off); |
| 3936 | 3939 | const simm13 = math.cast(i13, real_offset) orelse |
| 3937 | 3940 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3938 | try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(pt)); | |
| 3941 | try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(zcu)); | |
| 3939 | 3942 | }, |
| 3940 | 3943 | } |
| 3941 | 3944 | } |
| 3942 | 3945 | |
| 3943 | 3946 | fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void { |
| 3944 | 3947 | const pt = self.pt; |
| 3945 | const mod = pt.zcu; | |
| 3946 | const abi_size = ty.abiSize(pt); | |
| 3948 | const zcu = pt.zcu; | |
| 3949 | const abi_size = ty.abiSize(zcu); | |
| 3947 | 3950 | switch (mcv) { |
| 3948 | 3951 | .dead => unreachable, |
| 3949 | 3952 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -3951,7 +3954,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3951 | 3954 | if (!self.wantSafety()) |
| 3952 | 3955 | return; // The already existing value will do just fine. |
| 3953 | 3956 | // TODO Upgrade this to a memset call when we have that available. |
| 3954 | switch (ty.abiSize(pt)) { | |
| 3957 | switch (ty.abiSize(zcu)) { | |
| 3955 | 3958 | 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }), |
| 3956 | 3959 | 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }), |
| 3957 | 3960 | 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), |
| ... | ... | @@ -3977,11 +3980,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3977 | 3980 | const reg_lock = self.register_manager.lockReg(rwo.reg); |
| 3978 | 3981 | defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg); |
| 3979 | 3982 | |
| 3980 | const wrapped_ty = ty.structFieldType(0, mod); | |
| 3983 | const wrapped_ty = ty.structFieldType(0, zcu); | |
| 3981 | 3984 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg }); |
| 3982 | 3985 | |
| 3983 | const overflow_bit_ty = ty.structFieldType(1, mod); | |
| 3984 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, pt))); | |
| 3986 | const overflow_bit_ty = ty.structFieldType(1, zcu); | |
| 3987 | const overflow_bit_offset = @as(u32, @intCast(ty.structFieldOffset(1, zcu))); | |
| 3985 | 3988 | const cond_reg = try self.register_manager.allocReg(null, gp); |
| 3986 | 3989 | |
| 3987 | 3990 | // TODO handle floating point CCRs |
| ... | ... | @@ -4154,14 +4157,14 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 4154 | 4157 | |
| 4155 | 4158 | fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue { |
| 4156 | 4159 | const pt = self.pt; |
| 4157 | const mod = pt.zcu; | |
| 4158 | const error_type = ty.errorUnionSet(mod); | |
| 4159 | const payload_type = ty.errorUnionPayload(mod); | |
| 4160 | const zcu = pt.zcu; | |
| 4161 | const error_type = ty.errorUnionSet(zcu); | |
| 4162 | const payload_type = ty.errorUnionPayload(zcu); | |
| 4160 | 4163 | |
| 4161 | if (!error_type.hasRuntimeBits(pt)) { | |
| 4164 | if (!error_type.hasRuntimeBits(zcu)) { | |
| 4162 | 4165 | return MCValue{ .immediate = 0 }; // always false |
| 4163 | } else if (!payload_type.hasRuntimeBits(pt)) { | |
| 4164 | if (error_type.abiSize(pt) <= 8) { | |
| 4166 | } else if (!payload_type.hasRuntimeBits(zcu)) { | |
| 4167 | if (error_type.abiSize(zcu) <= 8) { | |
| 4165 | 4168 | const reg_mcv: MCValue = switch (operand) { |
| 4166 | 4169 | .register => operand, |
| 4167 | 4170 | else => .{ .register = try self.copyToTmpRegister(error_type, operand) }, |
| ... | ... | @@ -4253,9 +4256,9 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { |
| 4253 | 4256 | |
| 4254 | 4257 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 4255 | 4258 | const pt = self.pt; |
| 4256 | const mod = pt.zcu; | |
| 4257 | const elem_ty = ptr_ty.childType(mod); | |
| 4258 | const elem_size = elem_ty.abiSize(pt); | |
| 4259 | const zcu = pt.zcu; | |
| 4260 | const elem_ty = ptr_ty.childType(zcu); | |
| 4261 | const elem_size = elem_ty.abiSize(zcu); | |
| 4259 | 4262 | |
| 4260 | 4263 | switch (ptr) { |
| 4261 | 4264 | .none => unreachable, |
| ... | ... | @@ -4446,9 +4449,9 @@ fn realStackOffset(off: u32) u32 { |
| 4446 | 4449 | /// Caller must call `CallMCValues.deinit`. |
| 4447 | 4450 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues { |
| 4448 | 4451 | const pt = self.pt; |
| 4449 | const mod = pt.zcu; | |
| 4450 | const ip = &mod.intern_pool; | |
| 4451 | const fn_info = mod.typeToFunc(fn_ty).?; | |
| 4452 | const zcu = pt.zcu; | |
| 4453 | const ip = &zcu.intern_pool; | |
| 4454 | const fn_info = zcu.typeToFunc(fn_ty).?; | |
| 4452 | 4455 | const cc = fn_info.cc; |
| 4453 | 4456 | var result: CallMCValues = .{ |
| 4454 | 4457 | .args = try self.gpa.alloc(MCValue, fn_info.param_types.len), |
| ... | ... | @@ -4459,7 +4462,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4459 | 4462 | }; |
| 4460 | 4463 | errdefer self.gpa.free(result.args); |
| 4461 | 4464 | |
| 4462 | const ret_ty = fn_ty.fnReturnType(mod); | |
| 4465 | const ret_ty = fn_ty.fnReturnType(zcu); | |
| 4463 | 4466 | |
| 4464 | 4467 | switch (cc) { |
| 4465 | 4468 | .Naked => { |
| ... | ... | @@ -4487,7 +4490,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4487 | 4490 | }; |
| 4488 | 4491 | |
| 4489 | 4492 | for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| { |
| 4490 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))); | |
| 4493 | const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(zcu))); | |
| 4491 | 4494 | if (param_size <= 8) { |
| 4492 | 4495 | if (next_register < argument_registers.len) { |
| 4493 | 4496 | result_arg.* = .{ .register = argument_registers[next_register] }; |
| ... | ... | @@ -4514,12 +4517,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4514 | 4517 | result.stack_byte_count = next_stack_offset; |
| 4515 | 4518 | result.stack_align = .@"16"; |
| 4516 | 4519 | |
| 4517 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 4520 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 4518 | 4521 | result.return_value = .{ .unreach = {} }; |
| 4519 | } else if (!ret_ty.hasRuntimeBits(pt)) { | |
| 4522 | } else if (!ret_ty.hasRuntimeBits(zcu)) { | |
| 4520 | 4523 | result.return_value = .{ .none = {} }; |
| 4521 | 4524 | } else { |
| 4522 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt)); | |
| 4525 | const ret_ty_size: u32 = @intCast(ret_ty.abiSize(zcu)); | |
| 4523 | 4526 | // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller. |
| 4524 | 4527 | if (ret_ty_size <= 8) { |
| 4525 | 4528 | result.return_value = switch (role) { |
| ... | ... | @@ -4542,7 +4545,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 4542 | 4545 | const ty = self.typeOf(ref); |
| 4543 | 4546 | |
| 4544 | 4547 | // If the type has no codegen bits, no need to store it. |
| 4545 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 4548 | if (!ty.hasRuntimeBitsIgnoreComptime(pt.zcu)) return .none; | |
| 4546 | 4549 | |
| 4547 | 4550 | if (ref.toIndex()) |inst| { |
| 4548 | 4551 | return self.getResolvedInstValue(inst); |
| ... | ... | @@ -4656,7 +4659,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void |
| 4656 | 4659 | |
| 4657 | 4660 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 4658 | 4661 | const pt = self.pt; |
| 4659 | const abi_size = value_ty.abiSize(pt); | |
| 4662 | const abi_size = value_ty.abiSize(pt.zcu); | |
| 4660 | 4663 | |
| 4661 | 4664 | switch (ptr) { |
| 4662 | 4665 | .none => unreachable, |
| ... | ... | @@ -4698,11 +4701,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 4698 | 4701 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 4699 | 4702 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 4700 | 4703 | const pt = self.pt; |
| 4701 | const mod = pt.zcu; | |
| 4704 | const zcu = pt.zcu; | |
| 4702 | 4705 | const mcv = try self.resolveInst(operand); |
| 4703 | 4706 | const ptr_ty = self.typeOf(operand); |
| 4704 | const struct_ty = ptr_ty.childType(mod); | |
| 4705 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, pt))); | |
| 4707 | const struct_ty = ptr_ty.childType(zcu); | |
| 4708 | const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, zcu))); | |
| 4706 | 4709 | switch (mcv) { |
| 4707 | 4710 | .ptr_stack_offset => |off| { |
| 4708 | 4711 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
src/arch/wasm/CodeGen.zig+542-539| ... | ... | @@ -788,10 +788,10 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 788 | 788 | assert(!gop.found_existing); |
| 789 | 789 | |
| 790 | 790 | const pt = func.pt; |
| 791 | const mod = pt.zcu; | |
| 791 | const zcu = pt.zcu; | |
| 792 | 792 | const val = (try func.air.value(ref, pt)).?; |
| 793 | 793 | const ty = func.typeOf(ref); |
| 794 | if (!ty.hasRuntimeBitsIgnoreComptime(pt) and !ty.isInt(mod) and !ty.isError(mod)) { | |
| 794 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu) and !ty.isInt(zcu) and !ty.isError(zcu)) { | |
| 795 | 795 | gop.value_ptr.* = .none; |
| 796 | 796 | return gop.value_ptr.*; |
| 797 | 797 | } |
| ... | ... | @@ -1001,9 +1001,9 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32 |
| 1001 | 1001 | |
| 1002 | 1002 | /// Using a given `Type`, returns the corresponding valtype for .auto callconv |
| 1003 | 1003 | fn typeToValtype(ty: Type, pt: Zcu.PerThread, target: std.Target) wasm.Valtype { |
| 1004 | const mod = pt.zcu; | |
| 1005 | const ip = &mod.intern_pool; | |
| 1006 | return switch (ty.zigTypeTag(mod)) { | |
| 1004 | const zcu = pt.zcu; | |
| 1005 | const ip = &zcu.intern_pool; | |
| 1006 | return switch (ty.zigTypeTag(zcu)) { | |
| 1007 | 1007 | .Float => switch (ty.floatBits(target)) { |
| 1008 | 1008 | 16 => .i32, // stored/loaded as u16 |
| 1009 | 1009 | 32 => .f32, |
| ... | ... | @@ -1011,26 +1011,26 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread, target: std.Target) wasm.Valtype { |
| 1011 | 1011 | 80, 128 => .i32, |
| 1012 | 1012 | else => unreachable, |
| 1013 | 1013 | }, |
| 1014 | .Int, .Enum => switch (ty.intInfo(pt.zcu).bits) { | |
| 1014 | .Int, .Enum => switch (ty.intInfo(zcu).bits) { | |
| 1015 | 1015 | 0...32 => .i32, |
| 1016 | 1016 | 33...64 => .i64, |
| 1017 | 1017 | else => .i32, |
| 1018 | 1018 | }, |
| 1019 | 1019 | .Struct => blk: { |
| 1020 | if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| { | |
| 1020 | if (zcu.typeToPackedStruct(ty)) |packed_struct| { | |
| 1021 | 1021 | const backing_int_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)); |
| 1022 | 1022 | break :blk typeToValtype(backing_int_ty, pt, target); |
| 1023 | 1023 | } else { |
| 1024 | 1024 | break :blk .i32; |
| 1025 | 1025 | } |
| 1026 | 1026 | }, |
| 1027 | .Vector => switch (determineSimdStoreStrategy(ty, pt, target)) { | |
| 1027 | .Vector => switch (determineSimdStoreStrategy(ty, zcu, target)) { | |
| 1028 | 1028 | .direct => .v128, |
| 1029 | 1029 | .unrolled => .i32, |
| 1030 | 1030 | }, |
| 1031 | .Union => switch (ty.containerLayout(pt.zcu)) { | |
| 1031 | .Union => switch (ty.containerLayout(zcu)) { | |
| 1032 | 1032 | .@"packed" => blk: { |
| 1033 | const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(pt)))) catch @panic("out of memory"); | |
| 1033 | const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(zcu)))) catch @panic("out of memory"); | |
| 1034 | 1034 | break :blk typeToValtype(int_ty, pt, target); |
| 1035 | 1035 | }, |
| 1036 | 1036 | else => .i32, |
| ... | ... | @@ -1148,7 +1148,7 @@ fn genFunctype( |
| 1148 | 1148 | pt: Zcu.PerThread, |
| 1149 | 1149 | target: std.Target, |
| 1150 | 1150 | ) !wasm.Type { |
| 1151 | const mod = pt.zcu; | |
| 1151 | const zcu = pt.zcu; | |
| 1152 | 1152 | var temp_params = std.ArrayList(wasm.Valtype).init(gpa); |
| 1153 | 1153 | defer temp_params.deinit(); |
| 1154 | 1154 | var returns = std.ArrayList(wasm.Valtype).init(gpa); |
| ... | ... | @@ -1156,30 +1156,30 @@ fn genFunctype( |
| 1156 | 1156 | |
| 1157 | 1157 | if (firstParamSRet(cc, return_type, pt, target)) { |
| 1158 | 1158 | try temp_params.append(.i32); // memory address is always a 32-bit handle |
| 1159 | } else if (return_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1159 | } else if (return_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1160 | 1160 | if (cc == .C) { |
| 1161 | const res_classes = abi.classifyType(return_type, pt); | |
| 1161 | const res_classes = abi.classifyType(return_type, zcu); | |
| 1162 | 1162 | assert(res_classes[0] == .direct and res_classes[1] == .none); |
| 1163 | const scalar_type = abi.scalarType(return_type, pt); | |
| 1163 | const scalar_type = abi.scalarType(return_type, zcu); | |
| 1164 | 1164 | try returns.append(typeToValtype(scalar_type, pt, target)); |
| 1165 | 1165 | } else { |
| 1166 | 1166 | try returns.append(typeToValtype(return_type, pt, target)); |
| 1167 | 1167 | } |
| 1168 | } else if (return_type.isError(mod)) { | |
| 1168 | } else if (return_type.isError(zcu)) { | |
| 1169 | 1169 | try returns.append(.i32); |
| 1170 | 1170 | } |
| 1171 | 1171 | |
| 1172 | 1172 | // param types |
| 1173 | 1173 | for (params) |param_type_ip| { |
| 1174 | 1174 | const param_type = Type.fromInterned(param_type_ip); |
| 1175 | if (!param_type.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1175 | if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1176 | 1176 | |
| 1177 | 1177 | switch (cc) { |
| 1178 | 1178 | .C => { |
| 1179 | const param_classes = abi.classifyType(param_type, pt); | |
| 1179 | const param_classes = abi.classifyType(param_type, zcu); | |
| 1180 | 1180 | if (param_classes[1] == .none) { |
| 1181 | 1181 | if (param_classes[0] == .direct) { |
| 1182 | const scalar_type = abi.scalarType(param_type, pt); | |
| 1182 | const scalar_type = abi.scalarType(param_type, zcu); | |
| 1183 | 1183 | try temp_params.append(typeToValtype(scalar_type, pt, target)); |
| 1184 | 1184 | } else { |
| 1185 | 1185 | try temp_params.append(typeToValtype(param_type, pt, target)); |
| ... | ... | @@ -1242,10 +1242,10 @@ pub fn generate( |
| 1242 | 1242 | |
| 1243 | 1243 | fn genFunc(func: *CodeGen) InnerError!void { |
| 1244 | 1244 | const pt = func.pt; |
| 1245 | const mod = pt.zcu; | |
| 1246 | const ip = &mod.intern_pool; | |
| 1247 | const fn_ty = mod.navValue(func.owner_nav).typeOf(mod); | |
| 1248 | const fn_info = mod.typeToFunc(fn_ty).?; | |
| 1245 | const zcu = pt.zcu; | |
| 1246 | const ip = &zcu.intern_pool; | |
| 1247 | const fn_ty = zcu.navValue(func.owner_nav).typeOf(zcu); | |
| 1248 | const fn_info = zcu.typeToFunc(fn_ty).?; | |
| 1249 | 1249 | var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt, func.target.*); |
| 1250 | 1250 | defer func_type.deinit(func.gpa); |
| 1251 | 1251 | _ = try func.bin_file.storeNavType(func.owner_nav, func_type); |
| ... | ... | @@ -1273,7 +1273,7 @@ fn genFunc(func: *CodeGen) InnerError!void { |
| 1273 | 1273 | if (func_type.returns.len != 0 and func.air.instructions.len > 0) { |
| 1274 | 1274 | const inst: Air.Inst.Index = @enumFromInt(func.air.instructions.len - 1); |
| 1275 | 1275 | const last_inst_ty = func.typeOfIndex(inst); |
| 1276 | if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(pt) or last_inst_ty.isNoReturn(mod)) { | |
| 1276 | if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(zcu) or last_inst_ty.isNoReturn(zcu)) { | |
| 1277 | 1277 | try func.addTag(.@"unreachable"); |
| 1278 | 1278 | } |
| 1279 | 1279 | } |
| ... | ... | @@ -1356,9 +1356,9 @@ const CallWValues = struct { |
| 1356 | 1356 | |
| 1357 | 1357 | fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues { |
| 1358 | 1358 | const pt = func.pt; |
| 1359 | const mod = pt.zcu; | |
| 1360 | const ip = &mod.intern_pool; | |
| 1361 | const fn_info = mod.typeToFunc(fn_ty).?; | |
| 1359 | const zcu = pt.zcu; | |
| 1360 | const ip = &zcu.intern_pool; | |
| 1361 | const fn_info = zcu.typeToFunc(fn_ty).?; | |
| 1362 | 1362 | const cc = fn_info.cc; |
| 1363 | 1363 | var result: CallWValues = .{ |
| 1364 | 1364 | .args = &.{}, |
| ... | ... | @@ -1381,7 +1381,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1381 | 1381 | switch (cc) { |
| 1382 | 1382 | .Unspecified => { |
| 1383 | 1383 | for (fn_info.param_types.get(ip)) |ty| { |
| 1384 | if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1384 | if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1385 | 1385 | continue; |
| 1386 | 1386 | } |
| 1387 | 1387 | |
| ... | ... | @@ -1391,7 +1391,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1391 | 1391 | }, |
| 1392 | 1392 | .C => { |
| 1393 | 1393 | for (fn_info.param_types.get(ip)) |ty| { |
| 1394 | const ty_classes = abi.classifyType(Type.fromInterned(ty), pt); | |
| 1394 | const ty_classes = abi.classifyType(Type.fromInterned(ty), zcu); | |
| 1395 | 1395 | for (ty_classes) |class| { |
| 1396 | 1396 | if (class == .none) continue; |
| 1397 | 1397 | try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } }); |
| ... | ... | @@ -1409,7 +1409,7 @@ fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu. |
| 1409 | 1409 | switch (cc) { |
| 1410 | 1410 | .Unspecified, .Inline => return isByRef(return_type, pt, target), |
| 1411 | 1411 | .C => { |
| 1412 | const ty_classes = abi.classifyType(return_type, pt); | |
| 1412 | const ty_classes = abi.classifyType(return_type, pt.zcu); | |
| 1413 | 1413 | if (ty_classes[0] == .indirect) return true; |
| 1414 | 1414 | if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true; |
| 1415 | 1415 | return false; |
| ... | ... | @@ -1426,16 +1426,16 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: |
| 1426 | 1426 | } |
| 1427 | 1427 | |
| 1428 | 1428 | const pt = func.pt; |
| 1429 | const mod = pt.zcu; | |
| 1430 | const ty_classes = abi.classifyType(ty, pt); | |
| 1429 | const zcu = pt.zcu; | |
| 1430 | const ty_classes = abi.classifyType(ty, zcu); | |
| 1431 | 1431 | assert(ty_classes[0] != .none); |
| 1432 | switch (ty.zigTypeTag(mod)) { | |
| 1432 | switch (ty.zigTypeTag(zcu)) { | |
| 1433 | 1433 | .Struct, .Union => { |
| 1434 | 1434 | if (ty_classes[0] == .indirect) { |
| 1435 | 1435 | return func.lowerToStack(value); |
| 1436 | 1436 | } |
| 1437 | 1437 | assert(ty_classes[0] == .direct); |
| 1438 | const scalar_type = abi.scalarType(ty, pt); | |
| 1438 | const scalar_type = abi.scalarType(ty, zcu); | |
| 1439 | 1439 | switch (value) { |
| 1440 | 1440 | .memory, |
| 1441 | 1441 | .memory_offset, |
| ... | ... | @@ -1450,7 +1450,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: |
| 1450 | 1450 | return func.lowerToStack(value); |
| 1451 | 1451 | } |
| 1452 | 1452 | assert(ty_classes[0] == .direct and ty_classes[1] == .direct); |
| 1453 | assert(ty.abiSize(pt) == 16); | |
| 1453 | assert(ty.abiSize(zcu) == 16); | |
| 1454 | 1454 | // in this case we have an integer or float that must be lowered as 2 i64's. |
| 1455 | 1455 | try func.emitWValue(value); |
| 1456 | 1456 | try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 }); |
| ... | ... | @@ -1517,18 +1517,18 @@ fn restoreStackPointer(func: *CodeGen) !void { |
| 1517 | 1517 | /// |
| 1518 | 1518 | /// Asserts Type has codegenbits |
| 1519 | 1519 | fn allocStack(func: *CodeGen, ty: Type) !WValue { |
| 1520 | const pt = func.pt; | |
| 1521 | assert(ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 1520 | const zcu = func.pt.zcu; | |
| 1521 | assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 1522 | 1522 | if (func.initial_stack_value == .none) { |
| 1523 | 1523 | try func.initializeStack(); |
| 1524 | 1524 | } |
| 1525 | 1525 | |
| 1526 | const abi_size = std.math.cast(u32, ty.abiSize(pt)) orelse { | |
| 1526 | const abi_size = std.math.cast(u32, ty.abiSize(zcu)) orelse { | |
| 1527 | 1527 | return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ |
| 1528 | ty.fmt(pt), ty.abiSize(pt), | |
| 1528 | ty.fmt(func.pt), ty.abiSize(zcu), | |
| 1529 | 1529 | }); |
| 1530 | 1530 | }; |
| 1531 | const abi_align = ty.abiAlignment(pt); | |
| 1531 | const abi_align = ty.abiAlignment(zcu); | |
| 1532 | 1532 | |
| 1533 | 1533 | func.stack_alignment = func.stack_alignment.max(abi_align); |
| 1534 | 1534 | |
| ... | ... | @@ -1544,22 +1544,22 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue { |
| 1544 | 1544 | /// if it is set, to ensure the stack alignment will be set correctly. |
| 1545 | 1545 | fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue { |
| 1546 | 1546 | const pt = func.pt; |
| 1547 | const mod = pt.zcu; | |
| 1547 | const zcu = pt.zcu; | |
| 1548 | 1548 | const ptr_ty = func.typeOfIndex(inst); |
| 1549 | const pointee_ty = ptr_ty.childType(mod); | |
| 1549 | const pointee_ty = ptr_ty.childType(zcu); | |
| 1550 | 1550 | |
| 1551 | 1551 | if (func.initial_stack_value == .none) { |
| 1552 | 1552 | try func.initializeStack(); |
| 1553 | 1553 | } |
| 1554 | 1554 | |
| 1555 | if (!pointee_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1555 | if (!pointee_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1556 | 1556 | return func.allocStack(Type.usize); // create a value containing just the stack pointer. |
| 1557 | 1557 | } |
| 1558 | 1558 | |
| 1559 | const abi_alignment = ptr_ty.ptrAlignment(pt); | |
| 1560 | const abi_size = std.math.cast(u32, pointee_ty.abiSize(pt)) orelse { | |
| 1559 | const abi_alignment = ptr_ty.ptrAlignment(zcu); | |
| 1560 | const abi_size = std.math.cast(u32, pointee_ty.abiSize(zcu)) orelse { | |
| 1561 | 1561 | return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ |
| 1562 | pointee_ty.fmt(pt), pointee_ty.abiSize(pt), | |
| 1562 | pointee_ty.fmt(pt), pointee_ty.abiSize(zcu), | |
| 1563 | 1563 | }); |
| 1564 | 1564 | }; |
| 1565 | 1565 | func.stack_alignment = func.stack_alignment.max(abi_alignment); |
| ... | ... | @@ -1716,9 +1716,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch { |
| 1716 | 1716 | /// For a given `Type`, will return true when the type will be passed |
| 1717 | 1717 | /// by reference, rather than by value |
| 1718 | 1718 | fn isByRef(ty: Type, pt: Zcu.PerThread, target: std.Target) bool { |
| 1719 | const mod = pt.zcu; | |
| 1720 | const ip = &mod.intern_pool; | |
| 1721 | switch (ty.zigTypeTag(mod)) { | |
| 1719 | const zcu = pt.zcu; | |
| 1720 | const ip = &zcu.intern_pool; | |
| 1721 | switch (ty.zigTypeTag(zcu)) { | |
| 1722 | 1722 | .Type, |
| 1723 | 1723 | .ComptimeInt, |
| 1724 | 1724 | .ComptimeFloat, |
| ... | ... | @@ -1738,41 +1738,41 @@ fn isByRef(ty: Type, pt: Zcu.PerThread, target: std.Target) bool { |
| 1738 | 1738 | |
| 1739 | 1739 | .Array, |
| 1740 | 1740 | .Frame, |
| 1741 | => return ty.hasRuntimeBitsIgnoreComptime(pt), | |
| 1741 | => return ty.hasRuntimeBitsIgnoreComptime(zcu), | |
| 1742 | 1742 | .Union => { |
| 1743 | if (mod.typeToUnion(ty)) |union_obj| { | |
| 1743 | if (zcu.typeToUnion(ty)) |union_obj| { | |
| 1744 | 1744 | if (union_obj.flagsUnordered(ip).layout == .@"packed") { |
| 1745 | return ty.abiSize(pt) > 8; | |
| 1745 | return ty.abiSize(zcu) > 8; | |
| 1746 | 1746 | } |
| 1747 | 1747 | } |
| 1748 | return ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 1748 | return ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 1749 | 1749 | }, |
| 1750 | 1750 | .Struct => { |
| 1751 | if (mod.typeToPackedStruct(ty)) |packed_struct| { | |
| 1751 | if (zcu.typeToPackedStruct(ty)) |packed_struct| { | |
| 1752 | 1752 | return isByRef(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt, target); |
| 1753 | 1753 | } |
| 1754 | return ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 1754 | return ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 1755 | 1755 | }, |
| 1756 | .Vector => return determineSimdStoreStrategy(ty, pt, target) == .unrolled, | |
| 1757 | .Int => return ty.intInfo(mod).bits > 64, | |
| 1758 | .Enum => return ty.intInfo(mod).bits > 64, | |
| 1756 | .Vector => return determineSimdStoreStrategy(ty, zcu, target) == .unrolled, | |
| 1757 | .Int => return ty.intInfo(zcu).bits > 64, | |
| 1758 | .Enum => return ty.intInfo(zcu).bits > 64, | |
| 1759 | 1759 | .Float => return ty.floatBits(target) > 64, |
| 1760 | 1760 | .ErrorUnion => { |
| 1761 | const pl_ty = ty.errorUnionPayload(mod); | |
| 1762 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1761 | const pl_ty = ty.errorUnionPayload(zcu); | |
| 1762 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1763 | 1763 | return false; |
| 1764 | 1764 | } |
| 1765 | 1765 | return true; |
| 1766 | 1766 | }, |
| 1767 | 1767 | .Optional => { |
| 1768 | if (ty.isPtrLikeOptional(mod)) return false; | |
| 1769 | const pl_type = ty.optionalChild(mod); | |
| 1770 | if (pl_type.zigTypeTag(mod) == .ErrorSet) return false; | |
| 1771 | return pl_type.hasRuntimeBitsIgnoreComptime(pt); | |
| 1768 | if (ty.isPtrLikeOptional(zcu)) return false; | |
| 1769 | const pl_type = ty.optionalChild(zcu); | |
| 1770 | if (pl_type.zigTypeTag(zcu) == .ErrorSet) return false; | |
| 1771 | return pl_type.hasRuntimeBitsIgnoreComptime(zcu); | |
| 1772 | 1772 | }, |
| 1773 | 1773 | .Pointer => { |
| 1774 | 1774 | // Slices act like struct and will be passed by reference |
| 1775 | if (ty.isSlice(mod)) return true; | |
| 1775 | if (ty.isSlice(zcu)) return true; | |
| 1776 | 1776 | return false; |
| 1777 | 1777 | }, |
| 1778 | 1778 | } |
| ... | ... | @@ -1787,9 +1787,9 @@ const SimdStoreStrategy = enum { |
| 1787 | 1787 | /// This means when a given type is 128 bits and either the simd128 or relaxed-simd |
| 1788 | 1788 | /// features are enabled, the function will return `.direct`. This would allow to store |
| 1789 | 1789 | /// it using a instruction, rather than an unrolled version. |
| 1790 | fn determineSimdStoreStrategy(ty: Type, pt: Zcu.PerThread, target: std.Target) SimdStoreStrategy { | |
| 1791 | std.debug.assert(ty.zigTypeTag(pt.zcu) == .Vector); | |
| 1792 | if (ty.bitSize(pt) != 128) return .unrolled; | |
| 1790 | fn determineSimdStoreStrategy(ty: Type, zcu: *Zcu, target: std.Target) SimdStoreStrategy { | |
| 1791 | std.debug.assert(ty.zigTypeTag(zcu) == .Vector); | |
| 1792 | if (ty.bitSize(zcu) != 128) return .unrolled; | |
| 1793 | 1793 | const hasFeature = std.Target.wasm.featureSetHas; |
| 1794 | 1794 | const features = target.cpu.features; |
| 1795 | 1795 | if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) { |
| ... | ... | @@ -2069,8 +2069,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2069 | 2069 | |
| 2070 | 2070 | fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2071 | 2071 | const pt = func.pt; |
| 2072 | const mod = pt.zcu; | |
| 2073 | const ip = &mod.intern_pool; | |
| 2072 | const zcu = pt.zcu; | |
| 2073 | const ip = &zcu.intern_pool; | |
| 2074 | 2074 | |
| 2075 | 2075 | for (body) |inst| { |
| 2076 | 2076 | if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip)) { |
| ... | ... | @@ -2091,37 +2091,37 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2091 | 2091 | |
| 2092 | 2092 | fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2093 | 2093 | const pt = func.pt; |
| 2094 | const mod = pt.zcu; | |
| 2094 | const zcu = pt.zcu; | |
| 2095 | 2095 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2096 | 2096 | const operand = try func.resolveInst(un_op); |
| 2097 | const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?; | |
| 2097 | const fn_info = zcu.typeToFunc(zcu.navValue(func.owner_nav).typeOf(zcu)).?; | |
| 2098 | 2098 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 2099 | 2099 | |
| 2100 | 2100 | // result must be stored in the stack and we return a pointer |
| 2101 | 2101 | // to the stack instead |
| 2102 | 2102 | if (func.return_value != .none) { |
| 2103 | 2103 | try func.store(func.return_value, operand, ret_ty, 0); |
| 2104 | } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2105 | switch (ret_ty.zigTypeTag(mod)) { | |
| 2104 | } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2105 | switch (ret_ty.zigTypeTag(zcu)) { | |
| 2106 | 2106 | // Aggregate types can be lowered as a singular value |
| 2107 | 2107 | .Struct, .Union => { |
| 2108 | const scalar_type = abi.scalarType(ret_ty, pt); | |
| 2108 | const scalar_type = abi.scalarType(ret_ty, zcu); | |
| 2109 | 2109 | try func.emitWValue(operand); |
| 2110 | 2110 | const opcode = buildOpcode(.{ |
| 2111 | 2111 | .op = .load, |
| 2112 | .width = @as(u8, @intCast(scalar_type.abiSize(pt) * 8)), | |
| 2113 | .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned, | |
| 2112 | .width = @as(u8, @intCast(scalar_type.abiSize(zcu) * 8)), | |
| 2113 | .signedness = if (scalar_type.isSignedInt(zcu)) .signed else .unsigned, | |
| 2114 | 2114 | .valtype1 = typeToValtype(scalar_type, pt, func.target.*), |
| 2115 | 2115 | }); |
| 2116 | 2116 | try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{ |
| 2117 | 2117 | .offset = operand.offset(), |
| 2118 | .alignment = @intCast(scalar_type.abiAlignment(pt).toByteUnits().?), | |
| 2118 | .alignment = @intCast(scalar_type.abiAlignment(zcu).toByteUnits().?), | |
| 2119 | 2119 | }); |
| 2120 | 2120 | }, |
| 2121 | 2121 | else => try func.emitWValue(operand), |
| 2122 | 2122 | } |
| 2123 | 2123 | } else { |
| 2124 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and ret_ty.isError(mod)) { | |
| 2124 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and ret_ty.isError(zcu)) { | |
| 2125 | 2125 | try func.addImm32(0); |
| 2126 | 2126 | } else { |
| 2127 | 2127 | try func.emitWValue(operand); |
| ... | ... | @@ -2135,15 +2135,15 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2135 | 2135 | |
| 2136 | 2136 | fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2137 | 2137 | const pt = func.pt; |
| 2138 | const mod = pt.zcu; | |
| 2139 | const child_type = func.typeOfIndex(inst).childType(mod); | |
| 2138 | const zcu = pt.zcu; | |
| 2139 | const child_type = func.typeOfIndex(inst).childType(zcu); | |
| 2140 | 2140 | |
| 2141 | 2141 | const result = result: { |
| 2142 | if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 2142 | if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2143 | 2143 | break :result try func.allocStack(Type.usize); // create pointer to void |
| 2144 | 2144 | } |
| 2145 | 2145 | |
| 2146 | const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?; | |
| 2146 | const fn_info = zcu.typeToFunc(zcu.navValue(func.owner_nav).typeOf(zcu)).?; | |
| 2147 | 2147 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*)) { |
| 2148 | 2148 | break :result func.return_value; |
| 2149 | 2149 | } |
| ... | ... | @@ -2156,14 +2156,14 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2156 | 2156 | |
| 2157 | 2157 | fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2158 | 2158 | const pt = func.pt; |
| 2159 | const mod = pt.zcu; | |
| 2159 | const zcu = pt.zcu; | |
| 2160 | 2160 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2161 | 2161 | const operand = try func.resolveInst(un_op); |
| 2162 | const ret_ty = func.typeOf(un_op).childType(mod); | |
| 2162 | const ret_ty = func.typeOf(un_op).childType(zcu); | |
| 2163 | 2163 | |
| 2164 | const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?; | |
| 2165 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2166 | if (ret_ty.isError(mod)) { | |
| 2164 | const fn_info = zcu.typeToFunc(zcu.navValue(func.owner_nav).typeOf(zcu)).?; | |
| 2165 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2166 | if (ret_ty.isError(zcu)) { | |
| 2167 | 2167 | try func.addImm32(0); |
| 2168 | 2168 | } |
| 2169 | 2169 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*)) { |
| ... | ... | @@ -2184,15 +2184,15 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2184 | 2184 | const ty = func.typeOf(pl_op.operand); |
| 2185 | 2185 | |
| 2186 | 2186 | const pt = func.pt; |
| 2187 | const mod = pt.zcu; | |
| 2188 | const ip = &mod.intern_pool; | |
| 2189 | const fn_ty = switch (ty.zigTypeTag(mod)) { | |
| 2187 | const zcu = pt.zcu; | |
| 2188 | const ip = &zcu.intern_pool; | |
| 2189 | const fn_ty = switch (ty.zigTypeTag(zcu)) { | |
| 2190 | 2190 | .Fn => ty, |
| 2191 | .Pointer => ty.childType(mod), | |
| 2191 | .Pointer => ty.childType(zcu), | |
| 2192 | 2192 | else => unreachable, |
| 2193 | 2193 | }; |
| 2194 | const ret_ty = fn_ty.fnReturnType(mod); | |
| 2195 | const fn_info = mod.typeToFunc(fn_ty).?; | |
| 2194 | const ret_ty = fn_ty.fnReturnType(zcu); | |
| 2195 | const fn_info = zcu.typeToFunc(fn_ty).?; | |
| 2196 | 2196 | const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*); |
| 2197 | 2197 | |
| 2198 | 2198 | const callee: ?InternPool.Nav.Index = blk: { |
| ... | ... | @@ -2205,7 +2205,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2205 | 2205 | }, |
| 2206 | 2206 | .@"extern" => |@"extern"| { |
| 2207 | 2207 | const ext_nav = ip.getNav(@"extern".owner_nav); |
| 2208 | const ext_info = mod.typeToFunc(Type.fromInterned(@"extern".ty)).?; | |
| 2208 | const ext_info = zcu.typeToFunc(Type.fromInterned(@"extern".ty)).?; | |
| 2209 | 2209 | var func_type = try genFunctype( |
| 2210 | 2210 | func.gpa, |
| 2211 | 2211 | ext_info.cc, |
| ... | ... | @@ -2248,9 +2248,9 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2248 | 2248 | const arg_val = try func.resolveInst(arg); |
| 2249 | 2249 | |
| 2250 | 2250 | const arg_ty = func.typeOf(arg); |
| 2251 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 2251 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 2252 | 2252 | |
| 2253 | try func.lowerArg(mod.typeToFunc(fn_ty).?.cc, arg_ty, arg_val); | |
| 2253 | try func.lowerArg(zcu.typeToFunc(fn_ty).?.cc, arg_ty, arg_val); | |
| 2254 | 2254 | } |
| 2255 | 2255 | |
| 2256 | 2256 | if (callee) |direct| { |
| ... | ... | @@ -2259,7 +2259,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2259 | 2259 | } else { |
| 2260 | 2260 | // in this case we call a function pointer |
| 2261 | 2261 | // so load its value onto the stack |
| 2262 | std.debug.assert(ty.zigTypeTag(mod) == .Pointer); | |
| 2262 | std.debug.assert(ty.zigTypeTag(zcu) == .Pointer); | |
| 2263 | 2263 | const operand = try func.resolveInst(pl_op.operand); |
| 2264 | 2264 | try func.emitWValue(operand); |
| 2265 | 2265 | |
| ... | ... | @@ -2271,18 +2271,18 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2271 | 2271 | } |
| 2272 | 2272 | |
| 2273 | 2273 | const result_value = result_value: { |
| 2274 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) { | |
| 2274 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { | |
| 2275 | 2275 | break :result_value .none; |
| 2276 | } else if (ret_ty.isNoReturn(mod)) { | |
| 2276 | } else if (ret_ty.isNoReturn(zcu)) { | |
| 2277 | 2277 | try func.addTag(.@"unreachable"); |
| 2278 | 2278 | break :result_value .none; |
| 2279 | 2279 | } else if (first_param_sret) { |
| 2280 | 2280 | break :result_value sret; |
| 2281 | 2281 | // TODO: Make this less fragile and optimize |
| 2282 | } else if (mod.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(mod) == .Struct or ret_ty.zigTypeTag(mod) == .Union) { | |
| 2282 | } else if (zcu.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(zcu) == .Struct or ret_ty.zigTypeTag(zcu) == .Union) { | |
| 2283 | 2283 | const result_local = try func.allocLocal(ret_ty); |
| 2284 | 2284 | try func.addLabel(.local_set, result_local.local.value); |
| 2285 | const scalar_type = abi.scalarType(ret_ty, pt); | |
| 2285 | const scalar_type = abi.scalarType(ret_ty, zcu); | |
| 2286 | 2286 | const result = try func.allocStack(scalar_type); |
| 2287 | 2287 | try func.store(result, result_local, scalar_type, 0); |
| 2288 | 2288 | break :result_value result; |
| ... | ... | @@ -2306,7 +2306,7 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2306 | 2306 | |
| 2307 | 2307 | fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 2308 | 2308 | const pt = func.pt; |
| 2309 | const mod = pt.zcu; | |
| 2309 | const zcu = pt.zcu; | |
| 2310 | 2310 | if (safety) { |
| 2311 | 2311 | // TODO if the value is undef, write 0xaa bytes to dest |
| 2312 | 2312 | } else { |
| ... | ... | @@ -2317,8 +2317,8 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2317 | 2317 | const lhs = try func.resolveInst(bin_op.lhs); |
| 2318 | 2318 | const rhs = try func.resolveInst(bin_op.rhs); |
| 2319 | 2319 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 2320 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 2321 | const ty = ptr_ty.childType(mod); | |
| 2320 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 2321 | const ty = ptr_ty.childType(zcu); | |
| 2322 | 2322 | |
| 2323 | 2323 | if (ptr_info.packed_offset.host_size == 0) { |
| 2324 | 2324 | try func.store(lhs, rhs, ty, 0); |
| ... | ... | @@ -2331,7 +2331,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2331 | 2331 | return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{}); |
| 2332 | 2332 | } |
| 2333 | 2333 | |
| 2334 | var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(pt)))) - 1)); | |
| 2334 | var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(zcu)))) - 1)); | |
| 2335 | 2335 | mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset)); |
| 2336 | 2336 | mask ^= ~@as(u64, 0); |
| 2337 | 2337 | const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4) |
| ... | ... | @@ -2343,9 +2343,9 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2343 | 2343 | else |
| 2344 | 2344 | .{ .imm64 = mask }; |
| 2345 | 2345 | const wrap_mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4) |
| 2346 | .{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) } | |
| 2346 | .{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(zcu))) } | |
| 2347 | 2347 | else |
| 2348 | .{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) }; | |
| 2348 | .{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(zcu)) }; | |
| 2349 | 2349 | |
| 2350 | 2350 | try func.emitWValue(lhs); |
| 2351 | 2351 | const loaded = try func.load(lhs, int_elem_ty, 0); |
| ... | ... | @@ -2366,12 +2366,12 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2366 | 2366 | fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void { |
| 2367 | 2367 | assert(!(lhs != .stack and rhs == .stack)); |
| 2368 | 2368 | const pt = func.pt; |
| 2369 | const mod = pt.zcu; | |
| 2370 | const abi_size = ty.abiSize(pt); | |
| 2371 | switch (ty.zigTypeTag(mod)) { | |
| 2369 | const zcu = pt.zcu; | |
| 2370 | const abi_size = ty.abiSize(zcu); | |
| 2371 | switch (ty.zigTypeTag(zcu)) { | |
| 2372 | 2372 | .ErrorUnion => { |
| 2373 | const pl_ty = ty.errorUnionPayload(mod); | |
| 2374 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2373 | const pl_ty = ty.errorUnionPayload(zcu); | |
| 2374 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2375 | 2375 | return func.store(lhs, rhs, Type.anyerror, 0); |
| 2376 | 2376 | } |
| 2377 | 2377 | |
| ... | ... | @@ -2379,14 +2379,14 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2379 | 2379 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); |
| 2380 | 2380 | }, |
| 2381 | 2381 | .Optional => { |
| 2382 | if (ty.isPtrLikeOptional(mod)) { | |
| 2382 | if (ty.isPtrLikeOptional(zcu)) { | |
| 2383 | 2383 | return func.store(lhs, rhs, Type.usize, 0); |
| 2384 | 2384 | } |
| 2385 | const pl_ty = ty.optionalChild(mod); | |
| 2386 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2385 | const pl_ty = ty.optionalChild(zcu); | |
| 2386 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2387 | 2387 | return func.store(lhs, rhs, Type.u8, 0); |
| 2388 | 2388 | } |
| 2389 | if (pl_ty.zigTypeTag(mod) == .ErrorSet) { | |
| 2389 | if (pl_ty.zigTypeTag(zcu) == .ErrorSet) { | |
| 2390 | 2390 | return func.store(lhs, rhs, Type.anyerror, 0); |
| 2391 | 2391 | } |
| 2392 | 2392 | |
| ... | ... | @@ -2397,7 +2397,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2397 | 2397 | const len = @as(u32, @intCast(abi_size)); |
| 2398 | 2398 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); |
| 2399 | 2399 | }, |
| 2400 | .Vector => switch (determineSimdStoreStrategy(ty, pt, func.target.*)) { | |
| 2400 | .Vector => switch (determineSimdStoreStrategy(ty, zcu, func.target.*)) { | |
| 2401 | 2401 | .unrolled => { |
| 2402 | 2402 | const len: u32 = @intCast(abi_size); |
| 2403 | 2403 | return func.memcpy(lhs, rhs, .{ .imm32 = len }); |
| ... | ... | @@ -2411,13 +2411,13 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2411 | 2411 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ |
| 2412 | 2412 | std.wasm.simdOpcode(.v128_store), |
| 2413 | 2413 | offset + lhs.offset(), |
| 2414 | @intCast(ty.abiAlignment(pt).toByteUnits() orelse 0), | |
| 2414 | @intCast(ty.abiAlignment(zcu).toByteUnits() orelse 0), | |
| 2415 | 2415 | }); |
| 2416 | 2416 | return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 2417 | 2417 | }, |
| 2418 | 2418 | }, |
| 2419 | 2419 | .Pointer => { |
| 2420 | if (ty.isSlice(mod)) { | |
| 2420 | if (ty.isSlice(zcu)) { | |
| 2421 | 2421 | // store pointer first |
| 2422 | 2422 | // lower it to the stack so we do not have to store rhs into a local first |
| 2423 | 2423 | try func.emitWValue(lhs); |
| ... | ... | @@ -2441,7 +2441,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2441 | 2441 | try func.store(.stack, msb, Type.u64, 8 + lhs.offset()); |
| 2442 | 2442 | return; |
| 2443 | 2443 | } else if (abi_size > 16) { |
| 2444 | try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(pt))) }); | |
| 2444 | try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(zcu))) }); | |
| 2445 | 2445 | }, |
| 2446 | 2446 | else => if (abi_size > 8) { |
| 2447 | 2447 | return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{ |
| ... | ... | @@ -2467,21 +2467,21 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2467 | 2467 | Mir.Inst.Tag.fromOpcode(opcode), |
| 2468 | 2468 | .{ |
| 2469 | 2469 | .offset = offset + lhs.offset(), |
| 2470 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 2470 | .alignment = @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 2471 | 2471 | }, |
| 2472 | 2472 | ); |
| 2473 | 2473 | } |
| 2474 | 2474 | |
| 2475 | 2475 | fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2476 | 2476 | const pt = func.pt; |
| 2477 | const mod = pt.zcu; | |
| 2477 | const zcu = pt.zcu; | |
| 2478 | 2478 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2479 | 2479 | const operand = try func.resolveInst(ty_op.operand); |
| 2480 | 2480 | const ty = ty_op.ty.toType(); |
| 2481 | 2481 | const ptr_ty = func.typeOf(ty_op.operand); |
| 2482 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 2482 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 2483 | 2483 | |
| 2484 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{ty_op.operand}); | |
| 2484 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return func.finishAir(inst, .none, &.{ty_op.operand}); | |
| 2485 | 2485 | |
| 2486 | 2486 | const result = result: { |
| 2487 | 2487 | if (isByRef(ty, pt, func.target.*)) { |
| ... | ... | @@ -2515,36 +2515,36 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2515 | 2515 | /// NOTE: Leaves the value on the stack. |
| 2516 | 2516 | fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue { |
| 2517 | 2517 | const pt = func.pt; |
| 2518 | const mod = pt.zcu; | |
| 2518 | const zcu = pt.zcu; | |
| 2519 | 2519 | // load local's value from memory by its stack position |
| 2520 | 2520 | try func.emitWValue(operand); |
| 2521 | 2521 | |
| 2522 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2522 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2523 | 2523 | // TODO: Add helper functions for simd opcodes |
| 2524 | 2524 | const extra_index = @as(u32, @intCast(func.mir_extra.items.len)); |
| 2525 | 2525 | // stores as := opcode, offset, alignment (opcode::memarg) |
| 2526 | 2526 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ |
| 2527 | 2527 | std.wasm.simdOpcode(.v128_load), |
| 2528 | 2528 | offset + operand.offset(), |
| 2529 | @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 2529 | @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 2530 | 2530 | }); |
| 2531 | 2531 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 2532 | 2532 | return .stack; |
| 2533 | 2533 | } |
| 2534 | 2534 | |
| 2535 | const abi_size: u8 = @intCast(ty.abiSize(pt)); | |
| 2535 | const abi_size: u8 = @intCast(ty.abiSize(zcu)); | |
| 2536 | 2536 | const opcode = buildOpcode(.{ |
| 2537 | 2537 | .valtype1 = typeToValtype(ty, pt, func.target.*), |
| 2538 | 2538 | .width = abi_size * 8, |
| 2539 | 2539 | .op = .load, |
| 2540 | .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned, | |
| 2540 | .signedness = if (ty.isSignedInt(zcu)) .signed else .unsigned, | |
| 2541 | 2541 | }); |
| 2542 | 2542 | |
| 2543 | 2543 | try func.addMemArg( |
| 2544 | 2544 | Mir.Inst.Tag.fromOpcode(opcode), |
| 2545 | 2545 | .{ |
| 2546 | 2546 | .offset = offset + operand.offset(), |
| 2547 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 2547 | .alignment = @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 2548 | 2548 | }, |
| 2549 | 2549 | ); |
| 2550 | 2550 | |
| ... | ... | @@ -2553,13 +2553,13 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu |
| 2553 | 2553 | |
| 2554 | 2554 | fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2555 | 2555 | const pt = func.pt; |
| 2556 | const mod = pt.zcu; | |
| 2556 | const zcu = pt.zcu; | |
| 2557 | 2557 | const arg_index = func.arg_index; |
| 2558 | 2558 | const arg = func.args[arg_index]; |
| 2559 | const cc = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?.cc; | |
| 2559 | const cc = zcu.typeToFunc(zcu.navValue(func.owner_nav).typeOf(zcu)).?.cc; | |
| 2560 | 2560 | const arg_ty = func.typeOfIndex(inst); |
| 2561 | 2561 | if (cc == .C) { |
| 2562 | const arg_classes = abi.classifyType(arg_ty, pt); | |
| 2562 | const arg_classes = abi.classifyType(arg_ty, zcu); | |
| 2563 | 2563 | for (arg_classes) |class| { |
| 2564 | 2564 | if (class != .none) { |
| 2565 | 2565 | func.arg_index += 1; |
| ... | ... | @@ -2569,7 +2569,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2569 | 2569 | // When we have an argument that's passed using more than a single parameter, |
| 2570 | 2570 | // we combine them into a single stack value |
| 2571 | 2571 | if (arg_classes[0] == .direct and arg_classes[1] == .direct) { |
| 2572 | if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) { | |
| 2572 | if (arg_ty.zigTypeTag(zcu) != .Int and arg_ty.zigTypeTag(zcu) != .Float) { | |
| 2573 | 2573 | return func.fail( |
| 2574 | 2574 | "TODO: Implement C-ABI argument for type '{}'", |
| 2575 | 2575 | .{arg_ty.fmt(pt)}, |
| ... | ... | @@ -2602,6 +2602,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2602 | 2602 | |
| 2603 | 2603 | fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2604 | 2604 | const pt = func.pt; |
| 2605 | const zcu = pt.zcu; | |
| 2605 | 2606 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2606 | 2607 | const lhs = try func.resolveInst(bin_op.lhs); |
| 2607 | 2608 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | ... | @@ -2615,10 +2616,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2615 | 2616 | // For big integers we can ignore this as we will call into compiler-rt which handles this. |
| 2616 | 2617 | const result = switch (op) { |
| 2617 | 2618 | .shr, .shl => result: { |
| 2618 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse { | |
| 2619 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(zcu))) orelse { | |
| 2619 | 2620 | return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); |
| 2620 | 2621 | }; |
| 2621 | const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?; | |
| 2622 | const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(zcu))).?; | |
| 2622 | 2623 | const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) |
| 2623 | 2624 | try (try func.intcast(rhs, rhs_ty, lhs_ty)).toLocal(func, lhs_ty) |
| 2624 | 2625 | else |
| ... | ... | @@ -2635,7 +2636,7 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2635 | 2636 | /// NOTE: THis leaves the value on top of the stack. |
| 2636 | 2637 | fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { |
| 2637 | 2638 | const pt = func.pt; |
| 2638 | const mod = pt.zcu; | |
| 2639 | const zcu = pt.zcu; | |
| 2639 | 2640 | assert(!(lhs != .stack and rhs == .stack)); |
| 2640 | 2641 | |
| 2641 | 2642 | if (ty.isAnyFloat()) { |
| ... | ... | @@ -2644,7 +2645,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2644 | 2645 | } |
| 2645 | 2646 | |
| 2646 | 2647 | if (isByRef(ty, pt, func.target.*)) { |
| 2647 | if (ty.zigTypeTag(mod) == .Int) { | |
| 2648 | if (ty.zigTypeTag(zcu) == .Int) { | |
| 2648 | 2649 | return func.binOpBigInt(lhs, rhs, ty, op); |
| 2649 | 2650 | } else { |
| 2650 | 2651 | return func.fail( |
| ... | ... | @@ -2657,7 +2658,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2657 | 2658 | const opcode: wasm.Opcode = buildOpcode(.{ |
| 2658 | 2659 | .op = op, |
| 2659 | 2660 | .valtype1 = typeToValtype(ty, pt, func.target.*), |
| 2660 | .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned, | |
| 2661 | .signedness = if (ty.isSignedInt(zcu)) .signed else .unsigned, | |
| 2661 | 2662 | }); |
| 2662 | 2663 | try func.emitWValue(lhs); |
| 2663 | 2664 | try func.emitWValue(rhs); |
| ... | ... | @@ -2669,8 +2670,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2669 | 2670 | |
| 2670 | 2671 | fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { |
| 2671 | 2672 | const pt = func.pt; |
| 2672 | const mod = pt.zcu; | |
| 2673 | const int_info = ty.intInfo(mod); | |
| 2673 | const zcu = pt.zcu; | |
| 2674 | const int_info = ty.intInfo(zcu); | |
| 2674 | 2675 | if (int_info.bits > 128) { |
| 2675 | 2676 | return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{}); |
| 2676 | 2677 | } |
| ... | ... | @@ -2812,17 +2813,17 @@ const FloatOp = enum { |
| 2812 | 2813 | |
| 2813 | 2814 | fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2814 | 2815 | const pt = func.pt; |
| 2815 | const mod = pt.zcu; | |
| 2816 | const zcu = pt.zcu; | |
| 2816 | 2817 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2817 | 2818 | const operand = try func.resolveInst(ty_op.operand); |
| 2818 | 2819 | const ty = func.typeOf(ty_op.operand); |
| 2819 | const scalar_ty = ty.scalarType(mod); | |
| 2820 | const scalar_ty = ty.scalarType(zcu); | |
| 2820 | 2821 | |
| 2821 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 2822 | .Int => if (ty.zigTypeTag(mod) == .Vector) { | |
| 2822 | switch (scalar_ty.zigTypeTag(zcu)) { | |
| 2823 | .Int => if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2823 | 2824 | return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)}); |
| 2824 | 2825 | } else { |
| 2825 | const int_bits = ty.intInfo(mod).bits; | |
| 2826 | const int_bits = ty.intInfo(zcu).bits; | |
| 2826 | 2827 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 2827 | 2828 | return func.fail("TODO: airAbs for signed integers larger than '{d}' bits", .{int_bits}); |
| 2828 | 2829 | }; |
| ... | ... | @@ -2903,8 +2904,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError |
| 2903 | 2904 | |
| 2904 | 2905 | fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue { |
| 2905 | 2906 | const pt = func.pt; |
| 2906 | const mod = pt.zcu; | |
| 2907 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 2907 | const zcu = pt.zcu; | |
| 2908 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 2908 | 2909 | return func.fail("TODO: Implement floatOps for vectors", .{}); |
| 2909 | 2910 | } |
| 2910 | 2911 | |
| ... | ... | @@ -3010,7 +3011,7 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue { |
| 3010 | 3011 | |
| 3011 | 3012 | fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 3012 | 3013 | const pt = func.pt; |
| 3013 | const mod = pt.zcu; | |
| 3014 | const zcu = pt.zcu; | |
| 3014 | 3015 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3015 | 3016 | |
| 3016 | 3017 | const lhs = try func.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3018,7 +3019,7 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 3018 | 3019 | const lhs_ty = func.typeOf(bin_op.lhs); |
| 3019 | 3020 | const rhs_ty = func.typeOf(bin_op.rhs); |
| 3020 | 3021 | |
| 3021 | if (lhs_ty.zigTypeTag(mod) == .Vector or rhs_ty.zigTypeTag(mod) == .Vector) { | |
| 3022 | if (lhs_ty.zigTypeTag(zcu) == .Vector or rhs_ty.zigTypeTag(zcu) == .Vector) { | |
| 3022 | 3023 | return func.fail("TODO: Implement wrapping arithmetic for vectors", .{}); |
| 3023 | 3024 | } |
| 3024 | 3025 | |
| ... | ... | @@ -3029,10 +3030,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 3029 | 3030 | // For big integers we can ignore this as we will call into compiler-rt which handles this. |
| 3030 | 3031 | const result = switch (op) { |
| 3031 | 3032 | .shr, .shl => result: { |
| 3032 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse { | |
| 3033 | const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(zcu))) orelse { | |
| 3033 | 3034 | return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)}); |
| 3034 | 3035 | }; |
| 3035 | const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?; | |
| 3036 | const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(zcu))).?; | |
| 3036 | 3037 | const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) |
| 3037 | 3038 | try (try func.intcast(rhs, rhs_ty, lhs_ty)).toLocal(func, lhs_ty) |
| 3038 | 3039 | else |
| ... | ... | @@ -3058,9 +3059,9 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr |
| 3058 | 3059 | /// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack, if wrapping was needed. |
| 3059 | 3060 | fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3060 | 3061 | const pt = func.pt; |
| 3061 | const mod = pt.zcu; | |
| 3062 | assert(ty.abiSize(pt) <= 16); | |
| 3063 | const int_bits: u16 = @intCast(ty.bitSize(pt)); // TODO use ty.intInfo(mod).bits | |
| 3062 | const zcu = pt.zcu; | |
| 3063 | assert(ty.abiSize(zcu) <= 16); | |
| 3064 | const int_bits: u16 = @intCast(ty.bitSize(zcu)); // TODO use ty.intInfo(zcu).bits | |
| 3064 | 3065 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 3065 | 3066 | return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{int_bits}); |
| 3066 | 3067 | }; |
| ... | ... | @@ -3070,7 +3071,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3070 | 3071 | switch (wasm_bits) { |
| 3071 | 3072 | 32 => { |
| 3072 | 3073 | try func.emitWValue(operand); |
| 3073 | if (ty.isSignedInt(mod)) { | |
| 3074 | if (ty.isSignedInt(zcu)) { | |
| 3074 | 3075 | try func.addImm32(32 - int_bits); |
| 3075 | 3076 | try func.addTag(.i32_shl); |
| 3076 | 3077 | try func.addImm32(32 - int_bits); |
| ... | ... | @@ -3083,7 +3084,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3083 | 3084 | }, |
| 3084 | 3085 | 64 => { |
| 3085 | 3086 | try func.emitWValue(operand); |
| 3086 | if (ty.isSignedInt(mod)) { | |
| 3087 | if (ty.isSignedInt(zcu)) { | |
| 3087 | 3088 | try func.addImm64(64 - int_bits); |
| 3088 | 3089 | try func.addTag(.i64_shl); |
| 3089 | 3090 | try func.addImm64(64 - int_bits); |
| ... | ... | @@ -3104,7 +3105,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3104 | 3105 | |
| 3105 | 3106 | try func.emitWValue(result); |
| 3106 | 3107 | _ = try func.load(operand, Type.u64, 8); |
| 3107 | if (ty.isSignedInt(mod)) { | |
| 3108 | if (ty.isSignedInt(zcu)) { | |
| 3108 | 3109 | try func.addImm64(128 - int_bits); |
| 3109 | 3110 | try func.addTag(.i64_shl); |
| 3110 | 3111 | try func.addImm64(128 - int_bits); |
| ... | ... | @@ -3145,13 +3146,13 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr |
| 3145 | 3146 | }; |
| 3146 | 3147 | }, |
| 3147 | 3148 | .Struct => switch (base_ty.containerLayout(zcu)) { |
| 3148 | .auto => base_ty.structFieldOffset(@intCast(field.index), pt), | |
| 3149 | .auto => base_ty.structFieldOffset(@intCast(field.index), zcu), | |
| 3149 | 3150 | .@"extern", .@"packed" => unreachable, |
| 3150 | 3151 | }, |
| 3151 | 3152 | .Union => switch (base_ty.containerLayout(zcu)) { |
| 3152 | 3153 | .auto => off: { |
| 3153 | 3154 | // Keep in sync with the `un` case of `generateSymbol`. |
| 3154 | const layout = base_ty.unionGetLayout(pt); | |
| 3155 | const layout = base_ty.unionGetLayout(zcu); | |
| 3155 | 3156 | if (layout.payload_size == 0) break :off 0; |
| 3156 | 3157 | if (layout.tag_size == 0) break :off 0; |
| 3157 | 3158 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| ... | ... | @@ -3178,15 +3179,15 @@ fn lowerUavRef( |
| 3178 | 3179 | offset: u32, |
| 3179 | 3180 | ) InnerError!WValue { |
| 3180 | 3181 | const pt = func.pt; |
| 3181 | const mod = pt.zcu; | |
| 3182 | const ty = Type.fromInterned(mod.intern_pool.typeOf(uav.val)); | |
| 3182 | const zcu = pt.zcu; | |
| 3183 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(uav.val)); | |
| 3183 | 3184 | |
| 3184 | const is_fn_body = ty.zigTypeTag(mod) == .Fn; | |
| 3185 | if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3185 | const is_fn_body = ty.zigTypeTag(zcu) == .Fn; | |
| 3186 | if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3186 | 3187 | return .{ .imm32 = 0xaaaaaaaa }; |
| 3187 | 3188 | } |
| 3188 | 3189 | |
| 3189 | const decl_align = mod.intern_pool.indexToKey(uav.orig_ty).ptr_type.flags.alignment; | |
| 3190 | const decl_align = zcu.intern_pool.indexToKey(uav.orig_ty).ptr_type.flags.alignment; | |
| 3190 | 3191 | const res = try func.bin_file.lowerUav(pt, uav.val, decl_align, func.src_loc); |
| 3191 | 3192 | const target_sym_index = switch (res) { |
| 3192 | 3193 | .mcv => |mcv| mcv.load_symbol, |
| ... | ... | @@ -3204,19 +3205,19 @@ fn lowerUavRef( |
| 3204 | 3205 | |
| 3205 | 3206 | fn lowerNavRef(func: *CodeGen, nav_index: InternPool.Nav.Index, offset: u32) InnerError!WValue { |
| 3206 | 3207 | const pt = func.pt; |
| 3207 | const mod = pt.zcu; | |
| 3208 | const ip = &mod.intern_pool; | |
| 3208 | const zcu = pt.zcu; | |
| 3209 | const ip = &zcu.intern_pool; | |
| 3209 | 3210 | |
| 3210 | 3211 | // check if decl is an alias to a function, in which case we |
| 3211 | 3212 | // want to lower the actual decl, rather than the alias itself. |
| 3212 | const owner_nav = switch (ip.indexToKey(mod.navValue(nav_index).toIntern())) { | |
| 3213 | const owner_nav = switch (ip.indexToKey(zcu.navValue(nav_index).toIntern())) { | |
| 3213 | 3214 | .func => |function| function.owner_nav, |
| 3214 | 3215 | .variable => |variable| variable.owner_nav, |
| 3215 | 3216 | .@"extern" => |@"extern"| @"extern".owner_nav, |
| 3216 | 3217 | else => nav_index, |
| 3217 | 3218 | }; |
| 3218 | 3219 | const nav_ty = ip.getNav(owner_nav).typeOf(ip); |
| 3219 | if (!ip.isFunctionType(nav_ty) and !Type.fromInterned(nav_ty).hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3220 | if (!ip.isFunctionType(nav_ty) and !Type.fromInterned(nav_ty).hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3220 | 3221 | return .{ .imm32 = 0xaaaaaaaa }; |
| 3221 | 3222 | } |
| 3222 | 3223 | |
| ... | ... | @@ -3234,10 +3235,10 @@ fn lowerNavRef(func: *CodeGen, nav_index: InternPool.Nav.Index, offset: u32) Inn |
| 3234 | 3235 | /// Asserts that `isByRef` returns `false` for `ty`. |
| 3235 | 3236 | fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3236 | 3237 | const pt = func.pt; |
| 3237 | const mod = pt.zcu; | |
| 3238 | const zcu = pt.zcu; | |
| 3238 | 3239 | assert(!isByRef(ty, pt, func.target.*)); |
| 3239 | const ip = &mod.intern_pool; | |
| 3240 | if (val.isUndefDeep(mod)) return func.emitUndefined(ty); | |
| 3240 | const ip = &zcu.intern_pool; | |
| 3241 | if (val.isUndefDeep(zcu)) return func.emitUndefined(ty); | |
| 3241 | 3242 | |
| 3242 | 3243 | switch (ip.indexToKey(val.ip_index)) { |
| 3243 | 3244 | .int_type, |
| ... | ... | @@ -3280,16 +3281,16 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3280 | 3281 | .empty_enum_value, |
| 3281 | 3282 | => unreachable, // non-runtime values |
| 3282 | 3283 | .int => { |
| 3283 | const int_info = ty.intInfo(mod); | |
| 3284 | const int_info = ty.intInfo(zcu); | |
| 3284 | 3285 | switch (int_info.signedness) { |
| 3285 | 3286 | .signed => switch (int_info.bits) { |
| 3286 | 0...32 => return .{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) }, | |
| 3287 | 33...64 => return .{ .imm64 = @bitCast(val.toSignedInt(pt)) }, | |
| 3287 | 0...32 => return .{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(zcu)))) }, | |
| 3288 | 33...64 => return .{ .imm64 = @bitCast(val.toSignedInt(zcu)) }, | |
| 3288 | 3289 | else => unreachable, |
| 3289 | 3290 | }, |
| 3290 | 3291 | .unsigned => switch (int_info.bits) { |
| 3291 | 0...32 => return .{ .imm32 = @intCast(val.toUnsignedInt(pt)) }, | |
| 3292 | 33...64 => return .{ .imm64 = val.toUnsignedInt(pt) }, | |
| 3292 | 0...32 => return .{ .imm32 = @intCast(val.toUnsignedInt(zcu)) }, | |
| 3293 | 33...64 => return .{ .imm64 = val.toUnsignedInt(zcu) }, | |
| 3293 | 3294 | else => unreachable, |
| 3294 | 3295 | }, |
| 3295 | 3296 | } |
| ... | ... | @@ -3302,9 +3303,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3302 | 3303 | const err_int_ty = try pt.errorIntType(); |
| 3303 | 3304 | const err_ty, const err_val = switch (error_union.val) { |
| 3304 | 3305 | .err_name => |err_name| .{ |
| 3305 | ty.errorUnionSet(mod), | |
| 3306 | ty.errorUnionSet(zcu), | |
| 3306 | 3307 | Value.fromInterned(try pt.intern(.{ .err = .{ |
| 3307 | .ty = ty.errorUnionSet(mod).toIntern(), | |
| 3308 | .ty = ty.errorUnionSet(zcu).toIntern(), | |
| 3308 | 3309 | .name = err_name, |
| 3309 | 3310 | } })), |
| 3310 | 3311 | }, |
| ... | ... | @@ -3313,8 +3314,8 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3313 | 3314 | try pt.intValue(err_int_ty, 0), |
| 3314 | 3315 | }, |
| 3315 | 3316 | }; |
| 3316 | const payload_type = ty.errorUnionPayload(mod); | |
| 3317 | if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3317 | const payload_type = ty.errorUnionPayload(zcu); | |
| 3318 | if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3318 | 3319 | // We use the error type directly as the type. |
| 3319 | 3320 | return func.lowerConstant(err_val, err_ty); |
| 3320 | 3321 | } |
| ... | ... | @@ -3339,20 +3340,20 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3339 | 3340 | }, |
| 3340 | 3341 | }, |
| 3341 | 3342 | .ptr => return func.lowerPtr(val.toIntern(), 0), |
| 3342 | .opt => if (ty.optionalReprIsPayload(mod)) { | |
| 3343 | const pl_ty = ty.optionalChild(mod); | |
| 3344 | if (val.optionalValue(mod)) |payload| { | |
| 3343 | .opt => if (ty.optionalReprIsPayload(zcu)) { | |
| 3344 | const pl_ty = ty.optionalChild(zcu); | |
| 3345 | if (val.optionalValue(zcu)) |payload| { | |
| 3345 | 3346 | return func.lowerConstant(payload, pl_ty); |
| 3346 | 3347 | } else { |
| 3347 | 3348 | return .{ .imm32 = 0 }; |
| 3348 | 3349 | } |
| 3349 | 3350 | } else { |
| 3350 | return .{ .imm32 = @intFromBool(!val.isNull(mod)) }; | |
| 3351 | return .{ .imm32 = @intFromBool(!val.isNull(zcu)) }; | |
| 3351 | 3352 | }, |
| 3352 | 3353 | .aggregate => switch (ip.indexToKey(ty.ip_index)) { |
| 3353 | 3354 | .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}), |
| 3354 | 3355 | .vector_type => { |
| 3355 | assert(determineSimdStoreStrategy(ty, pt, func.target.*) == .direct); | |
| 3356 | assert(determineSimdStoreStrategy(ty, zcu, func.target.*) == .direct); | |
| 3356 | 3357 | var buf: [16]u8 = undefined; |
| 3357 | 3358 | val.writeToMemory(ty, pt, &buf) catch unreachable; |
| 3358 | 3359 | return func.storeSimdImmd(buf); |
| ... | ... | @@ -3378,8 +3379,8 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3378 | 3379 | const constant_ty = if (un.tag == .none) |
| 3379 | 3380 | try ty.unionBackingType(pt) |
| 3380 | 3381 | else field_ty: { |
| 3381 | const union_obj = mod.typeToUnion(ty).?; | |
| 3382 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | |
| 3382 | const union_obj = zcu.typeToUnion(ty).?; | |
| 3383 | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | |
| 3383 | 3384 | break :field_ty Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 3384 | 3385 | }; |
| 3385 | 3386 | return func.lowerConstant(Value.fromInterned(un.val), constant_ty); |
| ... | ... | @@ -3398,11 +3399,11 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue { |
| 3398 | 3399 | |
| 3399 | 3400 | fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3400 | 3401 | const pt = func.pt; |
| 3401 | const mod = pt.zcu; | |
| 3402 | const ip = &mod.intern_pool; | |
| 3403 | switch (ty.zigTypeTag(mod)) { | |
| 3402 | const zcu = pt.zcu; | |
| 3403 | const ip = &zcu.intern_pool; | |
| 3404 | switch (ty.zigTypeTag(zcu)) { | |
| 3404 | 3405 | .Bool, .ErrorSet => return .{ .imm32 = 0xaaaaaaaa }, |
| 3405 | .Int, .Enum => switch (ty.intInfo(mod).bits) { | |
| 3406 | .Int, .Enum => switch (ty.intInfo(zcu).bits) { | |
| 3406 | 3407 | 0...32 => return .{ .imm32 = 0xaaaaaaaa }, |
| 3407 | 3408 | 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa }, |
| 3408 | 3409 | else => unreachable, |
| ... | ... | @@ -3419,8 +3420,8 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3419 | 3420 | else => unreachable, |
| 3420 | 3421 | }, |
| 3421 | 3422 | .Optional => { |
| 3422 | const pl_ty = ty.optionalChild(mod); | |
| 3423 | if (ty.optionalReprIsPayload(mod)) { | |
| 3423 | const pl_ty = ty.optionalChild(zcu); | |
| 3424 | if (ty.optionalReprIsPayload(zcu)) { | |
| 3424 | 3425 | return func.emitUndefined(pl_ty); |
| 3425 | 3426 | } |
| 3426 | 3427 | return .{ .imm32 = 0xaaaaaaaa }; |
| ... | ... | @@ -3429,10 +3430,10 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3429 | 3430 | return .{ .imm32 = 0xaaaaaaaa }; |
| 3430 | 3431 | }, |
| 3431 | 3432 | .Struct => { |
| 3432 | const packed_struct = mod.typeToPackedStruct(ty).?; | |
| 3433 | const packed_struct = zcu.typeToPackedStruct(ty).?; | |
| 3433 | 3434 | return func.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip))); |
| 3434 | 3435 | }, |
| 3435 | else => return func.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(mod)}), | |
| 3436 | else => return func.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(zcu)}), | |
| 3436 | 3437 | } |
| 3437 | 3438 | } |
| 3438 | 3439 | |
| ... | ... | @@ -3441,8 +3442,8 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3441 | 3442 | /// as an integer value. |
| 3442 | 3443 | fn valueAsI32(func: *const CodeGen, val: Value) i32 { |
| 3443 | 3444 | const pt = func.pt; |
| 3444 | const mod = pt.zcu; | |
| 3445 | const ip = &mod.intern_pool; | |
| 3445 | const zcu = pt.zcu; | |
| 3446 | const ip = &zcu.intern_pool; | |
| 3446 | 3447 | |
| 3447 | 3448 | switch (val.toIntern()) { |
| 3448 | 3449 | .bool_true => return 1, |
| ... | ... | @@ -3465,12 +3466,13 @@ fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread |
| 3465 | 3466 | } |
| 3466 | 3467 | |
| 3467 | 3468 | fn intStorageAsI32(storage: InternPool.Key.Int.Storage, pt: Zcu.PerThread) i32 { |
| 3469 | const zcu = pt.zcu; | |
| 3468 | 3470 | return switch (storage) { |
| 3469 | 3471 | .i64 => |x| @as(i32, @intCast(x)), |
| 3470 | 3472 | .u64 => |x| @as(i32, @bitCast(@as(u32, @intCast(x)))), |
| 3471 | 3473 | .big_int => unreachable, |
| 3472 | .lazy_align => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiAlignment(pt).toByteUnits() orelse 0)))), | |
| 3473 | .lazy_size => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiSize(pt))))), | |
| 3474 | .lazy_align => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0)))), | |
| 3475 | .lazy_size => |ty| @as(i32, @bitCast(@as(u32, @intCast(Type.fromInterned(ty).abiSize(zcu))))), | |
| 3474 | 3476 | }; |
| 3475 | 3477 | } |
| 3476 | 3478 | |
| ... | ... | @@ -3599,10 +3601,10 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In |
| 3599 | 3601 | fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 3600 | 3602 | assert(!(lhs != .stack and rhs == .stack)); |
| 3601 | 3603 | const pt = func.pt; |
| 3602 | const mod = pt.zcu; | |
| 3603 | if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) { | |
| 3604 | const payload_ty = ty.optionalChild(mod); | |
| 3605 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3604 | const zcu = pt.zcu; | |
| 3605 | if (ty.zigTypeTag(zcu) == .Optional and !ty.optionalReprIsPayload(zcu)) { | |
| 3606 | const payload_ty = ty.optionalChild(zcu); | |
| 3607 | if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3606 | 3608 | // When we hit this case, we must check the value of optionals |
| 3607 | 3609 | // that are not pointers. This means first checking against non-null for |
| 3608 | 3610 | // both lhs and rhs, as well as checking the payload are matching of lhs and rhs |
| ... | ... | @@ -3616,10 +3618,10 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO |
| 3616 | 3618 | |
| 3617 | 3619 | const signedness: std.builtin.Signedness = blk: { |
| 3618 | 3620 | // by default we tell the operand type is unsigned (i.e. bools and enum values) |
| 3619 | if (ty.zigTypeTag(mod) != .Int) break :blk .unsigned; | |
| 3621 | if (ty.zigTypeTag(zcu) != .Int) break :blk .unsigned; | |
| 3620 | 3622 | |
| 3621 | 3623 | // incase of an actual integer, we emit the correct signedness |
| 3622 | break :blk ty.intInfo(mod).signedness; | |
| 3624 | break :blk ty.intInfo(zcu).signedness; | |
| 3623 | 3625 | }; |
| 3624 | 3626 | |
| 3625 | 3627 | // ensure that when we compare pointers, we emit |
| ... | ... | @@ -3708,12 +3710,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3708 | 3710 | } |
| 3709 | 3711 | |
| 3710 | 3712 | fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3711 | const pt = func.pt; | |
| 3713 | const zcu = func.pt.zcu; | |
| 3712 | 3714 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 3713 | 3715 | const block = func.blocks.get(br.block_inst).?; |
| 3714 | 3716 | |
| 3715 | 3717 | // if operand has codegen bits we should break with a value |
| 3716 | if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3718 | if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3717 | 3719 | const operand = try func.resolveInst(br.operand); |
| 3718 | 3720 | try func.lowerToStack(operand); |
| 3719 | 3721 | |
| ... | ... | @@ -3736,17 +3738,17 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3736 | 3738 | const operand = try func.resolveInst(ty_op.operand); |
| 3737 | 3739 | const operand_ty = func.typeOf(ty_op.operand); |
| 3738 | 3740 | const pt = func.pt; |
| 3739 | const mod = pt.zcu; | |
| 3741 | const zcu = pt.zcu; | |
| 3740 | 3742 | |
| 3741 | 3743 | const result = result: { |
| 3742 | if (operand_ty.zigTypeTag(mod) == .Bool) { | |
| 3744 | if (operand_ty.zigTypeTag(zcu) == .Bool) { | |
| 3743 | 3745 | try func.emitWValue(operand); |
| 3744 | 3746 | try func.addTag(.i32_eqz); |
| 3745 | 3747 | const not_tmp = try func.allocLocal(operand_ty); |
| 3746 | 3748 | try func.addLabel(.local_set, not_tmp.local.value); |
| 3747 | 3749 | break :result not_tmp; |
| 3748 | 3750 | } else { |
| 3749 | const int_info = operand_ty.intInfo(mod); | |
| 3751 | const int_info = operand_ty.intInfo(zcu); | |
| 3750 | 3752 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 3751 | 3753 | return func.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(pt)}); |
| 3752 | 3754 | }; |
| ... | ... | @@ -3816,14 +3818,14 @@ fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3816 | 3818 | |
| 3817 | 3819 | fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3818 | 3820 | const pt = func.pt; |
| 3819 | const mod = pt.zcu; | |
| 3821 | const zcu = pt.zcu; | |
| 3820 | 3822 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3821 | 3823 | const operand = try func.resolveInst(ty_op.operand); |
| 3822 | 3824 | const wanted_ty = func.typeOfIndex(inst); |
| 3823 | 3825 | const given_ty = func.typeOf(ty_op.operand); |
| 3824 | 3826 | |
| 3825 | const bit_size = given_ty.bitSize(pt); | |
| 3826 | const needs_wrapping = (given_ty.isSignedInt(mod) != wanted_ty.isSignedInt(mod)) and | |
| 3827 | const bit_size = given_ty.bitSize(zcu); | |
| 3828 | const needs_wrapping = (given_ty.isSignedInt(zcu) != wanted_ty.isSignedInt(zcu)) and | |
| 3827 | 3829 | bit_size != 32 and bit_size != 64 and bit_size != 128; |
| 3828 | 3830 | |
| 3829 | 3831 | const result = result: { |
| ... | ... | @@ -3860,12 +3862,12 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3860 | 3862 | |
| 3861 | 3863 | fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue { |
| 3862 | 3864 | const pt = func.pt; |
| 3863 | const mod = pt.zcu; | |
| 3865 | const zcu = pt.zcu; | |
| 3864 | 3866 | // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction |
| 3865 | 3867 | if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand; |
| 3866 | 3868 | if (wanted_ty.ip_index == .f16_type or given_ty.ip_index == .f16_type) return operand; |
| 3867 | if (wanted_ty.bitSize(pt) > 64) return operand; | |
| 3868 | assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod))); | |
| 3869 | if (wanted_ty.bitSize(zcu) > 64) return operand; | |
| 3870 | assert((wanted_ty.isInt(zcu) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(zcu))); | |
| 3869 | 3871 | |
| 3870 | 3872 | const opcode = buildOpcode(.{ |
| 3871 | 3873 | .op = .reinterpret, |
| ... | ... | @@ -3879,24 +3881,24 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn |
| 3879 | 3881 | |
| 3880 | 3882 | fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3881 | 3883 | const pt = func.pt; |
| 3882 | const mod = pt.zcu; | |
| 3884 | const zcu = pt.zcu; | |
| 3883 | 3885 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3884 | 3886 | const extra = func.air.extraData(Air.StructField, ty_pl.payload); |
| 3885 | 3887 | |
| 3886 | 3888 | const struct_ptr = try func.resolveInst(extra.data.struct_operand); |
| 3887 | 3889 | const struct_ptr_ty = func.typeOf(extra.data.struct_operand); |
| 3888 | const struct_ty = struct_ptr_ty.childType(mod); | |
| 3890 | const struct_ty = struct_ptr_ty.childType(zcu); | |
| 3889 | 3891 | const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index); |
| 3890 | 3892 | return func.finishAir(inst, result, &.{extra.data.struct_operand}); |
| 3891 | 3893 | } |
| 3892 | 3894 | |
| 3893 | 3895 | fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void { |
| 3894 | 3896 | const pt = func.pt; |
| 3895 | const mod = pt.zcu; | |
| 3897 | const zcu = pt.zcu; | |
| 3896 | 3898 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3897 | 3899 | const struct_ptr = try func.resolveInst(ty_op.operand); |
| 3898 | 3900 | const struct_ptr_ty = func.typeOf(ty_op.operand); |
| 3899 | const struct_ty = struct_ptr_ty.childType(mod); | |
| 3901 | const struct_ty = struct_ptr_ty.childType(zcu); | |
| 3900 | 3902 | |
| 3901 | 3903 | const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ptr_ty, struct_ty, index); |
| 3902 | 3904 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| ... | ... | @@ -3912,23 +3914,23 @@ fn structFieldPtr( |
| 3912 | 3914 | index: u32, |
| 3913 | 3915 | ) InnerError!WValue { |
| 3914 | 3916 | const pt = func.pt; |
| 3915 | const mod = pt.zcu; | |
| 3917 | const zcu = pt.zcu; | |
| 3916 | 3918 | const result_ty = func.typeOfIndex(inst); |
| 3917 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); | |
| 3919 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu); | |
| 3918 | 3920 | |
| 3919 | const offset = switch (struct_ty.containerLayout(mod)) { | |
| 3920 | .@"packed" => switch (struct_ty.zigTypeTag(mod)) { | |
| 3921 | const offset = switch (struct_ty.containerLayout(zcu)) { | |
| 3922 | .@"packed" => switch (struct_ty.zigTypeTag(zcu)) { | |
| 3921 | 3923 | .Struct => offset: { |
| 3922 | if (result_ty.ptrInfo(mod).packed_offset.host_size != 0) { | |
| 3924 | if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) { | |
| 3923 | 3925 | break :offset @as(u32, 0); |
| 3924 | 3926 | } |
| 3925 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 3927 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 3926 | 3928 | break :offset @divExact(pt.structPackedFieldBitOffset(struct_type, index) + struct_ptr_ty_info.packed_offset.bit_offset, 8); |
| 3927 | 3929 | }, |
| 3928 | 3930 | .Union => 0, |
| 3929 | 3931 | else => unreachable, |
| 3930 | 3932 | }, |
| 3931 | else => struct_ty.structFieldOffset(index, pt), | |
| 3933 | else => struct_ty.structFieldOffset(index, zcu), | |
| 3932 | 3934 | }; |
| 3933 | 3935 | // save a load and store when we can simply reuse the operand |
| 3934 | 3936 | if (offset == 0) { |
| ... | ... | @@ -3944,24 +3946,24 @@ fn structFieldPtr( |
| 3944 | 3946 | |
| 3945 | 3947 | fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3946 | 3948 | const pt = func.pt; |
| 3947 | const mod = pt.zcu; | |
| 3948 | const ip = &mod.intern_pool; | |
| 3949 | const zcu = pt.zcu; | |
| 3950 | const ip = &zcu.intern_pool; | |
| 3949 | 3951 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3950 | 3952 | const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data; |
| 3951 | 3953 | |
| 3952 | 3954 | const struct_ty = func.typeOf(struct_field.struct_operand); |
| 3953 | 3955 | const operand = try func.resolveInst(struct_field.struct_operand); |
| 3954 | 3956 | const field_index = struct_field.field_index; |
| 3955 | const field_ty = struct_ty.structFieldType(field_index, mod); | |
| 3956 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{struct_field.struct_operand}); | |
| 3957 | const field_ty = struct_ty.structFieldType(field_index, zcu); | |
| 3958 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return func.finishAir(inst, .none, &.{struct_field.struct_operand}); | |
| 3957 | 3959 | |
| 3958 | const result: WValue = switch (struct_ty.containerLayout(mod)) { | |
| 3959 | .@"packed" => switch (struct_ty.zigTypeTag(mod)) { | |
| 3960 | const result: WValue = switch (struct_ty.containerLayout(zcu)) { | |
| 3961 | .@"packed" => switch (struct_ty.zigTypeTag(zcu)) { | |
| 3960 | 3962 | .Struct => result: { |
| 3961 | const packed_struct = mod.typeToPackedStruct(struct_ty).?; | |
| 3963 | const packed_struct = zcu.typeToPackedStruct(struct_ty).?; | |
| 3962 | 3964 | const offset = pt.structPackedFieldBitOffset(packed_struct, field_index); |
| 3963 | 3965 | const backing_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)); |
| 3964 | const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse { | |
| 3966 | const wasm_bits = toWasmBits(backing_ty.intInfo(zcu).bits) orelse { | |
| 3965 | 3967 | return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{}); |
| 3966 | 3968 | }; |
| 3967 | 3969 | const const_wvalue: WValue = if (wasm_bits == 32) |
| ... | ... | @@ -3977,16 +3979,16 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3977 | 3979 | else |
| 3978 | 3980 | try func.binOp(operand, const_wvalue, backing_ty, .shr); |
| 3979 | 3981 | |
| 3980 | if (field_ty.zigTypeTag(mod) == .Float) { | |
| 3981 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); | |
| 3982 | if (field_ty.zigTypeTag(zcu) == .Float) { | |
| 3983 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(zcu)))); | |
| 3982 | 3984 | const truncated = try func.trunc(shifted_value, int_type, backing_ty); |
| 3983 | 3985 | break :result try func.bitcast(field_ty, int_type, truncated); |
| 3984 | } else if (field_ty.isPtrAtRuntime(mod) and packed_struct.field_types.len == 1) { | |
| 3986 | } else if (field_ty.isPtrAtRuntime(zcu) and packed_struct.field_types.len == 1) { | |
| 3985 | 3987 | // In this case we do not have to perform any transformations, |
| 3986 | 3988 | // we can simply reuse the operand. |
| 3987 | 3989 | break :result func.reuseOperand(struct_field.struct_operand, operand); |
| 3988 | } else if (field_ty.isPtrAtRuntime(mod)) { | |
| 3989 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); | |
| 3990 | } else if (field_ty.isPtrAtRuntime(zcu)) { | |
| 3991 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(zcu)))); | |
| 3990 | 3992 | break :result try func.trunc(shifted_value, int_type, backing_ty); |
| 3991 | 3993 | } |
| 3992 | 3994 | break :result try func.trunc(shifted_value, field_ty, backing_ty); |
| ... | ... | @@ -4002,13 +4004,13 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4002 | 4004 | } |
| 4003 | 4005 | } |
| 4004 | 4006 | |
| 4005 | const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(struct_ty.bitSize(pt)))); | |
| 4006 | if (field_ty.zigTypeTag(mod) == .Float) { | |
| 4007 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); | |
| 4007 | const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(struct_ty.bitSize(zcu)))); | |
| 4008 | if (field_ty.zigTypeTag(zcu) == .Float) { | |
| 4009 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(zcu)))); | |
| 4008 | 4010 | const truncated = try func.trunc(operand, int_type, union_int_type); |
| 4009 | 4011 | break :result try func.bitcast(field_ty, int_type, truncated); |
| 4010 | } else if (field_ty.isPtrAtRuntime(mod)) { | |
| 4011 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt)))); | |
| 4012 | } else if (field_ty.isPtrAtRuntime(zcu)) { | |
| 4013 | const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(zcu)))); | |
| 4012 | 4014 | break :result try func.trunc(operand, int_type, union_int_type); |
| 4013 | 4015 | } |
| 4014 | 4016 | break :result try func.trunc(operand, field_ty, union_int_type); |
| ... | ... | @@ -4016,7 +4018,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4016 | 4018 | else => unreachable, |
| 4017 | 4019 | }, |
| 4018 | 4020 | else => result: { |
| 4019 | const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, pt)) orelse { | |
| 4021 | const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, zcu)) orelse { | |
| 4020 | 4022 | return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)}); |
| 4021 | 4023 | }; |
| 4022 | 4024 | if (isByRef(field_ty, pt, func.target.*)) { |
| ... | ... | @@ -4036,7 +4038,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4036 | 4038 | |
| 4037 | 4039 | fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4038 | 4040 | const pt = func.pt; |
| 4039 | const mod = pt.zcu; | |
| 4041 | const zcu = pt.zcu; | |
| 4040 | 4042 | // result type is always 'noreturn' |
| 4041 | 4043 | const blocktype = wasm.block_empty; |
| 4042 | 4044 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | ... | @@ -4093,7 +4095,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4093 | 4095 | // When the target is an integer size larger than u32, we have no way to use the value |
| 4094 | 4096 | // as an index, therefore we also use an if/else-chain for those cases. |
| 4095 | 4097 | // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'. |
| 4096 | const is_sparse = highest - lowest > 50 or target_ty.bitSize(pt) > 32; | |
| 4098 | const is_sparse = highest - lowest > 50 or target_ty.bitSize(zcu) > 32; | |
| 4097 | 4099 | |
| 4098 | 4100 | const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]); |
| 4099 | 4101 | const has_else_body = else_body.len != 0; |
| ... | ... | @@ -4138,7 +4140,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4138 | 4140 | // for errors that are not present in any branch. This is fine as this default |
| 4139 | 4141 | // case will never be hit for those cases but we do save runtime cost and size |
| 4140 | 4142 | // by using a jump table for this instead of if-else chains. |
| 4141 | break :blk if (has_else_body or target_ty.zigTypeTag(mod) == .ErrorSet) case_i else unreachable; | |
| 4143 | break :blk if (has_else_body or target_ty.zigTypeTag(zcu) == .ErrorSet) case_i else unreachable; | |
| 4142 | 4144 | }; |
| 4143 | 4145 | func.mir_extra.appendAssumeCapacity(idx); |
| 4144 | 4146 | } else if (has_else_body) { |
| ... | ... | @@ -4149,10 +4151,10 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4149 | 4151 | |
| 4150 | 4152 | const signedness: std.builtin.Signedness = blk: { |
| 4151 | 4153 | // by default we tell the operand type is unsigned (i.e. bools and enum values) |
| 4152 | if (target_ty.zigTypeTag(mod) != .Int) break :blk .unsigned; | |
| 4154 | if (target_ty.zigTypeTag(zcu) != .Int) break :blk .unsigned; | |
| 4153 | 4155 | |
| 4154 | 4156 | // incase of an actual integer, we emit the correct signedness |
| 4155 | break :blk target_ty.intInfo(mod).signedness; | |
| 4157 | break :blk target_ty.intInfo(zcu).signedness; | |
| 4156 | 4158 | }; |
| 4157 | 4159 | |
| 4158 | 4160 | try func.branches.ensureUnusedCapacity(func.gpa, case_list.items.len + @intFromBool(has_else_body)); |
| ... | ... | @@ -4217,14 +4219,14 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4217 | 4219 | |
| 4218 | 4220 | fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void { |
| 4219 | 4221 | const pt = func.pt; |
| 4220 | const mod = pt.zcu; | |
| 4222 | const zcu = pt.zcu; | |
| 4221 | 4223 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4222 | 4224 | const operand = try func.resolveInst(un_op); |
| 4223 | 4225 | const err_union_ty = func.typeOf(un_op); |
| 4224 | const pl_ty = err_union_ty.errorUnionPayload(mod); | |
| 4226 | const pl_ty = err_union_ty.errorUnionPayload(zcu); | |
| 4225 | 4227 | |
| 4226 | 4228 | const result: WValue = result: { |
| 4227 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 4229 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 4228 | 4230 | switch (opcode) { |
| 4229 | 4231 | .i32_ne => break :result .{ .imm32 = 0 }, |
| 4230 | 4232 | .i32_eq => break :result .{ .imm32 = 1 }, |
| ... | ... | @@ -4233,10 +4235,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro |
| 4233 | 4235 | } |
| 4234 | 4236 | |
| 4235 | 4237 | try func.emitWValue(operand); |
| 4236 | if (pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4238 | if (pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4237 | 4239 | try func.addMemArg(.i32_load16_u, .{ |
| 4238 | .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, pt))), | |
| 4239 | .alignment = @intCast(Type.anyerror.abiAlignment(pt).toByteUnits().?), | |
| 4240 | .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))), | |
| 4241 | .alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?), | |
| 4240 | 4242 | }); |
| 4241 | 4243 | } |
| 4242 | 4244 | |
| ... | ... | @@ -4250,23 +4252,23 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro |
| 4250 | 4252 | |
| 4251 | 4253 | fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 4252 | 4254 | const pt = func.pt; |
| 4253 | const mod = pt.zcu; | |
| 4255 | const zcu = pt.zcu; | |
| 4254 | 4256 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4255 | 4257 | |
| 4256 | 4258 | const operand = try func.resolveInst(ty_op.operand); |
| 4257 | 4259 | const op_ty = func.typeOf(ty_op.operand); |
| 4258 | const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty; | |
| 4259 | const payload_ty = err_ty.errorUnionPayload(mod); | |
| 4260 | const err_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty; | |
| 4261 | const payload_ty = err_ty.errorUnionPayload(zcu); | |
| 4260 | 4262 | |
| 4261 | 4263 | const result: WValue = result: { |
| 4262 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4264 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4263 | 4265 | if (op_is_ptr) { |
| 4264 | 4266 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4265 | 4267 | } |
| 4266 | 4268 | break :result .none; |
| 4267 | 4269 | } |
| 4268 | 4270 | |
| 4269 | const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))); | |
| 4271 | const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))); | |
| 4270 | 4272 | if (op_is_ptr or isByRef(payload_ty, pt, func.target.*)) { |
| 4271 | 4273 | break :result try func.buildPointerOffset(operand, pl_offset, .new); |
| 4272 | 4274 | } |
| ... | ... | @@ -4278,30 +4280,30 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo |
| 4278 | 4280 | |
| 4279 | 4281 | fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 4280 | 4282 | const pt = func.pt; |
| 4281 | const mod = pt.zcu; | |
| 4283 | const zcu = pt.zcu; | |
| 4282 | 4284 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4283 | 4285 | |
| 4284 | 4286 | const operand = try func.resolveInst(ty_op.operand); |
| 4285 | 4287 | const op_ty = func.typeOf(ty_op.operand); |
| 4286 | const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty; | |
| 4287 | const payload_ty = err_ty.errorUnionPayload(mod); | |
| 4288 | const err_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty; | |
| 4289 | const payload_ty = err_ty.errorUnionPayload(zcu); | |
| 4288 | 4290 | |
| 4289 | 4291 | const result: WValue = result: { |
| 4290 | if (err_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 4292 | if (err_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 4291 | 4293 | break :result .{ .imm32 = 0 }; |
| 4292 | 4294 | } |
| 4293 | 4295 | |
| 4294 | if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4296 | if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4295 | 4297 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4296 | 4298 | } |
| 4297 | 4299 | |
| 4298 | break :result try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt))); | |
| 4300 | break :result try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, zcu))); | |
| 4299 | 4301 | }; |
| 4300 | 4302 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| 4301 | 4303 | } |
| 4302 | 4304 | |
| 4303 | 4305 | fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4304 | const pt = func.pt; | |
| 4306 | const zcu = func.pt.zcu; | |
| 4305 | 4307 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4306 | 4308 | |
| 4307 | 4309 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4309,18 +4311,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 4309 | 4311 | |
| 4310 | 4312 | const pl_ty = func.typeOf(ty_op.operand); |
| 4311 | 4313 | const result = result: { |
| 4312 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4314 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4313 | 4315 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4314 | 4316 | } |
| 4315 | 4317 | |
| 4316 | 4318 | const err_union = try func.allocStack(err_ty); |
| 4317 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, pt))), .new); | |
| 4319 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, zcu))), .new); | |
| 4318 | 4320 | try func.store(payload_ptr, operand, pl_ty, 0); |
| 4319 | 4321 | |
| 4320 | 4322 | // ensure we also write '0' to the error part, so any present stack value gets overwritten by it. |
| 4321 | 4323 | try func.emitWValue(err_union); |
| 4322 | 4324 | try func.addImm32(0); |
| 4323 | const err_val_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 4325 | const err_val_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 4324 | 4326 | try func.addMemArg(.i32_store16, .{ |
| 4325 | 4327 | .offset = err_union.offset() + err_val_offset, |
| 4326 | 4328 | .alignment = 2, |
| ... | ... | @@ -4332,25 +4334,25 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 4332 | 4334 | |
| 4333 | 4335 | fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4334 | 4336 | const pt = func.pt; |
| 4335 | const mod = pt.zcu; | |
| 4337 | const zcu = pt.zcu; | |
| 4336 | 4338 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4337 | 4339 | |
| 4338 | 4340 | const operand = try func.resolveInst(ty_op.operand); |
| 4339 | 4341 | const err_ty = ty_op.ty.toType(); |
| 4340 | const pl_ty = err_ty.errorUnionPayload(mod); | |
| 4342 | const pl_ty = err_ty.errorUnionPayload(zcu); | |
| 4341 | 4343 | |
| 4342 | 4344 | const result = result: { |
| 4343 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4345 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4344 | 4346 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4345 | 4347 | } |
| 4346 | 4348 | |
| 4347 | 4349 | const err_union = try func.allocStack(err_ty); |
| 4348 | 4350 | // store error value |
| 4349 | try func.store(err_union, operand, Type.anyerror, @intCast(errUnionErrorOffset(pl_ty, pt))); | |
| 4351 | try func.store(err_union, operand, Type.anyerror, @intCast(errUnionErrorOffset(pl_ty, zcu))); | |
| 4350 | 4352 | |
| 4351 | 4353 | // write 'undefined' to the payload |
| 4352 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, pt))), .new); | |
| 4353 | const len = @as(u32, @intCast(err_ty.errorUnionPayload(mod).abiSize(pt))); | |
| 4354 | const payload_ptr = try func.buildPointerOffset(err_union, @as(u32, @intCast(errUnionPayloadOffset(pl_ty, zcu))), .new); | |
| 4355 | const len = @as(u32, @intCast(err_ty.errorUnionPayload(zcu).abiSize(zcu))); | |
| 4354 | 4356 | try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa }); |
| 4355 | 4357 | |
| 4356 | 4358 | break :result err_union; |
| ... | ... | @@ -4365,16 +4367,16 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4365 | 4367 | const operand = try func.resolveInst(ty_op.operand); |
| 4366 | 4368 | const operand_ty = func.typeOf(ty_op.operand); |
| 4367 | 4369 | const pt = func.pt; |
| 4368 | const mod = pt.zcu; | |
| 4369 | if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) { | |
| 4370 | const zcu = pt.zcu; | |
| 4371 | if (ty.zigTypeTag(zcu) == .Vector or operand_ty.zigTypeTag(zcu) == .Vector) { | |
| 4370 | 4372 | return func.fail("todo Wasm intcast for vectors", .{}); |
| 4371 | 4373 | } |
| 4372 | if (ty.abiSize(pt) > 16 or operand_ty.abiSize(pt) > 16) { | |
| 4374 | if (ty.abiSize(zcu) > 16 or operand_ty.abiSize(zcu) > 16) { | |
| 4373 | 4375 | return func.fail("todo Wasm intcast for bitsize > 128", .{}); |
| 4374 | 4376 | } |
| 4375 | 4377 | |
| 4376 | const op_bits = toWasmBits(@intCast(operand_ty.bitSize(pt))).?; | |
| 4377 | const wanted_bits = toWasmBits(@intCast(ty.bitSize(pt))).?; | |
| 4378 | const op_bits = toWasmBits(@intCast(operand_ty.bitSize(zcu))).?; | |
| 4379 | const wanted_bits = toWasmBits(@intCast(ty.bitSize(zcu))).?; | |
| 4378 | 4380 | const result = if (op_bits == wanted_bits) |
| 4379 | 4381 | func.reuseOperand(ty_op.operand, operand) |
| 4380 | 4382 | else |
| ... | ... | @@ -4389,9 +4391,9 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4389 | 4391 | /// NOTE: May leave the result on the top of the stack. |
| 4390 | 4392 | fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue { |
| 4391 | 4393 | const pt = func.pt; |
| 4392 | const mod = pt.zcu; | |
| 4393 | const given_bitsize = @as(u16, @intCast(given.bitSize(pt))); | |
| 4394 | const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(pt))); | |
| 4394 | const zcu = pt.zcu; | |
| 4395 | const given_bitsize = @as(u16, @intCast(given.bitSize(zcu))); | |
| 4396 | const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(zcu))); | |
| 4395 | 4397 | assert(given_bitsize <= 128); |
| 4396 | 4398 | assert(wanted_bitsize <= 128); |
| 4397 | 4399 | |
| ... | ... | @@ -4407,7 +4409,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 4407 | 4409 | return .stack; |
| 4408 | 4410 | } else if (op_bits == 32 and wanted_bits == 64) { |
| 4409 | 4411 | try func.emitWValue(operand); |
| 4410 | try func.addTag(if (wanted.isSignedInt(mod)) .i64_extend_i32_s else .i64_extend_i32_u); | |
| 4412 | try func.addTag(if (wanted.isSignedInt(zcu)) .i64_extend_i32_s else .i64_extend_i32_u); | |
| 4411 | 4413 | return .stack; |
| 4412 | 4414 | } else if (wanted_bits == 128) { |
| 4413 | 4415 | // for 128bit integers we store the integer in the virtual stack, rather than a local |
| ... | ... | @@ -4417,7 +4419,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 4417 | 4419 | // for 32 bit integers, we first coerce the value into a 64 bit integer before storing it |
| 4418 | 4420 | // meaning less store operations are required. |
| 4419 | 4421 | const lhs = if (op_bits == 32) blk: { |
| 4420 | const sign_ty = if (wanted.isSignedInt(mod)) Type.i64 else Type.u64; | |
| 4422 | const sign_ty = if (wanted.isSignedInt(zcu)) Type.i64 else Type.u64; | |
| 4421 | 4423 | break :blk try (try func.intcast(operand, given, sign_ty)).toLocal(func, sign_ty); |
| 4422 | 4424 | } else operand; |
| 4423 | 4425 | |
| ... | ... | @@ -4425,7 +4427,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 4425 | 4427 | try func.store(.stack, lhs, Type.u64, 0 + stack_ptr.offset()); |
| 4426 | 4428 | |
| 4427 | 4429 | // For signed integers we shift lsb by 63 (64bit integer - 1 sign bit) and store remaining value |
| 4428 | if (wanted.isSignedInt(mod)) { | |
| 4430 | if (wanted.isSignedInt(zcu)) { | |
| 4429 | 4431 | try func.emitWValue(stack_ptr); |
| 4430 | 4432 | const shr = try func.binOp(lhs, .{ .imm64 = 63 }, Type.i64, .shr); |
| 4431 | 4433 | try func.store(.stack, shr, Type.u64, 8 + stack_ptr.offset()); |
| ... | ... | @@ -4439,12 +4441,12 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 4439 | 4441 | |
| 4440 | 4442 | fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void { |
| 4441 | 4443 | const pt = func.pt; |
| 4442 | const mod = pt.zcu; | |
| 4444 | const zcu = pt.zcu; | |
| 4443 | 4445 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4444 | 4446 | const operand = try func.resolveInst(un_op); |
| 4445 | 4447 | |
| 4446 | 4448 | const op_ty = func.typeOf(un_op); |
| 4447 | const optional_ty = if (op_kind == .ptr) op_ty.childType(mod) else op_ty; | |
| 4449 | const optional_ty = if (op_kind == .ptr) op_ty.childType(zcu) else op_ty; | |
| 4448 | 4450 | const result = try func.isNull(operand, optional_ty, opcode); |
| 4449 | 4451 | return func.finishAir(inst, result, &.{un_op}); |
| 4450 | 4452 | } |
| ... | ... | @@ -4453,19 +4455,19 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: |
| 4453 | 4455 | /// NOTE: Leaves the result on the stack |
| 4454 | 4456 | fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue { |
| 4455 | 4457 | const pt = func.pt; |
| 4456 | const mod = pt.zcu; | |
| 4458 | const zcu = pt.zcu; | |
| 4457 | 4459 | try func.emitWValue(operand); |
| 4458 | const payload_ty = optional_ty.optionalChild(mod); | |
| 4459 | if (!optional_ty.optionalReprIsPayload(mod)) { | |
| 4460 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 4461 | if (!optional_ty.optionalReprIsPayload(zcu)) { | |
| 4460 | 4462 | // When payload is zero-bits, we can treat operand as a value, rather than |
| 4461 | 4463 | // a pointer to the stack value |
| 4462 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4463 | const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse { | |
| 4464 | if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4465 | const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse { | |
| 4464 | 4466 | return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(pt)}); |
| 4465 | 4467 | }; |
| 4466 | 4468 | try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 }); |
| 4467 | 4469 | } |
| 4468 | } else if (payload_ty.isSlice(mod)) { | |
| 4470 | } else if (payload_ty.isSlice(zcu)) { | |
| 4469 | 4471 | switch (func.arch()) { |
| 4470 | 4472 | .wasm32 => try func.addMemArg(.i32_load, .{ .offset = operand.offset(), .alignment = 4 }), |
| 4471 | 4473 | .wasm64 => try func.addMemArg(.i64_load, .{ .offset = operand.offset(), .alignment = 8 }), |
| ... | ... | @@ -4482,17 +4484,17 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod |
| 4482 | 4484 | |
| 4483 | 4485 | fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4484 | 4486 | const pt = func.pt; |
| 4485 | const mod = pt.zcu; | |
| 4487 | const zcu = pt.zcu; | |
| 4486 | 4488 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4487 | 4489 | const opt_ty = func.typeOf(ty_op.operand); |
| 4488 | 4490 | const payload_ty = func.typeOfIndex(inst); |
| 4489 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4491 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4490 | 4492 | return func.finishAir(inst, .none, &.{ty_op.operand}); |
| 4491 | 4493 | } |
| 4492 | 4494 | |
| 4493 | 4495 | const result = result: { |
| 4494 | 4496 | const operand = try func.resolveInst(ty_op.operand); |
| 4495 | if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand); | |
| 4497 | if (opt_ty.optionalReprIsPayload(zcu)) break :result func.reuseOperand(ty_op.operand, operand); | |
| 4496 | 4498 | |
| 4497 | 4499 | if (isByRef(payload_ty, pt, func.target.*)) { |
| 4498 | 4500 | break :result try func.buildPointerOffset(operand, 0, .new); |
| ... | ... | @@ -4505,14 +4507,14 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4505 | 4507 | |
| 4506 | 4508 | fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4507 | 4509 | const pt = func.pt; |
| 4508 | const mod = pt.zcu; | |
| 4510 | const zcu = pt.zcu; | |
| 4509 | 4511 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4510 | 4512 | const operand = try func.resolveInst(ty_op.operand); |
| 4511 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); | |
| 4513 | const opt_ty = func.typeOf(ty_op.operand).childType(zcu); | |
| 4512 | 4514 | |
| 4513 | 4515 | const result = result: { |
| 4514 | const payload_ty = opt_ty.optionalChild(mod); | |
| 4515 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or opt_ty.optionalReprIsPayload(mod)) { | |
| 4516 | const payload_ty = opt_ty.optionalChild(zcu); | |
| 4517 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu) or opt_ty.optionalReprIsPayload(zcu)) { | |
| 4516 | 4518 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4517 | 4519 | } |
| 4518 | 4520 | |
| ... | ... | @@ -4523,20 +4525,20 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4523 | 4525 | |
| 4524 | 4526 | fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4525 | 4527 | const pt = func.pt; |
| 4526 | const mod = pt.zcu; | |
| 4528 | const zcu = pt.zcu; | |
| 4527 | 4529 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4528 | 4530 | const operand = try func.resolveInst(ty_op.operand); |
| 4529 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); | |
| 4530 | const payload_ty = opt_ty.optionalChild(mod); | |
| 4531 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4531 | const opt_ty = func.typeOf(ty_op.operand).childType(zcu); | |
| 4532 | const payload_ty = opt_ty.optionalChild(zcu); | |
| 4533 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4532 | 4534 | return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()}); |
| 4533 | 4535 | } |
| 4534 | 4536 | |
| 4535 | if (opt_ty.optionalReprIsPayload(mod)) { | |
| 4537 | if (opt_ty.optionalReprIsPayload(zcu)) { | |
| 4536 | 4538 | return func.finishAir(inst, operand, &.{ty_op.operand}); |
| 4537 | 4539 | } |
| 4538 | 4540 | |
| 4539 | const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse { | |
| 4541 | const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse { | |
| 4540 | 4542 | return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(pt)}); |
| 4541 | 4543 | }; |
| 4542 | 4544 | |
| ... | ... | @@ -4552,10 +4554,10 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4552 | 4554 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4553 | 4555 | const payload_ty = func.typeOf(ty_op.operand); |
| 4554 | 4556 | const pt = func.pt; |
| 4555 | const mod = pt.zcu; | |
| 4557 | const zcu = pt.zcu; | |
| 4556 | 4558 | |
| 4557 | 4559 | const result = result: { |
| 4558 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4560 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4559 | 4561 | const non_null_bit = try func.allocStack(Type.u1); |
| 4560 | 4562 | try func.emitWValue(non_null_bit); |
| 4561 | 4563 | try func.addImm32(1); |
| ... | ... | @@ -4565,10 +4567,10 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4565 | 4567 | |
| 4566 | 4568 | const operand = try func.resolveInst(ty_op.operand); |
| 4567 | 4569 | const op_ty = func.typeOfIndex(inst); |
| 4568 | if (op_ty.optionalReprIsPayload(mod)) { | |
| 4570 | if (op_ty.optionalReprIsPayload(zcu)) { | |
| 4569 | 4571 | break :result func.reuseOperand(ty_op.operand, operand); |
| 4570 | 4572 | } |
| 4571 | const offset = std.math.cast(u32, payload_ty.abiSize(pt)) orelse { | |
| 4573 | const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse { | |
| 4572 | 4574 | return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(pt)}); |
| 4573 | 4575 | }; |
| 4574 | 4576 | |
| ... | ... | @@ -4610,14 +4612,14 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4610 | 4612 | |
| 4611 | 4613 | fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4612 | 4614 | const pt = func.pt; |
| 4613 | const mod = pt.zcu; | |
| 4615 | const zcu = pt.zcu; | |
| 4614 | 4616 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4615 | 4617 | |
| 4616 | 4618 | const slice_ty = func.typeOf(bin_op.lhs); |
| 4617 | 4619 | const slice = try func.resolveInst(bin_op.lhs); |
| 4618 | 4620 | const index = try func.resolveInst(bin_op.rhs); |
| 4619 | const elem_ty = slice_ty.childType(mod); | |
| 4620 | const elem_size = elem_ty.abiSize(pt); | |
| 4621 | const elem_ty = slice_ty.childType(zcu); | |
| 4622 | const elem_size = elem_ty.abiSize(zcu); | |
| 4621 | 4623 | |
| 4622 | 4624 | // load pointer onto stack |
| 4623 | 4625 | _ = try func.load(slice, Type.usize, 0); |
| ... | ... | @@ -4638,12 +4640,12 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4638 | 4640 | |
| 4639 | 4641 | fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4640 | 4642 | const pt = func.pt; |
| 4641 | const mod = pt.zcu; | |
| 4643 | const zcu = pt.zcu; | |
| 4642 | 4644 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4643 | 4645 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4644 | 4646 | |
| 4645 | const elem_ty = ty_pl.ty.toType().childType(mod); | |
| 4646 | const elem_size = elem_ty.abiSize(pt); | |
| 4647 | const elem_ty = ty_pl.ty.toType().childType(zcu); | |
| 4648 | const elem_size = elem_ty.abiSize(zcu); | |
| 4647 | 4649 | |
| 4648 | 4650 | const slice = try func.resolveInst(bin_op.lhs); |
| 4649 | 4651 | const index = try func.resolveInst(bin_op.rhs); |
| ... | ... | @@ -4682,13 +4684,13 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4682 | 4684 | const wanted_ty: Type = ty_op.ty.toType(); |
| 4683 | 4685 | const op_ty = func.typeOf(ty_op.operand); |
| 4684 | 4686 | const pt = func.pt; |
| 4685 | const mod = pt.zcu; | |
| 4687 | const zcu = pt.zcu; | |
| 4686 | 4688 | |
| 4687 | if (wanted_ty.zigTypeTag(mod) == .Vector or op_ty.zigTypeTag(mod) == .Vector) { | |
| 4689 | if (wanted_ty.zigTypeTag(zcu) == .Vector or op_ty.zigTypeTag(zcu) == .Vector) { | |
| 4688 | 4690 | return func.fail("TODO: trunc for vectors", .{}); |
| 4689 | 4691 | } |
| 4690 | 4692 | |
| 4691 | const result = if (op_ty.bitSize(pt) == wanted_ty.bitSize(pt)) | |
| 4693 | const result = if (op_ty.bitSize(zcu) == wanted_ty.bitSize(zcu)) | |
| 4692 | 4694 | func.reuseOperand(ty_op.operand, operand) |
| 4693 | 4695 | else |
| 4694 | 4696 | try func.trunc(operand, wanted_ty, op_ty); |
| ... | ... | @@ -4700,13 +4702,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4700 | 4702 | /// NOTE: Resulting value is left on the stack. |
| 4701 | 4703 | fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue { |
| 4702 | 4704 | const pt = func.pt; |
| 4703 | const given_bits = @as(u16, @intCast(given_ty.bitSize(pt))); | |
| 4705 | const zcu = pt.zcu; | |
| 4706 | const given_bits = @as(u16, @intCast(given_ty.bitSize(zcu))); | |
| 4704 | 4707 | if (toWasmBits(given_bits) == null) { |
| 4705 | 4708 | return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits}); |
| 4706 | 4709 | } |
| 4707 | 4710 | |
| 4708 | 4711 | var result = try func.intcast(operand, given_ty, wanted_ty); |
| 4709 | const wanted_bits = @as(u16, @intCast(wanted_ty.bitSize(pt))); | |
| 4712 | const wanted_bits = @as(u16, @intCast(wanted_ty.bitSize(zcu))); | |
| 4710 | 4713 | const wasm_bits = toWasmBits(wanted_bits).?; |
| 4711 | 4714 | if (wasm_bits != wanted_bits) { |
| 4712 | 4715 | result = try func.wrapOperand(result, wanted_ty); |
| ... | ... | @@ -4724,23 +4727,23 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4724 | 4727 | |
| 4725 | 4728 | fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4726 | 4729 | const pt = func.pt; |
| 4727 | const mod = pt.zcu; | |
| 4730 | const zcu = pt.zcu; | |
| 4728 | 4731 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4729 | 4732 | |
| 4730 | 4733 | const operand = try func.resolveInst(ty_op.operand); |
| 4731 | const array_ty = func.typeOf(ty_op.operand).childType(mod); | |
| 4734 | const array_ty = func.typeOf(ty_op.operand).childType(zcu); | |
| 4732 | 4735 | const slice_ty = ty_op.ty.toType(); |
| 4733 | 4736 | |
| 4734 | 4737 | // create a slice on the stack |
| 4735 | 4738 | const slice_local = try func.allocStack(slice_ty); |
| 4736 | 4739 | |
| 4737 | 4740 | // store the array ptr in the slice |
| 4738 | if (array_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4741 | if (array_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4739 | 4742 | try func.store(slice_local, operand, Type.usize, 0); |
| 4740 | 4743 | } |
| 4741 | 4744 | |
| 4742 | 4745 | // store the length of the array in the slice |
| 4743 | const array_len: u32 = @intCast(array_ty.arrayLen(mod)); | |
| 4746 | const array_len: u32 = @intCast(array_ty.arrayLen(zcu)); | |
| 4744 | 4747 | try func.store(slice_local, .{ .imm32 = array_len }, Type.usize, func.ptrSize()); |
| 4745 | 4748 | |
| 4746 | 4749 | return func.finishAir(inst, slice_local, &.{ty_op.operand}); |
| ... | ... | @@ -4748,11 +4751,11 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4748 | 4751 | |
| 4749 | 4752 | fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4750 | 4753 | const pt = func.pt; |
| 4751 | const mod = pt.zcu; | |
| 4754 | const zcu = pt.zcu; | |
| 4752 | 4755 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4753 | 4756 | const operand = try func.resolveInst(un_op); |
| 4754 | 4757 | const ptr_ty = func.typeOf(un_op); |
| 4755 | const result = if (ptr_ty.isSlice(mod)) | |
| 4758 | const result = if (ptr_ty.isSlice(zcu)) | |
| 4756 | 4759 | try func.slicePtr(operand) |
| 4757 | 4760 | else switch (operand) { |
| 4758 | 4761 | // for stack offset, return a pointer to this offset. |
| ... | ... | @@ -4764,17 +4767,17 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4764 | 4767 | |
| 4765 | 4768 | fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4766 | 4769 | const pt = func.pt; |
| 4767 | const mod = pt.zcu; | |
| 4770 | const zcu = pt.zcu; | |
| 4768 | 4771 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4769 | 4772 | |
| 4770 | 4773 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 4771 | 4774 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4772 | 4775 | const index = try func.resolveInst(bin_op.rhs); |
| 4773 | const elem_ty = ptr_ty.childType(mod); | |
| 4774 | const elem_size = elem_ty.abiSize(pt); | |
| 4776 | const elem_ty = ptr_ty.childType(zcu); | |
| 4777 | const elem_size = elem_ty.abiSize(zcu); | |
| 4775 | 4778 | |
| 4776 | 4779 | // load pointer onto the stack |
| 4777 | if (ptr_ty.isSlice(mod)) { | |
| 4780 | if (ptr_ty.isSlice(zcu)) { | |
| 4778 | 4781 | _ = try func.load(ptr, Type.usize, 0); |
| 4779 | 4782 | } else { |
| 4780 | 4783 | try func.lowerToStack(ptr); |
| ... | ... | @@ -4796,19 +4799,19 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4796 | 4799 | |
| 4797 | 4800 | fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4798 | 4801 | const pt = func.pt; |
| 4799 | const mod = pt.zcu; | |
| 4802 | const zcu = pt.zcu; | |
| 4800 | 4803 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4801 | 4804 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4802 | 4805 | |
| 4803 | 4806 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 4804 | const elem_ty = ty_pl.ty.toType().childType(mod); | |
| 4805 | const elem_size = elem_ty.abiSize(pt); | |
| 4807 | const elem_ty = ty_pl.ty.toType().childType(zcu); | |
| 4808 | const elem_size = elem_ty.abiSize(zcu); | |
| 4806 | 4809 | |
| 4807 | 4810 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4808 | 4811 | const index = try func.resolveInst(bin_op.rhs); |
| 4809 | 4812 | |
| 4810 | 4813 | // load pointer onto the stack |
| 4811 | if (ptr_ty.isSlice(mod)) { | |
| 4814 | if (ptr_ty.isSlice(zcu)) { | |
| 4812 | 4815 | _ = try func.load(ptr, Type.usize, 0); |
| 4813 | 4816 | } else { |
| 4814 | 4817 | try func.lowerToStack(ptr); |
| ... | ... | @@ -4825,16 +4828,16 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4825 | 4828 | |
| 4826 | 4829 | fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4827 | 4830 | const pt = func.pt; |
| 4828 | const mod = pt.zcu; | |
| 4831 | const zcu = pt.zcu; | |
| 4829 | 4832 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4830 | 4833 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4831 | 4834 | |
| 4832 | 4835 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4833 | 4836 | const offset = try func.resolveInst(bin_op.rhs); |
| 4834 | 4837 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 4835 | const pointee_ty = switch (ptr_ty.ptrSize(mod)) { | |
| 4836 | .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type | |
| 4837 | else => ptr_ty.childType(mod), | |
| 4838 | const pointee_ty = switch (ptr_ty.ptrSize(zcu)) { | |
| 4839 | .One => ptr_ty.childType(zcu).childType(zcu), // ptr to array, so get array element type | |
| 4840 | else => ptr_ty.childType(zcu), | |
| 4838 | 4841 | }; |
| 4839 | 4842 | |
| 4840 | 4843 | const valtype = typeToValtype(Type.usize, pt, func.target.*); |
| ... | ... | @@ -4843,7 +4846,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4843 | 4846 | |
| 4844 | 4847 | try func.lowerToStack(ptr); |
| 4845 | 4848 | try func.emitWValue(offset); |
| 4846 | try func.addImm32(@intCast(pointee_ty.abiSize(pt))); | |
| 4849 | try func.addImm32(@intCast(pointee_ty.abiSize(zcu))); | |
| 4847 | 4850 | try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode)); |
| 4848 | 4851 | try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode)); |
| 4849 | 4852 | |
| ... | ... | @@ -4852,7 +4855,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4852 | 4855 | |
| 4853 | 4856 | fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 4854 | 4857 | const pt = func.pt; |
| 4855 | const mod = pt.zcu; | |
| 4858 | const zcu = pt.zcu; | |
| 4856 | 4859 | if (safety) { |
| 4857 | 4860 | // TODO if the value is undef, write 0xaa bytes to dest |
| 4858 | 4861 | } else { |
| ... | ... | @@ -4863,16 +4866,16 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 4863 | 4866 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4864 | 4867 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 4865 | 4868 | const value = try func.resolveInst(bin_op.rhs); |
| 4866 | const len = switch (ptr_ty.ptrSize(mod)) { | |
| 4869 | const len = switch (ptr_ty.ptrSize(zcu)) { | |
| 4867 | 4870 | .Slice => try func.sliceLen(ptr), |
| 4868 | .One => @as(WValue, .{ .imm32 = @as(u32, @intCast(ptr_ty.childType(mod).arrayLen(mod))) }), | |
| 4871 | .One => @as(WValue, .{ .imm32 = @as(u32, @intCast(ptr_ty.childType(zcu).arrayLen(zcu))) }), | |
| 4869 | 4872 | .C, .Many => unreachable, |
| 4870 | 4873 | }; |
| 4871 | 4874 | |
| 4872 | const elem_ty = if (ptr_ty.ptrSize(mod) == .One) | |
| 4873 | ptr_ty.childType(mod).childType(mod) | |
| 4875 | const elem_ty = if (ptr_ty.ptrSize(zcu) == .One) | |
| 4876 | ptr_ty.childType(zcu).childType(zcu) | |
| 4874 | 4877 | else |
| 4875 | ptr_ty.childType(mod); | |
| 4878 | ptr_ty.childType(zcu); | |
| 4876 | 4879 | |
| 4877 | 4880 | const dst_ptr = try func.sliceOrArrayPtr(ptr, ptr_ty); |
| 4878 | 4881 | try func.memset(elem_ty, dst_ptr, len, value); |
| ... | ... | @@ -4886,7 +4889,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 4886 | 4889 | /// we implement it manually. |
| 4887 | 4890 | fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void { |
| 4888 | 4891 | const pt = func.pt; |
| 4889 | const abi_size = @as(u32, @intCast(elem_ty.abiSize(pt))); | |
| 4892 | const abi_size = @as(u32, @intCast(elem_ty.abiSize(pt.zcu))); | |
| 4890 | 4893 | |
| 4891 | 4894 | // When bulk_memory is enabled, we lower it to wasm's memset instruction. |
| 4892 | 4895 | // If not, we lower it ourselves. |
| ... | ... | @@ -4975,14 +4978,14 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue |
| 4975 | 4978 | |
| 4976 | 4979 | fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4977 | 4980 | const pt = func.pt; |
| 4978 | const mod = pt.zcu; | |
| 4981 | const zcu = pt.zcu; | |
| 4979 | 4982 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4980 | 4983 | |
| 4981 | 4984 | const array_ty = func.typeOf(bin_op.lhs); |
| 4982 | 4985 | const array = try func.resolveInst(bin_op.lhs); |
| 4983 | 4986 | const index = try func.resolveInst(bin_op.rhs); |
| 4984 | const elem_ty = array_ty.childType(mod); | |
| 4985 | const elem_size = elem_ty.abiSize(pt); | |
| 4987 | const elem_ty = array_ty.childType(zcu); | |
| 4988 | const elem_size = elem_ty.abiSize(zcu); | |
| 4986 | 4989 | |
| 4987 | 4990 | if (isByRef(array_ty, pt, func.target.*)) { |
| 4988 | 4991 | try func.lowerToStack(array); |
| ... | ... | @@ -4991,15 +4994,15 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4991 | 4994 | try func.addTag(.i32_mul); |
| 4992 | 4995 | try func.addTag(.i32_add); |
| 4993 | 4996 | } else { |
| 4994 | std.debug.assert(array_ty.zigTypeTag(mod) == .Vector); | |
| 4997 | std.debug.assert(array_ty.zigTypeTag(zcu) == .Vector); | |
| 4995 | 4998 | |
| 4996 | 4999 | switch (index) { |
| 4997 | 5000 | inline .imm32, .imm64 => |lane| { |
| 4998 | const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(pt)) { | |
| 4999 | 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u, | |
| 5000 | 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u, | |
| 5001 | 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane, | |
| 5002 | 64 => if (elem_ty.isInt(mod)) .i64x2_extract_lane else .f64x2_extract_lane, | |
| 5001 | const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(zcu)) { | |
| 5002 | 8 => if (elem_ty.isSignedInt(zcu)) .i8x16_extract_lane_s else .i8x16_extract_lane_u, | |
| 5003 | 16 => if (elem_ty.isSignedInt(zcu)) .i16x8_extract_lane_s else .i16x8_extract_lane_u, | |
| 5004 | 32 => if (elem_ty.isInt(zcu)) .i32x4_extract_lane else .f32x4_extract_lane, | |
| 5005 | 64 => if (elem_ty.isInt(zcu)) .i64x2_extract_lane else .f64x2_extract_lane, | |
| 5003 | 5006 | else => unreachable, |
| 5004 | 5007 | }; |
| 5005 | 5008 | |
| ... | ... | @@ -5037,7 +5040,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5037 | 5040 | |
| 5038 | 5041 | fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5039 | 5042 | const pt = func.pt; |
| 5040 | const mod = pt.zcu; | |
| 5043 | const zcu = pt.zcu; | |
| 5041 | 5044 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5042 | 5045 | |
| 5043 | 5046 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -5045,7 +5048,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5045 | 5048 | const op_bits = op_ty.floatBits(func.target.*); |
| 5046 | 5049 | |
| 5047 | 5050 | const dest_ty = func.typeOfIndex(inst); |
| 5048 | const dest_info = dest_ty.intInfo(mod); | |
| 5051 | const dest_info = dest_ty.intInfo(zcu); | |
| 5049 | 5052 | |
| 5050 | 5053 | if (dest_info.bits > 128) { |
| 5051 | 5054 | return func.fail("TODO: intFromFloat for integers/floats with bitsize {}", .{dest_info.bits}); |
| ... | ... | @@ -5082,12 +5085,12 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5082 | 5085 | |
| 5083 | 5086 | fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5084 | 5087 | const pt = func.pt; |
| 5085 | const mod = pt.zcu; | |
| 5088 | const zcu = pt.zcu; | |
| 5086 | 5089 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5087 | 5090 | |
| 5088 | 5091 | const operand = try func.resolveInst(ty_op.operand); |
| 5089 | 5092 | const op_ty = func.typeOf(ty_op.operand); |
| 5090 | const op_info = op_ty.intInfo(mod); | |
| 5093 | const op_info = op_ty.intInfo(zcu); | |
| 5091 | 5094 | |
| 5092 | 5095 | const dest_ty = func.typeOfIndex(inst); |
| 5093 | 5096 | const dest_bits = dest_ty.floatBits(func.target.*); |
| ... | ... | @@ -5127,19 +5130,19 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5127 | 5130 | |
| 5128 | 5131 | fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5129 | 5132 | const pt = func.pt; |
| 5130 | const mod = pt.zcu; | |
| 5133 | const zcu = pt.zcu; | |
| 5131 | 5134 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5132 | 5135 | const operand = try func.resolveInst(ty_op.operand); |
| 5133 | 5136 | const ty = func.typeOfIndex(inst); |
| 5134 | const elem_ty = ty.childType(mod); | |
| 5137 | const elem_ty = ty.childType(zcu); | |
| 5135 | 5138 | |
| 5136 | if (determineSimdStoreStrategy(ty, pt, func.target.*) == .direct) blk: { | |
| 5139 | if (determineSimdStoreStrategy(ty, zcu, func.target.*) == .direct) blk: { | |
| 5137 | 5140 | switch (operand) { |
| 5138 | 5141 | // when the operand lives in the linear memory section, we can directly |
| 5139 | 5142 | // load and splat the value at once. Meaning we do not first have to load |
| 5140 | 5143 | // the scalar value onto the stack. |
| 5141 | 5144 | .stack_offset, .memory, .memory_offset => { |
| 5142 | const opcode = switch (elem_ty.bitSize(pt)) { | |
| 5145 | const opcode = switch (elem_ty.bitSize(zcu)) { | |
| 5143 | 5146 | 8 => std.wasm.simdOpcode(.v128_load8_splat), |
| 5144 | 5147 | 16 => std.wasm.simdOpcode(.v128_load16_splat), |
| 5145 | 5148 | 32 => std.wasm.simdOpcode(.v128_load32_splat), |
| ... | ... | @@ -5153,17 +5156,17 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5153 | 5156 | try func.mir_extra.appendSlice(func.gpa, &[_]u32{ |
| 5154 | 5157 | opcode, |
| 5155 | 5158 | operand.offset(), |
| 5156 | @intCast(elem_ty.abiAlignment(pt).toByteUnits().?), | |
| 5159 | @intCast(elem_ty.abiAlignment(zcu).toByteUnits().?), | |
| 5157 | 5160 | }); |
| 5158 | 5161 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 5159 | 5162 | return func.finishAir(inst, .stack, &.{ty_op.operand}); |
| 5160 | 5163 | }, |
| 5161 | 5164 | .local => { |
| 5162 | const opcode = switch (elem_ty.bitSize(pt)) { | |
| 5165 | const opcode = switch (elem_ty.bitSize(zcu)) { | |
| 5163 | 5166 | 8 => std.wasm.simdOpcode(.i8x16_splat), |
| 5164 | 5167 | 16 => std.wasm.simdOpcode(.i16x8_splat), |
| 5165 | 32 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat), | |
| 5166 | 64 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat), | |
| 5168 | 32 => if (elem_ty.isInt(zcu)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat), | |
| 5169 | 64 => if (elem_ty.isInt(zcu)) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat), | |
| 5167 | 5170 | else => break :blk, // Cannot make use of simd-instructions |
| 5168 | 5171 | }; |
| 5169 | 5172 | try func.emitWValue(operand); |
| ... | ... | @@ -5175,14 +5178,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5175 | 5178 | else => unreachable, |
| 5176 | 5179 | } |
| 5177 | 5180 | } |
| 5178 | const elem_size = elem_ty.bitSize(pt); | |
| 5179 | const vector_len = @as(usize, @intCast(ty.vectorLen(mod))); | |
| 5181 | const elem_size = elem_ty.bitSize(zcu); | |
| 5182 | const vector_len = @as(usize, @intCast(ty.vectorLen(zcu))); | |
| 5180 | 5183 | if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) { |
| 5181 | 5184 | return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size}); |
| 5182 | 5185 | } |
| 5183 | 5186 | |
| 5184 | 5187 | const result = try func.allocStack(ty); |
| 5185 | const elem_byte_size = @as(u32, @intCast(elem_ty.abiSize(pt))); | |
| 5188 | const elem_byte_size = @as(u32, @intCast(elem_ty.abiSize(zcu))); | |
| 5186 | 5189 | var index: usize = 0; |
| 5187 | 5190 | var offset: u32 = 0; |
| 5188 | 5191 | while (index < vector_len) : (index += 1) { |
| ... | ... | @@ -5203,7 +5206,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5203 | 5206 | |
| 5204 | 5207 | fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5205 | 5208 | const pt = func.pt; |
| 5206 | const mod = pt.zcu; | |
| 5209 | const zcu = pt.zcu; | |
| 5207 | 5210 | const inst_ty = func.typeOfIndex(inst); |
| 5208 | 5211 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5209 | 5212 | const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| ... | ... | @@ -5213,15 +5216,15 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5213 | 5216 | const mask = Value.fromInterned(extra.mask); |
| 5214 | 5217 | const mask_len = extra.mask_len; |
| 5215 | 5218 | |
| 5216 | const child_ty = inst_ty.childType(mod); | |
| 5217 | const elem_size = child_ty.abiSize(pt); | |
| 5219 | const child_ty = inst_ty.childType(zcu); | |
| 5220 | const elem_size = child_ty.abiSize(zcu); | |
| 5218 | 5221 | |
| 5219 | 5222 | // TODO: One of them could be by ref; handle in loop |
| 5220 | 5223 | if (isByRef(func.typeOf(extra.a), pt, func.target.*) or isByRef(inst_ty, pt, func.target.*)) { |
| 5221 | 5224 | const result = try func.allocStack(inst_ty); |
| 5222 | 5225 | |
| 5223 | 5226 | for (0..mask_len) |index| { |
| 5224 | const value = (try mask.elemValue(pt, index)).toSignedInt(pt); | |
| 5227 | const value = (try mask.elemValue(pt, index)).toSignedInt(zcu); | |
| 5225 | 5228 | |
| 5226 | 5229 | try func.emitWValue(result); |
| 5227 | 5230 | |
| ... | ... | @@ -5241,7 +5244,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5241 | 5244 | |
| 5242 | 5245 | var lanes = mem.asBytes(operands[1..]); |
| 5243 | 5246 | for (0..@as(usize, @intCast(mask_len))) |index| { |
| 5244 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(pt); | |
| 5247 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(zcu); | |
| 5245 | 5248 | const base_index = if (mask_elem >= 0) |
| 5246 | 5249 | @as(u8, @intCast(@as(i64, @intCast(elem_size)) * mask_elem)) |
| 5247 | 5250 | else |
| ... | ... | @@ -5273,20 +5276,20 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5273 | 5276 | |
| 5274 | 5277 | fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5275 | 5278 | const pt = func.pt; |
| 5276 | const mod = pt.zcu; | |
| 5277 | const ip = &mod.intern_pool; | |
| 5279 | const zcu = pt.zcu; | |
| 5280 | const ip = &zcu.intern_pool; | |
| 5278 | 5281 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5279 | 5282 | const result_ty = func.typeOfIndex(inst); |
| 5280 | const len = @as(usize, @intCast(result_ty.arrayLen(mod))); | |
| 5283 | const len = @as(usize, @intCast(result_ty.arrayLen(zcu))); | |
| 5281 | 5284 | const elements = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[ty_pl.payload..][0..len])); |
| 5282 | 5285 | |
| 5283 | 5286 | const result: WValue = result_value: { |
| 5284 | switch (result_ty.zigTypeTag(mod)) { | |
| 5287 | switch (result_ty.zigTypeTag(zcu)) { | |
| 5285 | 5288 | .Array => { |
| 5286 | 5289 | const result = try func.allocStack(result_ty); |
| 5287 | const elem_ty = result_ty.childType(mod); | |
| 5288 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(pt))); | |
| 5289 | const sentinel = if (result_ty.sentinel(mod)) |sent| blk: { | |
| 5290 | const elem_ty = result_ty.childType(zcu); | |
| 5291 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(zcu))); | |
| 5292 | const sentinel = if (result_ty.sentinel(zcu)) |sent| blk: { | |
| 5290 | 5293 | break :blk try func.lowerConstant(sent, elem_ty); |
| 5291 | 5294 | } else null; |
| 5292 | 5295 | |
| ... | ... | @@ -5321,18 +5324,18 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5321 | 5324 | } |
| 5322 | 5325 | break :result_value result; |
| 5323 | 5326 | }, |
| 5324 | .Struct => switch (result_ty.containerLayout(mod)) { | |
| 5327 | .Struct => switch (result_ty.containerLayout(zcu)) { | |
| 5325 | 5328 | .@"packed" => { |
| 5326 | 5329 | if (isByRef(result_ty, pt, func.target.*)) { |
| 5327 | 5330 | return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{}); |
| 5328 | 5331 | } |
| 5329 | const packed_struct = mod.typeToPackedStruct(result_ty).?; | |
| 5332 | const packed_struct = zcu.typeToPackedStruct(result_ty).?; | |
| 5330 | 5333 | const field_types = packed_struct.field_types; |
| 5331 | 5334 | const backing_type = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)); |
| 5332 | 5335 | |
| 5333 | 5336 | // ensure the result is zero'd |
| 5334 | 5337 | const result = try func.allocLocal(backing_type); |
| 5335 | if (backing_type.bitSize(pt) <= 32) | |
| 5338 | if (backing_type.bitSize(zcu) <= 32) | |
| 5336 | 5339 | try func.addImm32(0) |
| 5337 | 5340 | else |
| 5338 | 5341 | try func.addImm64(0); |
| ... | ... | @@ -5341,15 +5344,15 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5341 | 5344 | var current_bit: u16 = 0; |
| 5342 | 5345 | for (elements, 0..) |elem, elem_index| { |
| 5343 | 5346 | const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]); |
| 5344 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 5347 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 5345 | 5348 | |
| 5346 | const shift_val: WValue = if (backing_type.bitSize(pt) <= 32) | |
| 5349 | const shift_val: WValue = if (backing_type.bitSize(zcu) <= 32) | |
| 5347 | 5350 | .{ .imm32 = current_bit } |
| 5348 | 5351 | else |
| 5349 | 5352 | .{ .imm64 = current_bit }; |
| 5350 | 5353 | |
| 5351 | 5354 | const value = try func.resolveInst(elem); |
| 5352 | const value_bit_size: u16 = @intCast(field_ty.bitSize(pt)); | |
| 5355 | const value_bit_size: u16 = @intCast(field_ty.bitSize(zcu)); | |
| 5353 | 5356 | const int_ty = try pt.intType(.unsigned, value_bit_size); |
| 5354 | 5357 | |
| 5355 | 5358 | // load our current result on stack so we can perform all transformations |
| ... | ... | @@ -5375,8 +5378,8 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5375 | 5378 | for (elements, 0..) |elem, elem_index| { |
| 5376 | 5379 | if (try result_ty.structFieldValueComptime(pt, elem_index) != null) continue; |
| 5377 | 5380 | |
| 5378 | const elem_ty = result_ty.structFieldType(elem_index, mod); | |
| 5379 | const field_offset = result_ty.structFieldOffset(elem_index, pt); | |
| 5381 | const elem_ty = result_ty.structFieldType(elem_index, zcu); | |
| 5382 | const field_offset = result_ty.structFieldOffset(elem_index, zcu); | |
| 5380 | 5383 | _ = try func.buildPointerOffset(offset, @intCast(field_offset - prev_field_offset), .modify); |
| 5381 | 5384 | prev_field_offset = field_offset; |
| 5382 | 5385 | |
| ... | ... | @@ -5404,21 +5407,21 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5404 | 5407 | |
| 5405 | 5408 | fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5406 | 5409 | const pt = func.pt; |
| 5407 | const mod = pt.zcu; | |
| 5408 | const ip = &mod.intern_pool; | |
| 5410 | const zcu = pt.zcu; | |
| 5411 | const ip = &zcu.intern_pool; | |
| 5409 | 5412 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5410 | 5413 | const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 5411 | 5414 | |
| 5412 | 5415 | const result = result: { |
| 5413 | 5416 | const union_ty = func.typeOfIndex(inst); |
| 5414 | const layout = union_ty.unionGetLayout(pt); | |
| 5415 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 5417 | const layout = union_ty.unionGetLayout(zcu); | |
| 5418 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 5416 | 5419 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 5417 | 5420 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 5418 | 5421 | |
| 5419 | 5422 | const tag_int = blk: { |
| 5420 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | |
| 5421 | const enum_field_index = tag_ty.enumFieldIndex(field_name, mod).?; | |
| 5423 | const tag_ty = union_ty.unionTagTypeHypothetical(zcu); | |
| 5424 | const enum_field_index = tag_ty.enumFieldIndex(field_name, zcu).?; | |
| 5422 | 5425 | const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index); |
| 5423 | 5426 | break :blk try func.lowerConstant(tag_val, tag_ty); |
| 5424 | 5427 | }; |
| ... | ... | @@ -5458,13 +5461,13 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5458 | 5461 | break :result result_ptr; |
| 5459 | 5462 | } else { |
| 5460 | 5463 | const operand = try func.resolveInst(extra.init); |
| 5461 | const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(union_ty.bitSize(pt)))); | |
| 5462 | if (field_ty.zigTypeTag(mod) == .Float) { | |
| 5463 | const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt))); | |
| 5464 | const union_int_type = try pt.intType(.unsigned, @as(u16, @intCast(union_ty.bitSize(zcu)))); | |
| 5465 | if (field_ty.zigTypeTag(zcu) == .Float) { | |
| 5466 | const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(zcu))); | |
| 5464 | 5467 | const bitcasted = try func.bitcast(field_ty, int_type, operand); |
| 5465 | 5468 | break :result try func.trunc(bitcasted, int_type, union_int_type); |
| 5466 | } else if (field_ty.isPtrAtRuntime(mod)) { | |
| 5467 | const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt))); | |
| 5469 | } else if (field_ty.isPtrAtRuntime(zcu)) { | |
| 5470 | const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(zcu))); | |
| 5468 | 5471 | break :result try func.intcast(operand, int_type, union_int_type); |
| 5469 | 5472 | } |
| 5470 | 5473 | break :result try func.intcast(operand, field_ty, union_int_type); |
| ... | ... | @@ -5497,10 +5500,10 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void { |
| 5497 | 5500 | |
| 5498 | 5501 | fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 5499 | 5502 | const pt = func.pt; |
| 5500 | const mod = pt.zcu; | |
| 5501 | assert(operand_ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 5503 | const zcu = pt.zcu; | |
| 5504 | assert(operand_ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 5502 | 5505 | assert(op == .eq or op == .neq); |
| 5503 | const payload_ty = operand_ty.optionalChild(mod); | |
| 5506 | const payload_ty = operand_ty.optionalChild(zcu); | |
| 5504 | 5507 | |
| 5505 | 5508 | // We store the final result in here that will be validated |
| 5506 | 5509 | // if the optional is truly equal. |
| ... | ... | @@ -5534,11 +5537,11 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: |
| 5534 | 5537 | /// TODO: Lower this to compiler_rt call when bitsize > 128 |
| 5535 | 5538 | fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 5536 | 5539 | const pt = func.pt; |
| 5537 | const mod = pt.zcu; | |
| 5538 | assert(operand_ty.abiSize(pt) >= 16); | |
| 5540 | const zcu = pt.zcu; | |
| 5541 | assert(operand_ty.abiSize(zcu) >= 16); | |
| 5539 | 5542 | assert(!(lhs != .stack and rhs == .stack)); |
| 5540 | if (operand_ty.bitSize(pt) > 128) { | |
| 5541 | return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(pt)}); | |
| 5543 | if (operand_ty.bitSize(zcu) > 128) { | |
| 5544 | return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(zcu)}); | |
| 5542 | 5545 | } |
| 5543 | 5546 | |
| 5544 | 5547 | var lhs_msb = try (try func.load(lhs, Type.u64, 8)).toLocal(func, Type.u64); |
| ... | ... | @@ -5561,7 +5564,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std |
| 5561 | 5564 | } |
| 5562 | 5565 | }, |
| 5563 | 5566 | else => { |
| 5564 | const ty = if (operand_ty.isSignedInt(mod)) Type.i64 else Type.u64; | |
| 5567 | const ty = if (operand_ty.isSignedInt(zcu)) Type.i64 else Type.u64; | |
| 5565 | 5568 | // leave those value on top of the stack for '.select' |
| 5566 | 5569 | const lhs_lsb = try func.load(lhs, Type.u64, 0); |
| 5567 | 5570 | const rhs_lsb = try func.load(rhs, Type.u64, 0); |
| ... | ... | @@ -5577,11 +5580,11 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std |
| 5577 | 5580 | |
| 5578 | 5581 | fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5579 | 5582 | const pt = func.pt; |
| 5580 | const mod = pt.zcu; | |
| 5583 | const zcu = pt.zcu; | |
| 5581 | 5584 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5582 | const un_ty = func.typeOf(bin_op.lhs).childType(mod); | |
| 5585 | const un_ty = func.typeOf(bin_op.lhs).childType(zcu); | |
| 5583 | 5586 | const tag_ty = func.typeOf(bin_op.rhs); |
| 5584 | const layout = un_ty.unionGetLayout(pt); | |
| 5587 | const layout = un_ty.unionGetLayout(zcu); | |
| 5585 | 5588 | if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs }); |
| 5586 | 5589 | |
| 5587 | 5590 | const union_ptr = try func.resolveInst(bin_op.lhs); |
| ... | ... | @@ -5601,12 +5604,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5601 | 5604 | } |
| 5602 | 5605 | |
| 5603 | 5606 | fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5604 | const pt = func.pt; | |
| 5607 | const zcu = func.pt.zcu; | |
| 5605 | 5608 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5606 | 5609 | |
| 5607 | 5610 | const un_ty = func.typeOf(ty_op.operand); |
| 5608 | 5611 | const tag_ty = func.typeOfIndex(inst); |
| 5609 | const layout = un_ty.unionGetLayout(pt); | |
| 5612 | const layout = un_ty.unionGetLayout(zcu); | |
| 5610 | 5613 | if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand}); |
| 5611 | 5614 | |
| 5612 | 5615 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -5705,11 +5708,11 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 5705 | 5708 | |
| 5706 | 5709 | fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5707 | 5710 | const pt = func.pt; |
| 5708 | const mod = pt.zcu; | |
| 5711 | const zcu = pt.zcu; | |
| 5709 | 5712 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5710 | 5713 | |
| 5711 | const err_set_ty = func.typeOf(ty_op.operand).childType(mod); | |
| 5712 | const payload_ty = err_set_ty.errorUnionPayload(mod); | |
| 5714 | const err_set_ty = func.typeOf(ty_op.operand).childType(zcu); | |
| 5715 | const payload_ty = err_set_ty.errorUnionPayload(zcu); | |
| 5713 | 5716 | const operand = try func.resolveInst(ty_op.operand); |
| 5714 | 5717 | |
| 5715 | 5718 | // set error-tag to '0' to annotate error union is non-error |
| ... | ... | @@ -5717,28 +5720,28 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi |
| 5717 | 5720 | operand, |
| 5718 | 5721 | .{ .imm32 = 0 }, |
| 5719 | 5722 | Type.anyerror, |
| 5720 | @intCast(errUnionErrorOffset(payload_ty, pt)), | |
| 5723 | @intCast(errUnionErrorOffset(payload_ty, zcu)), | |
| 5721 | 5724 | ); |
| 5722 | 5725 | |
| 5723 | 5726 | const result = result: { |
| 5724 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5727 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5725 | 5728 | break :result func.reuseOperand(ty_op.operand, operand); |
| 5726 | 5729 | } |
| 5727 | 5730 | |
| 5728 | break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))), .new); | |
| 5731 | break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))), .new); | |
| 5729 | 5732 | }; |
| 5730 | 5733 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| 5731 | 5734 | } |
| 5732 | 5735 | |
| 5733 | 5736 | fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5734 | 5737 | const pt = func.pt; |
| 5735 | const mod = pt.zcu; | |
| 5738 | const zcu = pt.zcu; | |
| 5736 | 5739 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5737 | 5740 | const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5738 | 5741 | |
| 5739 | 5742 | const field_ptr = try func.resolveInst(extra.field_ptr); |
| 5740 | const parent_ty = ty_pl.ty.toType().childType(mod); | |
| 5741 | const field_offset = parent_ty.structFieldOffset(extra.field_index, pt); | |
| 5743 | const parent_ty = ty_pl.ty.toType().childType(zcu); | |
| 5744 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); | |
| 5742 | 5745 | |
| 5743 | 5746 | const result = if (field_offset != 0) result: { |
| 5744 | 5747 | const base = try func.buildPointerOffset(field_ptr, 0, .new); |
| ... | ... | @@ -5754,8 +5757,8 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5754 | 5757 | |
| 5755 | 5758 | fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue { |
| 5756 | 5759 | const pt = func.pt; |
| 5757 | const mod = pt.zcu; | |
| 5758 | if (ptr_ty.isSlice(mod)) { | |
| 5760 | const zcu = pt.zcu; | |
| 5761 | if (ptr_ty.isSlice(zcu)) { | |
| 5759 | 5762 | return func.slicePtr(ptr); |
| 5760 | 5763 | } else { |
| 5761 | 5764 | return ptr; |
| ... | ... | @@ -5764,26 +5767,26 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue |
| 5764 | 5767 | |
| 5765 | 5768 | fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5766 | 5769 | const pt = func.pt; |
| 5767 | const mod = pt.zcu; | |
| 5770 | const zcu = pt.zcu; | |
| 5768 | 5771 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5769 | 5772 | const dst = try func.resolveInst(bin_op.lhs); |
| 5770 | 5773 | const dst_ty = func.typeOf(bin_op.lhs); |
| 5771 | const ptr_elem_ty = dst_ty.childType(mod); | |
| 5774 | const ptr_elem_ty = dst_ty.childType(zcu); | |
| 5772 | 5775 | const src = try func.resolveInst(bin_op.rhs); |
| 5773 | 5776 | const src_ty = func.typeOf(bin_op.rhs); |
| 5774 | const len = switch (dst_ty.ptrSize(mod)) { | |
| 5777 | const len = switch (dst_ty.ptrSize(zcu)) { | |
| 5775 | 5778 | .Slice => blk: { |
| 5776 | 5779 | const slice_len = try func.sliceLen(dst); |
| 5777 | if (ptr_elem_ty.abiSize(pt) != 1) { | |
| 5780 | if (ptr_elem_ty.abiSize(zcu) != 1) { | |
| 5778 | 5781 | try func.emitWValue(slice_len); |
| 5779 | try func.emitWValue(.{ .imm32 = @as(u32, @intCast(ptr_elem_ty.abiSize(pt))) }); | |
| 5782 | try func.emitWValue(.{ .imm32 = @as(u32, @intCast(ptr_elem_ty.abiSize(zcu))) }); | |
| 5780 | 5783 | try func.addTag(.i32_mul); |
| 5781 | 5784 | try func.addLabel(.local_set, slice_len.local.value); |
| 5782 | 5785 | } |
| 5783 | 5786 | break :blk slice_len; |
| 5784 | 5787 | }, |
| 5785 | 5788 | .One => @as(WValue, .{ |
| 5786 | .imm32 = @as(u32, @intCast(ptr_elem_ty.arrayLen(mod) * ptr_elem_ty.childType(mod).abiSize(pt))), | |
| 5789 | .imm32 = @as(u32, @intCast(ptr_elem_ty.arrayLen(zcu) * ptr_elem_ty.childType(zcu).abiSize(zcu))), | |
| 5787 | 5790 | }), |
| 5788 | 5791 | .C, .Many => unreachable, |
| 5789 | 5792 | }; |
| ... | ... | @@ -5805,17 +5808,17 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5805 | 5808 | |
| 5806 | 5809 | fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5807 | 5810 | const pt = func.pt; |
| 5808 | const mod = pt.zcu; | |
| 5811 | const zcu = pt.zcu; | |
| 5809 | 5812 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5810 | 5813 | |
| 5811 | 5814 | const operand = try func.resolveInst(ty_op.operand); |
| 5812 | 5815 | const op_ty = func.typeOf(ty_op.operand); |
| 5813 | 5816 | |
| 5814 | if (op_ty.zigTypeTag(mod) == .Vector) { | |
| 5817 | if (op_ty.zigTypeTag(zcu) == .Vector) { | |
| 5815 | 5818 | return func.fail("TODO: Implement @popCount for vectors", .{}); |
| 5816 | 5819 | } |
| 5817 | 5820 | |
| 5818 | const int_info = op_ty.intInfo(mod); | |
| 5821 | const int_info = op_ty.intInfo(zcu); | |
| 5819 | 5822 | const bits = int_info.bits; |
| 5820 | 5823 | const wasm_bits = toWasmBits(bits) orelse { |
| 5821 | 5824 | return func.fail("TODO: Implement @popCount for integers with bitsize '{d}'", .{bits}); |
| ... | ... | @@ -5824,14 +5827,14 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5824 | 5827 | switch (wasm_bits) { |
| 5825 | 5828 | 32 => { |
| 5826 | 5829 | try func.emitWValue(operand); |
| 5827 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { | |
| 5830 | if (op_ty.isSignedInt(zcu) and bits != wasm_bits) { | |
| 5828 | 5831 | _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits)); |
| 5829 | 5832 | } |
| 5830 | 5833 | try func.addTag(.i32_popcnt); |
| 5831 | 5834 | }, |
| 5832 | 5835 | 64 => { |
| 5833 | 5836 | try func.emitWValue(operand); |
| 5834 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { | |
| 5837 | if (op_ty.isSignedInt(zcu) and bits != wasm_bits) { | |
| 5835 | 5838 | _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits)); |
| 5836 | 5839 | } |
| 5837 | 5840 | try func.addTag(.i64_popcnt); |
| ... | ... | @@ -5842,7 +5845,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5842 | 5845 | _ = try func.load(operand, Type.u64, 0); |
| 5843 | 5846 | try func.addTag(.i64_popcnt); |
| 5844 | 5847 | _ = try func.load(operand, Type.u64, 8); |
| 5845 | if (op_ty.isSignedInt(mod) and bits != wasm_bits) { | |
| 5848 | if (op_ty.isSignedInt(zcu) and bits != wasm_bits) { | |
| 5846 | 5849 | _ = try func.wrapOperand(.stack, try pt.intType(.unsigned, bits - 64)); |
| 5847 | 5850 | } |
| 5848 | 5851 | try func.addTag(.i64_popcnt); |
| ... | ... | @@ -5857,17 +5860,17 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5857 | 5860 | |
| 5858 | 5861 | fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5859 | 5862 | const pt = func.pt; |
| 5860 | const mod = pt.zcu; | |
| 5863 | const zcu = pt.zcu; | |
| 5861 | 5864 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5862 | 5865 | |
| 5863 | 5866 | const operand = try func.resolveInst(ty_op.operand); |
| 5864 | 5867 | const ty = func.typeOf(ty_op.operand); |
| 5865 | 5868 | |
| 5866 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 5869 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 5867 | 5870 | return func.fail("TODO: Implement @bitReverse for vectors", .{}); |
| 5868 | 5871 | } |
| 5869 | 5872 | |
| 5870 | const int_info = ty.intInfo(mod); | |
| 5873 | const int_info = ty.intInfo(zcu); | |
| 5871 | 5874 | const bits = int_info.bits; |
| 5872 | 5875 | const wasm_bits = toWasmBits(bits) orelse { |
| 5873 | 5876 | return func.fail("TODO: Implement @bitReverse for integers with bitsize '{d}'", .{bits}); |
| ... | ... | @@ -5933,7 +5936,7 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5933 | 5936 | defer tmp.free(func); |
| 5934 | 5937 | try func.addLabel(.local_tee, tmp.local.value); |
| 5935 | 5938 | try func.emitWValue(.{ .imm64 = 128 - bits }); |
| 5936 | if (ty.isSignedInt(mod)) { | |
| 5939 | if (ty.isSignedInt(zcu)) { | |
| 5937 | 5940 | try func.addTag(.i64_shr_s); |
| 5938 | 5941 | } else { |
| 5939 | 5942 | try func.addTag(.i64_shr_u); |
| ... | ... | @@ -5969,7 +5972,7 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5969 | 5972 | const pt = func.pt; |
| 5970 | 5973 | const error_table_symbol = try func.bin_file.getErrorTableSymbol(pt); |
| 5971 | 5974 | const name_ty = Type.slice_const_u8_sentinel_0; |
| 5972 | const abi_size = name_ty.abiSize(pt); | |
| 5975 | const abi_size = name_ty.abiSize(pt.zcu); | |
| 5973 | 5976 | |
| 5974 | 5977 | const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation |
| 5975 | 5978 | try func.emitWValue(error_name_value); |
| ... | ... | @@ -6000,8 +6003,8 @@ fn airPtrSliceFieldPtr(func: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerE |
| 6000 | 6003 | |
| 6001 | 6004 | /// NOTE: Allocates place for result on virtual stack, when integer size > 64 bits |
| 6002 | 6005 | fn intZeroValue(func: *CodeGen, ty: Type) InnerError!WValue { |
| 6003 | const mod = func.bin_file.base.comp.module.?; | |
| 6004 | const int_info = ty.intInfo(mod); | |
| 6006 | const zcu = func.bin_file.base.comp.module.?; | |
| 6007 | const int_info = ty.intInfo(zcu); | |
| 6005 | 6008 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6006 | 6009 | return func.fail("TODO: Implement intZeroValue for integer bitsize: {d}", .{int_info.bits}); |
| 6007 | 6010 | }; |
| ... | ... | @@ -6027,13 +6030,13 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro |
| 6027 | 6030 | const rhs = try func.resolveInst(extra.rhs); |
| 6028 | 6031 | const ty = func.typeOf(extra.lhs); |
| 6029 | 6032 | const pt = func.pt; |
| 6030 | const mod = pt.zcu; | |
| 6033 | const zcu = pt.zcu; | |
| 6031 | 6034 | |
| 6032 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6035 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6033 | 6036 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| 6034 | 6037 | } |
| 6035 | 6038 | |
| 6036 | const int_info = ty.intInfo(mod); | |
| 6039 | const int_info = ty.intInfo(zcu); | |
| 6037 | 6040 | const is_signed = int_info.signedness == .signed; |
| 6038 | 6041 | if (int_info.bits > 128) { |
| 6039 | 6042 | return func.fail("TODO: Implement {{add/sub}}_with_overflow for integer bitsize: {d}", .{int_info.bits}); |
| ... | ... | @@ -6058,7 +6061,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro |
| 6058 | 6061 | defer bit_tmp.free(func); |
| 6059 | 6062 | |
| 6060 | 6063 | const result = try func.allocStack(func.typeOfIndex(inst)); |
| 6061 | const offset: u32 = @intCast(ty.abiSize(pt)); | |
| 6064 | const offset: u32 = @intCast(ty.abiSize(zcu)); | |
| 6062 | 6065 | try func.store(result, op_tmp, ty, 0); |
| 6063 | 6066 | try func.store(result, bit_tmp, Type.u1, offset); |
| 6064 | 6067 | |
| ... | ... | @@ -6067,7 +6070,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro |
| 6067 | 6070 | |
| 6068 | 6071 | fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6069 | 6072 | const pt = func.pt; |
| 6070 | const mod = pt.zcu; | |
| 6073 | const zcu = pt.zcu; | |
| 6071 | 6074 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6072 | 6075 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6073 | 6076 | |
| ... | ... | @@ -6076,18 +6079,18 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6076 | 6079 | const ty = func.typeOf(extra.lhs); |
| 6077 | 6080 | const rhs_ty = func.typeOf(extra.rhs); |
| 6078 | 6081 | |
| 6079 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6082 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6080 | 6083 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| 6081 | 6084 | } |
| 6082 | 6085 | |
| 6083 | const int_info = ty.intInfo(mod); | |
| 6086 | const int_info = ty.intInfo(zcu); | |
| 6084 | 6087 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6085 | 6088 | return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits}); |
| 6086 | 6089 | }; |
| 6087 | 6090 | |
| 6088 | 6091 | // Ensure rhs is coerced to lhs as they must have the same WebAssembly types |
| 6089 | 6092 | // before we can perform any binary operation. |
| 6090 | const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(mod).bits).?; | |
| 6093 | const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(zcu).bits).?; | |
| 6091 | 6094 | // If wasm_bits == 128, compiler-rt expects i32 for shift |
| 6092 | 6095 | const rhs_final = if (wasm_bits != rhs_wasm_bits and wasm_bits == 64) blk: { |
| 6093 | 6096 | const rhs_casted = try func.intcast(rhs, rhs_ty, ty); |
| ... | ... | @@ -6105,7 +6108,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6105 | 6108 | defer overflow_local.free(func); |
| 6106 | 6109 | |
| 6107 | 6110 | const result = try func.allocStack(func.typeOfIndex(inst)); |
| 6108 | const offset: u32 = @intCast(ty.abiSize(pt)); | |
| 6111 | const offset: u32 = @intCast(ty.abiSize(zcu)); | |
| 6109 | 6112 | try func.store(result, shl, ty, 0); |
| 6110 | 6113 | try func.store(result, overflow_local, Type.u1, offset); |
| 6111 | 6114 | |
| ... | ... | @@ -6120,9 +6123,9 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6120 | 6123 | const rhs = try func.resolveInst(extra.rhs); |
| 6121 | 6124 | const ty = func.typeOf(extra.lhs); |
| 6122 | 6125 | const pt = func.pt; |
| 6123 | const mod = pt.zcu; | |
| 6126 | const zcu = pt.zcu; | |
| 6124 | 6127 | |
| 6125 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6128 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6126 | 6129 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| 6127 | 6130 | } |
| 6128 | 6131 | |
| ... | ... | @@ -6131,7 +6134,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6131 | 6134 | var overflow_bit = try func.ensureAllocLocal(Type.u1); |
| 6132 | 6135 | defer overflow_bit.free(func); |
| 6133 | 6136 | |
| 6134 | const int_info = ty.intInfo(mod); | |
| 6137 | const int_info = ty.intInfo(zcu); | |
| 6135 | 6138 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6136 | 6139 | return func.fail("TODO: Implement `@mulWithOverflow` for integer bitsize: {d}", .{int_info.bits}); |
| 6137 | 6140 | }; |
| ... | ... | @@ -6238,7 +6241,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6238 | 6241 | defer bin_op_local.free(func); |
| 6239 | 6242 | |
| 6240 | 6243 | const result = try func.allocStack(func.typeOfIndex(inst)); |
| 6241 | const offset: u32 = @intCast(ty.abiSize(pt)); | |
| 6244 | const offset: u32 = @intCast(ty.abiSize(zcu)); | |
| 6242 | 6245 | try func.store(result, bin_op_local, ty, 0); |
| 6243 | 6246 | try func.store(result, overflow_bit, Type.u1, offset); |
| 6244 | 6247 | |
| ... | ... | @@ -6248,22 +6251,22 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6248 | 6251 | fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6249 | 6252 | assert(op == .max or op == .min); |
| 6250 | 6253 | const pt = func.pt; |
| 6251 | const mod = pt.zcu; | |
| 6254 | const zcu = pt.zcu; | |
| 6252 | 6255 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6253 | 6256 | |
| 6254 | 6257 | const ty = func.typeOfIndex(inst); |
| 6255 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6258 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6256 | 6259 | return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{}); |
| 6257 | 6260 | } |
| 6258 | 6261 | |
| 6259 | if (ty.abiSize(pt) > 16) { | |
| 6262 | if (ty.abiSize(zcu) > 16) { | |
| 6260 | 6263 | return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{}); |
| 6261 | 6264 | } |
| 6262 | 6265 | |
| 6263 | 6266 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6264 | 6267 | const rhs = try func.resolveInst(bin_op.rhs); |
| 6265 | 6268 | |
| 6266 | if (ty.zigTypeTag(mod) == .Float) { | |
| 6269 | if (ty.zigTypeTag(zcu) == .Float) { | |
| 6267 | 6270 | var fn_name_buf: [64]u8 = undefined; |
| 6268 | 6271 | const float_bits = ty.floatBits(func.target.*); |
| 6269 | 6272 | const fn_name = std.fmt.bufPrint(&fn_name_buf, "{s}f{s}{s}", .{ |
| ... | ... | @@ -6288,12 +6291,12 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6288 | 6291 | |
| 6289 | 6292 | fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6290 | 6293 | const pt = func.pt; |
| 6291 | const mod = pt.zcu; | |
| 6294 | const zcu = pt.zcu; | |
| 6292 | 6295 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6293 | 6296 | const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data; |
| 6294 | 6297 | |
| 6295 | 6298 | const ty = func.typeOfIndex(inst); |
| 6296 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6299 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6297 | 6300 | return func.fail("TODO: `@mulAdd` for vectors", .{}); |
| 6298 | 6301 | } |
| 6299 | 6302 | |
| ... | ... | @@ -6323,16 +6326,16 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6323 | 6326 | |
| 6324 | 6327 | fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6325 | 6328 | const pt = func.pt; |
| 6326 | const mod = pt.zcu; | |
| 6329 | const zcu = pt.zcu; | |
| 6327 | 6330 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6328 | 6331 | |
| 6329 | 6332 | const ty = func.typeOf(ty_op.operand); |
| 6330 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6333 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6331 | 6334 | return func.fail("TODO: `@clz` for vectors", .{}); |
| 6332 | 6335 | } |
| 6333 | 6336 | |
| 6334 | 6337 | const operand = try func.resolveInst(ty_op.operand); |
| 6335 | const int_info = ty.intInfo(mod); | |
| 6338 | const int_info = ty.intInfo(zcu); | |
| 6336 | 6339 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6337 | 6340 | return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits}); |
| 6338 | 6341 | }; |
| ... | ... | @@ -6374,17 +6377,17 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6374 | 6377 | |
| 6375 | 6378 | fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6376 | 6379 | const pt = func.pt; |
| 6377 | const mod = pt.zcu; | |
| 6380 | const zcu = pt.zcu; | |
| 6378 | 6381 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6379 | 6382 | |
| 6380 | 6383 | const ty = func.typeOf(ty_op.operand); |
| 6381 | 6384 | |
| 6382 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6385 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6383 | 6386 | return func.fail("TODO: `@ctz` for vectors", .{}); |
| 6384 | 6387 | } |
| 6385 | 6388 | |
| 6386 | 6389 | const operand = try func.resolveInst(ty_op.operand); |
| 6387 | const int_info = ty.intInfo(mod); | |
| 6390 | const int_info = ty.intInfo(zcu); | |
| 6388 | 6391 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6389 | 6392 | return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits}); |
| 6390 | 6393 | }; |
| ... | ... | @@ -6497,12 +6500,12 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6497 | 6500 | |
| 6498 | 6501 | fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6499 | 6502 | const pt = func.pt; |
| 6500 | const mod = pt.zcu; | |
| 6503 | const zcu = pt.zcu; | |
| 6501 | 6504 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6502 | 6505 | const extra = func.air.extraData(Air.TryPtr, ty_pl.payload); |
| 6503 | 6506 | const err_union_ptr = try func.resolveInst(extra.data.ptr); |
| 6504 | 6507 | const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]); |
| 6505 | const err_union_ty = func.typeOf(extra.data.ptr).childType(mod); | |
| 6508 | const err_union_ty = func.typeOf(extra.data.ptr).childType(zcu); | |
| 6506 | 6509 | const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true); |
| 6507 | 6510 | return func.finishAir(inst, result, &.{extra.data.ptr}); |
| 6508 | 6511 | } |
| ... | ... | @@ -6516,25 +6519,25 @@ fn lowerTry( |
| 6516 | 6519 | operand_is_ptr: bool, |
| 6517 | 6520 | ) InnerError!WValue { |
| 6518 | 6521 | const pt = func.pt; |
| 6519 | const mod = pt.zcu; | |
| 6522 | const zcu = pt.zcu; | |
| 6520 | 6523 | if (operand_is_ptr) { |
| 6521 | 6524 | return func.fail("TODO: lowerTry for pointers", .{}); |
| 6522 | 6525 | } |
| 6523 | 6526 | |
| 6524 | const pl_ty = err_union_ty.errorUnionPayload(mod); | |
| 6525 | const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 6527 | const pl_ty = err_union_ty.errorUnionPayload(zcu); | |
| 6528 | const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 6526 | 6529 | |
| 6527 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 6530 | if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 6528 | 6531 | // Block we can jump out of when error is not set |
| 6529 | 6532 | try func.startBlock(.block, wasm.block_empty); |
| 6530 | 6533 | |
| 6531 | 6534 | // check if the error tag is set for the error union. |
| 6532 | 6535 | try func.emitWValue(err_union); |
| 6533 | 6536 | if (pl_has_bits) { |
| 6534 | const err_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 6537 | const err_offset: u32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 6535 | 6538 | try func.addMemArg(.i32_load16_u, .{ |
| 6536 | 6539 | .offset = err_union.offset() + err_offset, |
| 6537 | .alignment = @intCast(Type.anyerror.abiAlignment(pt).toByteUnits().?), | |
| 6540 | .alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?), | |
| 6538 | 6541 | }); |
| 6539 | 6542 | } |
| 6540 | 6543 | try func.addTag(.i32_eqz); |
| ... | ... | @@ -6556,7 +6559,7 @@ fn lowerTry( |
| 6556 | 6559 | return .none; |
| 6557 | 6560 | } |
| 6558 | 6561 | |
| 6559 | const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); | |
| 6562 | const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | |
| 6560 | 6563 | if (isByRef(pl_ty, pt, func.target.*)) { |
| 6561 | 6564 | return buildPointerOffset(func, err_union, pl_offset, .new); |
| 6562 | 6565 | } |
| ... | ... | @@ -6566,16 +6569,16 @@ fn lowerTry( |
| 6566 | 6569 | |
| 6567 | 6570 | fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6568 | 6571 | const pt = func.pt; |
| 6569 | const mod = pt.zcu; | |
| 6572 | const zcu = pt.zcu; | |
| 6570 | 6573 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6571 | 6574 | |
| 6572 | 6575 | const ty = func.typeOfIndex(inst); |
| 6573 | 6576 | const operand = try func.resolveInst(ty_op.operand); |
| 6574 | 6577 | |
| 6575 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 6578 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 6576 | 6579 | return func.fail("TODO: @byteSwap for vectors", .{}); |
| 6577 | 6580 | } |
| 6578 | const int_info = ty.intInfo(mod); | |
| 6581 | const int_info = ty.intInfo(zcu); | |
| 6579 | 6582 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 6580 | 6583 | return func.fail("TODO: @byteSwap for integers with bitsize {d}", .{int_info.bits}); |
| 6581 | 6584 | }; |
| ... | ... | @@ -6649,15 +6652,15 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6649 | 6652 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6650 | 6653 | |
| 6651 | 6654 | const pt = func.pt; |
| 6652 | const mod = pt.zcu; | |
| 6655 | const zcu = pt.zcu; | |
| 6653 | 6656 | const ty = func.typeOfIndex(inst); |
| 6654 | 6657 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6655 | 6658 | const rhs = try func.resolveInst(bin_op.rhs); |
| 6656 | 6659 | |
| 6657 | if (ty.isUnsignedInt(mod)) { | |
| 6660 | if (ty.isUnsignedInt(zcu)) { | |
| 6658 | 6661 | _ = try func.binOp(lhs, rhs, ty, .div); |
| 6659 | } else if (ty.isSignedInt(mod)) { | |
| 6660 | const int_bits = ty.intInfo(mod).bits; | |
| 6662 | } else if (ty.isSignedInt(zcu)) { | |
| 6663 | const int_bits = ty.intInfo(zcu).bits; | |
| 6661 | 6664 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 6662 | 6665 | return func.fail("TODO: `@divFloor` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits}); |
| 6663 | 6666 | }; |
| ... | ... | @@ -6767,19 +6770,19 @@ fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6767 | 6770 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6768 | 6771 | |
| 6769 | 6772 | const pt = func.pt; |
| 6770 | const mod = pt.zcu; | |
| 6773 | const zcu = pt.zcu; | |
| 6771 | 6774 | const ty = func.typeOfIndex(inst); |
| 6772 | 6775 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6773 | 6776 | const rhs = try func.resolveInst(bin_op.rhs); |
| 6774 | 6777 | |
| 6775 | if (ty.isUnsignedInt(mod)) { | |
| 6778 | if (ty.isUnsignedInt(zcu)) { | |
| 6776 | 6779 | _ = try func.binOp(lhs, rhs, ty, .rem); |
| 6777 | } else if (ty.isSignedInt(mod)) { | |
| 6780 | } else if (ty.isSignedInt(zcu)) { | |
| 6778 | 6781 | // The wasm rem instruction gives the remainder after truncating division (rounding towards |
| 6779 | 6782 | // 0), equivalent to @rem. |
| 6780 | 6783 | // We make use of the fact that: |
| 6781 | 6784 | // @mod(a, b) = @rem(@rem(a, b) + b, b) |
| 6782 | const int_bits = ty.intInfo(mod).bits; | |
| 6785 | const int_bits = ty.intInfo(zcu).bits; | |
| 6783 | 6786 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 6784 | 6787 | return func.fail("TODO: `@mod` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits}); |
| 6785 | 6788 | }; |
| ... | ... | @@ -6802,9 +6805,9 @@ fn airSatMul(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6802 | 6805 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6803 | 6806 | |
| 6804 | 6807 | const pt = func.pt; |
| 6805 | const mod = pt.zcu; | |
| 6808 | const zcu = pt.zcu; | |
| 6806 | 6809 | const ty = func.typeOfIndex(inst); |
| 6807 | const int_info = ty.intInfo(mod); | |
| 6810 | const int_info = ty.intInfo(zcu); | |
| 6808 | 6811 | const is_signed = int_info.signedness == .signed; |
| 6809 | 6812 | |
| 6810 | 6813 | const lhs = try func.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6903,12 +6906,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6903 | 6906 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6904 | 6907 | |
| 6905 | 6908 | const pt = func.pt; |
| 6906 | const mod = pt.zcu; | |
| 6909 | const zcu = pt.zcu; | |
| 6907 | 6910 | const ty = func.typeOfIndex(inst); |
| 6908 | 6911 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6909 | 6912 | const rhs = try func.resolveInst(bin_op.rhs); |
| 6910 | 6913 | |
| 6911 | const int_info = ty.intInfo(mod); | |
| 6914 | const int_info = ty.intInfo(zcu); | |
| 6912 | 6915 | const is_signed = int_info.signedness == .signed; |
| 6913 | 6916 | |
| 6914 | 6917 | if (int_info.bits > 64) { |
| ... | ... | @@ -6950,8 +6953,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6950 | 6953 | |
| 6951 | 6954 | fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue { |
| 6952 | 6955 | const pt = func.pt; |
| 6953 | const mod = pt.zcu; | |
| 6954 | const int_info = ty.intInfo(mod); | |
| 6956 | const zcu = pt.zcu; | |
| 6957 | const int_info = ty.intInfo(zcu); | |
| 6955 | 6958 | const wasm_bits = toWasmBits(int_info.bits).?; |
| 6956 | 6959 | const is_wasm_bits = wasm_bits == int_info.bits; |
| 6957 | 6960 | const ext_ty = if (!is_wasm_bits) try pt.intType(int_info.signedness, wasm_bits) else ty; |
| ... | ... | @@ -7009,9 +7012,9 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7009 | 7012 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7010 | 7013 | |
| 7011 | 7014 | const pt = func.pt; |
| 7012 | const mod = pt.zcu; | |
| 7015 | const zcu = pt.zcu; | |
| 7013 | 7016 | const ty = func.typeOfIndex(inst); |
| 7014 | const int_info = ty.intInfo(mod); | |
| 7017 | const int_info = ty.intInfo(zcu); | |
| 7015 | 7018 | const is_signed = int_info.signedness == .signed; |
| 7016 | 7019 | if (int_info.bits > 64) { |
| 7017 | 7020 | return func.fail("TODO: Saturating shifting left for integers with bitsize '{d}'", .{int_info.bits}); |
| ... | ... | @@ -7130,7 +7133,7 @@ fn callIntrinsic( |
| 7130 | 7133 | |
| 7131 | 7134 | // Always pass over C-ABI |
| 7132 | 7135 | const pt = func.pt; |
| 7133 | const mod = pt.zcu; | |
| 7136 | const zcu = pt.zcu; | |
| 7134 | 7137 | var func_type = try genFunctype(func.gpa, .C, param_types, return_type, pt, func.target.*); |
| 7135 | 7138 | defer func_type.deinit(func.gpa); |
| 7136 | 7139 | const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type); |
| ... | ... | @@ -7148,16 +7151,16 @@ fn callIntrinsic( |
| 7148 | 7151 | // Lower all arguments to the stack before we call our function |
| 7149 | 7152 | for (args, 0..) |arg, arg_i| { |
| 7150 | 7153 | assert(!(want_sret_param and arg == .stack)); |
| 7151 | assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(pt)); | |
| 7154 | assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(zcu)); | |
| 7152 | 7155 | try func.lowerArg(.C, Type.fromInterned(param_types[arg_i]), arg); |
| 7153 | 7156 | } |
| 7154 | 7157 | |
| 7155 | 7158 | // Actually call our intrinsic |
| 7156 | 7159 | try func.addLabel(.call, @intFromEnum(symbol_index)); |
| 7157 | 7160 | |
| 7158 | if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7161 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7159 | 7162 | return .none; |
| 7160 | } else if (return_type.isNoReturn(mod)) { | |
| 7163 | } else if (return_type.isNoReturn(zcu)) { | |
| 7161 | 7164 | try func.addTag(.@"unreachable"); |
| 7162 | 7165 | return .none; |
| 7163 | 7166 | } else if (want_sret_param) { |
| ... | ... | @@ -7184,8 +7187,8 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7184 | 7187 | |
| 7185 | 7188 | fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7186 | 7189 | const pt = func.pt; |
| 7187 | const mod = pt.zcu; | |
| 7188 | const ip = &mod.intern_pool; | |
| 7190 | const zcu = pt.zcu; | |
| 7191 | const ip = &zcu.intern_pool; | |
| 7189 | 7192 | |
| 7190 | 7193 | var arena_allocator = std.heap.ArenaAllocator.init(func.gpa); |
| 7191 | 7194 | defer arena_allocator.deinit(); |
| ... | ... | @@ -7198,9 +7201,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7198 | 7201 | return @intFromEnum(loc.index); |
| 7199 | 7202 | } |
| 7200 | 7203 | |
| 7201 | const int_tag_ty = enum_ty.intTagType(mod); | |
| 7204 | const int_tag_ty = enum_ty.intTagType(zcu); | |
| 7202 | 7205 | |
| 7203 | if (int_tag_ty.bitSize(pt) > 64) { | |
| 7206 | if (int_tag_ty.bitSize(zcu) > 64) { | |
| 7204 | 7207 | return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{}); |
| 7205 | 7208 | } |
| 7206 | 7209 | |
| ... | ... | @@ -7220,7 +7223,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7220 | 7223 | |
| 7221 | 7224 | // TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse. |
| 7222 | 7225 | // generate an if-else chain for each tag value as well as constant. |
| 7223 | const tag_names = enum_ty.enumFields(mod); | |
| 7226 | const tag_names = enum_ty.enumFields(zcu); | |
| 7224 | 7227 | for (0..tag_names.len) |tag_index| { |
| 7225 | 7228 | const tag_name = tag_names.get(ip)[tag_index]; |
| 7226 | 7229 | const tag_name_len = tag_name.length(ip); |
| ... | ... | @@ -7345,15 +7348,15 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7345 | 7348 | |
| 7346 | 7349 | fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7347 | 7350 | const pt = func.pt; |
| 7348 | const mod = pt.zcu; | |
| 7349 | const ip = &mod.intern_pool; | |
| 7351 | const zcu = pt.zcu; | |
| 7352 | const ip = &zcu.intern_pool; | |
| 7350 | 7353 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7351 | 7354 | |
| 7352 | 7355 | const operand = try func.resolveInst(ty_op.operand); |
| 7353 | 7356 | const error_set_ty = ty_op.ty.toType(); |
| 7354 | 7357 | const result = try func.allocLocal(Type.bool); |
| 7355 | 7358 | |
| 7356 | const names = error_set_ty.errorSetNames(mod); | |
| 7359 | const names = error_set_ty.errorSetNames(zcu); | |
| 7357 | 7360 | var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len); |
| 7358 | 7361 | defer values.deinit(); |
| 7359 | 7362 | |
| ... | ... | @@ -7432,12 +7435,12 @@ inline fn useAtomicFeature(func: *const CodeGen) bool { |
| 7432 | 7435 | |
| 7433 | 7436 | fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7434 | 7437 | const pt = func.pt; |
| 7435 | const mod = pt.zcu; | |
| 7438 | const zcu = pt.zcu; | |
| 7436 | 7439 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7437 | 7440 | const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 7438 | 7441 | |
| 7439 | 7442 | const ptr_ty = func.typeOf(extra.ptr); |
| 7440 | const ty = ptr_ty.childType(mod); | |
| 7443 | const ty = ptr_ty.childType(zcu); | |
| 7441 | 7444 | const result_ty = func.typeOfIndex(inst); |
| 7442 | 7445 | |
| 7443 | 7446 | const ptr_operand = try func.resolveInst(extra.ptr); |
| ... | ... | @@ -7451,7 +7454,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7451 | 7454 | try func.emitWValue(ptr_operand); |
| 7452 | 7455 | try func.lowerToStack(expected_val); |
| 7453 | 7456 | try func.lowerToStack(new_val); |
| 7454 | try func.addAtomicMemArg(switch (ty.abiSize(pt)) { | |
| 7457 | try func.addAtomicMemArg(switch (ty.abiSize(zcu)) { | |
| 7455 | 7458 | 1 => .i32_atomic_rmw8_cmpxchg_u, |
| 7456 | 7459 | 2 => .i32_atomic_rmw16_cmpxchg_u, |
| 7457 | 7460 | 4 => .i32_atomic_rmw_cmpxchg, |
| ... | ... | @@ -7459,14 +7462,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7459 | 7462 | else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}), |
| 7460 | 7463 | }, .{ |
| 7461 | 7464 | .offset = ptr_operand.offset(), |
| 7462 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 7465 | .alignment = @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 7463 | 7466 | }); |
| 7464 | 7467 | try func.addLabel(.local_tee, val_local.local.value); |
| 7465 | 7468 | _ = try func.cmp(.stack, expected_val, ty, .eq); |
| 7466 | 7469 | try func.addLabel(.local_set, cmp_result.local.value); |
| 7467 | 7470 | break :val val_local; |
| 7468 | 7471 | } else val: { |
| 7469 | if (ty.abiSize(pt) > 8) { | |
| 7472 | if (ty.abiSize(zcu) > 8) { | |
| 7470 | 7473 | return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{}); |
| 7471 | 7474 | } |
| 7472 | 7475 | const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty); |
| ... | ... | @@ -7490,7 +7493,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7490 | 7493 | try func.addTag(.i32_and); |
| 7491 | 7494 | const and_result = try WValue.toLocal(.stack, func, Type.bool); |
| 7492 | 7495 | const result_ptr = try func.allocStack(result_ty); |
| 7493 | try func.store(result_ptr, and_result, Type.bool, @as(u32, @intCast(ty.abiSize(pt)))); | |
| 7496 | try func.store(result_ptr, and_result, Type.bool, @as(u32, @intCast(ty.abiSize(zcu)))); | |
| 7494 | 7497 | try func.store(result_ptr, ptr_val, ty, 0); |
| 7495 | 7498 | break :val result_ptr; |
| 7496 | 7499 | } else val: { |
| ... | ... | @@ -7511,7 +7514,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7511 | 7514 | const ty = func.typeOfIndex(inst); |
| 7512 | 7515 | |
| 7513 | 7516 | if (func.useAtomicFeature()) { |
| 7514 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) { | |
| 7517 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt.zcu)) { | |
| 7515 | 7518 | 1 => .i32_atomic_load8_u, |
| 7516 | 7519 | 2 => .i32_atomic_load16_u, |
| 7517 | 7520 | 4 => .i32_atomic_load, |
| ... | ... | @@ -7521,7 +7524,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7521 | 7524 | try func.emitWValue(ptr); |
| 7522 | 7525 | try func.addAtomicMemArg(tag, .{ |
| 7523 | 7526 | .offset = ptr.offset(), |
| 7524 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 7527 | .alignment = @intCast(ty.abiAlignment(pt.zcu).toByteUnits().?), | |
| 7525 | 7528 | }); |
| 7526 | 7529 | } else { |
| 7527 | 7530 | _ = try func.load(ptr, ty, 0); |
| ... | ... | @@ -7532,7 +7535,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7532 | 7535 | |
| 7533 | 7536 | fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7534 | 7537 | const pt = func.pt; |
| 7535 | const mod = pt.zcu; | |
| 7538 | const zcu = pt.zcu; | |
| 7536 | 7539 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 7537 | 7540 | const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 7538 | 7541 | |
| ... | ... | @@ -7556,7 +7559,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7556 | 7559 | try func.emitWValue(ptr); |
| 7557 | 7560 | try func.emitWValue(value); |
| 7558 | 7561 | if (op == .Nand) { |
| 7559 | const wasm_bits = toWasmBits(@intCast(ty.bitSize(pt))).?; | |
| 7562 | const wasm_bits = toWasmBits(@intCast(ty.bitSize(zcu))).?; | |
| 7560 | 7563 | |
| 7561 | 7564 | const and_res = try func.binOp(value, operand, ty, .@"and"); |
| 7562 | 7565 | if (wasm_bits == 32) |
| ... | ... | @@ -7573,7 +7576,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7573 | 7576 | try func.addTag(.select); |
| 7574 | 7577 | } |
| 7575 | 7578 | try func.addAtomicMemArg( |
| 7576 | switch (ty.abiSize(pt)) { | |
| 7579 | switch (ty.abiSize(zcu)) { | |
| 7577 | 7580 | 1 => .i32_atomic_rmw8_cmpxchg_u, |
| 7578 | 7581 | 2 => .i32_atomic_rmw16_cmpxchg_u, |
| 7579 | 7582 | 4 => .i32_atomic_rmw_cmpxchg, |
| ... | ... | @@ -7582,7 +7585,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7582 | 7585 | }, |
| 7583 | 7586 | .{ |
| 7584 | 7587 | .offset = ptr.offset(), |
| 7585 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 7588 | .alignment = @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 7586 | 7589 | }, |
| 7587 | 7590 | ); |
| 7588 | 7591 | const select_res = try func.allocLocal(ty); |
| ... | ... | @@ -7601,7 +7604,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7601 | 7604 | else => { |
| 7602 | 7605 | try func.emitWValue(ptr); |
| 7603 | 7606 | try func.emitWValue(operand); |
| 7604 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) { | |
| 7607 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(zcu)) { | |
| 7605 | 7608 | 1 => switch (op) { |
| 7606 | 7609 | .Xchg => .i32_atomic_rmw8_xchg_u, |
| 7607 | 7610 | .Add => .i32_atomic_rmw8_add_u, |
| ... | ... | @@ -7642,7 +7645,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7642 | 7645 | }; |
| 7643 | 7646 | try func.addAtomicMemArg(tag, .{ |
| 7644 | 7647 | .offset = ptr.offset(), |
| 7645 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 7648 | .alignment = @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 7646 | 7649 | }); |
| 7647 | 7650 | return func.finishAir(inst, .stack, &.{ pl_op.operand, extra.operand }); |
| 7648 | 7651 | }, |
| ... | ... | @@ -7670,7 +7673,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7670 | 7673 | .Xor => .xor, |
| 7671 | 7674 | else => unreachable, |
| 7672 | 7675 | }); |
| 7673 | if (ty.isInt(mod) and (op == .Add or op == .Sub)) { | |
| 7676 | if (ty.isInt(zcu) and (op == .Add or op == .Sub)) { | |
| 7674 | 7677 | _ = try func.wrapOperand(.stack, ty); |
| 7675 | 7678 | } |
| 7676 | 7679 | try func.store(.stack, .stack, ty, ptr.offset()); |
| ... | ... | @@ -7686,7 +7689,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7686 | 7689 | try func.store(.stack, .stack, ty, ptr.offset()); |
| 7687 | 7690 | }, |
| 7688 | 7691 | .Nand => { |
| 7689 | const wasm_bits = toWasmBits(@intCast(ty.bitSize(pt))).?; | |
| 7692 | const wasm_bits = toWasmBits(@intCast(ty.bitSize(zcu))).?; | |
| 7690 | 7693 | |
| 7691 | 7694 | try func.emitWValue(ptr); |
| 7692 | 7695 | const and_res = try func.binOp(result, operand, ty, .@"and"); |
| ... | ... | @@ -7721,16 +7724,16 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7721 | 7724 | |
| 7722 | 7725 | fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7723 | 7726 | const pt = func.pt; |
| 7724 | const mod = pt.zcu; | |
| 7727 | const zcu = pt.zcu; | |
| 7725 | 7728 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7726 | 7729 | |
| 7727 | 7730 | const ptr = try func.resolveInst(bin_op.lhs); |
| 7728 | 7731 | const operand = try func.resolveInst(bin_op.rhs); |
| 7729 | 7732 | const ptr_ty = func.typeOf(bin_op.lhs); |
| 7730 | const ty = ptr_ty.childType(mod); | |
| 7733 | const ty = ptr_ty.childType(zcu); | |
| 7731 | 7734 | |
| 7732 | 7735 | if (func.useAtomicFeature()) { |
| 7733 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(pt)) { | |
| 7736 | const tag: wasm.AtomicsOpcode = switch (ty.abiSize(zcu)) { | |
| 7734 | 7737 | 1 => .i32_atomic_store8, |
| 7735 | 7738 | 2 => .i32_atomic_store16, |
| 7736 | 7739 | 4 => .i32_atomic_store, |
| ... | ... | @@ -7741,7 +7744,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7741 | 7744 | try func.lowerToStack(operand); |
| 7742 | 7745 | try func.addAtomicMemArg(tag, .{ |
| 7743 | 7746 | .offset = ptr.offset(), |
| 7744 | .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?), | |
| 7747 | .alignment = @intCast(ty.abiAlignment(zcu).toByteUnits().?), | |
| 7745 | 7748 | }); |
| 7746 | 7749 | } else { |
| 7747 | 7750 | try func.store(ptr, operand, ty, 0); |
| ... | ... | @@ -7760,12 +7763,12 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7760 | 7763 | |
| 7761 | 7764 | fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type { |
| 7762 | 7765 | const pt = func.pt; |
| 7763 | const mod = pt.zcu; | |
| 7764 | return func.air.typeOf(inst, &mod.intern_pool); | |
| 7766 | const zcu = pt.zcu; | |
| 7767 | return func.air.typeOf(inst, &zcu.intern_pool); | |
| 7765 | 7768 | } |
| 7766 | 7769 | |
| 7767 | 7770 | fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type { |
| 7768 | 7771 | const pt = func.pt; |
| 7769 | const mod = pt.zcu; | |
| 7770 | return func.air.typeOfIndex(inst, &mod.intern_pool); | |
| 7772 | const zcu = pt.zcu; | |
| 7773 | return func.air.typeOfIndex(inst, &zcu.intern_pool); | |
| 7771 | 7774 | } |
src/arch/wasm/abi.zig+27-29| ... | ... | @@ -22,16 +22,15 @@ const direct: [2]Class = .{ .direct, .none }; |
| 22 | 22 | /// Classifies a given Zig type to determine how they must be passed |
| 23 | 23 | /// or returned as value within a wasm function. |
| 24 | 24 | /// When all elements result in `.none`, no value must be passed in or returned. |
| 25 | pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class { | |
| 26 | const mod = pt.zcu; | |
| 27 | const ip = &mod.intern_pool; | |
| 28 | const target = mod.getTarget(); | |
| 29 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return none; | |
| 30 | switch (ty.zigTypeTag(mod)) { | |
| 25 | pub fn classifyType(ty: Type, zcu: *Zcu) [2]Class { | |
| 26 | const ip = &zcu.intern_pool; | |
| 27 | const target = zcu.getTarget(); | |
| 28 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return none; | |
| 29 | switch (ty.zigTypeTag(zcu)) { | |
| 31 | 30 | .Struct => { |
| 32 | const struct_type = pt.zcu.typeToStruct(ty).?; | |
| 31 | const struct_type = zcu.typeToStruct(ty).?; | |
| 33 | 32 | if (struct_type.layout == .@"packed") { |
| 34 | if (ty.bitSize(pt) <= 64) return direct; | |
| 33 | if (ty.bitSize(zcu) <= 64) return direct; | |
| 35 | 34 | return .{ .direct, .direct }; |
| 36 | 35 | } |
| 37 | 36 | if (struct_type.field_types.len > 1) { |
| ... | ... | @@ -41,13 +40,13 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class { |
| 41 | 40 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]); |
| 42 | 41 | const explicit_align = struct_type.fieldAlign(ip, 0); |
| 43 | 42 | if (explicit_align != .none) { |
| 44 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(pt))) | |
| 43 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu))) | |
| 45 | 44 | return memory; |
| 46 | 45 | } |
| 47 | return classifyType(field_ty, pt); | |
| 46 | return classifyType(field_ty, zcu); | |
| 48 | 47 | }, |
| 49 | 48 | .Int, .Enum, .ErrorSet => { |
| 50 | const int_bits = ty.intInfo(pt.zcu).bits; | |
| 49 | const int_bits = ty.intInfo(zcu).bits; | |
| 51 | 50 | if (int_bits <= 64) return direct; |
| 52 | 51 | if (int_bits <= 128) return .{ .direct, .direct }; |
| 53 | 52 | return memory; |
| ... | ... | @@ -62,24 +61,24 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class { |
| 62 | 61 | .Vector => return direct, |
| 63 | 62 | .Array => return memory, |
| 64 | 63 | .Optional => { |
| 65 | assert(ty.isPtrLikeOptional(pt.zcu)); | |
| 64 | assert(ty.isPtrLikeOptional(zcu)); | |
| 66 | 65 | return direct; |
| 67 | 66 | }, |
| 68 | 67 | .Pointer => { |
| 69 | assert(!ty.isSlice(pt.zcu)); | |
| 68 | assert(!ty.isSlice(zcu)); | |
| 70 | 69 | return direct; |
| 71 | 70 | }, |
| 72 | 71 | .Union => { |
| 73 | const union_obj = pt.zcu.typeToUnion(ty).?; | |
| 72 | const union_obj = zcu.typeToUnion(ty).?; | |
| 74 | 73 | if (union_obj.flagsUnordered(ip).layout == .@"packed") { |
| 75 | if (ty.bitSize(pt) <= 64) return direct; | |
| 74 | if (ty.bitSize(zcu) <= 64) return direct; | |
| 76 | 75 | return .{ .direct, .direct }; |
| 77 | 76 | } |
| 78 | const layout = ty.unionGetLayout(pt); | |
| 77 | const layout = ty.unionGetLayout(zcu); | |
| 79 | 78 | assert(layout.tag_size == 0); |
| 80 | 79 | if (union_obj.field_types.len > 1) return memory; |
| 81 | 80 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 82 | return classifyType(first_field_ty, pt); | |
| 81 | return classifyType(first_field_ty, zcu); | |
| 83 | 82 | }, |
| 84 | 83 | .ErrorUnion, |
| 85 | 84 | .Frame, |
| ... | ... | @@ -101,29 +100,28 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class { |
| 101 | 100 | /// Returns the scalar type a given type can represent. |
| 102 | 101 | /// Asserts given type can be represented as scalar, such as |
| 103 | 102 | /// a struct with a single scalar field. |
| 104 | pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type { | |
| 105 | const mod = pt.zcu; | |
| 106 | const ip = &mod.intern_pool; | |
| 107 | switch (ty.zigTypeTag(mod)) { | |
| 103 | pub fn scalarType(ty: Type, zcu: *Zcu) Type { | |
| 104 | const ip = &zcu.intern_pool; | |
| 105 | switch (ty.zigTypeTag(zcu)) { | |
| 108 | 106 | .Struct => { |
| 109 | if (mod.typeToPackedStruct(ty)) |packed_struct| { | |
| 110 | return scalarType(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt); | |
| 107 | if (zcu.typeToPackedStruct(ty)) |packed_struct| { | |
| 108 | return scalarType(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), zcu); | |
| 111 | 109 | } else { |
| 112 | assert(ty.structFieldCount(mod) == 1); | |
| 113 | return scalarType(ty.structFieldType(0, mod), pt); | |
| 110 | assert(ty.structFieldCount(zcu) == 1); | |
| 111 | return scalarType(ty.structFieldType(0, zcu), zcu); | |
| 114 | 112 | } |
| 115 | 113 | }, |
| 116 | 114 | .Union => { |
| 117 | const union_obj = mod.typeToUnion(ty).?; | |
| 115 | const union_obj = zcu.typeToUnion(ty).?; | |
| 118 | 116 | if (union_obj.flagsUnordered(ip).layout != .@"packed") { |
| 119 | const layout = pt.getUnionLayout(union_obj); | |
| 117 | const layout = Type.getUnionLayout(union_obj, zcu); | |
| 120 | 118 | if (layout.payload_size == 0 and layout.tag_size != 0) { |
| 121 | return scalarType(ty.unionTagTypeSafety(mod).?, pt); | |
| 119 | return scalarType(ty.unionTagTypeSafety(zcu).?, zcu); | |
| 122 | 120 | } |
| 123 | 121 | assert(union_obj.field_types.len == 1); |
| 124 | 122 | } |
| 125 | 123 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 126 | return scalarType(first_field_ty, pt); | |
| 124 | return scalarType(first_field_ty, zcu); | |
| 127 | 125 | }, |
| 128 | 126 | else => return ty, |
| 129 | 127 | } |
src/arch/x86_64/CodeGen.zig+726-722| ... | ... | @@ -732,14 +732,14 @@ const FrameAlloc = struct { |
| 732 | 732 | .ref_count = 0, |
| 733 | 733 | }; |
| 734 | 734 | } |
| 735 | fn initType(ty: Type, pt: Zcu.PerThread) FrameAlloc { | |
| 735 | fn initType(ty: Type, zcu: *Zcu) FrameAlloc { | |
| 736 | 736 | return init(.{ |
| 737 | .size = ty.abiSize(pt), | |
| 738 | .alignment = ty.abiAlignment(pt), | |
| 737 | .size = ty.abiSize(zcu), | |
| 738 | .alignment = ty.abiAlignment(zcu), | |
| 739 | 739 | }); |
| 740 | 740 | } |
| 741 | fn initSpill(ty: Type, pt: Zcu.PerThread) FrameAlloc { | |
| 742 | const abi_size = ty.abiSize(pt); | |
| 741 | fn initSpill(ty: Type, zcu: *Zcu) FrameAlloc { | |
| 742 | const abi_size = ty.abiSize(zcu); | |
| 743 | 743 | const spill_size = if (abi_size < 8) |
| 744 | 744 | math.ceilPowerOfTwoAssert(u64, abi_size) |
| 745 | 745 | else |
| ... | ... | @@ -747,7 +747,7 @@ const FrameAlloc = struct { |
| 747 | 747 | return init(.{ |
| 748 | 748 | .size = spill_size, |
| 749 | 749 | .pad = @intCast(spill_size - abi_size), |
| 750 | .alignment = ty.abiAlignment(pt).maxStrict( | |
| 750 | .alignment = ty.abiAlignment(zcu).maxStrict( | |
| 751 | 751 | Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), |
| 752 | 752 | ), |
| 753 | 753 | }); |
| ... | ... | @@ -756,7 +756,7 @@ const FrameAlloc = struct { |
| 756 | 756 | |
| 757 | 757 | const StackAllocation = struct { |
| 758 | 758 | inst: ?Air.Inst.Index, |
| 759 | /// TODO do we need size? should be determined by inst.ty.abiSize(pt) | |
| 759 | /// TODO do we need size? should be determined by inst.ty.abiSize(zcu) | |
| 760 | 760 | size: u32, |
| 761 | 761 | }; |
| 762 | 762 | |
| ... | ... | @@ -859,11 +859,11 @@ pub fn generate( |
| 859 | 859 | function.args = call_info.args; |
| 860 | 860 | function.ret_mcv = call_info.return_value; |
| 861 | 861 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ |
| 862 | .size = Type.usize.abiSize(pt), | |
| 863 | .alignment = Type.usize.abiAlignment(pt).min(call_info.stack_align), | |
| 862 | .size = Type.usize.abiSize(zcu), | |
| 863 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), | |
| 864 | 864 | })); |
| 865 | 865 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ |
| 866 | .size = Type.usize.abiSize(pt), | |
| 866 | .size = Type.usize.abiSize(zcu), | |
| 867 | 867 | .alignment = Alignment.min( |
| 868 | 868 | call_info.stack_align, |
| 869 | 869 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), |
| ... | ... | @@ -1872,8 +1872,8 @@ fn asmMemoryRegisterImmediate( |
| 1872 | 1872 | |
| 1873 | 1873 | fn gen(self: *Self) InnerError!void { |
| 1874 | 1874 | const pt = self.pt; |
| 1875 | const mod = pt.zcu; | |
| 1876 | const fn_info = mod.typeToFunc(self.fn_type).?; | |
| 1875 | const zcu = pt.zcu; | |
| 1876 | const fn_info = zcu.typeToFunc(self.fn_type).?; | |
| 1877 | 1877 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); |
| 1878 | 1878 | if (cc != .Naked) { |
| 1879 | 1879 | try self.asmRegister(.{ ._, .push }, .rbp); |
| ... | ... | @@ -1890,7 +1890,7 @@ fn gen(self: *Self) InnerError!void { |
| 1890 | 1890 | // The address where to store the return value for the caller is in a |
| 1891 | 1891 | // register which the callee is free to clobber. Therefore, we purposely |
| 1892 | 1892 | // spill it to stack immediately. |
| 1893 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, pt)); | |
| 1893 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, zcu)); | |
| 1894 | 1894 | try self.genSetMem( |
| 1895 | 1895 | .{ .frame = frame_index }, |
| 1896 | 1896 | 0, |
| ... | ... | @@ -2099,8 +2099,8 @@ fn checkInvariantsAfterAirInst(self: *Self, inst: Air.Inst.Index, old_air_bookke |
| 2099 | 2099 | |
| 2100 | 2100 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2101 | 2101 | const pt = self.pt; |
| 2102 | const mod = pt.zcu; | |
| 2103 | const ip = &mod.intern_pool; | |
| 2102 | const zcu = pt.zcu; | |
| 2103 | const ip = &zcu.intern_pool; | |
| 2104 | 2104 | const air_tags = self.air.instructions.items(.tag); |
| 2105 | 2105 | |
| 2106 | 2106 | self.arg_index = 0; |
| ... | ... | @@ -2370,9 +2370,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2370 | 2370 | |
| 2371 | 2371 | fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2372 | 2372 | const pt = self.pt; |
| 2373 | const mod = pt.zcu; | |
| 2374 | const ip = &mod.intern_pool; | |
| 2375 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(mod)) { | |
| 2373 | const zcu = pt.zcu; | |
| 2374 | const ip = &zcu.intern_pool; | |
| 2375 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) { | |
| 2376 | 2376 | .Enum => { |
| 2377 | 2377 | const enum_ty = Type.fromInterned(lazy_sym.ty); |
| 2378 | 2378 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); |
| ... | ... | @@ -2385,7 +2385,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2385 | 2385 | const ret_reg = param_regs[0]; |
| 2386 | 2386 | const enum_mcv = MCValue{ .register = param_regs[1] }; |
| 2387 | 2387 | |
| 2388 | const exitlude_jump_relocs = try self.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(mod)); | |
| 2388 | const exitlude_jump_relocs = try self.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(zcu)); | |
| 2389 | 2389 | defer self.gpa.free(exitlude_jump_relocs); |
| 2390 | 2390 | |
| 2391 | 2391 | const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | ... | @@ -2394,7 +2394,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2394 | 2394 | try self.genLazySymbolRef(.lea, data_reg, .{ .kind = .const_data, .ty = enum_ty.toIntern() }); |
| 2395 | 2395 | |
| 2396 | 2396 | var data_off: i32 = 0; |
| 2397 | const tag_names = enum_ty.enumFields(mod); | |
| 2397 | const tag_names = enum_ty.enumFields(zcu); | |
| 2398 | 2398 | for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| { |
| 2399 | 2399 | const tag_name_len = tag_names.get(ip)[tag_index].length(ip); |
| 2400 | 2400 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| ... | ... | @@ -2630,14 +2630,14 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex { |
| 2630 | 2630 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 2631 | 2631 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { |
| 2632 | 2632 | const pt = self.pt; |
| 2633 | const mod = pt.zcu; | |
| 2633 | const zcu = pt.zcu; | |
| 2634 | 2634 | const ptr_ty = self.typeOfIndex(inst); |
| 2635 | const val_ty = ptr_ty.childType(mod); | |
| 2635 | const val_ty = ptr_ty.childType(zcu); | |
| 2636 | 2636 | return self.allocFrameIndex(FrameAlloc.init(.{ |
| 2637 | .size = math.cast(u32, val_ty.abiSize(pt)) orelse { | |
| 2637 | .size = math.cast(u32, val_ty.abiSize(zcu)) orelse { | |
| 2638 | 2638 | return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)}); |
| 2639 | 2639 | }, |
| 2640 | .alignment = ptr_ty.ptrAlignment(pt).max(.@"1"), | |
| 2640 | .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"), | |
| 2641 | 2641 | })); |
| 2642 | 2642 | } |
| 2643 | 2643 | |
| ... | ... | @@ -2651,20 +2651,20 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue { |
| 2651 | 2651 | |
| 2652 | 2652 | fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue { |
| 2653 | 2653 | const pt = self.pt; |
| 2654 | const mod = pt.zcu; | |
| 2655 | const abi_size = math.cast(u32, ty.abiSize(pt)) orelse { | |
| 2654 | const zcu = pt.zcu; | |
| 2655 | const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse { | |
| 2656 | 2656 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)}); |
| 2657 | 2657 | }; |
| 2658 | 2658 | |
| 2659 | 2659 | if (reg_ok) need_mem: { |
| 2660 | if (abi_size <= @as(u32, switch (ty.zigTypeTag(mod)) { | |
| 2660 | if (abi_size <= @as(u32, switch (ty.zigTypeTag(zcu)) { | |
| 2661 | 2661 | .Float => switch (ty.floatBits(self.target.*)) { |
| 2662 | 2662 | 16, 32, 64, 128 => 16, |
| 2663 | 2663 | 80 => break :need_mem, |
| 2664 | 2664 | else => unreachable, |
| 2665 | 2665 | }, |
| 2666 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 2667 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 2666 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 2667 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 2668 | 2668 | 16, 32, 64, 128 => if (self.hasFeature(.avx)) 32 else 16, |
| 2669 | 2669 | 80 => break :need_mem, |
| 2670 | 2670 | else => unreachable, |
| ... | ... | @@ -2679,21 +2679,21 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b |
| 2679 | 2679 | } |
| 2680 | 2680 | } |
| 2681 | 2681 | |
| 2682 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, pt)); | |
| 2682 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, zcu)); | |
| 2683 | 2683 | return .{ .load_frame = .{ .index = frame_index } }; |
| 2684 | 2684 | } |
| 2685 | 2685 | |
| 2686 | 2686 | fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet { |
| 2687 | 2687 | const pt = self.pt; |
| 2688 | const mod = pt.zcu; | |
| 2689 | return switch (ty.zigTypeTag(mod)) { | |
| 2688 | const zcu = pt.zcu; | |
| 2689 | return switch (ty.zigTypeTag(zcu)) { | |
| 2690 | 2690 | .Float => switch (ty.floatBits(self.target.*)) { |
| 2691 | 2691 | 80 => abi.RegisterClass.x87, |
| 2692 | 2692 | else => abi.RegisterClass.sse, |
| 2693 | 2693 | }, |
| 2694 | .Vector => switch (ty.childType(mod).toIntern()) { | |
| 2694 | .Vector => switch (ty.childType(zcu).toIntern()) { | |
| 2695 | 2695 | .bool_type, .u1_type => abi.RegisterClass.gp, |
| 2696 | else => if (ty.isAbiInt(mod) and ty.intInfo(mod).bits == 1) | |
| 2696 | else => if (ty.isAbiInt(zcu) and ty.intInfo(zcu).bits == 1) | |
| 2697 | 2697 | abi.RegisterClass.gp |
| 2698 | 2698 | else |
| 2699 | 2699 | abi.RegisterClass.sse, |
| ... | ... | @@ -3001,13 +3001,13 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3001 | 3001 | |
| 3002 | 3002 | fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 3003 | 3003 | const pt = self.pt; |
| 3004 | const mod = pt.zcu; | |
| 3004 | const zcu = pt.zcu; | |
| 3005 | 3005 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3006 | 3006 | const dst_ty = self.typeOfIndex(inst); |
| 3007 | const dst_scalar_ty = dst_ty.scalarType(mod); | |
| 3007 | const dst_scalar_ty = dst_ty.scalarType(zcu); | |
| 3008 | 3008 | const dst_bits = dst_scalar_ty.floatBits(self.target.*); |
| 3009 | 3009 | const src_ty = self.typeOf(ty_op.operand); |
| 3010 | const src_scalar_ty = src_ty.scalarType(mod); | |
| 3010 | const src_scalar_ty = src_ty.scalarType(zcu); | |
| 3011 | 3011 | const src_bits = src_scalar_ty.floatBits(self.target.*); |
| 3012 | 3012 | |
| 3013 | 3013 | const result = result: { |
| ... | ... | @@ -3032,7 +3032,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 3032 | 3032 | }, |
| 3033 | 3033 | else => unreachable, |
| 3034 | 3034 | }) { |
| 3035 | if (dst_ty.isVector(mod)) break :result null; | |
| 3035 | if (dst_ty.isVector(zcu)) break :result null; | |
| 3036 | 3036 | var callee_buf: ["__extend?f?f2".len]u8 = undefined; |
| 3037 | 3037 | break :result try self.genCall(.{ .lib = .{ |
| 3038 | 3038 | .return_type = self.floatCompilerRtAbiType(dst_scalar_ty, src_scalar_ty).toIntern(), |
| ... | ... | @@ -3044,18 +3044,18 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 3044 | 3044 | } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }}); |
| 3045 | 3045 | } |
| 3046 | 3046 | |
| 3047 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 3047 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 3048 | 3048 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 3049 | 3049 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 3050 | 3050 | src_mcv |
| 3051 | 3051 | else |
| 3052 | 3052 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 3053 | 3053 | const dst_reg = dst_mcv.getReg().?; |
| 3054 | const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(pt), 16))); | |
| 3054 | const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(zcu), 16))); | |
| 3055 | 3055 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 3056 | 3056 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 3057 | 3057 | |
| 3058 | const vec_len = if (dst_ty.isVector(mod)) dst_ty.vectorLen(mod) else 1; | |
| 3058 | const vec_len = if (dst_ty.isVector(zcu)) dst_ty.vectorLen(zcu) else 1; | |
| 3059 | 3059 | if (src_bits == 16) { |
| 3060 | 3060 | assert(self.hasFeature(.f16c)); |
| 3061 | 3061 | const mat_src_reg = if (src_mcv.isRegister()) |
| ... | ... | @@ -3137,30 +3137,30 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 3137 | 3137 | |
| 3138 | 3138 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 3139 | 3139 | const pt = self.pt; |
| 3140 | const mod = pt.zcu; | |
| 3140 | const zcu = pt.zcu; | |
| 3141 | 3141 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3142 | 3142 | const src_ty = self.typeOf(ty_op.operand); |
| 3143 | 3143 | const dst_ty = self.typeOfIndex(inst); |
| 3144 | 3144 | |
| 3145 | 3145 | const result = @as(?MCValue, result: { |
| 3146 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 3146 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 3147 | 3147 | |
| 3148 | const src_int_info = src_ty.intInfo(mod); | |
| 3149 | const dst_int_info = dst_ty.intInfo(mod); | |
| 3148 | const src_int_info = src_ty.intInfo(zcu); | |
| 3149 | const dst_int_info = dst_ty.intInfo(zcu); | |
| 3150 | 3150 | const extend = switch (src_int_info.signedness) { |
| 3151 | 3151 | .signed => dst_int_info, |
| 3152 | 3152 | .unsigned => src_int_info, |
| 3153 | 3153 | }.signedness; |
| 3154 | 3154 | |
| 3155 | 3155 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 3156 | if (dst_ty.isVector(mod)) { | |
| 3157 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 3156 | if (dst_ty.isVector(zcu)) { | |
| 3157 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 3158 | 3158 | const max_abi_size = @max(dst_abi_size, src_abi_size); |
| 3159 | 3159 | if (max_abi_size > @as(u32, if (self.hasFeature(.avx2)) 32 else 16)) break :result null; |
| 3160 | 3160 | const has_avx = self.hasFeature(.avx); |
| 3161 | 3161 | |
| 3162 | const dst_elem_abi_size = dst_ty.childType(mod).abiSize(pt); | |
| 3163 | const src_elem_abi_size = src_ty.childType(mod).abiSize(pt); | |
| 3162 | const dst_elem_abi_size = dst_ty.childType(zcu).abiSize(zcu); | |
| 3163 | const src_elem_abi_size = src_ty.childType(zcu).abiSize(zcu); | |
| 3164 | 3164 | switch (math.order(dst_elem_abi_size, src_elem_abi_size)) { |
| 3165 | 3165 | .lt => { |
| 3166 | 3166 | const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) { |
| ... | ... | @@ -3396,13 +3396,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 3396 | 3396 | |
| 3397 | 3397 | fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3398 | 3398 | const pt = self.pt; |
| 3399 | const mod = pt.zcu; | |
| 3399 | const zcu = pt.zcu; | |
| 3400 | 3400 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3401 | 3401 | |
| 3402 | 3402 | const dst_ty = self.typeOfIndex(inst); |
| 3403 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 3403 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 3404 | 3404 | const src_ty = self.typeOf(ty_op.operand); |
| 3405 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 3405 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 3406 | 3406 | |
| 3407 | 3407 | const result = result: { |
| 3408 | 3408 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | ... | @@ -3414,7 +3414,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3414 | 3414 | src_mcv |
| 3415 | 3415 | else if (dst_abi_size <= 8) |
| 3416 | 3416 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv) |
| 3417 | else if (dst_abi_size <= 16 and !dst_ty.isVector(mod)) dst: { | |
| 3417 | else if (dst_abi_size <= 16 and !dst_ty.isVector(zcu)) dst: { | |
| 3418 | 3418 | const dst_regs = |
| 3419 | 3419 | try self.register_manager.allocRegs(2, .{ inst, inst }, abi.RegisterClass.gp); |
| 3420 | 3420 | const dst_mcv: MCValue = .{ .register_pair = dst_regs }; |
| ... | ... | @@ -3429,16 +3429,16 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3429 | 3429 | break :dst dst_mcv; |
| 3430 | 3430 | }; |
| 3431 | 3431 | |
| 3432 | if (dst_ty.zigTypeTag(mod) == .Vector) { | |
| 3433 | assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod)); | |
| 3434 | const dst_elem_ty = dst_ty.childType(mod); | |
| 3435 | const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(pt)); | |
| 3436 | const src_elem_ty = src_ty.childType(mod); | |
| 3437 | const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(pt)); | |
| 3432 | if (dst_ty.zigTypeTag(zcu) == .Vector) { | |
| 3433 | assert(src_ty.zigTypeTag(zcu) == .Vector and dst_ty.vectorLen(zcu) == src_ty.vectorLen(zcu)); | |
| 3434 | const dst_elem_ty = dst_ty.childType(zcu); | |
| 3435 | const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(zcu)); | |
| 3436 | const src_elem_ty = src_ty.childType(zcu); | |
| 3437 | const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(zcu)); | |
| 3438 | 3438 | |
| 3439 | 3439 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_elem_abi_size) { |
| 3440 | 3440 | 1 => switch (src_elem_abi_size) { |
| 3441 | 2 => switch (dst_ty.vectorLen(mod)) { | |
| 3441 | 2 => switch (dst_ty.vectorLen(zcu)) { | |
| 3442 | 3442 | 1...8 => if (self.hasFeature(.avx)) .{ .vp_b, .ackusw } else .{ .p_b, .ackusw }, |
| 3443 | 3443 | 9...16 => if (self.hasFeature(.avx2)) .{ .vp_b, .ackusw } else null, |
| 3444 | 3444 | else => null, |
| ... | ... | @@ -3446,7 +3446,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3446 | 3446 | else => null, |
| 3447 | 3447 | }, |
| 3448 | 3448 | 2 => switch (src_elem_abi_size) { |
| 3449 | 4 => switch (dst_ty.vectorLen(mod)) { | |
| 3449 | 4 => switch (dst_ty.vectorLen(zcu)) { | |
| 3450 | 3450 | 1...4 => if (self.hasFeature(.avx)) |
| 3451 | 3451 | .{ .vp_w, .ackusd } |
| 3452 | 3452 | else if (self.hasFeature(.sse4_1)) |
| ... | ... | @@ -3461,8 +3461,8 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3461 | 3461 | else => null, |
| 3462 | 3462 | }) orelse return self.fail("TODO implement airTrunc for {}", .{dst_ty.fmt(pt)}); |
| 3463 | 3463 | |
| 3464 | const dst_info = dst_elem_ty.intInfo(mod); | |
| 3465 | const src_info = src_elem_ty.intInfo(mod); | |
| 3464 | const dst_info = dst_elem_ty.intInfo(zcu); | |
| 3465 | const src_info = src_elem_ty.intInfo(zcu); | |
| 3466 | 3466 | |
| 3467 | 3467 | const mask_val = try pt.intValue(src_elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(64 - dst_info.bits)); |
| 3468 | 3468 | |
| ... | ... | @@ -3470,7 +3470,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3470 | 3470 | .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)), |
| 3471 | 3471 | .child = src_elem_ty.ip_index, |
| 3472 | 3472 | }); |
| 3473 | const splat_abi_size: u32 = @intCast(splat_ty.abiSize(pt)); | |
| 3473 | const splat_abi_size: u32 = @intCast(splat_ty.abiSize(zcu)); | |
| 3474 | 3474 | |
| 3475 | 3475 | const splat_val = try pt.intern(.{ .aggregate = .{ |
| 3476 | 3476 | .ty = splat_ty.ip_index, |
| ... | ... | @@ -3528,7 +3528,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3528 | 3528 | try self.truncateRegister(dst_ty, dst_mcv.register.to64()); |
| 3529 | 3529 | } |
| 3530 | 3530 | } else if (dst_abi_size <= 16) { |
| 3531 | const dst_info = dst_ty.intInfo(mod); | |
| 3531 | const dst_info = dst_ty.intInfo(zcu); | |
| 3532 | 3532 | const high_ty = try pt.intType(dst_info.signedness, dst_info.bits - 64); |
| 3533 | 3533 | if (self.regExtraBits(high_ty) > 0) { |
| 3534 | 3534 | try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); |
| ... | ... | @@ -3554,12 +3554,12 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 3554 | 3554 | } |
| 3555 | 3555 | |
| 3556 | 3556 | fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3557 | const pt = self.pt; | |
| 3557 | const zcu = self.pt.zcu; | |
| 3558 | 3558 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3559 | 3559 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3560 | 3560 | |
| 3561 | 3561 | const slice_ty = self.typeOfIndex(inst); |
| 3562 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); | |
| 3562 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | |
| 3563 | 3563 | |
| 3564 | 3564 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3565 | 3565 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); |
| ... | ... | @@ -3567,7 +3567,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3567 | 3567 | const len_ty = self.typeOf(bin_op.rhs); |
| 3568 | 3568 | try self.genSetMem( |
| 3569 | 3569 | .{ .frame = frame_index }, |
| 3570 | @intCast(ptr_ty.abiSize(pt)), | |
| 3570 | @intCast(ptr_ty.abiSize(zcu)), | |
| 3571 | 3571 | len_ty, |
| 3572 | 3572 | .{ .air_ref = bin_op.rhs }, |
| 3573 | 3573 | .{}, |
| ... | ... | @@ -3585,14 +3585,14 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3585 | 3585 | |
| 3586 | 3586 | fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3587 | 3587 | const pt = self.pt; |
| 3588 | const mod = pt.zcu; | |
| 3588 | const zcu = pt.zcu; | |
| 3589 | 3589 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3590 | 3590 | const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); |
| 3591 | 3591 | |
| 3592 | 3592 | const dst_ty = self.typeOfIndex(inst); |
| 3593 | if (dst_ty.isAbiInt(mod)) { | |
| 3594 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 3595 | const bit_size: u32 = @intCast(dst_ty.bitSize(pt)); | |
| 3593 | if (dst_ty.isAbiInt(zcu)) { | |
| 3594 | const abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 3595 | const bit_size: u32 = @intCast(dst_ty.bitSize(zcu)); | |
| 3596 | 3596 | if (abi_size * 8 > bit_size) { |
| 3597 | 3597 | const dst_lock = switch (dst_mcv) { |
| 3598 | 3598 | .register => |dst_reg| self.register_manager.lockRegAssumeUnused(dst_reg), |
| ... | ... | @@ -3607,7 +3607,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3607 | 3607 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3608 | 3608 | defer self.register_manager.unlockReg(tmp_lock); |
| 3609 | 3609 | |
| 3610 | const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(pt) - 1) % 64 + 1)); | |
| 3610 | const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(zcu) - 1) % 64 + 1)); | |
| 3611 | 3611 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 3612 | 3612 | try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{}); |
| 3613 | 3613 | try self.truncateRegister(dst_ty, tmp_reg); |
| ... | ... | @@ -3627,17 +3627,17 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void |
| 3627 | 3627 | |
| 3628 | 3628 | fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3629 | 3629 | const pt = self.pt; |
| 3630 | const mod = pt.zcu; | |
| 3630 | const zcu = pt.zcu; | |
| 3631 | 3631 | const air_tag = self.air.instructions.items(.tag); |
| 3632 | 3632 | const air_data = self.air.instructions.items(.data); |
| 3633 | 3633 | |
| 3634 | 3634 | const dst_ty = self.typeOf(dst_air); |
| 3635 | const dst_info = dst_ty.intInfo(mod); | |
| 3635 | const dst_info = dst_ty.intInfo(zcu); | |
| 3636 | 3636 | if (dst_air.toIndex()) |inst| { |
| 3637 | 3637 | switch (air_tag[@intFromEnum(inst)]) { |
| 3638 | 3638 | .intcast => { |
| 3639 | 3639 | const src_ty = self.typeOf(air_data[@intFromEnum(inst)].ty_op.operand); |
| 3640 | const src_info = src_ty.intInfo(mod); | |
| 3640 | const src_info = src_ty.intInfo(zcu); | |
| 3641 | 3641 | return @min(switch (src_info.signedness) { |
| 3642 | 3642 | .signed => switch (dst_info.signedness) { |
| 3643 | 3643 | .signed => src_info.bits, |
| ... | ... | @@ -3653,7 +3653,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3653 | 3653 | } |
| 3654 | 3654 | } else if (dst_air.toInterned()) |ip_index| { |
| 3655 | 3655 | var space: Value.BigIntSpace = undefined; |
| 3656 | const src_int = Value.fromInterned(ip_index).toBigInt(&space, pt); | |
| 3656 | const src_int = Value.fromInterned(ip_index).toBigInt(&space, zcu); | |
| 3657 | 3657 | return @as(u16, @intCast(src_int.bitCountTwosComp())) + |
| 3658 | 3658 | @intFromBool(src_int.positive and dst_info.signedness == .signed); |
| 3659 | 3659 | } |
| ... | ... | @@ -3662,18 +3662,18 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3662 | 3662 | |
| 3663 | 3663 | fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3664 | 3664 | const pt = self.pt; |
| 3665 | const mod = pt.zcu; | |
| 3665 | const zcu = pt.zcu; | |
| 3666 | 3666 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3667 | 3667 | const result = result: { |
| 3668 | 3668 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 3669 | 3669 | const dst_ty = self.typeOfIndex(inst); |
| 3670 | switch (dst_ty.zigTypeTag(mod)) { | |
| 3670 | switch (dst_ty.zigTypeTag(zcu)) { | |
| 3671 | 3671 | .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), |
| 3672 | 3672 | else => {}, |
| 3673 | 3673 | } |
| 3674 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 3674 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 3675 | 3675 | |
| 3676 | const dst_info = dst_ty.intInfo(mod); | |
| 3676 | const dst_info = dst_ty.intInfo(zcu); | |
| 3677 | 3677 | const src_ty = try pt.intType(dst_info.signedness, switch (tag) { |
| 3678 | 3678 | else => unreachable, |
| 3679 | 3679 | .mul, .mul_wrap => @max( |
| ... | ... | @@ -3683,20 +3683,20 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3683 | 3683 | ), |
| 3684 | 3684 | .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits, |
| 3685 | 3685 | }); |
| 3686 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 3686 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 3687 | 3687 | |
| 3688 | 3688 | if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) { |
| 3689 | 3689 | else => unreachable, |
| 3690 | 3690 | .mul, .mul_wrap => {}, |
| 3691 | 3691 | .div_trunc, .div_floor, .div_exact, .rem, .mod => { |
| 3692 | const signed = dst_ty.isSignedInt(mod); | |
| 3692 | const signed = dst_ty.isSignedInt(zcu); | |
| 3693 | 3693 | var callee_buf: ["__udiv?i3".len]u8 = undefined; |
| 3694 | 3694 | const signed_div_floor_state: struct { |
| 3695 | 3695 | frame_index: FrameIndex, |
| 3696 | 3696 | state: State, |
| 3697 | 3697 | reloc: Mir.Inst.Index, |
| 3698 | 3698 | } = if (signed and tag == .div_floor) state: { |
| 3699 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, pt)); | |
| 3699 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, zcu)); | |
| 3700 | 3700 | try self.asmMemoryImmediate( |
| 3701 | 3701 | .{ ._, .mov }, |
| 3702 | 3702 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| ... | ... | @@ -3771,7 +3771,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3771 | 3771 | .rem, .mod => "mod", |
| 3772 | 3772 | else => unreachable, |
| 3773 | 3773 | }, |
| 3774 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(pt))), | |
| 3774 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(zcu))), | |
| 3775 | 3775 | }) catch unreachable, |
| 3776 | 3776 | } }, |
| 3777 | 3777 | &.{ src_ty, src_ty }, |
| ... | ... | @@ -3800,7 +3800,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3800 | 3800 | .return_type = dst_ty.toIntern(), |
| 3801 | 3801 | .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, |
| 3802 | 3802 | .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{ |
| 3803 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(pt))), | |
| 3803 | intCompilerRtAbiName(@intCast(dst_ty.bitSize(zcu))), | |
| 3804 | 3804 | }) catch unreachable, |
| 3805 | 3805 | } }, |
| 3806 | 3806 | &.{ src_ty, src_ty }, |
| ... | ... | @@ -3892,10 +3892,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3892 | 3892 | |
| 3893 | 3893 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3894 | 3894 | const pt = self.pt; |
| 3895 | const mod = pt.zcu; | |
| 3895 | const zcu = pt.zcu; | |
| 3896 | 3896 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3897 | 3897 | const ty = self.typeOf(bin_op.lhs); |
| 3898 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail( | |
| 3898 | if (ty.zigTypeTag(zcu) == .Vector or ty.abiSize(zcu) > 8) return self.fail( | |
| 3899 | 3899 | "TODO implement airAddSat for {}", |
| 3900 | 3900 | .{ty.fmt(pt)}, |
| 3901 | 3901 | ); |
| ... | ... | @@ -3923,7 +3923,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3923 | 3923 | |
| 3924 | 3924 | const reg_bits = self.regBitSize(ty); |
| 3925 | 3925 | const reg_extra_bits = self.regExtraBits(ty); |
| 3926 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | |
| 3926 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { | |
| 3927 | 3927 | if (reg_extra_bits > 0) { |
| 3928 | 3928 | try self.genShiftBinOpMir( |
| 3929 | 3929 | .{ ._l, .sa }, |
| ... | ... | @@ -3962,7 +3962,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3962 | 3962 | break :cc .o; |
| 3963 | 3963 | } else cc: { |
| 3964 | 3964 | try self.genSetReg(limit_reg, ty, .{ |
| 3965 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(pt)), | |
| 3965 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(zcu)), | |
| 3966 | 3966 | }, .{}); |
| 3967 | 3967 | |
| 3968 | 3968 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); |
| ... | ... | @@ -3973,14 +3973,14 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3973 | 3973 | break :cc .c; |
| 3974 | 3974 | }; |
| 3975 | 3975 | |
| 3976 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); | |
| 3976 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2); | |
| 3977 | 3977 | try self.asmCmovccRegisterRegister( |
| 3978 | 3978 | cc, |
| 3979 | 3979 | registerAlias(dst_reg, cmov_abi_size), |
| 3980 | 3980 | registerAlias(limit_reg, cmov_abi_size), |
| 3981 | 3981 | ); |
| 3982 | 3982 | |
| 3983 | if (reg_extra_bits > 0 and ty.isSignedInt(mod)) try self.genShiftBinOpMir( | |
| 3983 | if (reg_extra_bits > 0 and ty.isSignedInt(zcu)) try self.genShiftBinOpMir( | |
| 3984 | 3984 | .{ ._r, .sa }, |
| 3985 | 3985 | ty, |
| 3986 | 3986 | dst_mcv, |
| ... | ... | @@ -3993,10 +3993,10 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3993 | 3993 | |
| 3994 | 3994 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3995 | 3995 | const pt = self.pt; |
| 3996 | const mod = pt.zcu; | |
| 3996 | const zcu = pt.zcu; | |
| 3997 | 3997 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3998 | 3998 | const ty = self.typeOf(bin_op.lhs); |
| 3999 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail( | |
| 3999 | if (ty.zigTypeTag(zcu) == .Vector or ty.abiSize(zcu) > 8) return self.fail( | |
| 4000 | 4000 | "TODO implement airSubSat for {}", |
| 4001 | 4001 | .{ty.fmt(pt)}, |
| 4002 | 4002 | ); |
| ... | ... | @@ -4024,7 +4024,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4024 | 4024 | |
| 4025 | 4025 | const reg_bits = self.regBitSize(ty); |
| 4026 | 4026 | const reg_extra_bits = self.regExtraBits(ty); |
| 4027 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | |
| 4027 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { | |
| 4028 | 4028 | if (reg_extra_bits > 0) { |
| 4029 | 4029 | try self.genShiftBinOpMir( |
| 4030 | 4030 | .{ ._l, .sa }, |
| ... | ... | @@ -4067,14 +4067,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4067 | 4067 | break :cc .c; |
| 4068 | 4068 | }; |
| 4069 | 4069 | |
| 4070 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); | |
| 4070 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2); | |
| 4071 | 4071 | try self.asmCmovccRegisterRegister( |
| 4072 | 4072 | cc, |
| 4073 | 4073 | registerAlias(dst_reg, cmov_abi_size), |
| 4074 | 4074 | registerAlias(limit_reg, cmov_abi_size), |
| 4075 | 4075 | ); |
| 4076 | 4076 | |
| 4077 | if (reg_extra_bits > 0 and ty.isSignedInt(mod)) try self.genShiftBinOpMir( | |
| 4077 | if (reg_extra_bits > 0 and ty.isSignedInt(zcu)) try self.genShiftBinOpMir( | |
| 4078 | 4078 | .{ ._r, .sa }, |
| 4079 | 4079 | ty, |
| 4080 | 4080 | dst_mcv, |
| ... | ... | @@ -4087,7 +4087,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4087 | 4087 | |
| 4088 | 4088 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4089 | 4089 | const pt = self.pt; |
| 4090 | const mod = pt.zcu; | |
| 4090 | const zcu = pt.zcu; | |
| 4091 | 4091 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4092 | 4092 | const ty = self.typeOf(bin_op.lhs); |
| 4093 | 4093 | |
| ... | ... | @@ -4170,7 +4170,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4170 | 4170 | break :result dst_mcv; |
| 4171 | 4171 | } |
| 4172 | 4172 | |
| 4173 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(pt) > 8) return self.fail( | |
| 4173 | if (ty.zigTypeTag(zcu) == .Vector or ty.abiSize(zcu) > 8) return self.fail( | |
| 4174 | 4174 | "TODO implement airMulSat for {}", |
| 4175 | 4175 | .{ty.fmt(pt)}, |
| 4176 | 4176 | ); |
| ... | ... | @@ -4199,7 +4199,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4199 | 4199 | defer self.register_manager.unlockReg(limit_lock); |
| 4200 | 4200 | |
| 4201 | 4201 | const reg_bits = self.regBitSize(ty); |
| 4202 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | |
| 4202 | const cc: Condition = if (ty.isSignedInt(zcu)) cc: { | |
| 4203 | 4203 | try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); |
| 4204 | 4204 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); |
| 4205 | 4205 | try self.genShiftBinOpMir( |
| ... | ... | @@ -4221,7 +4221,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4221 | 4221 | }; |
| 4222 | 4222 | |
| 4223 | 4223 | const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv); |
| 4224 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); | |
| 4224 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2); | |
| 4225 | 4225 | try self.asmCmovccRegisterRegister( |
| 4226 | 4226 | cc, |
| 4227 | 4227 | registerAlias(dst_mcv.register, cmov_abi_size), |
| ... | ... | @@ -4234,13 +4234,13 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4234 | 4234 | |
| 4235 | 4235 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4236 | 4236 | const pt = self.pt; |
| 4237 | const mod = pt.zcu; | |
| 4237 | const zcu = pt.zcu; | |
| 4238 | 4238 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4239 | 4239 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4240 | 4240 | const result: MCValue = result: { |
| 4241 | 4241 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4242 | 4242 | const ty = self.typeOf(bin_op.lhs); |
| 4243 | switch (ty.zigTypeTag(mod)) { | |
| 4243 | switch (ty.zigTypeTag(zcu)) { | |
| 4244 | 4244 | .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}), |
| 4245 | 4245 | .Int => { |
| 4246 | 4246 | try self.spillEflagsIfOccupied(); |
| ... | ... | @@ -4253,7 +4253,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4253 | 4253 | .sub_with_overflow => .sub, |
| 4254 | 4254 | else => unreachable, |
| 4255 | 4255 | }, bin_op.lhs, bin_op.rhs); |
| 4256 | const int_info = ty.intInfo(mod); | |
| 4256 | const int_info = ty.intInfo(zcu); | |
| 4257 | 4257 | const cc: Condition = switch (int_info.signedness) { |
| 4258 | 4258 | .unsigned => .c, |
| 4259 | 4259 | .signed => .o, |
| ... | ... | @@ -4270,17 +4270,17 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4270 | 4270 | } |
| 4271 | 4271 | |
| 4272 | 4272 | const frame_index = |
| 4273 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); | |
| 4273 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | |
| 4274 | 4274 | try self.genSetMem( |
| 4275 | 4275 | .{ .frame = frame_index }, |
| 4276 | @intCast(tuple_ty.structFieldOffset(1, pt)), | |
| 4276 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | |
| 4277 | 4277 | Type.u1, |
| 4278 | 4278 | .{ .eflags = cc }, |
| 4279 | 4279 | .{}, |
| 4280 | 4280 | ); |
| 4281 | 4281 | try self.genSetMem( |
| 4282 | 4282 | .{ .frame = frame_index }, |
| 4283 | @intCast(tuple_ty.structFieldOffset(0, pt)), | |
| 4283 | @intCast(tuple_ty.structFieldOffset(0, zcu)), | |
| 4284 | 4284 | ty, |
| 4285 | 4285 | partial_mcv, |
| 4286 | 4286 | .{}, |
| ... | ... | @@ -4289,7 +4289,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4289 | 4289 | } |
| 4290 | 4290 | |
| 4291 | 4291 | const frame_index = |
| 4292 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); | |
| 4292 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | |
| 4293 | 4293 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4294 | 4294 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4295 | 4295 | }, |
| ... | ... | @@ -4301,13 +4301,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4301 | 4301 | |
| 4302 | 4302 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4303 | 4303 | const pt = self.pt; |
| 4304 | const mod = pt.zcu; | |
| 4304 | const zcu = pt.zcu; | |
| 4305 | 4305 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4306 | 4306 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4307 | 4307 | const result: MCValue = result: { |
| 4308 | 4308 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4309 | 4309 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 4310 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 4310 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 4311 | 4311 | .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}), |
| 4312 | 4312 | .Int => { |
| 4313 | 4313 | try self.spillEflagsIfOccupied(); |
| ... | ... | @@ -4318,7 +4318,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4318 | 4318 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4319 | 4319 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4320 | 4320 | |
| 4321 | const int_info = lhs_ty.intInfo(mod); | |
| 4321 | const int_info = lhs_ty.intInfo(zcu); | |
| 4322 | 4322 | |
| 4323 | 4323 | const partial_mcv = try self.genShiftBinOp(.shl, null, lhs, rhs, lhs_ty, rhs_ty); |
| 4324 | 4324 | const partial_lock = switch (partial_mcv) { |
| ... | ... | @@ -4348,18 +4348,18 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4348 | 4348 | } |
| 4349 | 4349 | |
| 4350 | 4350 | const frame_index = |
| 4351 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); | |
| 4351 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | |
| 4352 | 4352 | try self.genSetMem( |
| 4353 | 4353 | .{ .frame = frame_index }, |
| 4354 | @intCast(tuple_ty.structFieldOffset(1, pt)), | |
| 4355 | tuple_ty.structFieldType(1, mod), | |
| 4354 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | |
| 4355 | tuple_ty.structFieldType(1, zcu), | |
| 4356 | 4356 | .{ .eflags = cc }, |
| 4357 | 4357 | .{}, |
| 4358 | 4358 | ); |
| 4359 | 4359 | try self.genSetMem( |
| 4360 | 4360 | .{ .frame = frame_index }, |
| 4361 | @intCast(tuple_ty.structFieldOffset(0, pt)), | |
| 4362 | tuple_ty.structFieldType(0, mod), | |
| 4361 | @intCast(tuple_ty.structFieldOffset(0, zcu)), | |
| 4362 | tuple_ty.structFieldType(0, zcu), | |
| 4363 | 4363 | partial_mcv, |
| 4364 | 4364 | .{}, |
| 4365 | 4365 | ); |
| ... | ... | @@ -4367,7 +4367,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4367 | 4367 | } |
| 4368 | 4368 | |
| 4369 | 4369 | const frame_index = |
| 4370 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); | |
| 4370 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | |
| 4371 | 4371 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4372 | 4372 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4373 | 4373 | }, |
| ... | ... | @@ -4385,15 +4385,15 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4385 | 4385 | overflow_cc: ?Condition, |
| 4386 | 4386 | ) !void { |
| 4387 | 4387 | const pt = self.pt; |
| 4388 | const mod = pt.zcu; | |
| 4388 | const zcu = pt.zcu; | |
| 4389 | 4389 | const src_lock = switch (src_mcv) { |
| 4390 | 4390 | .register => |reg| self.register_manager.lockReg(reg), |
| 4391 | 4391 | else => null, |
| 4392 | 4392 | }; |
| 4393 | 4393 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 4394 | 4394 | |
| 4395 | const ty = tuple_ty.structFieldType(0, mod); | |
| 4396 | const int_info = ty.intInfo(mod); | |
| 4395 | const ty = tuple_ty.structFieldType(0, zcu); | |
| 4396 | const int_info = ty.intInfo(zcu); | |
| 4397 | 4397 | |
| 4398 | 4398 | const hi_bits = (int_info.bits - 1) % 64 + 1; |
| 4399 | 4399 | const hi_ty = try pt.intType(int_info.signedness, hi_bits); |
| ... | ... | @@ -4432,7 +4432,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4432 | 4432 | ); |
| 4433 | 4433 | } |
| 4434 | 4434 | |
| 4435 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, pt)); | |
| 4435 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); | |
| 4436 | 4436 | if (hi_limb_off > 0) try self.genSetMem( |
| 4437 | 4437 | .{ .frame = frame_index }, |
| 4438 | 4438 | payload_off, |
| ... | ... | @@ -4449,8 +4449,8 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4449 | 4449 | ); |
| 4450 | 4450 | try self.genSetMem( |
| 4451 | 4451 | .{ .frame = frame_index }, |
| 4452 | @intCast(tuple_ty.structFieldOffset(1, pt)), | |
| 4453 | tuple_ty.structFieldType(1, mod), | |
| 4452 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | |
| 4453 | tuple_ty.structFieldType(1, zcu), | |
| 4454 | 4454 | if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne }, |
| 4455 | 4455 | .{}, |
| 4456 | 4456 | ); |
| ... | ... | @@ -4458,18 +4458,18 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4458 | 4458 | |
| 4459 | 4459 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4460 | 4460 | const pt = self.pt; |
| 4461 | const mod = pt.zcu; | |
| 4461 | const zcu = pt.zcu; | |
| 4462 | 4462 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4463 | 4463 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4464 | 4464 | const tuple_ty = self.typeOfIndex(inst); |
| 4465 | 4465 | const dst_ty = self.typeOf(bin_op.lhs); |
| 4466 | const result: MCValue = switch (dst_ty.zigTypeTag(mod)) { | |
| 4466 | const result: MCValue = switch (dst_ty.zigTypeTag(zcu)) { | |
| 4467 | 4467 | .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(pt)}), |
| 4468 | 4468 | .Int => result: { |
| 4469 | const dst_info = dst_ty.intInfo(mod); | |
| 4469 | const dst_info = dst_ty.intInfo(zcu); | |
| 4470 | 4470 | if (dst_info.bits > 128 and dst_info.signedness == .unsigned) { |
| 4471 | 4471 | const slow_inc = self.hasFeature(.slow_incdec); |
| 4472 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 4472 | const abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 4473 | 4473 | const limb_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| 4474 | 4474 | |
| 4475 | 4475 | try self.spillRegisters(&.{ .rax, .rcx, .rdx }); |
| ... | ... | @@ -4480,7 +4480,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4480 | 4480 | try self.genInlineMemset( |
| 4481 | 4481 | dst_mcv.address(), |
| 4482 | 4482 | .{ .immediate = 0 }, |
| 4483 | .{ .immediate = tuple_ty.abiSize(pt) }, | |
| 4483 | .{ .immediate = tuple_ty.abiSize(zcu) }, | |
| 4484 | 4484 | .{}, |
| 4485 | 4485 | ); |
| 4486 | 4486 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -4520,7 +4520,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4520 | 4520 | .index = temp_regs[3].to64(), |
| 4521 | 4521 | .scale = .@"8", |
| 4522 | 4522 | .disp = dst_mcv.load_frame.off + |
| 4523 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), | |
| 4523 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | |
| 4524 | 4524 | } }, |
| 4525 | 4525 | }, .rdx); |
| 4526 | 4526 | try self.asmSetccRegister(.c, .cl); |
| ... | ... | @@ -4544,7 +4544,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4544 | 4544 | .index = temp_regs[3].to64(), |
| 4545 | 4545 | .scale = .@"8", |
| 4546 | 4546 | .disp = dst_mcv.load_frame.off + |
| 4547 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))), | |
| 4547 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | |
| 4548 | 4548 | } }, |
| 4549 | 4549 | }, .rax); |
| 4550 | 4550 | try self.asmSetccRegister(.c, .ch); |
| ... | ... | @@ -4593,7 +4593,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4593 | 4593 | .mod = .{ .rm = .{ |
| 4594 | 4594 | .size = .byte, |
| 4595 | 4595 | .disp = dst_mcv.load_frame.off + |
| 4596 | @as(i32, @intCast(tuple_ty.structFieldOffset(1, pt))), | |
| 4596 | @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | |
| 4597 | 4597 | } }, |
| 4598 | 4598 | }, Immediate.u(1)); |
| 4599 | 4599 | self.performReloc(no_overflow); |
| ... | ... | @@ -4636,8 +4636,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4636 | 4636 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 4637 | 4637 | try self.genSetMem( |
| 4638 | 4638 | .{ .frame = dst_mcv.load_frame.index }, |
| 4639 | @intCast(tuple_ty.structFieldOffset(0, pt)), | |
| 4640 | tuple_ty.structFieldType(0, mod), | |
| 4639 | @intCast(tuple_ty.structFieldOffset(0, zcu)), | |
| 4640 | tuple_ty.structFieldType(0, zcu), | |
| 4641 | 4641 | result, |
| 4642 | 4642 | .{}, |
| 4643 | 4643 | ); |
| ... | ... | @@ -4648,8 +4648,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4648 | 4648 | ); |
| 4649 | 4649 | try self.genSetMem( |
| 4650 | 4650 | .{ .frame = dst_mcv.load_frame.index }, |
| 4651 | @intCast(tuple_ty.structFieldOffset(1, pt)), | |
| 4652 | tuple_ty.structFieldType(1, mod), | |
| 4651 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | |
| 4652 | tuple_ty.structFieldType(1, zcu), | |
| 4653 | 4653 | .{ .eflags = .ne }, |
| 4654 | 4654 | .{}, |
| 4655 | 4655 | ); |
| ... | ... | @@ -4760,15 +4760,15 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4760 | 4760 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 4761 | 4761 | try self.genSetMem( |
| 4762 | 4762 | .{ .frame = dst_mcv.load_frame.index }, |
| 4763 | @intCast(tuple_ty.structFieldOffset(0, pt)), | |
| 4764 | tuple_ty.structFieldType(0, mod), | |
| 4763 | @intCast(tuple_ty.structFieldOffset(0, zcu)), | |
| 4764 | tuple_ty.structFieldType(0, zcu), | |
| 4765 | 4765 | .{ .register_pair = .{ .rax, .rdx } }, |
| 4766 | 4766 | .{}, |
| 4767 | 4767 | ); |
| 4768 | 4768 | try self.genSetMem( |
| 4769 | 4769 | .{ .frame = dst_mcv.load_frame.index }, |
| 4770 | @intCast(tuple_ty.structFieldOffset(1, pt)), | |
| 4771 | tuple_ty.structFieldType(1, mod), | |
| 4770 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | |
| 4771 | tuple_ty.structFieldType(1, zcu), | |
| 4772 | 4772 | .{ .register = tmp_regs[1] }, |
| 4773 | 4773 | .{}, |
| 4774 | 4774 | ); |
| ... | ... | @@ -4800,7 +4800,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4800 | 4800 | self.eflags_inst = inst; |
| 4801 | 4801 | break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; |
| 4802 | 4802 | } else { |
| 4803 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); | |
| 4803 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | |
| 4804 | 4804 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4805 | 4805 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4806 | 4806 | }, |
| ... | ... | @@ -4811,19 +4811,19 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4811 | 4811 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 4812 | 4812 | }); |
| 4813 | 4813 | |
| 4814 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, pt)); | |
| 4814 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | |
| 4815 | 4815 | if (dst_info.bits >= lhs_active_bits + rhs_active_bits) { |
| 4816 | 4816 | try self.genSetMem( |
| 4817 | 4817 | .{ .frame = frame_index }, |
| 4818 | @intCast(tuple_ty.structFieldOffset(0, pt)), | |
| 4819 | tuple_ty.structFieldType(0, mod), | |
| 4818 | @intCast(tuple_ty.structFieldOffset(0, zcu)), | |
| 4819 | tuple_ty.structFieldType(0, zcu), | |
| 4820 | 4820 | partial_mcv, |
| 4821 | 4821 | .{}, |
| 4822 | 4822 | ); |
| 4823 | 4823 | try self.genSetMem( |
| 4824 | 4824 | .{ .frame = frame_index }, |
| 4825 | @intCast(tuple_ty.structFieldOffset(1, pt)), | |
| 4826 | tuple_ty.structFieldType(1, mod), | |
| 4825 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | |
| 4826 | tuple_ty.structFieldType(1, zcu), | |
| 4827 | 4827 | .{ .immediate = 0 }, // cc being set is impossible |
| 4828 | 4828 | .{}, |
| 4829 | 4829 | ); |
| ... | ... | @@ -4847,7 +4847,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4847 | 4847 | /// Quotient is saved in .rax and remainder in .rdx. |
| 4848 | 4848 | fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void { |
| 4849 | 4849 | const pt = self.pt; |
| 4850 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 4850 | const abi_size: u32 = @intCast(ty.abiSize(pt.zcu)); | |
| 4851 | 4851 | const bit_size: u32 = @intCast(self.regBitSize(ty)); |
| 4852 | 4852 | if (abi_size > 8) { |
| 4853 | 4853 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); |
| ... | ... | @@ -4897,9 +4897,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 4897 | 4897 | /// Clobbers .rax and .rdx registers. |
| 4898 | 4898 | fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue { |
| 4899 | 4899 | const pt = self.pt; |
| 4900 | const mod = pt.zcu; | |
| 4901 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 4902 | const int_info = ty.intInfo(mod); | |
| 4900 | const zcu = pt.zcu; | |
| 4901 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 4902 | const int_info = ty.intInfo(zcu); | |
| 4903 | 4903 | const dividend = switch (lhs) { |
| 4904 | 4904 | .register => |reg| reg, |
| 4905 | 4905 | else => try self.copyToTmpRegister(ty, lhs), |
| ... | ... | @@ -4950,7 +4950,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 4950 | 4950 | |
| 4951 | 4951 | fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4952 | 4952 | const pt = self.pt; |
| 4953 | const mod = pt.zcu; | |
| 4953 | const zcu = pt.zcu; | |
| 4954 | 4954 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4955 | 4955 | |
| 4956 | 4956 | const air_tags = self.air.instructions.items(.tag); |
| ... | ... | @@ -4958,7 +4958,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4958 | 4958 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4959 | 4959 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 4960 | 4960 | const result: MCValue = result: { |
| 4961 | switch (lhs_ty.zigTypeTag(mod)) { | |
| 4961 | switch (lhs_ty.zigTypeTag(zcu)) { | |
| 4962 | 4962 | .Int => { |
| 4963 | 4963 | try self.spillRegisters(&.{.rcx}); |
| 4964 | 4964 | try self.register_manager.getKnownReg(.rcx, null); |
| ... | ... | @@ -4977,7 +4977,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4977 | 4977 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 4978 | 4978 | defer self.register_manager.unlockReg(tmp_lock); |
| 4979 | 4979 | |
| 4980 | const lhs_bits: u31 = @intCast(lhs_ty.bitSize(pt)); | |
| 4980 | const lhs_bits: u31 = @intCast(lhs_ty.bitSize(zcu)); | |
| 4981 | 4981 | const tmp_ty = if (lhs_bits > 64) Type.usize else lhs_ty; |
| 4982 | 4982 | const off = frame_addr.off + (lhs_bits - 1) / 64 * 8; |
| 4983 | 4983 | try self.genSetReg( |
| ... | ... | @@ -5001,14 +5001,14 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5001 | 5001 | } |
| 5002 | 5002 | break :result dst_mcv; |
| 5003 | 5003 | }, |
| 5004 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 5005 | .Int => if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.childType(mod).intInfo(mod).bits) { | |
| 5004 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 5005 | .Int => if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.childType(zcu).intInfo(zcu).bits) { | |
| 5006 | 5006 | else => null, |
| 5007 | 16 => switch (lhs_ty.vectorLen(mod)) { | |
| 5007 | 16 => switch (lhs_ty.vectorLen(zcu)) { | |
| 5008 | 5008 | else => null, |
| 5009 | 5009 | 1...8 => switch (tag) { |
| 5010 | 5010 | else => unreachable, |
| 5011 | .shr, .shr_exact => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 5011 | .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 5012 | 5012 | .signed => if (self.hasFeature(.avx)) |
| 5013 | 5013 | .{ .vp_w, .sra } |
| 5014 | 5014 | else |
| ... | ... | @@ -5025,18 +5025,18 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5025 | 5025 | }, |
| 5026 | 5026 | 9...16 => switch (tag) { |
| 5027 | 5027 | else => unreachable, |
| 5028 | .shr, .shr_exact => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 5028 | .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 5029 | 5029 | .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .sra } else null, |
| 5030 | 5030 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .srl } else null, |
| 5031 | 5031 | }, |
| 5032 | 5032 | .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_w, .sll } else null, |
| 5033 | 5033 | }, |
| 5034 | 5034 | }, |
| 5035 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 5035 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 5036 | 5036 | else => null, |
| 5037 | 5037 | 1...4 => switch (tag) { |
| 5038 | 5038 | else => unreachable, |
| 5039 | .shr, .shr_exact => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 5039 | .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 5040 | 5040 | .signed => if (self.hasFeature(.avx)) |
| 5041 | 5041 | .{ .vp_d, .sra } |
| 5042 | 5042 | else |
| ... | ... | @@ -5053,18 +5053,18 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5053 | 5053 | }, |
| 5054 | 5054 | 5...8 => switch (tag) { |
| 5055 | 5055 | else => unreachable, |
| 5056 | .shr, .shr_exact => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 5056 | .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 5057 | 5057 | .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .sra } else null, |
| 5058 | 5058 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .srl } else null, |
| 5059 | 5059 | }, |
| 5060 | 5060 | .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_d, .sll } else null, |
| 5061 | 5061 | }, |
| 5062 | 5062 | }, |
| 5063 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 5063 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 5064 | 5064 | else => null, |
| 5065 | 5065 | 1...2 => switch (tag) { |
| 5066 | 5066 | else => unreachable, |
| 5067 | .shr, .shr_exact => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 5067 | .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 5068 | 5068 | .signed => if (self.hasFeature(.avx)) |
| 5069 | 5069 | .{ .vp_q, .sra } |
| 5070 | 5070 | else |
| ... | ... | @@ -5081,7 +5081,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5081 | 5081 | }, |
| 5082 | 5082 | 3...4 => switch (tag) { |
| 5083 | 5083 | else => unreachable, |
| 5084 | .shr, .shr_exact => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 5084 | .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 5085 | 5085 | .signed => if (self.hasFeature(.avx2)) .{ .vp_q, .sra } else null, |
| 5086 | 5086 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_q, .srl } else null, |
| 5087 | 5087 | }, |
| ... | ... | @@ -5089,10 +5089,10 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5089 | 5089 | }, |
| 5090 | 5090 | }, |
| 5091 | 5091 | })) |mir_tag| if (try self.air.value(bin_op.rhs, pt)) |rhs_val| { |
| 5092 | switch (mod.intern_pool.indexToKey(rhs_val.toIntern())) { | |
| 5092 | switch (zcu.intern_pool.indexToKey(rhs_val.toIntern())) { | |
| 5093 | 5093 | .aggregate => |rhs_aggregate| switch (rhs_aggregate.storage) { |
| 5094 | 5094 | .repeated_elem => |rhs_elem| { |
| 5095 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); | |
| 5095 | const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu)); | |
| 5096 | 5096 | |
| 5097 | 5097 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 5098 | 5098 | const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and |
| ... | ... | @@ -5112,7 +5112,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5112 | 5112 | self.register_manager.unlockReg(lock); |
| 5113 | 5113 | |
| 5114 | 5114 | const shift_imm = |
| 5115 | Immediate.u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(pt))); | |
| 5115 | Immediate.u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(zcu))); | |
| 5116 | 5116 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterImmediate( |
| 5117 | 5117 | mir_tag, |
| 5118 | 5118 | registerAlias(dst_reg, abi_size), |
| ... | ... | @@ -5134,7 +5134,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5134 | 5134 | } |
| 5135 | 5135 | } else if (bin_op.rhs.toIndex()) |rhs_inst| switch (air_tags[@intFromEnum(rhs_inst)]) { |
| 5136 | 5136 | .splat => { |
| 5137 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); | |
| 5137 | const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu)); | |
| 5138 | 5138 | |
| 5139 | 5139 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 5140 | 5140 | const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and |
| ... | ... | @@ -5161,7 +5161,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5161 | 5161 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 5162 | 5162 | .ty = mask_ty.toIntern(), |
| 5163 | 5163 | .storage = .{ .elems = &([1]InternPool.Index{ |
| 5164 | (try rhs_ty.childType(mod).maxIntScalar(pt, Type.u8)).toIntern(), | |
| 5164 | (try rhs_ty.childType(zcu).maxIntScalar(pt, Type.u8)).toIntern(), | |
| 5165 | 5165 | } ++ [1]InternPool.Index{ |
| 5166 | 5166 | (try pt.intValue(Type.u8, 0)).toIntern(), |
| 5167 | 5167 | } ** 15) }, |
| ... | ... | @@ -5224,11 +5224,11 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 5224 | 5224 | } |
| 5225 | 5225 | |
| 5226 | 5226 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5227 | const pt = self.pt; | |
| 5227 | const zcu = self.pt.zcu; | |
| 5228 | 5228 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5229 | 5229 | const result: MCValue = result: { |
| 5230 | 5230 | const pl_ty = self.typeOfIndex(inst); |
| 5231 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 5231 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 5232 | 5232 | |
| 5233 | 5233 | const opt_mcv = try self.resolveInst(ty_op.operand); |
| 5234 | 5234 | if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { |
| ... | ... | @@ -5271,15 +5271,15 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5271 | 5271 | |
| 5272 | 5272 | fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5273 | 5273 | const pt = self.pt; |
| 5274 | const mod = pt.zcu; | |
| 5274 | const zcu = pt.zcu; | |
| 5275 | 5275 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5276 | 5276 | const result = result: { |
| 5277 | 5277 | const dst_ty = self.typeOfIndex(inst); |
| 5278 | 5278 | const src_ty = self.typeOf(ty_op.operand); |
| 5279 | const opt_ty = src_ty.childType(mod); | |
| 5279 | const opt_ty = src_ty.childType(zcu); | |
| 5280 | 5280 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 5281 | 5281 | |
| 5282 | if (opt_ty.optionalReprIsPayload(mod)) { | |
| 5282 | if (opt_ty.optionalReprIsPayload(zcu)) { | |
| 5283 | 5283 | break :result if (self.liveness.isUnused(inst)) |
| 5284 | 5284 | .unreach |
| 5285 | 5285 | else if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| ... | ... | @@ -5296,8 +5296,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5296 | 5296 | else |
| 5297 | 5297 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 5298 | 5298 | |
| 5299 | const pl_ty = dst_ty.childType(mod); | |
| 5300 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt)); | |
| 5299 | const pl_ty = dst_ty.childType(zcu); | |
| 5300 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); | |
| 5301 | 5301 | try self.genSetMem( |
| 5302 | 5302 | .{ .reg = dst_mcv.getReg().? }, |
| 5303 | 5303 | pl_abi_size, |
| ... | ... | @@ -5312,23 +5312,23 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5312 | 5312 | |
| 5313 | 5313 | fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5314 | 5314 | const pt = self.pt; |
| 5315 | const mod = pt.zcu; | |
| 5315 | const zcu = pt.zcu; | |
| 5316 | 5316 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5317 | 5317 | const err_union_ty = self.typeOf(ty_op.operand); |
| 5318 | const err_ty = err_union_ty.errorUnionSet(mod); | |
| 5319 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 5318 | const err_ty = err_union_ty.errorUnionSet(zcu); | |
| 5319 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 5320 | 5320 | const operand = try self.resolveInst(ty_op.operand); |
| 5321 | 5321 | |
| 5322 | 5322 | const result: MCValue = result: { |
| 5323 | if (err_ty.errorSetIsEmpty(mod)) { | |
| 5323 | if (err_ty.errorSetIsEmpty(zcu)) { | |
| 5324 | 5324 | break :result MCValue{ .immediate = 0 }; |
| 5325 | 5325 | } |
| 5326 | 5326 | |
| 5327 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5327 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5328 | 5328 | break :result operand; |
| 5329 | 5329 | } |
| 5330 | 5330 | |
| 5331 | const err_off = errUnionErrorOffset(payload_ty, pt); | |
| 5331 | const err_off = errUnionErrorOffset(payload_ty, zcu); | |
| 5332 | 5332 | switch (operand) { |
| 5333 | 5333 | .register => |reg| { |
| 5334 | 5334 | // TODO reuse operand |
| ... | ... | @@ -5366,7 +5366,7 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5366 | 5366 | // *(E!T) -> E |
| 5367 | 5367 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5368 | 5368 | const pt = self.pt; |
| 5369 | const mod = pt.zcu; | |
| 5369 | const zcu = pt.zcu; | |
| 5370 | 5370 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5371 | 5371 | |
| 5372 | 5372 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -5383,11 +5383,11 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5383 | 5383 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 5384 | 5384 | defer self.register_manager.unlockReg(dst_lock); |
| 5385 | 5385 | |
| 5386 | const eu_ty = src_ty.childType(mod); | |
| 5387 | const pl_ty = eu_ty.errorUnionPayload(mod); | |
| 5388 | const err_ty = eu_ty.errorUnionSet(mod); | |
| 5389 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 5390 | const err_abi_size: u32 = @intCast(err_ty.abiSize(pt)); | |
| 5386 | const eu_ty = src_ty.childType(zcu); | |
| 5387 | const pl_ty = eu_ty.errorUnionPayload(zcu); | |
| 5388 | const err_ty = eu_ty.errorUnionSet(zcu); | |
| 5389 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 5390 | const err_abi_size: u32 = @intCast(err_ty.abiSize(zcu)); | |
| 5391 | 5391 | try self.asmRegisterMemory( |
| 5392 | 5392 | .{ ._, .mov }, |
| 5393 | 5393 | registerAlias(dst_reg, err_abi_size), |
| ... | ... | @@ -5414,7 +5414,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5414 | 5414 | |
| 5415 | 5415 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5416 | 5416 | const pt = self.pt; |
| 5417 | const mod = pt.zcu; | |
| 5417 | const zcu = pt.zcu; | |
| 5418 | 5418 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5419 | 5419 | const result: MCValue = result: { |
| 5420 | 5420 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -5426,11 +5426,11 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5426 | 5426 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| 5427 | 5427 | defer self.register_manager.unlockReg(src_lock); |
| 5428 | 5428 | |
| 5429 | const eu_ty = src_ty.childType(mod); | |
| 5430 | const pl_ty = eu_ty.errorUnionPayload(mod); | |
| 5431 | const err_ty = eu_ty.errorUnionSet(mod); | |
| 5432 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 5433 | const err_abi_size: u32 = @intCast(err_ty.abiSize(pt)); | |
| 5429 | const eu_ty = src_ty.childType(zcu); | |
| 5430 | const pl_ty = eu_ty.errorUnionPayload(zcu); | |
| 5431 | const err_ty = eu_ty.errorUnionSet(zcu); | |
| 5432 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 5433 | const err_abi_size: u32 = @intCast(err_ty.abiSize(zcu)); | |
| 5434 | 5434 | try self.asmMemoryImmediate( |
| 5435 | 5435 | .{ ._, .mov }, |
| 5436 | 5436 | .{ |
| ... | ... | @@ -5453,8 +5453,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5453 | 5453 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5454 | 5454 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5455 | 5455 | |
| 5456 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); | |
| 5457 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 5456 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | |
| 5457 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 5458 | 5458 | try self.asmRegisterMemory( |
| 5459 | 5459 | .{ ._, .lea }, |
| 5460 | 5460 | registerAlias(dst_reg, dst_abi_size), |
| ... | ... | @@ -5475,13 +5475,13 @@ fn genUnwrapErrUnionPayloadMir( |
| 5475 | 5475 | err_union: MCValue, |
| 5476 | 5476 | ) !MCValue { |
| 5477 | 5477 | const pt = self.pt; |
| 5478 | const mod = pt.zcu; | |
| 5479 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 5478 | const zcu = pt.zcu; | |
| 5479 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 5480 | 5480 | |
| 5481 | 5481 | const result: MCValue = result: { |
| 5482 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 5482 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 5483 | 5483 | |
| 5484 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, pt)); | |
| 5484 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu)); | |
| 5485 | 5485 | switch (err_union) { |
| 5486 | 5486 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ |
| 5487 | 5487 | .index = frame_addr.index, |
| ... | ... | @@ -5525,12 +5525,12 @@ fn genUnwrapErrUnionPayloadPtrMir( |
| 5525 | 5525 | ptr_mcv: MCValue, |
| 5526 | 5526 | ) !MCValue { |
| 5527 | 5527 | const pt = self.pt; |
| 5528 | const mod = pt.zcu; | |
| 5529 | const err_union_ty = ptr_ty.childType(mod); | |
| 5530 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 5528 | const zcu = pt.zcu; | |
| 5529 | const err_union_ty = ptr_ty.childType(zcu); | |
| 5530 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 5531 | 5531 | |
| 5532 | 5532 | const result: MCValue = result: { |
| 5533 | const payload_off = errUnionPayloadOffset(payload_ty, pt); | |
| 5533 | const payload_off = errUnionPayloadOffset(payload_ty, zcu); | |
| 5534 | 5534 | const result_mcv: MCValue = if (maybe_inst) |inst| |
| 5535 | 5535 | try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv) |
| 5536 | 5536 | else |
| ... | ... | @@ -5560,15 +5560,15 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 5560 | 5560 | |
| 5561 | 5561 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5562 | 5562 | const pt = self.pt; |
| 5563 | const mod = pt.zcu; | |
| 5563 | const zcu = pt.zcu; | |
| 5564 | 5564 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5565 | 5565 | const result: MCValue = result: { |
| 5566 | 5566 | const pl_ty = self.typeOf(ty_op.operand); |
| 5567 | if (!pl_ty.hasRuntimeBits(pt)) break :result .{ .immediate = 1 }; | |
| 5567 | if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 }; | |
| 5568 | 5568 | |
| 5569 | 5569 | const opt_ty = self.typeOfIndex(inst); |
| 5570 | 5570 | const pl_mcv = try self.resolveInst(ty_op.operand); |
| 5571 | const same_repr = opt_ty.optionalReprIsPayload(mod); | |
| 5571 | const same_repr = opt_ty.optionalReprIsPayload(zcu); | |
| 5572 | 5572 | if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv; |
| 5573 | 5573 | |
| 5574 | 5574 | const pl_lock: ?RegisterLock = switch (pl_mcv) { |
| ... | ... | @@ -5581,7 +5581,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5581 | 5581 | try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{}); |
| 5582 | 5582 | |
| 5583 | 5583 | if (!same_repr) { |
| 5584 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(pt)); | |
| 5584 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); | |
| 5585 | 5585 | switch (opt_mcv) { |
| 5586 | 5586 | else => unreachable, |
| 5587 | 5587 | |
| ... | ... | @@ -5615,20 +5615,20 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5615 | 5615 | /// T to E!T |
| 5616 | 5616 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5617 | 5617 | const pt = self.pt; |
| 5618 | const mod = pt.zcu; | |
| 5618 | const zcu = pt.zcu; | |
| 5619 | 5619 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5620 | 5620 | |
| 5621 | 5621 | const eu_ty = ty_op.ty.toType(); |
| 5622 | const pl_ty = eu_ty.errorUnionPayload(mod); | |
| 5623 | const err_ty = eu_ty.errorUnionSet(mod); | |
| 5622 | const pl_ty = eu_ty.errorUnionPayload(zcu); | |
| 5623 | const err_ty = eu_ty.errorUnionSet(zcu); | |
| 5624 | 5624 | const operand = try self.resolveInst(ty_op.operand); |
| 5625 | 5625 | |
| 5626 | 5626 | const result: MCValue = result: { |
| 5627 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .{ .immediate = 0 }; | |
| 5627 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 }; | |
| 5628 | 5628 | |
| 5629 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); | |
| 5630 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); | |
| 5631 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 5629 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | |
| 5630 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | |
| 5631 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 5632 | 5632 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); |
| 5633 | 5633 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{}); |
| 5634 | 5634 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| ... | ... | @@ -5639,19 +5639,19 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5639 | 5639 | /// E to E!T |
| 5640 | 5640 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5641 | 5641 | const pt = self.pt; |
| 5642 | const mod = pt.zcu; | |
| 5642 | const zcu = pt.zcu; | |
| 5643 | 5643 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5644 | 5644 | |
| 5645 | 5645 | const eu_ty = ty_op.ty.toType(); |
| 5646 | const pl_ty = eu_ty.errorUnionPayload(mod); | |
| 5647 | const err_ty = eu_ty.errorUnionSet(mod); | |
| 5646 | const pl_ty = eu_ty.errorUnionPayload(zcu); | |
| 5647 | const err_ty = eu_ty.errorUnionSet(zcu); | |
| 5648 | 5648 | |
| 5649 | 5649 | const result: MCValue = result: { |
| 5650 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result try self.resolveInst(ty_op.operand); | |
| 5650 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try self.resolveInst(ty_op.operand); | |
| 5651 | 5651 | |
| 5652 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, pt)); | |
| 5653 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, pt)); | |
| 5654 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, pt)); | |
| 5652 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | |
| 5653 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | |
| 5654 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | |
| 5655 | 5655 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); |
| 5656 | 5656 | const operand = try self.resolveInst(ty_op.operand); |
| 5657 | 5657 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{}); |
| ... | ... | @@ -5719,7 +5719,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5719 | 5719 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5720 | 5720 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5721 | 5721 | |
| 5722 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 5722 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu)); | |
| 5723 | 5723 | try self.asmRegisterMemory( |
| 5724 | 5724 | .{ ._, .lea }, |
| 5725 | 5725 | registerAlias(dst_reg, dst_abi_size), |
| ... | ... | @@ -5767,7 +5767,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi |
| 5767 | 5767 | |
| 5768 | 5768 | fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5769 | 5769 | const pt = self.pt; |
| 5770 | const mod = pt.zcu; | |
| 5770 | const zcu = pt.zcu; | |
| 5771 | 5771 | const slice_ty = self.typeOf(lhs); |
| 5772 | 5772 | const slice_mcv = try self.resolveInst(lhs); |
| 5773 | 5773 | const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) { |
| ... | ... | @@ -5776,9 +5776,9 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5776 | 5776 | }; |
| 5777 | 5777 | defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock); |
| 5778 | 5778 | |
| 5779 | const elem_ty = slice_ty.childType(mod); | |
| 5780 | const elem_size = elem_ty.abiSize(pt); | |
| 5781 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | |
| 5779 | const elem_ty = slice_ty.childType(zcu); | |
| 5780 | const elem_size = elem_ty.abiSize(zcu); | |
| 5781 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu); | |
| 5782 | 5782 | |
| 5783 | 5783 | const index_ty = self.typeOf(rhs); |
| 5784 | 5784 | const index_mcv = try self.resolveInst(rhs); |
| ... | ... | @@ -5804,15 +5804,15 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5804 | 5804 | |
| 5805 | 5805 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5806 | 5806 | const pt = self.pt; |
| 5807 | const mod = pt.zcu; | |
| 5807 | const zcu = pt.zcu; | |
| 5808 | 5808 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5809 | 5809 | |
| 5810 | 5810 | const result: MCValue = result: { |
| 5811 | 5811 | const elem_ty = self.typeOfIndex(inst); |
| 5812 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 5812 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 5813 | 5813 | |
| 5814 | 5814 | const slice_ty = self.typeOf(bin_op.lhs); |
| 5815 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | |
| 5815 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu); | |
| 5816 | 5816 | const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs); |
| 5817 | 5817 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 5818 | 5818 | try self.load(dst_mcv, slice_ptr_field_type, elem_ptr); |
| ... | ... | @@ -5830,12 +5830,12 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5830 | 5830 | |
| 5831 | 5831 | fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5832 | 5832 | const pt = self.pt; |
| 5833 | const mod = pt.zcu; | |
| 5833 | const zcu = pt.zcu; | |
| 5834 | 5834 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5835 | 5835 | |
| 5836 | 5836 | const result: MCValue = result: { |
| 5837 | 5837 | const array_ty = self.typeOf(bin_op.lhs); |
| 5838 | const elem_ty = array_ty.childType(mod); | |
| 5838 | const elem_ty = array_ty.childType(zcu); | |
| 5839 | 5839 | |
| 5840 | 5840 | const array_mcv = try self.resolveInst(bin_op.lhs); |
| 5841 | 5841 | const array_lock: ?RegisterLock = switch (array_mcv) { |
| ... | ... | @@ -5853,7 +5853,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5853 | 5853 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); |
| 5854 | 5854 | |
| 5855 | 5855 | try self.spillEflagsIfOccupied(); |
| 5856 | if (array_ty.isVector(mod) and elem_ty.bitSize(pt) == 1) { | |
| 5856 | if (array_ty.isVector(zcu) and elem_ty.bitSize(zcu) == 1) { | |
| 5857 | 5857 | const index_reg = switch (index_mcv) { |
| 5858 | 5858 | .register => |reg| reg, |
| 5859 | 5859 | else => try self.copyToTmpRegister(index_ty, index_mcv), |
| ... | ... | @@ -5866,7 +5866,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5866 | 5866 | index_reg.to64(), |
| 5867 | 5867 | ), |
| 5868 | 5868 | .sse => { |
| 5869 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, pt)); | |
| 5869 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | |
| 5870 | 5870 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 5871 | 5871 | try self.asmMemoryRegister( |
| 5872 | 5872 | .{ ._, .bt }, |
| ... | ... | @@ -5904,14 +5904,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5904 | 5904 | break :result .{ .register = dst_reg }; |
| 5905 | 5905 | } |
| 5906 | 5906 | |
| 5907 | const elem_abi_size = elem_ty.abiSize(pt); | |
| 5907 | const elem_abi_size = elem_ty.abiSize(zcu); | |
| 5908 | 5908 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 5909 | 5909 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 5910 | 5910 | defer self.register_manager.unlockReg(addr_lock); |
| 5911 | 5911 | |
| 5912 | 5912 | switch (array_mcv) { |
| 5913 | 5913 | .register => { |
| 5914 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, pt)); | |
| 5914 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | |
| 5915 | 5915 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 5916 | 5916 | try self.asmRegisterMemory( |
| 5917 | 5917 | .{ ._, .lea }, |
| ... | ... | @@ -5960,7 +5960,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5960 | 5960 | |
| 5961 | 5961 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5962 | 5962 | const pt = self.pt; |
| 5963 | const mod = pt.zcu; | |
| 5963 | const zcu = pt.zcu; | |
| 5964 | 5964 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5965 | 5965 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 5966 | 5966 | |
| ... | ... | @@ -5968,10 +5968,10 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5968 | 5968 | // additional `mov` is needed at the end to get the actual value |
| 5969 | 5969 | |
| 5970 | 5970 | const result = result: { |
| 5971 | const elem_ty = ptr_ty.elemType2(mod); | |
| 5972 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 5971 | const elem_ty = ptr_ty.elemType2(zcu); | |
| 5972 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 5973 | 5973 | |
| 5974 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 5974 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 5975 | 5975 | const index_ty = self.typeOf(bin_op.rhs); |
| 5976 | 5976 | const index_mcv = try self.resolveInst(bin_op.rhs); |
| 5977 | 5977 | const index_lock = switch (index_mcv) { |
| ... | ... | @@ -6011,7 +6011,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6011 | 6011 | |
| 6012 | 6012 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6013 | 6013 | const pt = self.pt; |
| 6014 | const mod = pt.zcu; | |
| 6014 | const zcu = pt.zcu; | |
| 6015 | 6015 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6016 | 6016 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6017 | 6017 | |
| ... | ... | @@ -6026,15 +6026,15 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6026 | 6026 | }; |
| 6027 | 6027 | defer if (base_ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 6028 | 6028 | |
| 6029 | if (elem_ptr_ty.ptrInfo(mod).flags.vector_index != .none) { | |
| 6029 | if (elem_ptr_ty.ptrInfo(zcu).flags.vector_index != .none) { | |
| 6030 | 6030 | break :result if (self.reuseOperand(inst, extra.lhs, 0, base_ptr_mcv)) |
| 6031 | 6031 | base_ptr_mcv |
| 6032 | 6032 | else |
| 6033 | 6033 | try self.copyToRegisterWithInstTracking(inst, elem_ptr_ty, base_ptr_mcv); |
| 6034 | 6034 | } |
| 6035 | 6035 | |
| 6036 | const elem_ty = base_ptr_ty.elemType2(mod); | |
| 6037 | const elem_abi_size = elem_ty.abiSize(pt); | |
| 6036 | const elem_ty = base_ptr_ty.elemType2(zcu); | |
| 6037 | const elem_abi_size = elem_ty.abiSize(zcu); | |
| 6038 | 6038 | const index_ty = self.typeOf(extra.rhs); |
| 6039 | 6039 | const index_mcv = try self.resolveInst(extra.rhs); |
| 6040 | 6040 | const index_lock: ?RegisterLock = switch (index_mcv) { |
| ... | ... | @@ -6057,12 +6057,12 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6057 | 6057 | |
| 6058 | 6058 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 6059 | 6059 | const pt = self.pt; |
| 6060 | const mod = pt.zcu; | |
| 6060 | const zcu = pt.zcu; | |
| 6061 | 6061 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6062 | 6062 | const ptr_union_ty = self.typeOf(bin_op.lhs); |
| 6063 | const union_ty = ptr_union_ty.childType(mod); | |
| 6063 | const union_ty = ptr_union_ty.childType(zcu); | |
| 6064 | 6064 | const tag_ty = self.typeOf(bin_op.rhs); |
| 6065 | const layout = union_ty.unionGetLayout(pt); | |
| 6065 | const layout = union_ty.unionGetLayout(zcu); | |
| 6066 | 6066 | |
| 6067 | 6067 | if (layout.tag_size == 0) { |
| 6068 | 6068 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | ... | @@ -6101,12 +6101,12 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 6101 | 6101 | } |
| 6102 | 6102 | |
| 6103 | 6103 | fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 6104 | const pt = self.pt; | |
| 6104 | const zcu = self.pt.zcu; | |
| 6105 | 6105 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6106 | 6106 | |
| 6107 | 6107 | const tag_ty = self.typeOfIndex(inst); |
| 6108 | 6108 | const union_ty = self.typeOf(ty_op.operand); |
| 6109 | const layout = union_ty.unionGetLayout(pt); | |
| 6109 | const layout = union_ty.unionGetLayout(zcu); | |
| 6110 | 6110 | |
| 6111 | 6111 | if (layout.tag_size == 0) { |
| 6112 | 6112 | return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -6120,7 +6120,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 6120 | 6120 | }; |
| 6121 | 6121 | defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); |
| 6122 | 6122 | |
| 6123 | const tag_abi_size = tag_ty.abiSize(pt); | |
| 6123 | const tag_abi_size = tag_ty.abiSize(zcu); | |
| 6124 | 6124 | const dst_mcv: MCValue = blk: { |
| 6125 | 6125 | switch (operand) { |
| 6126 | 6126 | .load_frame => |frame_addr| { |
| ... | ... | @@ -6159,14 +6159,14 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 6159 | 6159 | |
| 6160 | 6160 | fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6161 | 6161 | const pt = self.pt; |
| 6162 | const mod = pt.zcu; | |
| 6162 | const zcu = pt.zcu; | |
| 6163 | 6163 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6164 | 6164 | const result = result: { |
| 6165 | 6165 | try self.spillEflagsIfOccupied(); |
| 6166 | 6166 | |
| 6167 | 6167 | const dst_ty = self.typeOfIndex(inst); |
| 6168 | 6168 | const src_ty = self.typeOf(ty_op.operand); |
| 6169 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{ | |
| 6169 | if (src_ty.zigTypeTag(zcu) == .Vector) return self.fail("TODO implement airClz for {}", .{ | |
| 6170 | 6170 | src_ty.fmt(pt), |
| 6171 | 6171 | }); |
| 6172 | 6172 | |
| ... | ... | @@ -6186,8 +6186,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6186 | 6186 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 6187 | 6187 | defer self.register_manager.unlockReg(dst_lock); |
| 6188 | 6188 | |
| 6189 | const abi_size: u31 = @intCast(src_ty.abiSize(pt)); | |
| 6190 | const src_bits: u31 = @intCast(src_ty.bitSize(pt)); | |
| 6189 | const abi_size: u31 = @intCast(src_ty.abiSize(zcu)); | |
| 6190 | const src_bits: u31 = @intCast(src_ty.bitSize(zcu)); | |
| 6191 | 6191 | const has_lzcnt = self.hasFeature(.lzcnt); |
| 6192 | 6192 | if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) { |
| 6193 | 6193 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| ... | ... | @@ -6297,7 +6297,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6297 | 6297 | } |
| 6298 | 6298 | |
| 6299 | 6299 | assert(src_bits <= 64); |
| 6300 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(pt))), 2); | |
| 6300 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(zcu))), 2); | |
| 6301 | 6301 | if (math.isPowerOfTwo(src_bits)) { |
| 6302 | 6302 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ |
| 6303 | 6303 | .immediate = src_bits ^ (src_bits - 1), |
| ... | ... | @@ -6356,14 +6356,14 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 6356 | 6356 | |
| 6357 | 6357 | fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6358 | 6358 | const pt = self.pt; |
| 6359 | const mod = pt.zcu; | |
| 6359 | const zcu = pt.zcu; | |
| 6360 | 6360 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6361 | 6361 | const result = result: { |
| 6362 | 6362 | try self.spillEflagsIfOccupied(); |
| 6363 | 6363 | |
| 6364 | 6364 | const dst_ty = self.typeOfIndex(inst); |
| 6365 | 6365 | const src_ty = self.typeOf(ty_op.operand); |
| 6366 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airCtz for {}", .{ | |
| 6366 | if (src_ty.zigTypeTag(zcu) == .Vector) return self.fail("TODO implement airCtz for {}", .{ | |
| 6367 | 6367 | src_ty.fmt(pt), |
| 6368 | 6368 | }); |
| 6369 | 6369 | |
| ... | ... | @@ -6383,8 +6383,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6383 | 6383 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 6384 | 6384 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 6385 | 6385 | |
| 6386 | const abi_size: u31 = @intCast(src_ty.abiSize(pt)); | |
| 6387 | const src_bits: u31 = @intCast(src_ty.bitSize(pt)); | |
| 6386 | const abi_size: u31 = @intCast(src_ty.abiSize(zcu)); | |
| 6387 | const src_bits: u31 = @intCast(src_ty.bitSize(zcu)); | |
| 6388 | 6388 | const has_bmi = self.hasFeature(.bmi); |
| 6389 | 6389 | if (src_bits > @as(u32, if (has_bmi) 128 else 64)) { |
| 6390 | 6390 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| ... | ... | @@ -6505,7 +6505,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6505 | 6505 | try self.genBinOpMir(.{ ._, .bsf }, wide_ty, dst_mcv, .{ .register = wide_reg }); |
| 6506 | 6506 | } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv); |
| 6507 | 6507 | |
| 6508 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(pt))), 2); | |
| 6508 | const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(zcu))), 2); | |
| 6509 | 6509 | try self.asmCmovccRegisterRegister( |
| 6510 | 6510 | .z, |
| 6511 | 6511 | registerAlias(dst_reg, cmov_abi_size), |
| ... | ... | @@ -6518,14 +6518,14 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 6518 | 6518 | |
| 6519 | 6519 | fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { |
| 6520 | 6520 | const pt = self.pt; |
| 6521 | const mod = pt.zcu; | |
| 6521 | const zcu = pt.zcu; | |
| 6522 | 6522 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6523 | 6523 | const result: MCValue = result: { |
| 6524 | 6524 | try self.spillEflagsIfOccupied(); |
| 6525 | 6525 | |
| 6526 | 6526 | const src_ty = self.typeOf(ty_op.operand); |
| 6527 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 6528 | if (src_ty.zigTypeTag(mod) == .Vector or src_abi_size > 16) | |
| 6527 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 6528 | if (src_ty.zigTypeTag(zcu) == .Vector or src_abi_size > 16) | |
| 6529 | 6529 | return self.fail("TODO implement airPopCount for {}", .{src_ty.fmt(pt)}); |
| 6530 | 6530 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6531 | 6531 | |
| ... | ... | @@ -6562,7 +6562,7 @@ fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { |
| 6562 | 6562 | mat_src_mcv |
| 6563 | 6563 | else |
| 6564 | 6564 | .{ .register = mat_src_mcv.register_pair[0] }, false); |
| 6565 | const src_info = src_ty.intInfo(mod); | |
| 6565 | const src_info = src_ty.intInfo(zcu); | |
| 6566 | 6566 | const hi_ty = try pt.intType(src_info.signedness, (src_info.bits - 1) % 64 + 1); |
| 6567 | 6567 | try self.genPopCount(tmp_regs[1], hi_ty, if (mat_src_mcv.isMemory()) |
| 6568 | 6568 | mat_src_mcv.address().offset(8).deref() |
| ... | ... | @@ -6583,7 +6583,7 @@ fn genPopCount( |
| 6583 | 6583 | ) !void { |
| 6584 | 6584 | const pt = self.pt; |
| 6585 | 6585 | |
| 6586 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 6586 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt.zcu)); | |
| 6587 | 6587 | if (self.hasFeature(.popcnt)) return self.genBinOpMir( |
| 6588 | 6588 | .{ ._, .popcnt }, |
| 6589 | 6589 | if (src_abi_size > 1) src_ty else Type.u32, |
| ... | ... | @@ -6674,11 +6674,11 @@ fn genByteSwap( |
| 6674 | 6674 | mem_ok: bool, |
| 6675 | 6675 | ) !MCValue { |
| 6676 | 6676 | const pt = self.pt; |
| 6677 | const mod = pt.zcu; | |
| 6677 | const zcu = pt.zcu; | |
| 6678 | 6678 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6679 | 6679 | const has_movbe = self.hasFeature(.movbe); |
| 6680 | 6680 | |
| 6681 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail( | |
| 6681 | if (src_ty.zigTypeTag(zcu) == .Vector) return self.fail( | |
| 6682 | 6682 | "TODO implement genByteSwap for {}", |
| 6683 | 6683 | .{src_ty.fmt(pt)}, |
| 6684 | 6684 | ); |
| ... | ... | @@ -6689,7 +6689,7 @@ fn genByteSwap( |
| 6689 | 6689 | }; |
| 6690 | 6690 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 6691 | 6691 | |
| 6692 | const abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 6692 | const abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 6693 | 6693 | switch (abi_size) { |
| 6694 | 6694 | 0 => unreachable, |
| 6695 | 6695 | 1 => return if ((mem_ok or src_mcv.isRegister()) and |
| ... | ... | @@ -6838,35 +6838,35 @@ fn genByteSwap( |
| 6838 | 6838 | |
| 6839 | 6839 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 6840 | 6840 | const pt = self.pt; |
| 6841 | const mod = pt.zcu; | |
| 6841 | const zcu = pt.zcu; | |
| 6842 | 6842 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6843 | 6843 | |
| 6844 | 6844 | const src_ty = self.typeOf(ty_op.operand); |
| 6845 | const src_bits: u32 = @intCast(src_ty.bitSize(pt)); | |
| 6845 | const src_bits: u32 = @intCast(src_ty.bitSize(zcu)); | |
| 6846 | 6846 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6847 | 6847 | |
| 6848 | 6848 | const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true); |
| 6849 | 6849 | try self.genShiftBinOpMir( |
| 6850 | .{ ._r, switch (if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned) { | |
| 6850 | .{ ._r, switch (if (src_ty.isAbiInt(zcu)) src_ty.intInfo(zcu).signedness else .unsigned) { | |
| 6851 | 6851 | .signed => .sa, |
| 6852 | 6852 | .unsigned => .sh, |
| 6853 | 6853 | } }, |
| 6854 | 6854 | src_ty, |
| 6855 | 6855 | dst_mcv, |
| 6856 | 6856 | if (src_bits > 256) Type.u16 else Type.u8, |
| 6857 | .{ .immediate = src_ty.abiSize(pt) * 8 - src_bits }, | |
| 6857 | .{ .immediate = src_ty.abiSize(zcu) * 8 - src_bits }, | |
| 6858 | 6858 | ); |
| 6859 | 6859 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| 6860 | 6860 | } |
| 6861 | 6861 | |
| 6862 | 6862 | fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6863 | 6863 | const pt = self.pt; |
| 6864 | const mod = pt.zcu; | |
| 6864 | const zcu = pt.zcu; | |
| 6865 | 6865 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6866 | 6866 | |
| 6867 | 6867 | const src_ty = self.typeOf(ty_op.operand); |
| 6868 | const abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 6869 | const bit_size: u32 = @intCast(src_ty.bitSize(pt)); | |
| 6868 | const abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 6869 | const bit_size: u32 = @intCast(src_ty.bitSize(zcu)); | |
| 6870 | 6870 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 6871 | 6871 | |
| 6872 | 6872 | const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, false); |
| ... | ... | @@ -6973,7 +6973,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6973 | 6973 | |
| 6974 | 6974 | const extra_bits = abi_size * 8 - bit_size; |
| 6975 | 6975 | const signedness: std.builtin.Signedness = |
| 6976 | if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; | |
| 6976 | if (src_ty.isAbiInt(zcu)) src_ty.intInfo(zcu).signedness else .unsigned; | |
| 6977 | 6977 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { |
| 6978 | 6978 | .signed => .{ ._r, .sa }, |
| 6979 | 6979 | .unsigned => .{ ._r, .sh }, |
| ... | ... | @@ -6984,13 +6984,13 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6984 | 6984 | |
| 6985 | 6985 | fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) !void { |
| 6986 | 6986 | const pt = self.pt; |
| 6987 | const mod = pt.zcu; | |
| 6987 | const zcu = pt.zcu; | |
| 6988 | 6988 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 6989 | 6989 | |
| 6990 | 6990 | const result = result: { |
| 6991 | const scalar_bits = ty.scalarType(mod).floatBits(self.target.*); | |
| 6991 | const scalar_bits = ty.scalarType(zcu).floatBits(self.target.*); | |
| 6992 | 6992 | if (scalar_bits == 80) { |
| 6993 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement floatSign for {}", .{ | |
| 6993 | if (ty.zigTypeTag(zcu) != .Float) return self.fail("TODO implement floatSign for {}", .{ | |
| 6994 | 6994 | ty.fmt(pt), |
| 6995 | 6995 | }); |
| 6996 | 6996 | |
| ... | ... | @@ -7011,7 +7011,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 7011 | 7011 | break :result dst_mcv; |
| 7012 | 7012 | } |
| 7013 | 7013 | |
| 7014 | const abi_size: u32 = switch (ty.abiSize(pt)) { | |
| 7014 | const abi_size: u32 = switch (ty.abiSize(zcu)) { | |
| 7015 | 7015 | 1...16 => 16, |
| 7016 | 7016 | 17...32 => 32, |
| 7017 | 7017 | else => return self.fail("TODO implement floatSign for {}", .{ |
| ... | ... | @@ -7161,23 +7161,23 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void { |
| 7161 | 7161 | |
| 7162 | 7162 | fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { |
| 7163 | 7163 | const pt = self.pt; |
| 7164 | const mod = pt.zcu; | |
| 7165 | return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) { | |
| 7164 | const zcu = pt.zcu; | |
| 7165 | return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(zcu)) { | |
| 7166 | 7166 | .Float => switch (ty.floatBits(self.target.*)) { |
| 7167 | 7167 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, |
| 7168 | 7168 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round }, |
| 7169 | 7169 | 16, 80, 128 => null, |
| 7170 | 7170 | else => unreachable, |
| 7171 | 7171 | }, |
| 7172 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 7173 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 7174 | 32 => switch (ty.vectorLen(mod)) { | |
| 7172 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 7173 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 7174 | 32 => switch (ty.vectorLen(zcu)) { | |
| 7175 | 7175 | 1 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, |
| 7176 | 7176 | 2...4 => if (self.hasFeature(.avx)) .{ .v_ps, .round } else .{ ._ps, .round }, |
| 7177 | 7177 | 5...8 => if (self.hasFeature(.avx)) .{ .v_ps, .round } else null, |
| 7178 | 7178 | else => null, |
| 7179 | 7179 | }, |
| 7180 | 64 => switch (ty.vectorLen(mod)) { | |
| 7180 | 64 => switch (ty.vectorLen(zcu)) { | |
| 7181 | 7181 | 1 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round }, |
| 7182 | 7182 | 2 => if (self.hasFeature(.avx)) .{ .v_pd, .round } else .{ ._pd, .round }, |
| 7183 | 7183 | 3...4 => if (self.hasFeature(.avx)) .{ .v_pd, .round } else null, |
| ... | ... | @@ -7194,10 +7194,10 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { |
| 7194 | 7194 | |
| 7195 | 7195 | fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MCValue { |
| 7196 | 7196 | const pt = self.pt; |
| 7197 | const mod = pt.zcu; | |
| 7197 | const zcu = pt.zcu; | |
| 7198 | 7198 | if (self.getRoundTag(ty)) |_| return .none; |
| 7199 | 7199 | |
| 7200 | if (ty.zigTypeTag(mod) != .Float) | |
| 7200 | if (ty.zigTypeTag(zcu) != .Float) | |
| 7201 | 7201 | return self.fail("TODO implement genRound for {}", .{ty.fmt(pt)}); |
| 7202 | 7202 | |
| 7203 | 7203 | var callee_buf: ["__trunc?".len]u8 = undefined; |
| ... | ... | @@ -7223,7 +7223,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 7223 | 7223 | const result = try self.genRoundLibcall(ty, src_mcv, mode); |
| 7224 | 7224 | return self.genSetReg(dst_reg, ty, result, .{}); |
| 7225 | 7225 | }; |
| 7226 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 7226 | const abi_size: u32 = @intCast(ty.abiSize(pt.zcu)); | |
| 7227 | 7227 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 7228 | 7228 | switch (mir_tag[0]) { |
| 7229 | 7229 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( |
| ... | ... | @@ -7261,14 +7261,14 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 7261 | 7261 | |
| 7262 | 7262 | fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7263 | 7263 | const pt = self.pt; |
| 7264 | const mod = pt.zcu; | |
| 7264 | const zcu = pt.zcu; | |
| 7265 | 7265 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7266 | 7266 | const ty = self.typeOf(ty_op.operand); |
| 7267 | 7267 | |
| 7268 | 7268 | const result: MCValue = result: { |
| 7269 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { | |
| 7269 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(zcu)) { | |
| 7270 | 7270 | else => null, |
| 7271 | .Int => switch (ty.abiSize(pt)) { | |
| 7271 | .Int => switch (ty.abiSize(zcu)) { | |
| 7272 | 7272 | 0 => unreachable, |
| 7273 | 7273 | 1...8 => { |
| 7274 | 7274 | try self.spillEflagsIfOccupied(); |
| ... | ... | @@ -7277,7 +7277,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7277 | 7277 | |
| 7278 | 7278 | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); |
| 7279 | 7279 | |
| 7280 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(pt))), 2); | |
| 7280 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2); | |
| 7281 | 7281 | switch (src_mcv) { |
| 7282 | 7282 | .register => |val_reg| try self.asmCmovccRegisterRegister( |
| 7283 | 7283 | .l, |
| ... | ... | @@ -7336,7 +7336,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7336 | 7336 | break :result dst_mcv; |
| 7337 | 7337 | }, |
| 7338 | 7338 | else => { |
| 7339 | const abi_size: u31 = @intCast(ty.abiSize(pt)); | |
| 7339 | const abi_size: u31 = @intCast(ty.abiSize(zcu)); | |
| 7340 | 7340 | const limb_len = math.divCeil(u31, abi_size, 8) catch unreachable; |
| 7341 | 7341 | |
| 7342 | 7342 | const tmp_regs = |
| ... | ... | @@ -7397,11 +7397,11 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7397 | 7397 | }, |
| 7398 | 7398 | }, |
| 7399 | 7399 | .Float => return self.floatSign(inst, ty_op.operand, ty), |
| 7400 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 7400 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 7401 | 7401 | else => null, |
| 7402 | .Int => switch (ty.childType(mod).intInfo(mod).bits) { | |
| 7402 | .Int => switch (ty.childType(zcu).intInfo(zcu).bits) { | |
| 7403 | 7403 | else => null, |
| 7404 | 8 => switch (ty.vectorLen(mod)) { | |
| 7404 | 8 => switch (ty.vectorLen(zcu)) { | |
| 7405 | 7405 | else => null, |
| 7406 | 7406 | 1...16 => if (self.hasFeature(.avx)) |
| 7407 | 7407 | .{ .vp_b, .abs } |
| ... | ... | @@ -7411,7 +7411,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7411 | 7411 | null, |
| 7412 | 7412 | 17...32 => if (self.hasFeature(.avx2)) .{ .vp_b, .abs } else null, |
| 7413 | 7413 | }, |
| 7414 | 16 => switch (ty.vectorLen(mod)) { | |
| 7414 | 16 => switch (ty.vectorLen(zcu)) { | |
| 7415 | 7415 | else => null, |
| 7416 | 7416 | 1...8 => if (self.hasFeature(.avx)) |
| 7417 | 7417 | .{ .vp_w, .abs } |
| ... | ... | @@ -7421,7 +7421,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7421 | 7421 | null, |
| 7422 | 7422 | 9...16 => if (self.hasFeature(.avx2)) .{ .vp_w, .abs } else null, |
| 7423 | 7423 | }, |
| 7424 | 32 => switch (ty.vectorLen(mod)) { | |
| 7424 | 32 => switch (ty.vectorLen(zcu)) { | |
| 7425 | 7425 | else => null, |
| 7426 | 7426 | 1...4 => if (self.hasFeature(.avx)) |
| 7427 | 7427 | .{ .vp_d, .abs } |
| ... | ... | @@ -7436,7 +7436,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7436 | 7436 | }, |
| 7437 | 7437 | }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(pt)}); |
| 7438 | 7438 | |
| 7439 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 7439 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 7440 | 7440 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 7441 | 7441 | const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 7442 | 7442 | src_mcv.getReg().? |
| ... | ... | @@ -7462,13 +7462,13 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7462 | 7462 | |
| 7463 | 7463 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7464 | 7464 | const pt = self.pt; |
| 7465 | const mod = pt.zcu; | |
| 7465 | const zcu = pt.zcu; | |
| 7466 | 7466 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 7467 | 7467 | const ty = self.typeOf(un_op); |
| 7468 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 7468 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 7469 | 7469 | |
| 7470 | 7470 | const result: MCValue = result: { |
| 7471 | switch (ty.zigTypeTag(mod)) { | |
| 7471 | switch (ty.zigTypeTag(zcu)) { | |
| 7472 | 7472 | .Float => { |
| 7473 | 7473 | const float_bits = ty.floatBits(self.target.*); |
| 7474 | 7474 | if (switch (float_bits) { |
| ... | ... | @@ -7500,7 +7500,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7500 | 7500 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 7501 | 7501 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 7502 | 7502 | |
| 7503 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { | |
| 7503 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(zcu)) { | |
| 7504 | 7504 | .Float => switch (ty.floatBits(self.target.*)) { |
| 7505 | 7505 | 16 => { |
| 7506 | 7506 | assert(self.hasFeature(.f16c)); |
| ... | ... | @@ -7522,9 +7522,9 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7522 | 7522 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .sqrt } else .{ ._sd, .sqrt }, |
| 7523 | 7523 | else => unreachable, |
| 7524 | 7524 | }, |
| 7525 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 7526 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 7527 | 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen(mod)) { | |
| 7525 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 7526 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 7527 | 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen(zcu)) { | |
| 7528 | 7528 | 1 => { |
| 7529 | 7529 | try self.asmRegisterRegister( |
| 7530 | 7530 | .{ .v_ps, .cvtph2 }, |
| ... | ... | @@ -7575,13 +7575,13 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7575 | 7575 | }, |
| 7576 | 7576 | else => null, |
| 7577 | 7577 | } else null, |
| 7578 | 32 => switch (ty.vectorLen(mod)) { | |
| 7578 | 32 => switch (ty.vectorLen(zcu)) { | |
| 7579 | 7579 | 1 => if (self.hasFeature(.avx)) .{ .v_ss, .sqrt } else .{ ._ss, .sqrt }, |
| 7580 | 7580 | 2...4 => if (self.hasFeature(.avx)) .{ .v_ps, .sqrt } else .{ ._ps, .sqrt }, |
| 7581 | 7581 | 5...8 => if (self.hasFeature(.avx)) .{ .v_ps, .sqrt } else null, |
| 7582 | 7582 | else => null, |
| 7583 | 7583 | }, |
| 7584 | 64 => switch (ty.vectorLen(mod)) { | |
| 7584 | 64 => switch (ty.vectorLen(zcu)) { | |
| 7585 | 7585 | 1 => if (self.hasFeature(.avx)) .{ .v_sd, .sqrt } else .{ ._sd, .sqrt }, |
| 7586 | 7586 | 2 => if (self.hasFeature(.avx)) .{ .v_pd, .sqrt } else .{ ._pd, .sqrt }, |
| 7587 | 7587 | 3...4 => if (self.hasFeature(.avx)) .{ .v_pd, .sqrt } else null, |
| ... | ... | @@ -7708,14 +7708,14 @@ fn reuseOperandAdvanced( |
| 7708 | 7708 | |
| 7709 | 7709 | fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { |
| 7710 | 7710 | const pt = self.pt; |
| 7711 | const mod = pt.zcu; | |
| 7711 | const zcu = pt.zcu; | |
| 7712 | 7712 | |
| 7713 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 7713 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 7714 | 7714 | const val_ty = Type.fromInterned(ptr_info.child); |
| 7715 | if (!val_ty.hasRuntimeBitsIgnoreComptime(pt)) return; | |
| 7716 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); | |
| 7715 | if (!val_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; | |
| 7716 | const val_abi_size: u32 = @intCast(val_ty.abiSize(zcu)); | |
| 7717 | 7717 | |
| 7718 | const val_bit_size: u32 = @intCast(val_ty.bitSize(pt)); | |
| 7718 | const val_bit_size: u32 = @intCast(val_ty.bitSize(zcu)); | |
| 7719 | 7719 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 7720 | 7720 | .none => 0, |
| 7721 | 7721 | .runtime => unreachable, |
| ... | ... | @@ -7821,9 +7821,9 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 7821 | 7821 | |
| 7822 | 7822 | fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { |
| 7823 | 7823 | const pt = self.pt; |
| 7824 | const mod = pt.zcu; | |
| 7825 | const dst_ty = ptr_ty.childType(mod); | |
| 7826 | if (!dst_ty.hasRuntimeBitsIgnoreComptime(pt)) return; | |
| 7824 | const zcu = pt.zcu; | |
| 7825 | const dst_ty = ptr_ty.childType(zcu); | |
| 7826 | if (!dst_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; | |
| 7827 | 7827 | switch (ptr_mcv) { |
| 7828 | 7828 | .none, |
| 7829 | 7829 | .unreach, |
| ... | ... | @@ -7864,18 +7864,18 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 7864 | 7864 | |
| 7865 | 7865 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7866 | 7866 | const pt = self.pt; |
| 7867 | const mod = pt.zcu; | |
| 7867 | const zcu = pt.zcu; | |
| 7868 | 7868 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7869 | 7869 | const elem_ty = self.typeOfIndex(inst); |
| 7870 | 7870 | const result: MCValue = result: { |
| 7871 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 7871 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 7872 | 7872 | |
| 7873 | 7873 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); |
| 7874 | 7874 | const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx }); |
| 7875 | 7875 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); |
| 7876 | 7876 | |
| 7877 | 7877 | const ptr_ty = self.typeOf(ty_op.operand); |
| 7878 | const elem_size = elem_ty.abiSize(pt); | |
| 7878 | const elem_size = elem_ty.abiSize(zcu); | |
| 7879 | 7879 | |
| 7880 | 7880 | const elem_rc = self.regClassForType(elem_ty); |
| 7881 | 7881 | const ptr_rc = self.regClassForType(ptr_ty); |
| ... | ... | @@ -7888,14 +7888,14 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7888 | 7888 | else |
| 7889 | 7889 | try self.allocRegOrMem(inst, true); |
| 7890 | 7890 | |
| 7891 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 7891 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 7892 | 7892 | if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { |
| 7893 | 7893 | try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv); |
| 7894 | 7894 | } else { |
| 7895 | 7895 | try self.load(dst_mcv, ptr_ty, ptr_mcv); |
| 7896 | 7896 | } |
| 7897 | 7897 | |
| 7898 | if (elem_ty.isAbiInt(mod) and elem_size * 8 > elem_ty.bitSize(pt)) { | |
| 7898 | if (elem_ty.isAbiInt(zcu) and elem_size * 8 > elem_ty.bitSize(zcu)) { | |
| 7899 | 7899 | const high_mcv: MCValue = switch (dst_mcv) { |
| 7900 | 7900 | .register => |dst_reg| .{ .register = dst_reg }, |
| 7901 | 7901 | .register_pair => |dst_regs| .{ .register = dst_regs[1] }, |
| ... | ... | @@ -7923,16 +7923,16 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7923 | 7923 | |
| 7924 | 7924 | fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 7925 | 7925 | const pt = self.pt; |
| 7926 | const mod = pt.zcu; | |
| 7927 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 7926 | const zcu = pt.zcu; | |
| 7927 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 7928 | 7928 | const src_ty = Type.fromInterned(ptr_info.child); |
| 7929 | if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) return; | |
| 7929 | if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; | |
| 7930 | 7930 | |
| 7931 | 7931 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); |
| 7932 | 7932 | const limb_abi_bits = limb_abi_size * 8; |
| 7933 | 7933 | const limb_ty = try pt.intType(.unsigned, limb_abi_bits); |
| 7934 | 7934 | |
| 7935 | const src_bit_size = src_ty.bitSize(pt); | |
| 7935 | const src_bit_size = src_ty.bitSize(zcu); | |
| 7936 | 7936 | const ptr_bit_off = ptr_info.packed_offset.bit_offset + switch (ptr_info.flags.vector_index) { |
| 7937 | 7937 | .none => 0, |
| 7938 | 7938 | .runtime => unreachable, |
| ... | ... | @@ -8029,9 +8029,9 @@ fn store( |
| 8029 | 8029 | opts: CopyOptions, |
| 8030 | 8030 | ) InnerError!void { |
| 8031 | 8031 | const pt = self.pt; |
| 8032 | const mod = pt.zcu; | |
| 8033 | const src_ty = ptr_ty.childType(mod); | |
| 8034 | if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) return; | |
| 8032 | const zcu = pt.zcu; | |
| 8033 | const src_ty = ptr_ty.childType(zcu); | |
| 8034 | if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; | |
| 8035 | 8035 | switch (ptr_mcv) { |
| 8036 | 8036 | .none, |
| 8037 | 8037 | .unreach, |
| ... | ... | @@ -8072,7 +8072,7 @@ fn store( |
| 8072 | 8072 | |
| 8073 | 8073 | fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 8074 | 8074 | const pt = self.pt; |
| 8075 | const mod = pt.zcu; | |
| 8075 | const zcu = pt.zcu; | |
| 8076 | 8076 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8077 | 8077 | |
| 8078 | 8078 | result: { |
| ... | ... | @@ -8086,7 +8086,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 8086 | 8086 | const ptr_mcv = try self.resolveInst(bin_op.lhs); |
| 8087 | 8087 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 8088 | 8088 | |
| 8089 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 8089 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 8090 | 8090 | if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { |
| 8091 | 8091 | try self.packedStore(ptr_ty, ptr_mcv, src_mcv); |
| 8092 | 8092 | } else { |
| ... | ... | @@ -8111,16 +8111,16 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 8111 | 8111 | |
| 8112 | 8112 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 8113 | 8113 | const pt = self.pt; |
| 8114 | const mod = pt.zcu; | |
| 8114 | const zcu = pt.zcu; | |
| 8115 | 8115 | const ptr_field_ty = self.typeOfIndex(inst); |
| 8116 | 8116 | const ptr_container_ty = self.typeOf(operand); |
| 8117 | const container_ty = ptr_container_ty.childType(mod); | |
| 8117 | const container_ty = ptr_container_ty.childType(zcu); | |
| 8118 | 8118 | |
| 8119 | const field_off: i32 = switch (container_ty.containerLayout(mod)) { | |
| 8120 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, pt)), | |
| 8121 | .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(mod).packed_offset.bit_offset) + | |
| 8122 | (if (mod.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, index) else 0) - | |
| 8123 | ptr_field_ty.ptrInfo(mod).packed_offset.bit_offset, 8), | |
| 8119 | const field_off: i32 = switch (container_ty.containerLayout(zcu)) { | |
| 8120 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(index, zcu)), | |
| 8121 | .@"packed" => @divExact(@as(i32, ptr_container_ty.ptrInfo(zcu).packed_offset.bit_offset) + | |
| 8122 | (if (zcu.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, index) else 0) - | |
| 8123 | ptr_field_ty.ptrInfo(zcu).packed_offset.bit_offset, 8), | |
| 8124 | 8124 | }; |
| 8125 | 8125 | |
| 8126 | 8126 | const src_mcv = try self.resolveInst(operand); |
| ... | ... | @@ -8134,7 +8134,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 |
| 8134 | 8134 | |
| 8135 | 8135 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8136 | 8136 | const pt = self.pt; |
| 8137 | const mod = pt.zcu; | |
| 8137 | const zcu = pt.zcu; | |
| 8138 | 8138 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8139 | 8139 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 8140 | 8140 | const result: MCValue = result: { |
| ... | ... | @@ -8143,15 +8143,15 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8143 | 8143 | |
| 8144 | 8144 | const container_ty = self.typeOf(operand); |
| 8145 | 8145 | const container_rc = self.regClassForType(container_ty); |
| 8146 | const field_ty = container_ty.structFieldType(index, mod); | |
| 8147 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result .none; | |
| 8146 | const field_ty = container_ty.structFieldType(index, zcu); | |
| 8147 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | |
| 8148 | 8148 | const field_rc = self.regClassForType(field_ty); |
| 8149 | 8149 | const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp); |
| 8150 | 8150 | |
| 8151 | 8151 | const src_mcv = try self.resolveInst(operand); |
| 8152 | const field_off: u32 = switch (container_ty.containerLayout(mod)) { | |
| 8153 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, pt) * 8), | |
| 8154 | .@"packed" => if (mod.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0, | |
| 8152 | const field_off: u32 = switch (container_ty.containerLayout(zcu)) { | |
| 8153 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, zcu) * 8), | |
| 8154 | .@"packed" => if (zcu.typeToStruct(container_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0, | |
| 8155 | 8155 | }; |
| 8156 | 8156 | |
| 8157 | 8157 | switch (src_mcv) { |
| ... | ... | @@ -8182,7 +8182,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8182 | 8182 | ); |
| 8183 | 8183 | } |
| 8184 | 8184 | if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and |
| 8185 | container_ty.abiSize(pt) * 8 > field_ty.bitSize(pt)) | |
| 8185 | container_ty.abiSize(zcu) * 8 > field_ty.bitSize(zcu)) | |
| 8186 | 8186 | try self.truncateRegister(field_ty, dst_reg); |
| 8187 | 8187 | |
| 8188 | 8188 | break :result if (field_off == 0 or field_rc.supersetOf(abi.RegisterClass.gp)) |
| ... | ... | @@ -8194,7 +8194,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8194 | 8194 | const src_regs_lock = self.register_manager.lockRegsAssumeUnused(2, src_regs); |
| 8195 | 8195 | defer for (src_regs_lock) |lock| self.register_manager.unlockReg(lock); |
| 8196 | 8196 | |
| 8197 | const field_bit_size: u32 = @intCast(field_ty.bitSize(pt)); | |
| 8197 | const field_bit_size: u32 = @intCast(field_ty.bitSize(zcu)); | |
| 8198 | 8198 | const src_reg = if (field_off + field_bit_size <= 64) |
| 8199 | 8199 | src_regs[0] |
| 8200 | 8200 | else if (field_off >= 64) |
| ... | ... | @@ -8293,15 +8293,15 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8293 | 8293 | } |
| 8294 | 8294 | }, |
| 8295 | 8295 | .load_frame => |frame_addr| { |
| 8296 | const field_abi_size: u32 = @intCast(field_ty.abiSize(pt)); | |
| 8296 | const field_abi_size: u32 = @intCast(field_ty.abiSize(zcu)); | |
| 8297 | 8297 | if (field_off % 8 == 0) { |
| 8298 | 8298 | const field_byte_off = @divExact(field_off, 8); |
| 8299 | 8299 | const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref(); |
| 8300 | const field_bit_size = field_ty.bitSize(pt); | |
| 8300 | const field_bit_size = field_ty.bitSize(zcu); | |
| 8301 | 8301 | |
| 8302 | 8302 | if (field_abi_size <= 8) { |
| 8303 | 8303 | const int_ty = try pt.intType( |
| 8304 | if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned, | |
| 8304 | if (field_ty.isAbiInt(zcu)) field_ty.intInfo(zcu).signedness else .unsigned, | |
| 8305 | 8305 | @intCast(field_bit_size), |
| 8306 | 8306 | ); |
| 8307 | 8307 | |
| ... | ... | @@ -8321,7 +8321,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8321 | 8321 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 8322 | 8322 | } |
| 8323 | 8323 | |
| 8324 | const container_abi_size: u32 = @intCast(container_ty.abiSize(pt)); | |
| 8324 | const container_abi_size: u32 = @intCast(container_ty.abiSize(zcu)); | |
| 8325 | 8325 | const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and |
| 8326 | 8326 | self.reuseOperand(inst, operand, 0, src_mcv)) |
| 8327 | 8327 | off_mcv |
| ... | ... | @@ -8423,17 +8423,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8423 | 8423 | |
| 8424 | 8424 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 8425 | 8425 | const pt = self.pt; |
| 8426 | const mod = pt.zcu; | |
| 8426 | const zcu = pt.zcu; | |
| 8427 | 8427 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8428 | 8428 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 8429 | 8429 | |
| 8430 | 8430 | const inst_ty = self.typeOfIndex(inst); |
| 8431 | const parent_ty = inst_ty.childType(mod); | |
| 8432 | const field_off: i32 = switch (parent_ty.containerLayout(mod)) { | |
| 8433 | .auto, .@"extern" => @intCast(parent_ty.structFieldOffset(extra.field_index, pt)), | |
| 8434 | .@"packed" => @divExact(@as(i32, inst_ty.ptrInfo(mod).packed_offset.bit_offset) + | |
| 8435 | (if (mod.typeToStruct(parent_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0) - | |
| 8436 | self.typeOf(extra.field_ptr).ptrInfo(mod).packed_offset.bit_offset, 8), | |
| 8431 | const parent_ty = inst_ty.childType(zcu); | |
| 8432 | const field_off: i32 = switch (parent_ty.containerLayout(zcu)) { | |
| 8433 | .auto, .@"extern" => @intCast(parent_ty.structFieldOffset(extra.field_index, zcu)), | |
| 8434 | .@"packed" => @divExact(@as(i32, inst_ty.ptrInfo(zcu).packed_offset.bit_offset) + | |
| 8435 | (if (zcu.typeToStruct(parent_ty)) |struct_obj| pt.structPackedFieldBitOffset(struct_obj, extra.field_index) else 0) - | |
| 8436 | self.typeOf(extra.field_ptr).ptrInfo(zcu).packed_offset.bit_offset, 8), | |
| 8437 | 8437 | }; |
| 8438 | 8438 | |
| 8439 | 8439 | const src_mcv = try self.resolveInst(extra.field_ptr); |
| ... | ... | @@ -8448,9 +8448,9 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 8448 | 8448 | |
| 8449 | 8449 | fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue { |
| 8450 | 8450 | const pt = self.pt; |
| 8451 | const mod = pt.zcu; | |
| 8451 | const zcu = pt.zcu; | |
| 8452 | 8452 | const src_ty = self.typeOf(src_air); |
| 8453 | if (src_ty.zigTypeTag(mod) == .Vector) | |
| 8453 | if (src_ty.zigTypeTag(zcu) == .Vector) | |
| 8454 | 8454 | return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(pt)}); |
| 8455 | 8455 | |
| 8456 | 8456 | var src_mcv = try self.resolveInst(src_air); |
| ... | ... | @@ -8486,14 +8486,14 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 8486 | 8486 | }; |
| 8487 | 8487 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 8488 | 8488 | |
| 8489 | const abi_size: u16 = @intCast(src_ty.abiSize(pt)); | |
| 8489 | const abi_size: u16 = @intCast(src_ty.abiSize(zcu)); | |
| 8490 | 8490 | switch (tag) { |
| 8491 | 8491 | .not => { |
| 8492 | 8492 | const limb_abi_size: u16 = @min(abi_size, 8); |
| 8493 | 8493 | const int_info = if (src_ty.ip_index == .bool_type) |
| 8494 | 8494 | std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 } |
| 8495 | 8495 | else |
| 8496 | src_ty.intInfo(mod); | |
| 8496 | src_ty.intInfo(zcu); | |
| 8497 | 8497 | var byte_off: i32 = 0; |
| 8498 | 8498 | while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) { |
| 8499 | 8499 | const limb_bits: u16 = @intCast(@min(switch (int_info.signedness) { |
| ... | ... | @@ -8514,7 +8514,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 8514 | 8514 | }, |
| 8515 | 8515 | .neg => { |
| 8516 | 8516 | try self.genUnOpMir(.{ ._, .neg }, src_ty, dst_mcv); |
| 8517 | const bit_size = src_ty.intInfo(mod).bits; | |
| 8517 | const bit_size = src_ty.intInfo(zcu).bits; | |
| 8518 | 8518 | if (abi_size * 8 > bit_size) { |
| 8519 | 8519 | if (dst_mcv.isRegister()) { |
| 8520 | 8520 | try self.truncateRegister(src_ty, dst_mcv.getReg().?); |
| ... | ... | @@ -8537,7 +8537,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 8537 | 8537 | |
| 8538 | 8538 | fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void { |
| 8539 | 8539 | const pt = self.pt; |
| 8540 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 8540 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu)); | |
| 8541 | 8541 | if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(pt) }); |
| 8542 | 8542 | switch (dst_mcv) { |
| 8543 | 8543 | .none, |
| ... | ... | @@ -8586,8 +8586,9 @@ fn genShiftBinOpMir( |
| 8586 | 8586 | rhs_mcv: MCValue, |
| 8587 | 8587 | ) !void { |
| 8588 | 8588 | const pt = self.pt; |
| 8589 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); | |
| 8590 | const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(pt)); | |
| 8589 | const zcu = pt.zcu; | |
| 8590 | const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu)); | |
| 8591 | const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(zcu)); | |
| 8591 | 8592 | try self.spillEflagsIfOccupied(); |
| 8592 | 8593 | |
| 8593 | 8594 | if (abi_size > 16) { |
| ... | ... | @@ -9243,8 +9244,8 @@ fn genShiftBinOp( |
| 9243 | 9244 | rhs_ty: Type, |
| 9244 | 9245 | ) !MCValue { |
| 9245 | 9246 | const pt = self.pt; |
| 9246 | const mod = pt.zcu; | |
| 9247 | if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{ | |
| 9247 | const zcu = pt.zcu; | |
| 9248 | if (lhs_ty.zigTypeTag(zcu) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{ | |
| 9248 | 9249 | lhs_ty.fmt(pt), |
| 9249 | 9250 | }); |
| 9250 | 9251 | |
| ... | ... | @@ -9274,7 +9275,7 @@ fn genShiftBinOp( |
| 9274 | 9275 | break :dst dst_mcv; |
| 9275 | 9276 | }; |
| 9276 | 9277 | |
| 9277 | const signedness = lhs_ty.intInfo(mod).signedness; | |
| 9278 | const signedness = lhs_ty.intInfo(zcu).signedness; | |
| 9278 | 9279 | try self.genShiftBinOpMir(switch (air_tag) { |
| 9279 | 9280 | .shl, .shl_exact => switch (signedness) { |
| 9280 | 9281 | .signed => .{ ._l, .sa }, |
| ... | ... | @@ -9302,13 +9303,13 @@ fn genMulDivBinOp( |
| 9302 | 9303 | rhs_mcv: MCValue, |
| 9303 | 9304 | ) !MCValue { |
| 9304 | 9305 | const pt = self.pt; |
| 9305 | const mod = pt.zcu; | |
| 9306 | if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail( | |
| 9306 | const zcu = pt.zcu; | |
| 9307 | if (dst_ty.zigTypeTag(zcu) == .Vector or dst_ty.zigTypeTag(zcu) == .Float) return self.fail( | |
| 9307 | 9308 | "TODO implement genMulDivBinOp for {s} from {} to {}", |
| 9308 | 9309 | .{ @tagName(tag), src_ty.fmt(pt), dst_ty.fmt(pt) }, |
| 9309 | 9310 | ); |
| 9310 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 9311 | const src_abi_size: u32 = @intCast(src_ty.abiSize(pt)); | |
| 9311 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 9312 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); | |
| 9312 | 9313 | |
| 9313 | 9314 | assert(self.register_manager.isRegFree(.rax)); |
| 9314 | 9315 | assert(self.register_manager.isRegFree(.rcx)); |
| ... | ... | @@ -9384,7 +9385,7 @@ fn genMulDivBinOp( |
| 9384 | 9385 | .mul, .mul_wrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2, |
| 9385 | 9386 | .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_abi_size != src_abi_size, |
| 9386 | 9387 | } or src_abi_size > 8) { |
| 9387 | const src_info = src_ty.intInfo(mod); | |
| 9388 | const src_info = src_ty.intInfo(zcu); | |
| 9388 | 9389 | switch (tag) { |
| 9389 | 9390 | .mul, .mul_wrap => { |
| 9390 | 9391 | const slow_inc = self.hasFeature(.slow_incdec); |
| ... | ... | @@ -9555,7 +9556,7 @@ fn genMulDivBinOp( |
| 9555 | 9556 | const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx }); |
| 9556 | 9557 | defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); |
| 9557 | 9558 | |
| 9558 | const signedness = ty.intInfo(mod).signedness; | |
| 9559 | const signedness = ty.intInfo(zcu).signedness; | |
| 9559 | 9560 | switch (tag) { |
| 9560 | 9561 | .mul, |
| 9561 | 9562 | .mul_wrap, |
| ... | ... | @@ -9714,10 +9715,10 @@ fn genBinOp( |
| 9714 | 9715 | rhs_air: Air.Inst.Ref, |
| 9715 | 9716 | ) !MCValue { |
| 9716 | 9717 | const pt = self.pt; |
| 9717 | const mod = pt.zcu; | |
| 9718 | const zcu = pt.zcu; | |
| 9718 | 9719 | const lhs_ty = self.typeOf(lhs_air); |
| 9719 | 9720 | const rhs_ty = self.typeOf(rhs_air); |
| 9720 | const abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); | |
| 9721 | const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu)); | |
| 9721 | 9722 | |
| 9722 | 9723 | if (lhs_ty.isRuntimeFloat()) libcall: { |
| 9723 | 9724 | const float_bits = lhs_ty.floatBits(self.target.*); |
| ... | ... | @@ -9889,23 +9890,23 @@ fn genBinOp( |
| 9889 | 9890 | }; |
| 9890 | 9891 | } |
| 9891 | 9892 | |
| 9892 | const sse_op = switch (lhs_ty.zigTypeTag(mod)) { | |
| 9893 | const sse_op = switch (lhs_ty.zigTypeTag(zcu)) { | |
| 9893 | 9894 | else => false, |
| 9894 | 9895 | .Float => true, |
| 9895 | .Vector => switch (lhs_ty.childType(mod).toIntern()) { | |
| 9896 | .Vector => switch (lhs_ty.childType(zcu).toIntern()) { | |
| 9896 | 9897 | .bool_type, .u1_type => false, |
| 9897 | 9898 | else => true, |
| 9898 | 9899 | }, |
| 9899 | 9900 | }; |
| 9900 | if (sse_op and ((lhs_ty.scalarType(mod).isRuntimeFloat() and | |
| 9901 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or | |
| 9902 | lhs_ty.abiSize(pt) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))) | |
| 9901 | if (sse_op and ((lhs_ty.scalarType(zcu).isRuntimeFloat() and | |
| 9902 | lhs_ty.scalarType(zcu).floatBits(self.target.*) == 80) or | |
| 9903 | lhs_ty.abiSize(zcu) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))) | |
| 9903 | 9904 | return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(air_tag), lhs_ty.fmt(pt) }); |
| 9904 | 9905 | |
| 9905 | 9906 | const maybe_mask_reg = switch (air_tag) { |
| 9906 | 9907 | else => null, |
| 9907 | 9908 | .rem, .mod => unreachable, |
| 9908 | .max, .min => if (lhs_ty.scalarType(mod).isRuntimeFloat()) registerAlias( | |
| 9909 | .max, .min => if (lhs_ty.scalarType(zcu).isRuntimeFloat()) registerAlias( | |
| 9909 | 9910 | if (!self.hasFeature(.avx) and self.hasFeature(.sse4_1)) mask: { |
| 9910 | 9911 | try self.register_manager.getKnownReg(.xmm0, null); |
| 9911 | 9912 | break :mask .xmm0; |
| ... | ... | @@ -9917,8 +9918,8 @@ fn genBinOp( |
| 9917 | 9918 | if (maybe_mask_reg) |mask_reg| self.register_manager.lockRegAssumeUnused(mask_reg) else null; |
| 9918 | 9919 | defer if (mask_lock) |lock| self.register_manager.unlockReg(lock); |
| 9919 | 9920 | |
| 9920 | const ordered_air: [2]Air.Inst.Ref = if (lhs_ty.isVector(mod) and | |
| 9921 | switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 9921 | const ordered_air: [2]Air.Inst.Ref = if (lhs_ty.isVector(zcu) and | |
| 9922 | switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 9922 | 9923 | .Bool => false, |
| 9923 | 9924 | .Int => switch (air_tag) { |
| 9924 | 9925 | .cmp_lt, .cmp_gte => true, |
| ... | ... | @@ -9931,7 +9932,7 @@ fn genBinOp( |
| 9931 | 9932 | else => unreachable, |
| 9932 | 9933 | }) .{ rhs_air, lhs_air } else .{ lhs_air, rhs_air }; |
| 9933 | 9934 | |
| 9934 | if (lhs_ty.isAbiInt(mod)) for (ordered_air) |op_air| { | |
| 9935 | if (lhs_ty.isAbiInt(zcu)) for (ordered_air) |op_air| { | |
| 9935 | 9936 | switch (try self.resolveInst(op_air)) { |
| 9936 | 9937 | .register => |op_reg| switch (op_reg.class()) { |
| 9937 | 9938 | .sse => try self.register_manager.getReg(op_reg, null), |
| ... | ... | @@ -10056,7 +10057,7 @@ fn genBinOp( |
| 10056 | 10057 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 10057 | 10058 | defer self.register_manager.unlockReg(tmp_lock); |
| 10058 | 10059 | |
| 10059 | const elem_size = lhs_ty.elemType2(mod).abiSize(pt); | |
| 10060 | const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu); | |
| 10060 | 10061 | try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size }); |
| 10061 | 10062 | try self.genBinOpMir( |
| 10062 | 10063 | switch (air_tag) { |
| ... | ... | @@ -10112,7 +10113,7 @@ fn genBinOp( |
| 10112 | 10113 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 10113 | 10114 | defer self.register_manager.unlockReg(tmp_lock); |
| 10114 | 10115 | |
| 10115 | const signed = lhs_ty.isSignedInt(mod); | |
| 10116 | const signed = lhs_ty.isSignedInt(zcu); | |
| 10116 | 10117 | const cc: Condition = switch (air_tag) { |
| 10117 | 10118 | .min => if (signed) .nl else .nb, |
| 10118 | 10119 | .max => if (signed) .nge else .nae, |
| ... | ... | @@ -10188,7 +10189,7 @@ fn genBinOp( |
| 10188 | 10189 | |
| 10189 | 10190 | try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, dst_mcv, mat_src_mcv); |
| 10190 | 10191 | |
| 10191 | const int_info = lhs_ty.intInfo(mod); | |
| 10192 | const int_info = lhs_ty.intInfo(zcu); | |
| 10192 | 10193 | const cc: Condition = switch (int_info.signedness) { |
| 10193 | 10194 | .unsigned => switch (air_tag) { |
| 10194 | 10195 | .min => .a, |
| ... | ... | @@ -10202,7 +10203,7 @@ fn genBinOp( |
| 10202 | 10203 | }, |
| 10203 | 10204 | }; |
| 10204 | 10205 | |
| 10205 | const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(pt))), 2); | |
| 10206 | const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(zcu))), 2); | |
| 10206 | 10207 | const tmp_reg = switch (dst_mcv) { |
| 10207 | 10208 | .register => |reg| reg, |
| 10208 | 10209 | else => try self.copyToTmpRegister(lhs_ty, dst_mcv), |
| ... | ... | @@ -10271,7 +10272,7 @@ fn genBinOp( |
| 10271 | 10272 | }, |
| 10272 | 10273 | |
| 10273 | 10274 | .cmp_eq, .cmp_neq => { |
| 10274 | assert(lhs_ty.isVector(mod) and lhs_ty.childType(mod).toIntern() == .bool_type); | |
| 10275 | assert(lhs_ty.isVector(zcu) and lhs_ty.childType(zcu).toIntern() == .bool_type); | |
| 10275 | 10276 | try self.genBinOpMir(.{ ._, .xor }, lhs_ty, dst_mcv, src_mcv); |
| 10276 | 10277 | switch (air_tag) { |
| 10277 | 10278 | .cmp_eq => try self.genUnOpMir(.{ ._, .not }, lhs_ty, dst_mcv), |
| ... | ... | @@ -10288,7 +10289,7 @@ fn genBinOp( |
| 10288 | 10289 | } |
| 10289 | 10290 | |
| 10290 | 10291 | const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size); |
| 10291 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | |
| 10292 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 10292 | 10293 | else => unreachable, |
| 10293 | 10294 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 10294 | 10295 | 16 => { |
| ... | ... | @@ -10383,10 +10384,10 @@ fn genBinOp( |
| 10383 | 10384 | 80, 128 => null, |
| 10384 | 10385 | else => unreachable, |
| 10385 | 10386 | }, |
| 10386 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 10387 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 10387 | 10388 | else => null, |
| 10388 | .Int => switch (lhs_ty.childType(mod).intInfo(mod).bits) { | |
| 10389 | 8 => switch (lhs_ty.vectorLen(mod)) { | |
| 10389 | .Int => switch (lhs_ty.childType(zcu).intInfo(zcu).bits) { | |
| 10390 | 8 => switch (lhs_ty.vectorLen(zcu)) { | |
| 10390 | 10391 | 1...16 => switch (air_tag) { |
| 10391 | 10392 | .add, |
| 10392 | 10393 | .add_wrap, |
| ... | ... | @@ -10400,7 +10401,7 @@ fn genBinOp( |
| 10400 | 10401 | .{ .p_, .@"and" }, |
| 10401 | 10402 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, |
| 10402 | 10403 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, |
| 10403 | .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10404 | .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10404 | 10405 | .signed => if (self.hasFeature(.avx)) |
| 10405 | 10406 | .{ .vp_b, .mins } |
| 10406 | 10407 | else if (self.hasFeature(.sse4_1)) |
| ... | ... | @@ -10414,7 +10415,7 @@ fn genBinOp( |
| 10414 | 10415 | else |
| 10415 | 10416 | null, |
| 10416 | 10417 | }, |
| 10417 | .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10418 | .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10418 | 10419 | .signed => if (self.hasFeature(.avx)) |
| 10419 | 10420 | .{ .vp_b, .maxs } |
| 10420 | 10421 | else if (self.hasFeature(.sse4_1)) |
| ... | ... | @@ -10432,7 +10433,7 @@ fn genBinOp( |
| 10432 | 10433 | .cmp_lte, |
| 10433 | 10434 | .cmp_gte, |
| 10434 | 10435 | .cmp_gt, |
| 10435 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10436 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10436 | 10437 | .signed => if (self.hasFeature(.avx)) |
| 10437 | 10438 | .{ .vp_b, .cmpgt } |
| 10438 | 10439 | else |
| ... | ... | @@ -10454,11 +10455,11 @@ fn genBinOp( |
| 10454 | 10455 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, |
| 10455 | 10456 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, |
| 10456 | 10457 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, |
| 10457 | .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10458 | .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10458 | 10459 | .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null, |
| 10459 | 10460 | .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null, |
| 10460 | 10461 | }, |
| 10461 | .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10462 | .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10462 | 10463 | .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null, |
| 10463 | 10464 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null, |
| 10464 | 10465 | }, |
| ... | ... | @@ -10466,7 +10467,7 @@ fn genBinOp( |
| 10466 | 10467 | .cmp_lte, |
| 10467 | 10468 | .cmp_gte, |
| 10468 | 10469 | .cmp_gt, |
| 10469 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10470 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10470 | 10471 | .signed => if (self.hasFeature(.avx)) .{ .vp_b, .cmpgt } else null, |
| 10471 | 10472 | .unsigned => null, |
| 10472 | 10473 | }, |
| ... | ... | @@ -10477,7 +10478,7 @@ fn genBinOp( |
| 10477 | 10478 | }, |
| 10478 | 10479 | else => null, |
| 10479 | 10480 | }, |
| 10480 | 16 => switch (lhs_ty.vectorLen(mod)) { | |
| 10481 | 16 => switch (lhs_ty.vectorLen(zcu)) { | |
| 10481 | 10482 | 1...8 => switch (air_tag) { |
| 10482 | 10483 | .add, |
| 10483 | 10484 | .add_wrap, |
| ... | ... | @@ -10494,7 +10495,7 @@ fn genBinOp( |
| 10494 | 10495 | .{ .p_, .@"and" }, |
| 10495 | 10496 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, |
| 10496 | 10497 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, |
| 10497 | .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10498 | .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10498 | 10499 | .signed => if (self.hasFeature(.avx)) |
| 10499 | 10500 | .{ .vp_w, .mins } |
| 10500 | 10501 | else |
| ... | ... | @@ -10504,7 +10505,7 @@ fn genBinOp( |
| 10504 | 10505 | else |
| 10505 | 10506 | .{ .p_w, .minu }, |
| 10506 | 10507 | }, |
| 10507 | .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10508 | .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10508 | 10509 | .signed => if (self.hasFeature(.avx)) |
| 10509 | 10510 | .{ .vp_w, .maxs } |
| 10510 | 10511 | else |
| ... | ... | @@ -10518,7 +10519,7 @@ fn genBinOp( |
| 10518 | 10519 | .cmp_lte, |
| 10519 | 10520 | .cmp_gte, |
| 10520 | 10521 | .cmp_gt, |
| 10521 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10522 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10522 | 10523 | .signed => if (self.hasFeature(.avx)) |
| 10523 | 10524 | .{ .vp_w, .cmpgt } |
| 10524 | 10525 | else |
| ... | ... | @@ -10543,11 +10544,11 @@ fn genBinOp( |
| 10543 | 10544 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, |
| 10544 | 10545 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, |
| 10545 | 10546 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, |
| 10546 | .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10547 | .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10547 | 10548 | .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null, |
| 10548 | 10549 | .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null, |
| 10549 | 10550 | }, |
| 10550 | .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10551 | .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10551 | 10552 | .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null, |
| 10552 | 10553 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null, |
| 10553 | 10554 | }, |
| ... | ... | @@ -10555,7 +10556,7 @@ fn genBinOp( |
| 10555 | 10556 | .cmp_lte, |
| 10556 | 10557 | .cmp_gte, |
| 10557 | 10558 | .cmp_gt, |
| 10558 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10559 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10559 | 10560 | .signed => if (self.hasFeature(.avx)) .{ .vp_w, .cmpgt } else null, |
| 10560 | 10561 | .unsigned => null, |
| 10561 | 10562 | }, |
| ... | ... | @@ -10566,7 +10567,7 @@ fn genBinOp( |
| 10566 | 10567 | }, |
| 10567 | 10568 | else => null, |
| 10568 | 10569 | }, |
| 10569 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 10570 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 10570 | 10571 | 1...4 => switch (air_tag) { |
| 10571 | 10572 | .add, |
| 10572 | 10573 | .add_wrap, |
| ... | ... | @@ -10588,7 +10589,7 @@ fn genBinOp( |
| 10588 | 10589 | .{ .p_, .@"and" }, |
| 10589 | 10590 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, |
| 10590 | 10591 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, |
| 10591 | .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10592 | .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10592 | 10593 | .signed => if (self.hasFeature(.avx)) |
| 10593 | 10594 | .{ .vp_d, .mins } |
| 10594 | 10595 | else if (self.hasFeature(.sse4_1)) |
| ... | ... | @@ -10602,7 +10603,7 @@ fn genBinOp( |
| 10602 | 10603 | else |
| 10603 | 10604 | null, |
| 10604 | 10605 | }, |
| 10605 | .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10606 | .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10606 | 10607 | .signed => if (self.hasFeature(.avx)) |
| 10607 | 10608 | .{ .vp_d, .maxs } |
| 10608 | 10609 | else if (self.hasFeature(.sse4_1)) |
| ... | ... | @@ -10620,7 +10621,7 @@ fn genBinOp( |
| 10620 | 10621 | .cmp_lte, |
| 10621 | 10622 | .cmp_gte, |
| 10622 | 10623 | .cmp_gt, |
| 10623 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10624 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10624 | 10625 | .signed => if (self.hasFeature(.avx)) |
| 10625 | 10626 | .{ .vp_d, .cmpgt } |
| 10626 | 10627 | else |
| ... | ... | @@ -10645,11 +10646,11 @@ fn genBinOp( |
| 10645 | 10646 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, |
| 10646 | 10647 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, |
| 10647 | 10648 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, |
| 10648 | .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10649 | .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10649 | 10650 | .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null, |
| 10650 | 10651 | .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null, |
| 10651 | 10652 | }, |
| 10652 | .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10653 | .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10653 | 10654 | .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null, |
| 10654 | 10655 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null, |
| 10655 | 10656 | }, |
| ... | ... | @@ -10657,7 +10658,7 @@ fn genBinOp( |
| 10657 | 10658 | .cmp_lte, |
| 10658 | 10659 | .cmp_gte, |
| 10659 | 10660 | .cmp_gt, |
| 10660 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10661 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10661 | 10662 | .signed => if (self.hasFeature(.avx)) .{ .vp_d, .cmpgt } else null, |
| 10662 | 10663 | .unsigned => null, |
| 10663 | 10664 | }, |
| ... | ... | @@ -10668,7 +10669,7 @@ fn genBinOp( |
| 10668 | 10669 | }, |
| 10669 | 10670 | else => null, |
| 10670 | 10671 | }, |
| 10671 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 10672 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 10672 | 10673 | 1...2 => switch (air_tag) { |
| 10673 | 10674 | .add, |
| 10674 | 10675 | .add_wrap, |
| ... | ... | @@ -10686,7 +10687,7 @@ fn genBinOp( |
| 10686 | 10687 | .cmp_lte, |
| 10687 | 10688 | .cmp_gte, |
| 10688 | 10689 | .cmp_gt, |
| 10689 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10690 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10690 | 10691 | .signed => if (self.hasFeature(.avx)) |
| 10691 | 10692 | .{ .vp_q, .cmpgt } |
| 10692 | 10693 | else if (self.hasFeature(.sse4_2)) |
| ... | ... | @@ -10722,7 +10723,7 @@ fn genBinOp( |
| 10722 | 10723 | .cmp_lte, |
| 10723 | 10724 | .cmp_gt, |
| 10724 | 10725 | .cmp_gte, |
| 10725 | => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { | |
| 10726 | => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) { | |
| 10726 | 10727 | .signed => if (self.hasFeature(.avx)) .{ .vp_d, .cmpgt } else null, |
| 10727 | 10728 | .unsigned => null, |
| 10728 | 10729 | }, |
| ... | ... | @@ -10732,10 +10733,10 @@ fn genBinOp( |
| 10732 | 10733 | }, |
| 10733 | 10734 | else => null, |
| 10734 | 10735 | }, |
| 10735 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | |
| 10736 | .Float => switch (lhs_ty.childType(zcu).floatBits(self.target.*)) { | |
| 10736 | 10737 | 16 => tag: { |
| 10737 | 10738 | assert(self.hasFeature(.f16c)); |
| 10738 | switch (lhs_ty.vectorLen(mod)) { | |
| 10739 | switch (lhs_ty.vectorLen(zcu)) { | |
| 10739 | 10740 | 1 => { |
| 10740 | 10741 | const tmp_reg = (try self.register_manager.allocReg( |
| 10741 | 10742 | null, |
| ... | ... | @@ -10923,7 +10924,7 @@ fn genBinOp( |
| 10923 | 10924 | else => break :tag null, |
| 10924 | 10925 | } |
| 10925 | 10926 | }, |
| 10926 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 10927 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 10927 | 10928 | 1 => switch (air_tag) { |
| 10928 | 10929 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, |
| 10929 | 10930 | .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, |
| ... | ... | @@ -10976,7 +10977,7 @@ fn genBinOp( |
| 10976 | 10977 | } else null, |
| 10977 | 10978 | else => null, |
| 10978 | 10979 | }, |
| 10979 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 10980 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 10980 | 10981 | 1 => switch (air_tag) { |
| 10981 | 10982 | .add => if (self.hasFeature(.avx)) .{ .v_sd, .add } else .{ ._sd, .add }, |
| 10982 | 10983 | .sub => if (self.hasFeature(.avx)) .{ .v_sd, .sub } else .{ ._sd, .sub }, |
| ... | ... | @@ -11052,7 +11053,7 @@ fn genBinOp( |
| 11052 | 11053 | mir_tag, |
| 11053 | 11054 | dst_reg, |
| 11054 | 11055 | lhs_reg, |
| 11055 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11056 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11056 | 11057 | else => Memory.Size.fromSize(abi_size), |
| 11057 | 11058 | .Vector => Memory.Size.fromBitSize(dst_reg.bitSize()), |
| 11058 | 11059 | }), |
| ... | ... | @@ -11070,7 +11071,7 @@ fn genBinOp( |
| 11070 | 11071 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 11071 | 11072 | mir_tag, |
| 11072 | 11073 | dst_reg, |
| 11073 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11074 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11074 | 11075 | else => Memory.Size.fromSize(abi_size), |
| 11075 | 11076 | .Vector => Memory.Size.fromBitSize(dst_reg.bitSize()), |
| 11076 | 11077 | }), |
| ... | ... | @@ -11098,7 +11099,7 @@ fn genBinOp( |
| 11098 | 11099 | mir_tag, |
| 11099 | 11100 | dst_reg, |
| 11100 | 11101 | lhs_reg, |
| 11101 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11102 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11102 | 11103 | else => Memory.Size.fromSize(abi_size), |
| 11103 | 11104 | .Vector => Memory.Size.fromBitSize(dst_reg.bitSize()), |
| 11104 | 11105 | }), |
| ... | ... | @@ -11118,7 +11119,7 @@ fn genBinOp( |
| 11118 | 11119 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 11119 | 11120 | mir_tag, |
| 11120 | 11121 | dst_reg, |
| 11121 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11122 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11122 | 11123 | else => Memory.Size.fromSize(abi_size), |
| 11123 | 11124 | .Vector => Memory.Size.fromBitSize(dst_reg.bitSize()), |
| 11124 | 11125 | }), |
| ... | ... | @@ -11151,21 +11152,21 @@ fn genBinOp( |
| 11151 | 11152 | const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size); |
| 11152 | 11153 | |
| 11153 | 11154 | try self.asmRegisterRegisterRegisterImmediate( |
| 11154 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11155 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11155 | 11156 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 11156 | 11157 | 32 => .{ .v_ss, .cmp }, |
| 11157 | 11158 | 64 => .{ .v_sd, .cmp }, |
| 11158 | 11159 | 16, 80, 128 => null, |
| 11159 | 11160 | else => unreachable, |
| 11160 | 11161 | }, |
| 11161 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 11162 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | |
| 11163 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 11162 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 11163 | .Float => switch (lhs_ty.childType(zcu).floatBits(self.target.*)) { | |
| 11164 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11164 | 11165 | 1 => .{ .v_ss, .cmp }, |
| 11165 | 11166 | 2...8 => .{ .v_ps, .cmp }, |
| 11166 | 11167 | else => null, |
| 11167 | 11168 | }, |
| 11168 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 11169 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11169 | 11170 | 1 => .{ .v_sd, .cmp }, |
| 11170 | 11171 | 2...4 => .{ .v_pd, .cmp }, |
| 11171 | 11172 | else => null, |
| ... | ... | @@ -11185,20 +11186,20 @@ fn genBinOp( |
| 11185 | 11186 | Immediate.u(3), // unord |
| 11186 | 11187 | ); |
| 11187 | 11188 | try self.asmRegisterRegisterRegisterRegister( |
| 11188 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11189 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11189 | 11190 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 11190 | 11191 | 32 => .{ .v_ps, .blendv }, |
| 11191 | 11192 | 64 => .{ .v_pd, .blendv }, |
| 11192 | 11193 | 16, 80, 128 => null, |
| 11193 | 11194 | else => unreachable, |
| 11194 | 11195 | }, |
| 11195 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 11196 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | |
| 11197 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 11196 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 11197 | .Float => switch (lhs_ty.childType(zcu).floatBits(self.target.*)) { | |
| 11198 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11198 | 11199 | 1...8 => .{ .v_ps, .blendv }, |
| 11199 | 11200 | else => null, |
| 11200 | 11201 | }, |
| 11201 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 11202 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11202 | 11203 | 1...4 => .{ .v_pd, .blendv }, |
| 11203 | 11204 | else => null, |
| 11204 | 11205 | }, |
| ... | ... | @@ -11219,21 +11220,21 @@ fn genBinOp( |
| 11219 | 11220 | } else { |
| 11220 | 11221 | const has_blend = self.hasFeature(.sse4_1); |
| 11221 | 11222 | try self.asmRegisterRegisterImmediate( |
| 11222 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11223 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11223 | 11224 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 11224 | 11225 | 32 => .{ ._ss, .cmp }, |
| 11225 | 11226 | 64 => .{ ._sd, .cmp }, |
| 11226 | 11227 | 16, 80, 128 => null, |
| 11227 | 11228 | else => unreachable, |
| 11228 | 11229 | }, |
| 11229 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 11230 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | |
| 11231 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 11230 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 11231 | .Float => switch (lhs_ty.childType(zcu).floatBits(self.target.*)) { | |
| 11232 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11232 | 11233 | 1 => .{ ._ss, .cmp }, |
| 11233 | 11234 | 2...4 => .{ ._ps, .cmp }, |
| 11234 | 11235 | else => null, |
| 11235 | 11236 | }, |
| 11236 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 11237 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11237 | 11238 | 1 => .{ ._sd, .cmp }, |
| 11238 | 11239 | 2 => .{ ._pd, .cmp }, |
| 11239 | 11240 | else => null, |
| ... | ... | @@ -11252,20 +11253,20 @@ fn genBinOp( |
| 11252 | 11253 | Immediate.u(if (has_blend) 3 else 7), // unord, ord |
| 11253 | 11254 | ); |
| 11254 | 11255 | if (has_blend) try self.asmRegisterRegisterRegister( |
| 11255 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11256 | @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11256 | 11257 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 11257 | 11258 | 32 => .{ ._ps, .blendv }, |
| 11258 | 11259 | 64 => .{ ._pd, .blendv }, |
| 11259 | 11260 | 16, 80, 128 => null, |
| 11260 | 11261 | else => unreachable, |
| 11261 | 11262 | }, |
| 11262 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 11263 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | |
| 11264 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 11263 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 11264 | .Float => switch (lhs_ty.childType(zcu).floatBits(self.target.*)) { | |
| 11265 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11265 | 11266 | 1...4 => .{ ._ps, .blendv }, |
| 11266 | 11267 | else => null, |
| 11267 | 11268 | }, |
| 11268 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 11269 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11269 | 11270 | 1...2 => .{ ._pd, .blendv }, |
| 11270 | 11271 | else => null, |
| 11271 | 11272 | }, |
| ... | ... | @@ -11282,20 +11283,20 @@ fn genBinOp( |
| 11282 | 11283 | lhs_copy_reg.?, |
| 11283 | 11284 | mask_reg, |
| 11284 | 11285 | ) else { |
| 11285 | const mir_fixes = @as(?Mir.Inst.Fixes, switch (lhs_ty.zigTypeTag(mod)) { | |
| 11286 | const mir_fixes = @as(?Mir.Inst.Fixes, switch (lhs_ty.zigTypeTag(zcu)) { | |
| 11286 | 11287 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 11287 | 11288 | 32 => ._ps, |
| 11288 | 11289 | 64 => ._pd, |
| 11289 | 11290 | 16, 80, 128 => null, |
| 11290 | 11291 | else => unreachable, |
| 11291 | 11292 | }, |
| 11292 | .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 11293 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | |
| 11294 | 32 => switch (lhs_ty.vectorLen(mod)) { | |
| 11293 | .Vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 11294 | .Float => switch (lhs_ty.childType(zcu).floatBits(self.target.*)) { | |
| 11295 | 32 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11295 | 11296 | 1...4 => ._ps, |
| 11296 | 11297 | else => null, |
| 11297 | 11298 | }, |
| 11298 | 64 => switch (lhs_ty.vectorLen(mod)) { | |
| 11299 | 64 => switch (lhs_ty.vectorLen(zcu)) { | |
| 11299 | 11300 | 1...2 => ._pd, |
| 11300 | 11301 | else => null, |
| 11301 | 11302 | }, |
| ... | ... | @@ -11314,7 +11315,7 @@ fn genBinOp( |
| 11314 | 11315 | } |
| 11315 | 11316 | }, |
| 11316 | 11317 | .cmp_lt, .cmp_lte, .cmp_eq, .cmp_gte, .cmp_gt, .cmp_neq => { |
| 11317 | switch (lhs_ty.childType(mod).zigTypeTag(mod)) { | |
| 11318 | switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) { | |
| 11318 | 11319 | .Int => switch (air_tag) { |
| 11319 | 11320 | .cmp_lt, |
| 11320 | 11321 | .cmp_eq, |
| ... | ... | @@ -11395,8 +11396,8 @@ fn genBinOpMir( |
| 11395 | 11396 | src_mcv: MCValue, |
| 11396 | 11397 | ) !void { |
| 11397 | 11398 | const pt = self.pt; |
| 11398 | const mod = pt.zcu; | |
| 11399 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 11399 | const zcu = pt.zcu; | |
| 11400 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 11400 | 11401 | try self.spillEflagsIfOccupied(); |
| 11401 | 11402 | switch (dst_mcv) { |
| 11402 | 11403 | .none, |
| ... | ... | @@ -11643,7 +11644,7 @@ fn genBinOpMir( |
| 11643 | 11644 | defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock); |
| 11644 | 11645 | |
| 11645 | 11646 | const ty_signedness = |
| 11646 | if (ty.isAbiInt(mod)) ty.intInfo(mod).signedness else .unsigned; | |
| 11647 | if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned; | |
| 11647 | 11648 | const limb_ty = if (abi_size <= 8) ty else switch (ty_signedness) { |
| 11648 | 11649 | .signed => Type.usize, |
| 11649 | 11650 | .unsigned => Type.isize, |
| ... | ... | @@ -11820,7 +11821,7 @@ fn genBinOpMir( |
| 11820 | 11821 | /// Does not support byte-size operands. |
| 11821 | 11822 | fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 11822 | 11823 | const pt = self.pt; |
| 11823 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 11824 | const abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu)); | |
| 11824 | 11825 | try self.spillEflagsIfOccupied(); |
| 11825 | 11826 | switch (dst_mcv) { |
| 11826 | 11827 | .none, |
| ... | ... | @@ -12009,7 +12010,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 12009 | 12010 | try self.genInlineMemset( |
| 12010 | 12011 | dst_mcv.address().offset(@intFromBool(regs_frame_addr.regs > 0)), |
| 12011 | 12012 | .{ .immediate = 0 }, |
| 12012 | .{ .immediate = arg_ty.abiSize(pt) - @intFromBool(regs_frame_addr.regs > 0) }, | |
| 12013 | .{ .immediate = arg_ty.abiSize(zcu) - @intFromBool(regs_frame_addr.regs > 0) }, | |
| 12013 | 12014 | .{}, |
| 12014 | 12015 | ); |
| 12015 | 12016 | |
| ... | ... | @@ -12296,7 +12297,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12296 | 12297 | try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs)); |
| 12297 | 12298 | }, |
| 12298 | 12299 | .indirect => |reg_off| { |
| 12299 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, pt)); | |
| 12300 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, zcu)); | |
| 12300 | 12301 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); |
| 12301 | 12302 | try self.register_manager.getReg(reg_off.reg, null); |
| 12302 | 12303 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); |
| ... | ... | @@ -12368,7 +12369,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12368 | 12369 | .none, .unreach => {}, |
| 12369 | 12370 | .indirect => |reg_off| { |
| 12370 | 12371 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 12371 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, pt)); | |
| 12372 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, zcu)); | |
| 12372 | 12373 | try self.genSetReg(reg_off.reg, Type.usize, .{ |
| 12373 | 12374 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 12374 | 12375 | }, .{}); |
| ... | ... | @@ -12383,14 +12384,14 @@ fn genCall(self: *Self, info: union(enum) { |
| 12383 | 12384 | .none, .load_frame => {}, |
| 12384 | 12385 | .register => |dst_reg| switch (fn_info.cc) { |
| 12385 | 12386 | else => try self.genSetReg( |
| 12386 | registerAlias(dst_reg, @intCast(arg_ty.abiSize(pt))), | |
| 12387 | registerAlias(dst_reg, @intCast(arg_ty.abiSize(zcu))), | |
| 12387 | 12388 | arg_ty, |
| 12388 | 12389 | src_arg, |
| 12389 | 12390 | .{}, |
| 12390 | 12391 | ), |
| 12391 | 12392 | .C, .SysV, .Win64 => { |
| 12392 | 12393 | const promoted_ty = self.promoteInt(arg_ty); |
| 12393 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(pt)); | |
| 12394 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(zcu)); | |
| 12394 | 12395 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); |
| 12395 | 12396 | try self.genSetReg(dst_alias, promoted_ty, src_arg, .{}); |
| 12396 | 12397 | if (promoted_ty.toIntern() != arg_ty.toIntern()) |
| ... | ... | @@ -12514,10 +12515,10 @@ fn genCall(self: *Self, info: union(enum) { |
| 12514 | 12515 | |
| 12515 | 12516 | fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 12516 | 12517 | const pt = self.pt; |
| 12517 | const mod = pt.zcu; | |
| 12518 | const zcu = pt.zcu; | |
| 12518 | 12519 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 12519 | 12520 | |
| 12520 | const ret_ty = self.fn_type.fnReturnType(mod); | |
| 12521 | const ret_ty = self.fn_type.fnReturnType(zcu); | |
| 12521 | 12522 | switch (self.ret_mcv.short) { |
| 12522 | 12523 | .none => {}, |
| 12523 | 12524 | .register, |
| ... | ... | @@ -12570,7 +12571,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 12570 | 12571 | |
| 12571 | 12572 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12572 | 12573 | const pt = self.pt; |
| 12573 | const mod = pt.zcu; | |
| 12574 | const zcu = pt.zcu; | |
| 12574 | 12575 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 12575 | 12576 | var ty = self.typeOf(bin_op.lhs); |
| 12576 | 12577 | var null_compare: ?Mir.Inst.Index = null; |
| ... | ... | @@ -12602,7 +12603,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12602 | 12603 | }; |
| 12603 | 12604 | defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 12604 | 12605 | |
| 12605 | switch (ty.zigTypeTag(mod)) { | |
| 12606 | switch (ty.zigTypeTag(zcu)) { | |
| 12606 | 12607 | .Float => { |
| 12607 | 12608 | const float_bits = ty.floatBits(self.target.*); |
| 12608 | 12609 | if (switch (float_bits) { |
| ... | ... | @@ -12638,11 +12639,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12638 | 12639 | }; |
| 12639 | 12640 | } |
| 12640 | 12641 | }, |
| 12641 | .Optional => if (!ty.optionalReprIsPayload(mod)) { | |
| 12642 | .Optional => if (!ty.optionalReprIsPayload(zcu)) { | |
| 12642 | 12643 | const opt_ty = ty; |
| 12643 | const opt_abi_size: u31 = @intCast(opt_ty.abiSize(pt)); | |
| 12644 | ty = opt_ty.optionalChild(mod); | |
| 12645 | const payload_abi_size: u31 = @intCast(ty.abiSize(pt)); | |
| 12644 | const opt_abi_size: u31 = @intCast(opt_ty.abiSize(zcu)); | |
| 12645 | ty = opt_ty.optionalChild(zcu); | |
| 12646 | const payload_abi_size: u31 = @intCast(ty.abiSize(zcu)); | |
| 12646 | 12647 | |
| 12647 | 12648 | const temp_lhs_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 12648 | 12649 | const temp_lhs_lock = self.register_manager.lockRegAssumeUnused(temp_lhs_reg); |
| ... | ... | @@ -12699,9 +12700,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12699 | 12700 | else => {}, |
| 12700 | 12701 | } |
| 12701 | 12702 | |
| 12702 | switch (ty.zigTypeTag(mod)) { | |
| 12703 | switch (ty.zigTypeTag(zcu)) { | |
| 12703 | 12704 | else => { |
| 12704 | const abi_size: u16 = @intCast(ty.abiSize(pt)); | |
| 12705 | const abi_size: u16 = @intCast(ty.abiSize(zcu)); | |
| 12705 | 12706 | const may_flip: enum { |
| 12706 | 12707 | may_flip, |
| 12707 | 12708 | must_flip, |
| ... | ... | @@ -12734,7 +12735,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 12734 | 12735 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 12735 | 12736 | |
| 12736 | 12737 | break :result Condition.fromCompareOperator( |
| 12737 | if (ty.isAbiInt(mod)) ty.intInfo(mod).signedness else .unsigned, | |
| 12738 | if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned, | |
| 12738 | 12739 | result_op: { |
| 12739 | 12740 | const flipped_op = if (flipped) op.reverse() else op; |
| 12740 | 12741 | if (abi_size > 8) switch (flipped_op) { |
| ... | ... | @@ -13029,6 +13030,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { |
| 13029 | 13030 | |
| 13030 | 13031 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 13031 | 13032 | const pt = self.pt; |
| 13033 | const zcu = pt.zcu; | |
| 13032 | 13034 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 13033 | 13035 | |
| 13034 | 13036 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | ... | @@ -13040,7 +13042,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 13040 | 13042 | try self.spillEflagsIfOccupied(); |
| 13041 | 13043 | |
| 13042 | 13044 | const op_ty = self.typeOf(un_op); |
| 13043 | const op_abi_size: u32 = @intCast(op_ty.abiSize(pt)); | |
| 13045 | const op_abi_size: u32 = @intCast(op_ty.abiSize(zcu)); | |
| 13044 | 13046 | const op_mcv = try self.resolveInst(un_op); |
| 13045 | 13047 | const dst_reg = switch (op_mcv) { |
| 13046 | 13048 | .register => |reg| reg, |
| ... | ... | @@ -13164,7 +13166,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 13164 | 13166 | |
| 13165 | 13167 | fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { |
| 13166 | 13168 | const pt = self.pt; |
| 13167 | const abi_size = ty.abiSize(pt); | |
| 13169 | const abi_size = ty.abiSize(pt.zcu); | |
| 13168 | 13170 | switch (mcv) { |
| 13169 | 13171 | .eflags => |cc| { |
| 13170 | 13172 | // Here we map the opposites since the jump is to the false branch. |
| ... | ... | @@ -13237,7 +13239,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 13237 | 13239 | |
| 13238 | 13240 | fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { |
| 13239 | 13241 | const pt = self.pt; |
| 13240 | const mod = pt.zcu; | |
| 13242 | const zcu = pt.zcu; | |
| 13241 | 13243 | switch (opt_mcv) { |
| 13242 | 13244 | .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() }, |
| 13243 | 13245 | else => {}, |
| ... | ... | @@ -13245,12 +13247,12 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13245 | 13247 | |
| 13246 | 13248 | try self.spillEflagsIfOccupied(); |
| 13247 | 13249 | |
| 13248 | const pl_ty = opt_ty.optionalChild(mod); | |
| 13250 | const pl_ty = opt_ty.optionalChild(zcu); | |
| 13249 | 13251 | |
| 13250 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | |
| 13251 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } | |
| 13252 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) | |
| 13253 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } | |
| 13252 | 13254 | else |
| 13253 | .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool }; | |
| 13255 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; | |
| 13254 | 13256 | |
| 13255 | 13257 | self.eflags_inst = inst; |
| 13256 | 13258 | switch (opt_mcv) { |
| ... | ... | @@ -13279,14 +13281,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13279 | 13281 | |
| 13280 | 13282 | .register => |opt_reg| { |
| 13281 | 13283 | if (some_info.off == 0) { |
| 13282 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); | |
| 13284 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(zcu)); | |
| 13283 | 13285 | const alias_reg = registerAlias(opt_reg, some_abi_size); |
| 13284 | 13286 | assert(some_abi_size * 8 == alias_reg.bitSize()); |
| 13285 | 13287 | try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg); |
| 13286 | 13288 | return .{ .eflags = .z }; |
| 13287 | 13289 | } |
| 13288 | 13290 | assert(some_info.ty.ip_index == .bool_type); |
| 13289 | const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt)); | |
| 13291 | const opt_abi_size: u32 = @intCast(opt_ty.abiSize(zcu)); | |
| 13290 | 13292 | try self.asmRegisterImmediate( |
| 13291 | 13293 | .{ ._, .bt }, |
| 13292 | 13294 | registerAlias(opt_reg, opt_abi_size), |
| ... | ... | @@ -13306,7 +13308,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13306 | 13308 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 13307 | 13309 | |
| 13308 | 13310 | try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{}); |
| 13309 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); | |
| 13311 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(zcu)); | |
| 13310 | 13312 | try self.asmMemoryImmediate( |
| 13311 | 13313 | .{ ._, .cmp }, |
| 13312 | 13314 | .{ |
| ... | ... | @@ -13322,7 +13324,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13322 | 13324 | }, |
| 13323 | 13325 | |
| 13324 | 13326 | .indirect, .load_frame => { |
| 13325 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); | |
| 13327 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(zcu)); | |
| 13326 | 13328 | try self.asmMemoryImmediate( |
| 13327 | 13329 | .{ ._, .cmp }, |
| 13328 | 13330 | switch (opt_mcv) { |
| ... | ... | @@ -13351,16 +13353,16 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13351 | 13353 | |
| 13352 | 13354 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 13353 | 13355 | const pt = self.pt; |
| 13354 | const mod = pt.zcu; | |
| 13355 | const opt_ty = ptr_ty.childType(mod); | |
| 13356 | const pl_ty = opt_ty.optionalChild(mod); | |
| 13356 | const zcu = pt.zcu; | |
| 13357 | const opt_ty = ptr_ty.childType(zcu); | |
| 13358 | const pl_ty = opt_ty.optionalChild(zcu); | |
| 13357 | 13359 | |
| 13358 | 13360 | try self.spillEflagsIfOccupied(); |
| 13359 | 13361 | |
| 13360 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | |
| 13361 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } | |
| 13362 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) | |
| 13363 | .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } | |
| 13362 | 13364 | else |
| 13363 | .{ .off = @intCast(pl_ty.abiSize(pt)), .ty = Type.bool }; | |
| 13365 | .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; | |
| 13364 | 13366 | |
| 13365 | 13367 | const ptr_reg = switch (ptr_mcv) { |
| 13366 | 13368 | .register => |reg| reg, |
| ... | ... | @@ -13369,7 +13371,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 13369 | 13371 | const ptr_lock = self.register_manager.lockReg(ptr_reg); |
| 13370 | 13372 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 13371 | 13373 | |
| 13372 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(pt)); | |
| 13374 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(zcu)); | |
| 13373 | 13375 | try self.asmMemoryImmediate( |
| 13374 | 13376 | .{ ._, .cmp }, |
| 13375 | 13377 | .{ |
| ... | ... | @@ -13388,13 +13390,13 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 13388 | 13390 | |
| 13389 | 13391 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { |
| 13390 | 13392 | const pt = self.pt; |
| 13391 | const mod = pt.zcu; | |
| 13392 | const err_ty = eu_ty.errorUnionSet(mod); | |
| 13393 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false | |
| 13393 | const zcu = pt.zcu; | |
| 13394 | const err_ty = eu_ty.errorUnionSet(zcu); | |
| 13395 | if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false | |
| 13394 | 13396 | |
| 13395 | 13397 | try self.spillEflagsIfOccupied(); |
| 13396 | 13398 | |
| 13397 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), pt)); | |
| 13399 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), zcu)); | |
| 13398 | 13400 | switch (eu_mcv) { |
| 13399 | 13401 | .register => |reg| { |
| 13400 | 13402 | const eu_lock = self.register_manager.lockReg(reg); |
| ... | ... | @@ -13437,10 +13439,10 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) |
| 13437 | 13439 | |
| 13438 | 13440 | fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 13439 | 13441 | const pt = self.pt; |
| 13440 | const mod = pt.zcu; | |
| 13441 | const eu_ty = ptr_ty.childType(mod); | |
| 13442 | const err_ty = eu_ty.errorUnionSet(mod); | |
| 13443 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false | |
| 13442 | const zcu = pt.zcu; | |
| 13443 | const eu_ty = ptr_ty.childType(zcu); | |
| 13444 | const err_ty = eu_ty.errorUnionSet(zcu); | |
| 13445 | if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false | |
| 13444 | 13446 | |
| 13445 | 13447 | try self.spillEflagsIfOccupied(); |
| 13446 | 13448 | |
| ... | ... | @@ -13451,7 +13453,7 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV |
| 13451 | 13453 | const ptr_lock = self.register_manager.lockReg(ptr_reg); |
| 13452 | 13454 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 13453 | 13455 | |
| 13454 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), pt)); | |
| 13456 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), zcu)); | |
| 13455 | 13457 | try self.asmMemoryImmediate( |
| 13456 | 13458 | .{ ._, .cmp }, |
| 13457 | 13459 | .{ |
| ... | ... | @@ -13724,12 +13726,12 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) void { |
| 13724 | 13726 | } |
| 13725 | 13727 | |
| 13726 | 13728 | fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 13727 | const pt = self.pt; | |
| 13729 | const zcu = self.pt.zcu; | |
| 13728 | 13730 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 13729 | 13731 | |
| 13730 | 13732 | const block_ty = self.typeOfIndex(br.block_inst); |
| 13731 | 13733 | const block_unused = |
| 13732 | !block_ty.hasRuntimeBitsIgnoreComptime(pt) or self.liveness.isUnused(br.block_inst); | |
| 13734 | !block_ty.hasRuntimeBitsIgnoreComptime(zcu) or self.liveness.isUnused(br.block_inst); | |
| 13733 | 13735 | const block_tracking = self.inst_tracking.getPtr(br.block_inst).?; |
| 13734 | 13736 | const block_data = self.blocks.getPtr(br.block_inst).?; |
| 13735 | 13737 | const first_br = block_data.relocs.items.len == 0; |
| ... | ... | @@ -13786,7 +13788,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 13786 | 13788 | |
| 13787 | 13789 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13788 | 13790 | const pt = self.pt; |
| 13789 | const mod = pt.zcu; | |
| 13791 | const zcu = pt.zcu; | |
| 13790 | 13792 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 13791 | 13793 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 13792 | 13794 | const clobbers_len: u31 = @truncate(extra.data.flags); |
| ... | ... | @@ -13825,7 +13827,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13825 | 13827 | }; |
| 13826 | 13828 | const ty = switch (output) { |
| 13827 | 13829 | .none => self.typeOfIndex(inst), |
| 13828 | else => self.typeOf(output).childType(mod), | |
| 13830 | else => self.typeOf(output).childType(zcu), | |
| 13829 | 13831 | }; |
| 13830 | 13832 | const is_read = switch (constraint[0]) { |
| 13831 | 13833 | '=' => false, |
| ... | ... | @@ -13850,7 +13852,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13850 | 13852 | 'x' => abi.RegisterClass.sse, |
| 13851 | 13853 | else => unreachable, |
| 13852 | 13854 | }) orelse return self.fail("ran out of registers lowering inline asm", .{}), |
| 13853 | @intCast(ty.abiSize(pt)), | |
| 13855 | @intCast(ty.abiSize(zcu)), | |
| 13854 | 13856 | ) |
| 13855 | 13857 | else if (mem.eql(u8, rest, "m")) |
| 13856 | 13858 | if (output != .none) null else return self.fail( |
| ... | ... | @@ -13920,7 +13922,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13920 | 13922 | break :arg input_mcv; |
| 13921 | 13923 | const reg = try self.register_manager.allocReg(null, rc); |
| 13922 | 13924 | try self.genSetReg(reg, ty, input_mcv, .{}); |
| 13923 | break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(pt))) }; | |
| 13925 | break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(zcu))) }; | |
| 13924 | 13926 | } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n")) |
| 13925 | 13927 | switch (input_mcv) { |
| 13926 | 13928 | .immediate => |imm| .{ .immediate = imm }, |
| ... | ... | @@ -14497,18 +14499,18 @@ const MoveStrategy = union(enum) { |
| 14497 | 14499 | }; |
| 14498 | 14500 | fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy { |
| 14499 | 14501 | const pt = self.pt; |
| 14500 | const mod = pt.zcu; | |
| 14502 | const zcu = pt.zcu; | |
| 14501 | 14503 | switch (class) { |
| 14502 | 14504 | .general_purpose, .segment => return .{ .move = .{ ._, .mov } }, |
| 14503 | 14505 | .x87 => return .x87_load_store, |
| 14504 | 14506 | .mmx => {}, |
| 14505 | .sse => switch (ty.zigTypeTag(mod)) { | |
| 14507 | .sse => switch (ty.zigTypeTag(zcu)) { | |
| 14506 | 14508 | else => { |
| 14507 | const classes = mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .other), .none); | |
| 14509 | const classes = mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.*, .other), .none); | |
| 14508 | 14510 | assert(std.mem.indexOfNone(abi.Class, classes, &.{ |
| 14509 | 14511 | .integer, .sse, .sseup, .memory, .float, .float_combine, |
| 14510 | 14512 | }) == null); |
| 14511 | const abi_size = ty.abiSize(pt); | |
| 14513 | const abi_size = ty.abiSize(zcu); | |
| 14512 | 14514 | if (abi_size < 4 or |
| 14513 | 14515 | std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) { |
| 14514 | 14516 | 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ |
| ... | ... | @@ -14579,16 +14581,16 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14579 | 14581 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| 14580 | 14582 | else => {}, |
| 14581 | 14583 | }, |
| 14582 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 14583 | .Bool => switch (ty.vectorLen(mod)) { | |
| 14584 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 14585 | .Bool => switch (ty.vectorLen(zcu)) { | |
| 14584 | 14586 | 33...64 => return .{ .move = if (self.hasFeature(.avx)) |
| 14585 | 14587 | .{ .v_q, .mov } |
| 14586 | 14588 | else |
| 14587 | 14589 | .{ ._q, .mov } }, |
| 14588 | 14590 | else => {}, |
| 14589 | 14591 | }, |
| 14590 | .Int => switch (ty.childType(mod).intInfo(mod).bits) { | |
| 14591 | 1...8 => switch (ty.vectorLen(mod)) { | |
| 14592 | .Int => switch (ty.childType(zcu).intInfo(zcu).bits) { | |
| 14593 | 1...8 => switch (ty.vectorLen(zcu)) { | |
| 14592 | 14594 | 1...16 => return .{ .move = if (self.hasFeature(.avx)) |
| 14593 | 14595 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14594 | 14596 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14599,7 +14601,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14599 | 14601 | .{ .v_, .movdqu } }, |
| 14600 | 14602 | else => {}, |
| 14601 | 14603 | }, |
| 14602 | 9...16 => switch (ty.vectorLen(mod)) { | |
| 14604 | 9...16 => switch (ty.vectorLen(zcu)) { | |
| 14603 | 14605 | 1...8 => return .{ .move = if (self.hasFeature(.avx)) |
| 14604 | 14606 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14605 | 14607 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14610,7 +14612,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14610 | 14612 | .{ .v_, .movdqu } }, |
| 14611 | 14613 | else => {}, |
| 14612 | 14614 | }, |
| 14613 | 17...32 => switch (ty.vectorLen(mod)) { | |
| 14615 | 17...32 => switch (ty.vectorLen(zcu)) { | |
| 14614 | 14616 | 1...4 => return .{ .move = if (self.hasFeature(.avx)) |
| 14615 | 14617 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14616 | 14618 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14621,7 +14623,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14621 | 14623 | .{ .v_, .movdqu } }, |
| 14622 | 14624 | else => {}, |
| 14623 | 14625 | }, |
| 14624 | 33...64 => switch (ty.vectorLen(mod)) { | |
| 14626 | 33...64 => switch (ty.vectorLen(zcu)) { | |
| 14625 | 14627 | 1...2 => return .{ .move = if (self.hasFeature(.avx)) |
| 14626 | 14628 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14627 | 14629 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14632,7 +14634,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14632 | 14634 | .{ .v_, .movdqu } }, |
| 14633 | 14635 | else => {}, |
| 14634 | 14636 | }, |
| 14635 | 65...128 => switch (ty.vectorLen(mod)) { | |
| 14637 | 65...128 => switch (ty.vectorLen(zcu)) { | |
| 14636 | 14638 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 14637 | 14639 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14638 | 14640 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14643,7 +14645,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14643 | 14645 | .{ .v_, .movdqu } }, |
| 14644 | 14646 | else => {}, |
| 14645 | 14647 | }, |
| 14646 | 129...256 => switch (ty.vectorLen(mod)) { | |
| 14648 | 129...256 => switch (ty.vectorLen(zcu)) { | |
| 14647 | 14649 | 1 => if (self.hasFeature(.avx)) |
| 14648 | 14650 | return .{ .move = if (aligned) |
| 14649 | 14651 | .{ .v_, .movdqa } |
| ... | ... | @@ -14653,8 +14655,8 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14653 | 14655 | }, |
| 14654 | 14656 | else => {}, |
| 14655 | 14657 | }, |
| 14656 | .Pointer, .Optional => if (ty.childType(mod).isPtrAtRuntime(mod)) | |
| 14657 | switch (ty.vectorLen(mod)) { | |
| 14658 | .Pointer, .Optional => if (ty.childType(zcu).isPtrAtRuntime(zcu)) | |
| 14659 | switch (ty.vectorLen(zcu)) { | |
| 14658 | 14660 | 1...2 => return .{ .move = if (self.hasFeature(.avx)) |
| 14659 | 14661 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14660 | 14662 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14667,8 +14669,8 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14667 | 14669 | } |
| 14668 | 14670 | else |
| 14669 | 14671 | unreachable, |
| 14670 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 14671 | 16 => switch (ty.vectorLen(mod)) { | |
| 14672 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 14673 | 16 => switch (ty.vectorLen(zcu)) { | |
| 14672 | 14674 | 1...8 => return .{ .move = if (self.hasFeature(.avx)) |
| 14673 | 14675 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14674 | 14676 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14679,7 +14681,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14679 | 14681 | .{ .v_, .movdqu } }, |
| 14680 | 14682 | else => {}, |
| 14681 | 14683 | }, |
| 14682 | 32 => switch (ty.vectorLen(mod)) { | |
| 14684 | 32 => switch (ty.vectorLen(zcu)) { | |
| 14683 | 14685 | 1...4 => return .{ .move = if (self.hasFeature(.avx)) |
| 14684 | 14686 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 14685 | 14687 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| ... | ... | @@ -14690,7 +14692,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14690 | 14692 | .{ .v_ps, .movu } }, |
| 14691 | 14693 | else => {}, |
| 14692 | 14694 | }, |
| 14693 | 64 => switch (ty.vectorLen(mod)) { | |
| 14695 | 64 => switch (ty.vectorLen(zcu)) { | |
| 14694 | 14696 | 1...2 => return .{ .move = if (self.hasFeature(.avx)) |
| 14695 | 14697 | if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu } |
| 14696 | 14698 | else if (aligned) .{ ._pd, .mova } else .{ ._pd, .movu } }, |
| ... | ... | @@ -14701,7 +14703,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 14701 | 14703 | .{ .v_pd, .movu } }, |
| 14702 | 14704 | else => {}, |
| 14703 | 14705 | }, |
| 14704 | 128 => switch (ty.vectorLen(mod)) { | |
| 14706 | 128 => switch (ty.vectorLen(zcu)) { | |
| 14705 | 14707 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 14706 | 14708 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 14707 | 14709 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | ... | @@ -14804,7 +14806,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: Copy |
| 14804 | 14806 | } }, |
| 14805 | 14807 | else => unreachable, |
| 14806 | 14808 | }, opts); |
| 14807 | part_disp += @intCast(dst_ty.abiSize(pt)); | |
| 14809 | part_disp += @intCast(dst_ty.abiSize(pt.zcu)); | |
| 14808 | 14810 | } |
| 14809 | 14811 | }, |
| 14810 | 14812 | .indirect => |reg_off| try self.genSetMem( |
| ... | ... | @@ -14846,9 +14848,9 @@ fn genSetReg( |
| 14846 | 14848 | opts: CopyOptions, |
| 14847 | 14849 | ) InnerError!void { |
| 14848 | 14850 | const pt = self.pt; |
| 14849 | const mod = pt.zcu; | |
| 14850 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 14851 | if (ty.bitSize(pt) > dst_reg.bitSize()) | |
| 14851 | const zcu = pt.zcu; | |
| 14852 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 14853 | if (ty.bitSize(zcu) > dst_reg.bitSize()) | |
| 14852 | 14854 | return self.fail("genSetReg called with a value larger than dst_reg", .{}); |
| 14853 | 14855 | switch (src_mcv) { |
| 14854 | 14856 | .none, |
| ... | ... | @@ -14965,13 +14967,13 @@ fn genSetReg( |
| 14965 | 14967 | ), |
| 14966 | 14968 | .x87, .mmx, .ip => unreachable, |
| 14967 | 14969 | .sse => try self.asmRegisterRegister( |
| 14968 | @as(?Mir.Inst.FixedTag, switch (ty.scalarType(mod).zigTypeTag(mod)) { | |
| 14970 | @as(?Mir.Inst.FixedTag, switch (ty.scalarType(zcu).zigTypeTag(zcu)) { | |
| 14969 | 14971 | else => switch (abi_size) { |
| 14970 | 14972 | 1...16 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else .{ ._, .movdqa }, |
| 14971 | 14973 | 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null, |
| 14972 | 14974 | else => null, |
| 14973 | 14975 | }, |
| 14974 | .Float => switch (ty.scalarType(mod).floatBits(self.target.*)) { | |
| 14976 | .Float => switch (ty.scalarType(zcu).floatBits(self.target.*)) { | |
| 14975 | 14977 | 16, 128 => switch (abi_size) { |
| 14976 | 14978 | 2...16 => if (self.hasFeature(.avx)) |
| 14977 | 14979 | .{ .v_, .movdqa } |
| ... | ... | @@ -15035,7 +15037,7 @@ fn genSetReg( |
| 15035 | 15037 | return (try self.moveStrategy( |
| 15036 | 15038 | ty, |
| 15037 | 15039 | dst_reg.class(), |
| 15038 | ty.abiAlignment(pt).check(@as(u32, @bitCast(small_addr))), | |
| 15040 | ty.abiAlignment(zcu).check(@as(u32, @bitCast(small_addr))), | |
| 15039 | 15041 | )).read(self, registerAlias(dst_reg, abi_size), .{ |
| 15040 | 15042 | .base = .{ .reg = .ds }, |
| 15041 | 15043 | .mod = .{ .rm = .{ |
| ... | ... | @@ -15136,8 +15138,8 @@ fn genSetMem( |
| 15136 | 15138 | opts: CopyOptions, |
| 15137 | 15139 | ) InnerError!void { |
| 15138 | 15140 | const pt = self.pt; |
| 15139 | const mod = pt.zcu; | |
| 15140 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 15141 | const zcu = pt.zcu; | |
| 15142 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 15141 | 15143 | const dst_ptr_mcv: MCValue = switch (base) { |
| 15142 | 15144 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| 15143 | 15145 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| ... | ... | @@ -15159,8 +15161,8 @@ fn genSetMem( |
| 15159 | 15161 | ), |
| 15160 | 15162 | .immediate => |imm| switch (abi_size) { |
| 15161 | 15163 | 1, 2, 4 => { |
| 15162 | const immediate = switch (if (ty.isAbiInt(mod)) | |
| 15163 | ty.intInfo(mod).signedness | |
| 15164 | const immediate = switch (if (ty.isAbiInt(zcu)) | |
| 15165 | ty.intInfo(zcu).signedness | |
| 15164 | 15166 | else |
| 15165 | 15167 | .unsigned) { |
| 15166 | 15168 | .signed => Immediate.s(@truncate(@as(i64, @bitCast(imm)))), |
| ... | ... | @@ -15193,7 +15195,7 @@ fn genSetMem( |
| 15193 | 15195 | .size = .dword, |
| 15194 | 15196 | .disp = disp + offset, |
| 15195 | 15197 | } } }, |
| 15196 | if (ty.isSignedInt(mod)) Immediate.s( | |
| 15198 | if (ty.isSignedInt(zcu)) Immediate.s( | |
| 15197 | 15199 | @truncate(@as(i64, @bitCast(imm)) >> (math.cast(u6, offset * 8) orelse 63)), |
| 15198 | 15200 | ) else Immediate.u( |
| 15199 | 15201 | @as(u32, @truncate(if (math.cast(u6, offset * 8)) |shift| imm >> shift else 0)), |
| ... | ... | @@ -15263,33 +15265,33 @@ fn genSetMem( |
| 15263 | 15265 | var part_disp: i32 = disp; |
| 15264 | 15266 | for (try self.splitType(ty), src_regs) |src_ty, src_reg| { |
| 15265 | 15267 | try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts); |
| 15266 | part_disp += @intCast(src_ty.abiSize(pt)); | |
| 15268 | part_disp += @intCast(src_ty.abiSize(zcu)); | |
| 15267 | 15269 | } |
| 15268 | 15270 | }, |
| 15269 | .register_overflow => |ro| switch (ty.zigTypeTag(mod)) { | |
| 15271 | .register_overflow => |ro| switch (ty.zigTypeTag(zcu)) { | |
| 15270 | 15272 | .Struct => { |
| 15271 | 15273 | try self.genSetMem( |
| 15272 | 15274 | base, |
| 15273 | disp + @as(i32, @intCast(ty.structFieldOffset(0, pt))), | |
| 15274 | ty.structFieldType(0, mod), | |
| 15275 | disp + @as(i32, @intCast(ty.structFieldOffset(0, zcu))), | |
| 15276 | ty.structFieldType(0, zcu), | |
| 15275 | 15277 | .{ .register = ro.reg }, |
| 15276 | 15278 | opts, |
| 15277 | 15279 | ); |
| 15278 | 15280 | try self.genSetMem( |
| 15279 | 15281 | base, |
| 15280 | disp + @as(i32, @intCast(ty.structFieldOffset(1, pt))), | |
| 15281 | ty.structFieldType(1, mod), | |
| 15282 | disp + @as(i32, @intCast(ty.structFieldOffset(1, zcu))), | |
| 15283 | ty.structFieldType(1, zcu), | |
| 15282 | 15284 | .{ .eflags = ro.eflags }, |
| 15283 | 15285 | opts, |
| 15284 | 15286 | ); |
| 15285 | 15287 | }, |
| 15286 | 15288 | .Optional => { |
| 15287 | assert(!ty.optionalReprIsPayload(mod)); | |
| 15288 | const child_ty = ty.optionalChild(mod); | |
| 15289 | assert(!ty.optionalReprIsPayload(zcu)); | |
| 15290 | const child_ty = ty.optionalChild(zcu); | |
| 15289 | 15291 | try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts); |
| 15290 | 15292 | try self.genSetMem( |
| 15291 | 15293 | base, |
| 15292 | disp + @as(i32, @intCast(child_ty.abiSize(pt))), | |
| 15294 | disp + @as(i32, @intCast(child_ty.abiSize(zcu))), | |
| 15293 | 15295 | Type.bool, |
| 15294 | 15296 | .{ .eflags = ro.eflags }, |
| 15295 | 15297 | opts, |
| ... | ... | @@ -15521,14 +15523,14 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 15521 | 15523 | |
| 15522 | 15524 | fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15523 | 15525 | const pt = self.pt; |
| 15524 | const mod = pt.zcu; | |
| 15526 | const zcu = pt.zcu; | |
| 15525 | 15527 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15526 | 15528 | const dst_ty = self.typeOfIndex(inst); |
| 15527 | 15529 | const src_ty = self.typeOf(ty_op.operand); |
| 15528 | 15530 | |
| 15529 | 15531 | const result = result: { |
| 15530 | 15532 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 15531 | if (dst_ty.isPtrAtRuntime(mod) and src_ty.isPtrAtRuntime(mod)) switch (src_mcv) { | |
| 15533 | if (dst_ty.isPtrAtRuntime(zcu) and src_ty.isPtrAtRuntime(zcu)) switch (src_mcv) { | |
| 15532 | 15534 | .lea_frame => break :result src_mcv, |
| 15533 | 15535 | else => if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv, |
| 15534 | 15536 | }; |
| ... | ... | @@ -15539,10 +15541,10 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15539 | 15541 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 15540 | 15542 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 15541 | 15543 | |
| 15542 | const dst_mcv = if (dst_rc.supersetOf(src_rc) and dst_ty.abiSize(pt) <= src_ty.abiSize(pt) and | |
| 15544 | const dst_mcv = if (dst_rc.supersetOf(src_rc) and dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and | |
| 15543 | 15545 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { |
| 15544 | 15546 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 15545 | try self.genCopy(switch (math.order(dst_ty.abiSize(pt), src_ty.abiSize(pt))) { | |
| 15547 | try self.genCopy(switch (math.order(dst_ty.abiSize(zcu), src_ty.abiSize(zcu))) { | |
| 15546 | 15548 | .lt => dst_ty, |
| 15547 | 15549 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, |
| 15548 | 15550 | .gt => src_ty, |
| ... | ... | @@ -15552,12 +15554,12 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15552 | 15554 | |
| 15553 | 15555 | if (dst_ty.isRuntimeFloat()) break :result dst_mcv; |
| 15554 | 15556 | |
| 15555 | if (dst_ty.isAbiInt(mod) and src_ty.isAbiInt(mod) and | |
| 15556 | dst_ty.intInfo(mod).signedness == src_ty.intInfo(mod).signedness) break :result dst_mcv; | |
| 15557 | if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and | |
| 15558 | dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv; | |
| 15557 | 15559 | |
| 15558 | const abi_size = dst_ty.abiSize(pt); | |
| 15559 | const bit_size = dst_ty.bitSize(pt); | |
| 15560 | if (abi_size * 8 <= bit_size or dst_ty.isVector(mod)) break :result dst_mcv; | |
| 15560 | const abi_size = dst_ty.abiSize(zcu); | |
| 15561 | const bit_size = dst_ty.bitSize(zcu); | |
| 15562 | if (abi_size * 8 <= bit_size or dst_ty.isVector(zcu)) break :result dst_mcv; | |
| 15561 | 15563 | |
| 15562 | 15564 | const dst_limbs_len = math.divCeil(i32, @intCast(bit_size), 64) catch unreachable; |
| 15563 | 15565 | const high_mcv: MCValue = switch (dst_mcv) { |
| ... | ... | @@ -15586,20 +15588,20 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 15586 | 15588 | |
| 15587 | 15589 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 15588 | 15590 | const pt = self.pt; |
| 15589 | const mod = pt.zcu; | |
| 15591 | const zcu = pt.zcu; | |
| 15590 | 15592 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15591 | 15593 | |
| 15592 | 15594 | const slice_ty = self.typeOfIndex(inst); |
| 15593 | 15595 | const ptr_ty = self.typeOf(ty_op.operand); |
| 15594 | 15596 | const ptr = try self.resolveInst(ty_op.operand); |
| 15595 | const array_ty = ptr_ty.childType(mod); | |
| 15596 | const array_len = array_ty.arrayLen(mod); | |
| 15597 | const array_ty = ptr_ty.childType(zcu); | |
| 15598 | const array_len = array_ty.arrayLen(zcu); | |
| 15597 | 15599 | |
| 15598 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, pt)); | |
| 15600 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | |
| 15599 | 15601 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); |
| 15600 | 15602 | try self.genSetMem( |
| 15601 | 15603 | .{ .frame = frame_index }, |
| 15602 | @intCast(ptr_ty.abiSize(pt)), | |
| 15604 | @intCast(ptr_ty.abiSize(zcu)), | |
| 15603 | 15605 | Type.usize, |
| 15604 | 15606 | .{ .immediate = array_len }, |
| 15605 | 15607 | .{}, |
| ... | ... | @@ -15611,16 +15613,16 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 15611 | 15613 | |
| 15612 | 15614 | fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15613 | 15615 | const pt = self.pt; |
| 15614 | const mod = pt.zcu; | |
| 15616 | const zcu = pt.zcu; | |
| 15615 | 15617 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15616 | 15618 | |
| 15617 | 15619 | const dst_ty = self.typeOfIndex(inst); |
| 15618 | 15620 | const dst_bits = dst_ty.floatBits(self.target.*); |
| 15619 | 15621 | |
| 15620 | 15622 | const src_ty = self.typeOf(ty_op.operand); |
| 15621 | const src_bits: u32 = @intCast(src_ty.bitSize(pt)); | |
| 15623 | const src_bits: u32 = @intCast(src_ty.bitSize(zcu)); | |
| 15622 | 15624 | const src_signedness = |
| 15623 | if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; | |
| 15625 | if (src_ty.isAbiInt(zcu)) src_ty.intInfo(zcu).signedness else .unsigned; | |
| 15624 | 15626 | const src_size = math.divCeil(u32, @max(switch (src_signedness) { |
| 15625 | 15627 | .signed => src_bits, |
| 15626 | 15628 | .unsigned => src_bits + 1, |
| ... | ... | @@ -15666,7 +15668,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15666 | 15668 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 15667 | 15669 | defer self.register_manager.unlockReg(dst_lock); |
| 15668 | 15670 | |
| 15669 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(mod)) { | |
| 15671 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(zcu)) { | |
| 15670 | 15672 | .Float => switch (dst_ty.floatBits(self.target.*)) { |
| 15671 | 15673 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 }, |
| 15672 | 15674 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 }, |
| ... | ... | @@ -15691,13 +15693,13 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 15691 | 15693 | |
| 15692 | 15694 | fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 15693 | 15695 | const pt = self.pt; |
| 15694 | const mod = pt.zcu; | |
| 15696 | const zcu = pt.zcu; | |
| 15695 | 15697 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15696 | 15698 | |
| 15697 | 15699 | const dst_ty = self.typeOfIndex(inst); |
| 15698 | const dst_bits: u32 = @intCast(dst_ty.bitSize(pt)); | |
| 15700 | const dst_bits: u32 = @intCast(dst_ty.bitSize(zcu)); | |
| 15699 | 15701 | const dst_signedness = |
| 15700 | if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned; | |
| 15702 | if (dst_ty.isAbiInt(zcu)) dst_ty.intInfo(zcu).signedness else .unsigned; | |
| 15701 | 15703 | const dst_size = math.divCeil(u32, @max(switch (dst_signedness) { |
| 15702 | 15704 | .signed => dst_bits, |
| 15703 | 15705 | .unsigned => dst_bits + 1, |
| ... | ... | @@ -15768,7 +15770,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 15768 | 15770 | |
| 15769 | 15771 | const ptr_ty = self.typeOf(extra.ptr); |
| 15770 | 15772 | const val_ty = self.typeOf(extra.expected_value); |
| 15771 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); | |
| 15773 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt.zcu)); | |
| 15772 | 15774 | |
| 15773 | 15775 | try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx }); |
| 15774 | 15776 | const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx }); |
| ... | ... | @@ -15859,7 +15861,7 @@ fn atomicOp( |
| 15859 | 15861 | order: std.builtin.AtomicOrder, |
| 15860 | 15862 | ) InnerError!MCValue { |
| 15861 | 15863 | const pt = self.pt; |
| 15862 | const mod = pt.zcu; | |
| 15864 | const zcu = pt.zcu; | |
| 15863 | 15865 | const ptr_lock = switch (ptr_mcv) { |
| 15864 | 15866 | .register => |reg| self.register_manager.lockReg(reg), |
| 15865 | 15867 | else => null, |
| ... | ... | @@ -15872,7 +15874,7 @@ fn atomicOp( |
| 15872 | 15874 | }; |
| 15873 | 15875 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); |
| 15874 | 15876 | |
| 15875 | const val_abi_size: u32 = @intCast(val_ty.abiSize(pt)); | |
| 15877 | const val_abi_size: u32 = @intCast(val_ty.abiSize(zcu)); | |
| 15876 | 15878 | const mem_size = Memory.Size.fromSize(val_abi_size); |
| 15877 | 15879 | const ptr_mem: Memory = switch (ptr_mcv) { |
| 15878 | 15880 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), |
| ... | ... | @@ -16031,8 +16033,8 @@ fn atomicOp( |
| 16031 | 16033 | .Or => try self.genBinOpMir(.{ ._, .@"or" }, val_ty, tmp_mcv, val_mcv), |
| 16032 | 16034 | .Xor => try self.genBinOpMir(.{ ._, .xor }, val_ty, tmp_mcv, val_mcv), |
| 16033 | 16035 | .Min, .Max => { |
| 16034 | const cc: Condition = switch (if (val_ty.isAbiInt(mod)) | |
| 16035 | val_ty.intInfo(mod).signedness | |
| 16036 | const cc: Condition = switch (if (val_ty.isAbiInt(zcu)) | |
| 16037 | val_ty.intInfo(zcu).signedness | |
| 16036 | 16038 | else |
| 16037 | 16039 | .unsigned) { |
| 16038 | 16040 | .unsigned => switch (op) { |
| ... | ... | @@ -16156,8 +16158,8 @@ fn atomicOp( |
| 16156 | 16158 | try self.asmRegisterMemory(.{ ._, .xor }, .rcx, val_hi_mem); |
| 16157 | 16159 | }, |
| 16158 | 16160 | .Min, .Max => { |
| 16159 | const cc: Condition = switch (if (val_ty.isAbiInt(mod)) | |
| 16160 | val_ty.intInfo(mod).signedness | |
| 16161 | const cc: Condition = switch (if (val_ty.isAbiInt(zcu)) | |
| 16162 | val_ty.intInfo(zcu).signedness | |
| 16161 | 16163 | else |
| 16162 | 16164 | .unsigned) { |
| 16163 | 16165 | .unsigned => switch (op) { |
| ... | ... | @@ -16264,7 +16266,7 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr |
| 16264 | 16266 | |
| 16265 | 16267 | fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16266 | 16268 | const pt = self.pt; |
| 16267 | const mod = pt.zcu; | |
| 16269 | const zcu = pt.zcu; | |
| 16268 | 16270 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 16269 | 16271 | |
| 16270 | 16272 | result: { |
| ... | ... | @@ -16290,19 +16292,19 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16290 | 16292 | }; |
| 16291 | 16293 | defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock); |
| 16292 | 16294 | |
| 16293 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(pt)); | |
| 16295 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); | |
| 16294 | 16296 | |
| 16295 | 16297 | if (elem_abi_size == 1) { |
| 16296 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { | |
| 16298 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { | |
| 16297 | 16299 | // TODO: this only handles slices stored in the stack |
| 16298 | 16300 | .Slice => dst_ptr, |
| 16299 | 16301 | .One => dst_ptr, |
| 16300 | 16302 | .C, .Many => unreachable, |
| 16301 | 16303 | }; |
| 16302 | const len: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { | |
| 16304 | const len: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { | |
| 16303 | 16305 | // TODO: this only handles slices stored in the stack |
| 16304 | 16306 | .Slice => dst_ptr.address().offset(8).deref(), |
| 16305 | .One => .{ .immediate = dst_ptr_ty.childType(mod).arrayLen(mod) }, | |
| 16307 | .One => .{ .immediate = dst_ptr_ty.childType(zcu).arrayLen(zcu) }, | |
| 16306 | 16308 | .C, .Many => unreachable, |
| 16307 | 16309 | }; |
| 16308 | 16310 | const len_lock: ?RegisterLock = switch (len) { |
| ... | ... | @@ -16318,9 +16320,9 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16318 | 16320 | // Store the first element, and then rely on memcpy copying forwards. |
| 16319 | 16321 | // Length zero requires a runtime check - so we handle arrays specially |
| 16320 | 16322 | // here to elide it. |
| 16321 | switch (dst_ptr_ty.ptrSize(mod)) { | |
| 16323 | switch (dst_ptr_ty.ptrSize(zcu)) { | |
| 16322 | 16324 | .Slice => { |
| 16323 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(mod); | |
| 16325 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(zcu); | |
| 16324 | 16326 | |
| 16325 | 16327 | // TODO: this only handles slices stored in the stack |
| 16326 | 16328 | const ptr = dst_ptr; |
| ... | ... | @@ -16365,7 +16367,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16365 | 16367 | .One => { |
| 16366 | 16368 | const elem_ptr_ty = try pt.singleMutPtrType(elem_ty); |
| 16367 | 16369 | |
| 16368 | const len = dst_ptr_ty.childType(mod).arrayLen(mod); | |
| 16370 | const len = dst_ptr_ty.childType(zcu).arrayLen(zcu); | |
| 16369 | 16371 | |
| 16370 | 16372 | assert(len != 0); // prevented by Sema |
| 16371 | 16373 | try self.store(elem_ptr_ty, dst_ptr, src_val, .{ .safety = safety }); |
| ... | ... | @@ -16393,7 +16395,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 16393 | 16395 | |
| 16394 | 16396 | fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16395 | 16397 | const pt = self.pt; |
| 16396 | const mod = pt.zcu; | |
| 16398 | const zcu = pt.zcu; | |
| 16397 | 16399 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 16398 | 16400 | |
| 16399 | 16401 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); |
| ... | ... | @@ -16415,7 +16417,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16415 | 16417 | }; |
| 16416 | 16418 | defer if (src_ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 16417 | 16419 | |
| 16418 | const len: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { | |
| 16420 | const len: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { | |
| 16419 | 16421 | .Slice => len: { |
| 16420 | 16422 | const len_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 16421 | 16423 | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| ... | ... | @@ -16425,13 +16427,13 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16425 | 16427 | .{ .i_, .mul }, |
| 16426 | 16428 | len_reg, |
| 16427 | 16429 | try dst_ptr.address().offset(8).deref().mem(self, .qword), |
| 16428 | Immediate.s(@intCast(dst_ptr_ty.childType(mod).abiSize(pt))), | |
| 16430 | Immediate.s(@intCast(dst_ptr_ty.childType(zcu).abiSize(zcu))), | |
| 16429 | 16431 | ); |
| 16430 | 16432 | break :len .{ .register = len_reg }; |
| 16431 | 16433 | }, |
| 16432 | 16434 | .One => len: { |
| 16433 | const array_ty = dst_ptr_ty.childType(mod); | |
| 16434 | break :len .{ .immediate = array_ty.arrayLen(mod) * array_ty.childType(mod).abiSize(pt) }; | |
| 16435 | const array_ty = dst_ptr_ty.childType(zcu); | |
| 16436 | break :len .{ .immediate = array_ty.arrayLen(zcu) * array_ty.childType(zcu).abiSize(zcu) }; | |
| 16435 | 16437 | }, |
| 16436 | 16438 | .C, .Many => unreachable, |
| 16437 | 16439 | }; |
| ... | ... | @@ -16449,6 +16451,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 16449 | 16451 | |
| 16450 | 16452 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 16451 | 16453 | const pt = self.pt; |
| 16454 | const zcu = pt.zcu; | |
| 16452 | 16455 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 16453 | 16456 | const inst_ty = self.typeOfIndex(inst); |
| 16454 | 16457 | const enum_ty = self.typeOf(un_op); |
| ... | ... | @@ -16457,8 +16460,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 16457 | 16460 | // We need a properly aligned and sized call frame to be able to call this function. |
| 16458 | 16461 | { |
| 16459 | 16462 | const needed_call_frame = FrameAlloc.init(.{ |
| 16460 | .size = inst_ty.abiSize(pt), | |
| 16461 | .alignment = inst_ty.abiAlignment(pt), | |
| 16463 | .size = inst_ty.abiSize(zcu), | |
| 16464 | .alignment = inst_ty.abiAlignment(zcu), | |
| 16462 | 16465 | }); |
| 16463 | 16466 | const frame_allocs_slice = self.frame_allocs.slice(); |
| 16464 | 16467 | const stack_frame_size = |
| ... | ... | @@ -16590,15 +16593,15 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 16590 | 16593 | |
| 16591 | 16594 | fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16592 | 16595 | const pt = self.pt; |
| 16593 | const mod = pt.zcu; | |
| 16596 | const zcu = pt.zcu; | |
| 16594 | 16597 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 16595 | 16598 | const vector_ty = self.typeOfIndex(inst); |
| 16596 | const vector_len = vector_ty.vectorLen(mod); | |
| 16599 | const vector_len = vector_ty.vectorLen(zcu); | |
| 16597 | 16600 | const dst_rc = self.regClassForType(vector_ty); |
| 16598 | 16601 | const scalar_ty = self.typeOf(ty_op.operand); |
| 16599 | 16602 | |
| 16600 | 16603 | const result: MCValue = result: { |
| 16601 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 16604 | switch (scalar_ty.zigTypeTag(zcu)) { | |
| 16602 | 16605 | else => {}, |
| 16603 | 16606 | .Bool => { |
| 16604 | 16607 | const regs = |
| ... | ... | @@ -16641,7 +16644,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16641 | 16644 | break :result .{ .register = regs[0] }; |
| 16642 | 16645 | }, |
| 16643 | 16646 | .Int => if (self.hasFeature(.avx2)) avx2: { |
| 16644 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (scalar_ty.intInfo(mod).bits) { | |
| 16647 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (scalar_ty.intInfo(zcu).bits) { | |
| 16645 | 16648 | else => null, |
| 16646 | 16649 | 1...8 => switch (vector_len) { |
| 16647 | 16650 | else => null, |
| ... | ... | @@ -16672,15 +16675,15 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16672 | 16675 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 16673 | 16676 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 16674 | 16677 | mir_tag, |
| 16675 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))), | |
| 16678 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(zcu))), | |
| 16676 | 16679 | try src_mcv.mem(self, self.memSize(scalar_ty)), |
| 16677 | 16680 | ) else { |
| 16678 | 16681 | if (mir_tag[0] == .v_i128) break :avx2; |
| 16679 | 16682 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); |
| 16680 | 16683 | try self.asmRegisterRegister( |
| 16681 | 16684 | mir_tag, |
| 16682 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))), | |
| 16683 | registerAlias(dst_reg, @intCast(scalar_ty.abiSize(pt))), | |
| 16685 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(zcu))), | |
| 16686 | registerAlias(dst_reg, @intCast(scalar_ty.abiSize(zcu))), | |
| 16684 | 16687 | ); |
| 16685 | 16688 | } |
| 16686 | 16689 | break :result .{ .register = dst_reg }; |
| ... | ... | @@ -16692,8 +16695,8 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16692 | 16695 | try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{}); |
| 16693 | 16696 | if (vector_len == 1) break :result .{ .register = dst_reg }; |
| 16694 | 16697 | |
| 16695 | const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(pt))); | |
| 16696 | const scalar_bits = scalar_ty.intInfo(mod).bits; | |
| 16698 | const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(zcu))); | |
| 16699 | const scalar_bits = scalar_ty.intInfo(zcu).bits; | |
| 16697 | 16700 | if (switch (scalar_bits) { |
| 16698 | 16701 | 1...8 => true, |
| 16699 | 16702 | 9...128 => false, |
| ... | ... | @@ -16929,14 +16932,14 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 16929 | 16932 | |
| 16930 | 16933 | fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 16931 | 16934 | const pt = self.pt; |
| 16932 | const mod = pt.zcu; | |
| 16935 | const zcu = pt.zcu; | |
| 16933 | 16936 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 16934 | 16937 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 16935 | 16938 | const ty = self.typeOfIndex(inst); |
| 16936 | const vec_len = ty.vectorLen(mod); | |
| 16937 | const elem_ty = ty.childType(mod); | |
| 16938 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 16939 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 16939 | const vec_len = ty.vectorLen(zcu); | |
| 16940 | const elem_ty = ty.childType(zcu); | |
| 16941 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 16942 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 16940 | 16943 | const pred_ty = self.typeOf(pl_op.operand); |
| 16941 | 16944 | |
| 16942 | 16945 | const result = result: { |
| ... | ... | @@ -17160,7 +17163,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17160 | 17163 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 17161 | 17164 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 17162 | 17165 | |
| 17163 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 17166 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 17164 | 17167 | else => null, |
| 17165 | 17168 | .Int => switch (abi_size) { |
| 17166 | 17169 | 0 => unreachable, |
| ... | ... | @@ -17176,7 +17179,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17176 | 17179 | null, |
| 17177 | 17180 | else => null, |
| 17178 | 17181 | }, |
| 17179 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 17182 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 17180 | 17183 | else => unreachable, |
| 17181 | 17184 | 16, 80, 128 => null, |
| 17182 | 17185 | 32 => switch (vec_len) { |
| ... | ... | @@ -17230,7 +17233,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17230 | 17233 | try self.copyToTmpRegister(ty, lhs_mcv), abi_size), |
| 17231 | 17234 | mask_alias, |
| 17232 | 17235 | ) else { |
| 17233 | const mir_fixes = @as(?Mir.Inst.Fixes, switch (elem_ty.zigTypeTag(mod)) { | |
| 17236 | const mir_fixes = @as(?Mir.Inst.Fixes, switch (elem_ty.zigTypeTag(zcu)) { | |
| 17234 | 17237 | else => null, |
| 17235 | 17238 | .Int => .p_, |
| 17236 | 17239 | .Float => switch (elem_ty.floatBits(self.target.*)) { |
| ... | ... | @@ -17262,18 +17265,18 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17262 | 17265 | |
| 17263 | 17266 | fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17264 | 17267 | const pt = self.pt; |
| 17265 | const mod = pt.zcu; | |
| 17268 | const zcu = pt.zcu; | |
| 17266 | 17269 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 17267 | 17270 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 17268 | 17271 | |
| 17269 | 17272 | const dst_ty = self.typeOfIndex(inst); |
| 17270 | const elem_ty = dst_ty.childType(mod); | |
| 17271 | const elem_abi_size: u16 = @intCast(elem_ty.abiSize(pt)); | |
| 17272 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt)); | |
| 17273 | const elem_ty = dst_ty.childType(zcu); | |
| 17274 | const elem_abi_size: u16 = @intCast(elem_ty.abiSize(zcu)); | |
| 17275 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu)); | |
| 17273 | 17276 | const lhs_ty = self.typeOf(extra.a); |
| 17274 | const lhs_abi_size: u32 = @intCast(lhs_ty.abiSize(pt)); | |
| 17277 | const lhs_abi_size: u32 = @intCast(lhs_ty.abiSize(zcu)); | |
| 17275 | 17278 | const rhs_ty = self.typeOf(extra.b); |
| 17276 | const rhs_abi_size: u32 = @intCast(rhs_ty.abiSize(pt)); | |
| 17279 | const rhs_abi_size: u32 = @intCast(rhs_ty.abiSize(zcu)); | |
| 17277 | 17280 | const max_abi_size = @max(dst_abi_size, lhs_abi_size, rhs_abi_size); |
| 17278 | 17281 | |
| 17279 | 17282 | const ExpectedContents = [32]?i32; |
| ... | ... | @@ -17286,10 +17289,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17286 | 17289 | for (mask_elems, 0..) |*mask_elem, elem_index| { |
| 17287 | 17290 | const mask_elem_val = |
| 17288 | 17291 | Value.fromInterned(extra.mask).elemValue(pt, elem_index) catch unreachable; |
| 17289 | mask_elem.* = if (mask_elem_val.isUndef(mod)) | |
| 17292 | mask_elem.* = if (mask_elem_val.isUndef(zcu)) | |
| 17290 | 17293 | null |
| 17291 | 17294 | else |
| 17292 | @intCast(mask_elem_val.toSignedInt(pt)); | |
| 17295 | @intCast(mask_elem_val.toSignedInt(zcu)); | |
| 17293 | 17296 | } |
| 17294 | 17297 | |
| 17295 | 17298 | const has_avx = self.hasFeature(.avx); |
| ... | ... | @@ -18028,7 +18031,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18028 | 18031 | ); |
| 18029 | 18032 | |
| 18030 | 18033 | if (has_avx) try self.asmRegisterRegisterRegister( |
| 18031 | .{ switch (elem_ty.zigTypeTag(mod)) { | |
| 18034 | .{ switch (elem_ty.zigTypeTag(zcu)) { | |
| 18032 | 18035 | else => break :result null, |
| 18033 | 18036 | .Int => .vp_, |
| 18034 | 18037 | .Float => switch (elem_ty.floatBits(self.target.*)) { |
| ... | ... | @@ -18042,7 +18045,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18042 | 18045 | lhs_temp_alias, |
| 18043 | 18046 | rhs_temp_alias, |
| 18044 | 18047 | ) else try self.asmRegisterRegister( |
| 18045 | .{ switch (elem_ty.zigTypeTag(mod)) { | |
| 18048 | .{ switch (elem_ty.zigTypeTag(zcu)) { | |
| 18046 | 18049 | else => break :result null, |
| 18047 | 18050 | .Int => .p_, |
| 18048 | 18051 | .Float => switch (elem_ty.floatBits(self.target.*)) { |
| ... | ... | @@ -18068,19 +18071,19 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18068 | 18071 | |
| 18069 | 18072 | fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 18070 | 18073 | const pt = self.pt; |
| 18071 | const mod = pt.zcu; | |
| 18074 | const zcu = pt.zcu; | |
| 18072 | 18075 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 18073 | 18076 | |
| 18074 | 18077 | const result: MCValue = result: { |
| 18075 | 18078 | const operand_ty = self.typeOf(reduce.operand); |
| 18076 | if (operand_ty.isVector(mod) and operand_ty.childType(mod).toIntern() == .bool_type) { | |
| 18079 | if (operand_ty.isVector(zcu) and operand_ty.childType(zcu).toIntern() == .bool_type) { | |
| 18077 | 18080 | try self.spillEflagsIfOccupied(); |
| 18078 | 18081 | |
| 18079 | 18082 | const operand_mcv = try self.resolveInst(reduce.operand); |
| 18080 | const mask_len = (math.cast(u6, operand_ty.vectorLen(mod)) orelse | |
| 18083 | const mask_len = (math.cast(u6, operand_ty.vectorLen(zcu)) orelse | |
| 18081 | 18084 | return self.fail("TODO implement airReduce for {}", .{operand_ty.fmt(pt)})); |
| 18082 | 18085 | const mask = (@as(u64, 1) << mask_len) - 1; |
| 18083 | const abi_size: u32 = @intCast(operand_ty.abiSize(pt)); | |
| 18086 | const abi_size: u32 = @intCast(operand_ty.abiSize(zcu)); | |
| 18084 | 18087 | switch (reduce.operation) { |
| 18085 | 18088 | .Or => { |
| 18086 | 18089 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( |
| ... | ... | @@ -18126,36 +18129,36 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 18126 | 18129 | |
| 18127 | 18130 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18128 | 18131 | const pt = self.pt; |
| 18129 | const mod = pt.zcu; | |
| 18132 | const zcu = pt.zcu; | |
| 18130 | 18133 | const result_ty = self.typeOfIndex(inst); |
| 18131 | const len: usize = @intCast(result_ty.arrayLen(mod)); | |
| 18134 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | |
| 18132 | 18135 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 18133 | 18136 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]); |
| 18134 | 18137 | const result: MCValue = result: { |
| 18135 | switch (result_ty.zigTypeTag(mod)) { | |
| 18138 | switch (result_ty.zigTypeTag(zcu)) { | |
| 18136 | 18139 | .Struct => { |
| 18137 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); | |
| 18138 | if (result_ty.containerLayout(mod) == .@"packed") { | |
| 18139 | const struct_obj = mod.typeToStruct(result_ty).?; | |
| 18140 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | |
| 18141 | if (result_ty.containerLayout(zcu) == .@"packed") { | |
| 18142 | const struct_obj = zcu.typeToStruct(result_ty).?; | |
| 18140 | 18143 | try self.genInlineMemset( |
| 18141 | 18144 | .{ .lea_frame = .{ .index = frame_index } }, |
| 18142 | 18145 | .{ .immediate = 0 }, |
| 18143 | .{ .immediate = result_ty.abiSize(pt) }, | |
| 18146 | .{ .immediate = result_ty.abiSize(zcu) }, | |
| 18144 | 18147 | .{}, |
| 18145 | 18148 | ); |
| 18146 | 18149 | for (elements, 0..) |elem, elem_i_usize| { |
| 18147 | 18150 | const elem_i: u32 = @intCast(elem_i_usize); |
| 18148 | 18151 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 18149 | 18152 | |
| 18150 | const elem_ty = result_ty.structFieldType(elem_i, mod); | |
| 18151 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(pt)); | |
| 18153 | const elem_ty = result_ty.structFieldType(elem_i, zcu); | |
| 18154 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu)); | |
| 18152 | 18155 | if (elem_bit_size > 64) { |
| 18153 | 18156 | return self.fail( |
| 18154 | 18157 | "TODO airAggregateInit implement packed structs with large fields", |
| 18155 | 18158 | .{}, |
| 18156 | 18159 | ); |
| 18157 | 18160 | } |
| 18158 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 18161 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 18159 | 18162 | const elem_abi_bits = elem_abi_size * 8; |
| 18160 | 18163 | const elem_off = pt.structPackedFieldBitOffset(struct_obj, elem_i); |
| 18161 | 18164 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); |
| ... | ... | @@ -18229,8 +18232,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18229 | 18232 | } else for (elements, 0..) |elem, elem_i| { |
| 18230 | 18233 | if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue; |
| 18231 | 18234 | |
| 18232 | const elem_ty = result_ty.structFieldType(elem_i, mod); | |
| 18233 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, pt)); | |
| 18235 | const elem_ty = result_ty.structFieldType(elem_i, zcu); | |
| 18236 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu)); | |
| 18234 | 18237 | const elem_mcv = try self.resolveInst(elem); |
| 18235 | 18238 | const mat_elem_mcv = switch (elem_mcv) { |
| 18236 | 18239 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| ... | ... | @@ -18241,9 +18244,9 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18241 | 18244 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 18242 | 18245 | }, |
| 18243 | 18246 | .Array, .Vector => { |
| 18244 | const elem_ty = result_ty.childType(mod); | |
| 18245 | if (result_ty.isVector(mod) and elem_ty.toIntern() == .bool_type) { | |
| 18246 | const result_size: u32 = @intCast(result_ty.abiSize(pt)); | |
| 18247 | const elem_ty = result_ty.childType(zcu); | |
| 18248 | if (result_ty.isVector(zcu) and elem_ty.toIntern() == .bool_type) { | |
| 18249 | const result_size: u32 = @intCast(result_ty.abiSize(zcu)); | |
| 18247 | 18250 | const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); |
| 18248 | 18251 | try self.asmRegisterRegister( |
| 18249 | 18252 | .{ ._, .xor }, |
| ... | ... | @@ -18274,8 +18277,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18274 | 18277 | } |
| 18275 | 18278 | break :result .{ .register = dst_reg }; |
| 18276 | 18279 | } else { |
| 18277 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, pt)); | |
| 18278 | const elem_size: u32 = @intCast(elem_ty.abiSize(pt)); | |
| 18280 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | |
| 18281 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | |
| 18279 | 18282 | |
| 18280 | 18283 | for (elements, 0..) |elem, elem_i| { |
| 18281 | 18284 | const elem_mcv = try self.resolveInst(elem); |
| ... | ... | @@ -18292,7 +18295,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18292 | 18295 | .{}, |
| 18293 | 18296 | ); |
| 18294 | 18297 | } |
| 18295 | if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem( | |
| 18298 | if (result_ty.sentinel(zcu)) |sentinel| try self.genSetMem( | |
| 18296 | 18299 | .{ .frame = frame_index }, |
| 18297 | 18300 | @intCast(elem_size * elements.len), |
| 18298 | 18301 | elem_ty, |
| ... | ... | @@ -18318,18 +18321,18 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18318 | 18321 | |
| 18319 | 18322 | fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18320 | 18323 | const pt = self.pt; |
| 18321 | const mod = pt.zcu; | |
| 18322 | const ip = &mod.intern_pool; | |
| 18324 | const zcu = pt.zcu; | |
| 18325 | const ip = &zcu.intern_pool; | |
| 18323 | 18326 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 18324 | 18327 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 18325 | 18328 | const result: MCValue = result: { |
| 18326 | 18329 | const union_ty = self.typeOfIndex(inst); |
| 18327 | const layout = union_ty.unionGetLayout(pt); | |
| 18330 | const layout = union_ty.unionGetLayout(zcu); | |
| 18328 | 18331 | |
| 18329 | 18332 | const src_ty = self.typeOf(extra.init); |
| 18330 | 18333 | const src_mcv = try self.resolveInst(extra.init); |
| 18331 | 18334 | if (layout.tag_size == 0) { |
| 18332 | if (layout.abi_size <= src_ty.abiSize(pt) and | |
| 18335 | if (layout.abi_size <= src_ty.abiSize(zcu) and | |
| 18333 | 18336 | self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; |
| 18334 | 18337 | |
| 18335 | 18338 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| ... | ... | @@ -18339,13 +18342,13 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18339 | 18342 | |
| 18340 | 18343 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 18341 | 18344 | |
| 18342 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 18345 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 18343 | 18346 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 18344 | 18347 | const tag_ty = Type.fromInterned(union_obj.enum_tag_ty); |
| 18345 | const field_index = tag_ty.enumFieldIndex(field_name, mod).?; | |
| 18348 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; | |
| 18346 | 18349 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 18347 | 18350 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); |
| 18348 | const tag_int = tag_int_val.toUnsignedInt(pt); | |
| 18351 | const tag_int = tag_int_val.toUnsignedInt(zcu); | |
| 18349 | 18352 | const tag_off: i32 = @intCast(layout.tagOffset()); |
| 18350 | 18353 | try self.genCopy( |
| 18351 | 18354 | tag_ty, |
| ... | ... | @@ -18369,19 +18372,19 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { |
| 18369 | 18372 | |
| 18370 | 18373 | fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18371 | 18374 | const pt = self.pt; |
| 18372 | const mod = pt.zcu; | |
| 18375 | const zcu = pt.zcu; | |
| 18373 | 18376 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 18374 | 18377 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 18375 | 18378 | const ty = self.typeOfIndex(inst); |
| 18376 | 18379 | |
| 18377 | 18380 | const ops = [3]Air.Inst.Ref{ extra.lhs, extra.rhs, pl_op.operand }; |
| 18378 | 18381 | const result = result: { |
| 18379 | if (switch (ty.scalarType(mod).floatBits(self.target.*)) { | |
| 18382 | if (switch (ty.scalarType(zcu).floatBits(self.target.*)) { | |
| 18380 | 18383 | 16, 80, 128 => true, |
| 18381 | 18384 | 32, 64 => !self.hasFeature(.fma), |
| 18382 | 18385 | else => unreachable, |
| 18383 | 18386 | }) { |
| 18384 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement airMulAdd for {}", .{ | |
| 18387 | if (ty.zigTypeTag(zcu) != .Float) return self.fail("TODO implement airMulAdd for {}", .{ | |
| 18385 | 18388 | ty.fmt(pt), |
| 18386 | 18389 | }); |
| 18387 | 18390 | |
| ... | ... | @@ -18430,21 +18433,21 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18430 | 18433 | |
| 18431 | 18434 | const mir_tag = @as(?Mir.Inst.FixedTag, if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or |
| 18432 | 18435 | mem.eql(u2, &order, &.{ 3, 1, 2 })) |
| 18433 | switch (ty.zigTypeTag(mod)) { | |
| 18436 | switch (ty.zigTypeTag(zcu)) { | |
| 18434 | 18437 | .Float => switch (ty.floatBits(self.target.*)) { |
| 18435 | 18438 | 32 => .{ .v_ss, .fmadd132 }, |
| 18436 | 18439 | 64 => .{ .v_sd, .fmadd132 }, |
| 18437 | 18440 | 16, 80, 128 => null, |
| 18438 | 18441 | else => unreachable, |
| 18439 | 18442 | }, |
| 18440 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 18441 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 18442 | 32 => switch (ty.vectorLen(mod)) { | |
| 18443 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 18444 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 18445 | 32 => switch (ty.vectorLen(zcu)) { | |
| 18443 | 18446 | 1 => .{ .v_ss, .fmadd132 }, |
| 18444 | 18447 | 2...8 => .{ .v_ps, .fmadd132 }, |
| 18445 | 18448 | else => null, |
| 18446 | 18449 | }, |
| 18447 | 64 => switch (ty.vectorLen(mod)) { | |
| 18450 | 64 => switch (ty.vectorLen(zcu)) { | |
| 18448 | 18451 | 1 => .{ .v_sd, .fmadd132 }, |
| 18449 | 18452 | 2...4 => .{ .v_pd, .fmadd132 }, |
| 18450 | 18453 | else => null, |
| ... | ... | @@ -18457,21 +18460,21 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18457 | 18460 | else => unreachable, |
| 18458 | 18461 | } |
| 18459 | 18462 | else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 })) |
| 18460 | switch (ty.zigTypeTag(mod)) { | |
| 18463 | switch (ty.zigTypeTag(zcu)) { | |
| 18461 | 18464 | .Float => switch (ty.floatBits(self.target.*)) { |
| 18462 | 18465 | 32 => .{ .v_ss, .fmadd213 }, |
| 18463 | 18466 | 64 => .{ .v_sd, .fmadd213 }, |
| 18464 | 18467 | 16, 80, 128 => null, |
| 18465 | 18468 | else => unreachable, |
| 18466 | 18469 | }, |
| 18467 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 18468 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 18469 | 32 => switch (ty.vectorLen(mod)) { | |
| 18470 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 18471 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 18472 | 32 => switch (ty.vectorLen(zcu)) { | |
| 18470 | 18473 | 1 => .{ .v_ss, .fmadd213 }, |
| 18471 | 18474 | 2...8 => .{ .v_ps, .fmadd213 }, |
| 18472 | 18475 | else => null, |
| 18473 | 18476 | }, |
| 18474 | 64 => switch (ty.vectorLen(mod)) { | |
| 18477 | 64 => switch (ty.vectorLen(zcu)) { | |
| 18475 | 18478 | 1 => .{ .v_sd, .fmadd213 }, |
| 18476 | 18479 | 2...4 => .{ .v_pd, .fmadd213 }, |
| 18477 | 18480 | else => null, |
| ... | ... | @@ -18484,21 +18487,21 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18484 | 18487 | else => unreachable, |
| 18485 | 18488 | } |
| 18486 | 18489 | else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 })) |
| 18487 | switch (ty.zigTypeTag(mod)) { | |
| 18490 | switch (ty.zigTypeTag(zcu)) { | |
| 18488 | 18491 | .Float => switch (ty.floatBits(self.target.*)) { |
| 18489 | 18492 | 32 => .{ .v_ss, .fmadd231 }, |
| 18490 | 18493 | 64 => .{ .v_sd, .fmadd231 }, |
| 18491 | 18494 | 16, 80, 128 => null, |
| 18492 | 18495 | else => unreachable, |
| 18493 | 18496 | }, |
| 18494 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 18495 | .Float => switch (ty.childType(mod).floatBits(self.target.*)) { | |
| 18496 | 32 => switch (ty.vectorLen(mod)) { | |
| 18497 | .Vector => switch (ty.childType(zcu).zigTypeTag(zcu)) { | |
| 18498 | .Float => switch (ty.childType(zcu).floatBits(self.target.*)) { | |
| 18499 | 32 => switch (ty.vectorLen(zcu)) { | |
| 18497 | 18500 | 1 => .{ .v_ss, .fmadd231 }, |
| 18498 | 18501 | 2...8 => .{ .v_ps, .fmadd231 }, |
| 18499 | 18502 | else => null, |
| 18500 | 18503 | }, |
| 18501 | 64 => switch (ty.vectorLen(mod)) { | |
| 18504 | 64 => switch (ty.vectorLen(zcu)) { | |
| 18502 | 18505 | 1 => .{ .v_sd, .fmadd231 }, |
| 18503 | 18506 | 2...4 => .{ .v_pd, .fmadd231 }, |
| 18504 | 18507 | else => null, |
| ... | ... | @@ -18516,7 +18519,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18516 | 18519 | var mops: [3]MCValue = undefined; |
| 18517 | 18520 | for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv; |
| 18518 | 18521 | |
| 18519 | const abi_size: u32 = @intCast(ty.abiSize(pt)); | |
| 18522 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | |
| 18520 | 18523 | const mop1_reg = registerAlias(mops[0].getReg().?, abi_size); |
| 18521 | 18524 | const mop2_reg = registerAlias(mops[1].getReg().?, abi_size); |
| 18522 | 18525 | if (mops[2].isRegister()) try self.asmRegisterRegisterRegister( |
| ... | ... | @@ -18537,17 +18540,17 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 18537 | 18540 | |
| 18538 | 18541 | fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18539 | 18542 | const pt = self.pt; |
| 18540 | const mod = pt.zcu; | |
| 18543 | const zcu = pt.zcu; | |
| 18541 | 18544 | const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty; |
| 18542 | 18545 | const ptr_anyopaque_ty = try pt.singleMutPtrType(Type.anyopaque); |
| 18543 | 18546 | |
| 18544 | 18547 | const result: MCValue = switch (abi.resolveCallingConvention( |
| 18545 | self.fn_type.fnCallingConvention(mod), | |
| 18548 | self.fn_type.fnCallingConvention(zcu), | |
| 18546 | 18549 | self.target.*, |
| 18547 | 18550 | )) { |
| 18548 | 18551 | .SysV => result: { |
| 18549 | 18552 | const info = self.va_info.sysv; |
| 18550 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, pt)); | |
| 18553 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, zcu)); | |
| 18551 | 18554 | var field_off: u31 = 0; |
| 18552 | 18555 | // gp_offset: c_uint, |
| 18553 | 18556 | try self.genSetMem( |
| ... | ... | @@ -18557,7 +18560,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18557 | 18560 | .{ .immediate = info.gp_count * 8 }, |
| 18558 | 18561 | .{}, |
| 18559 | 18562 | ); |
| 18560 | field_off += @intCast(Type.c_uint.abiSize(pt)); | |
| 18563 | field_off += @intCast(Type.c_uint.abiSize(zcu)); | |
| 18561 | 18564 | // fp_offset: c_uint, |
| 18562 | 18565 | try self.genSetMem( |
| 18563 | 18566 | .{ .frame = dst_fi }, |
| ... | ... | @@ -18566,7 +18569,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18566 | 18569 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, |
| 18567 | 18570 | .{}, |
| 18568 | 18571 | ); |
| 18569 | field_off += @intCast(Type.c_uint.abiSize(pt)); | |
| 18572 | field_off += @intCast(Type.c_uint.abiSize(zcu)); | |
| 18570 | 18573 | // overflow_arg_area: *anyopaque, |
| 18571 | 18574 | try self.genSetMem( |
| 18572 | 18575 | .{ .frame = dst_fi }, |
| ... | ... | @@ -18575,7 +18578,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18575 | 18578 | .{ .lea_frame = info.overflow_arg_area }, |
| 18576 | 18579 | .{}, |
| 18577 | 18580 | ); |
| 18578 | field_off += @intCast(ptr_anyopaque_ty.abiSize(pt)); | |
| 18581 | field_off += @intCast(ptr_anyopaque_ty.abiSize(zcu)); | |
| 18579 | 18582 | // reg_save_area: *anyopaque, |
| 18580 | 18583 | try self.genSetMem( |
| 18581 | 18584 | .{ .frame = dst_fi }, |
| ... | ... | @@ -18584,7 +18587,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18584 | 18587 | .{ .lea_frame = info.reg_save_area }, |
| 18585 | 18588 | .{}, |
| 18586 | 18589 | ); |
| 18587 | field_off += @intCast(ptr_anyopaque_ty.abiSize(pt)); | |
| 18590 | field_off += @intCast(ptr_anyopaque_ty.abiSize(zcu)); | |
| 18588 | 18591 | break :result .{ .load_frame = .{ .index = dst_fi } }; |
| 18589 | 18592 | }, |
| 18590 | 18593 | .Win64 => return self.fail("TODO implement c_va_start for Win64", .{}), |
| ... | ... | @@ -18595,7 +18598,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18595 | 18598 | |
| 18596 | 18599 | fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18597 | 18600 | const pt = self.pt; |
| 18598 | const mod = pt.zcu; | |
| 18601 | const zcu = pt.zcu; | |
| 18599 | 18602 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 18600 | 18603 | const ty = self.typeOfIndex(inst); |
| 18601 | 18604 | const promote_ty = self.promoteVarArg(ty); |
| ... | ... | @@ -18603,7 +18606,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18603 | 18606 | const unused = self.liveness.isUnused(inst); |
| 18604 | 18607 | |
| 18605 | 18608 | const result: MCValue = switch (abi.resolveCallingConvention( |
| 18606 | self.fn_type.fnCallingConvention(mod), | |
| 18609 | self.fn_type.fnCallingConvention(zcu), | |
| 18607 | 18610 | self.target.*, |
| 18608 | 18611 | )) { |
| 18609 | 18612 | .SysV => result: { |
| ... | ... | @@ -18633,7 +18636,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18633 | 18636 | const overflow_arg_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 8 } }; |
| 18634 | 18637 | const reg_save_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 16 } }; |
| 18635 | 18638 | |
| 18636 | const classes = mem.sliceTo(&abi.classifySystemV(promote_ty, pt, self.target.*, .arg), .none); | |
| 18639 | const classes = mem.sliceTo(&abi.classifySystemV(promote_ty, zcu, self.target.*, .arg), .none); | |
| 18637 | 18640 | switch (classes[0]) { |
| 18638 | 18641 | .integer => { |
| 18639 | 18642 | assert(classes.len == 1); |
| ... | ... | @@ -18668,7 +18671,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18668 | 18671 | .base = .{ .reg = addr_reg }, |
| 18669 | 18672 | .mod = .{ .rm = .{ |
| 18670 | 18673 | .size = .qword, |
| 18671 | .disp = @intCast(@max(promote_ty.abiSize(pt), 8)), | |
| 18674 | .disp = @intCast(@max(promote_ty.abiSize(zcu), 8)), | |
| 18672 | 18675 | } }, |
| 18673 | 18676 | }); |
| 18674 | 18677 | try self.genCopy( |
| ... | ... | @@ -18716,7 +18719,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18716 | 18719 | .base = .{ .reg = addr_reg }, |
| 18717 | 18720 | .mod = .{ .rm = .{ |
| 18718 | 18721 | .size = .qword, |
| 18719 | .disp = @intCast(@max(promote_ty.abiSize(pt), 8)), | |
| 18722 | .disp = @intCast(@max(promote_ty.abiSize(zcu), 8)), | |
| 18720 | 18723 | } }, |
| 18721 | 18724 | }); |
| 18722 | 18725 | try self.genCopy( |
| ... | ... | @@ -18806,11 +18809,11 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void { |
| 18806 | 18809 | } |
| 18807 | 18810 | |
| 18808 | 18811 | fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 18809 | const pt = self.pt; | |
| 18812 | const zcu = self.pt.zcu; | |
| 18810 | 18813 | const ty = self.typeOf(ref); |
| 18811 | 18814 | |
| 18812 | 18815 | // If the type has no codegen bits, no need to store it. |
| 18813 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 18816 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none; | |
| 18814 | 18817 | |
| 18815 | 18818 | const mcv = if (ref.toIndex()) |inst| mcv: { |
| 18816 | 18819 | break :mcv self.inst_tracking.getPtr(inst).?.short; |
| ... | ... | @@ -18927,8 +18930,8 @@ fn resolveCallingConventionValues( |
| 18927 | 18930 | stack_frame_base: FrameIndex, |
| 18928 | 18931 | ) !CallMCValues { |
| 18929 | 18932 | const pt = self.pt; |
| 18930 | const mod = pt.zcu; | |
| 18931 | const ip = &mod.intern_pool; | |
| 18933 | const zcu = pt.zcu; | |
| 18934 | const ip = &zcu.intern_pool; | |
| 18932 | 18935 | const cc = fn_info.cc; |
| 18933 | 18936 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); |
| 18934 | 18937 | defer self.gpa.free(param_types); |
| ... | ... | @@ -18970,15 +18973,15 @@ fn resolveCallingConventionValues( |
| 18970 | 18973 | .SysV => {}, |
| 18971 | 18974 | .Win64 => { |
| 18972 | 18975 | // Align the stack to 16bytes before allocating shadow stack space (if any). |
| 18973 | result.stack_byte_count += @intCast(4 * Type.usize.abiSize(pt)); | |
| 18976 | result.stack_byte_count += @intCast(4 * Type.usize.abiSize(zcu)); | |
| 18974 | 18977 | }, |
| 18975 | 18978 | else => unreachable, |
| 18976 | 18979 | } |
| 18977 | 18980 | |
| 18978 | 18981 | // Return values |
| 18979 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 18982 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 18980 | 18983 | result.return_value = InstTracking.init(.unreach); |
| 18981 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 18984 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 18982 | 18985 | // TODO: is this even possible for C calling convention? |
| 18983 | 18986 | result.return_value = InstTracking.init(.none); |
| 18984 | 18987 | } else { |
| ... | ... | @@ -18986,15 +18989,15 @@ fn resolveCallingConventionValues( |
| 18986 | 18989 | var ret_tracking_i: usize = 0; |
| 18987 | 18990 | |
| 18988 | 18991 | const classes = switch (resolved_cc) { |
| 18989 | .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, pt, self.target.*, .ret), .none), | |
| 18990 | .Win64 => &.{abi.classifyWindows(ret_ty, pt)}, | |
| 18992 | .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, self.target.*, .ret), .none), | |
| 18993 | .Win64 => &.{abi.classifyWindows(ret_ty, zcu)}, | |
| 18991 | 18994 | else => unreachable, |
| 18992 | 18995 | }; |
| 18993 | 18996 | for (classes) |class| switch (class) { |
| 18994 | 18997 | .integer => { |
| 18995 | 18998 | const ret_int_reg = registerAlias( |
| 18996 | 18999 | abi.getCAbiIntReturnRegs(resolved_cc)[ret_int_reg_i], |
| 18997 | @intCast(@min(ret_ty.abiSize(pt), 8)), | |
| 19000 | @intCast(@min(ret_ty.abiSize(zcu), 8)), | |
| 18998 | 19001 | ); |
| 18999 | 19002 | ret_int_reg_i += 1; |
| 19000 | 19003 | |
| ... | ... | @@ -19004,7 +19007,7 @@ fn resolveCallingConventionValues( |
| 19004 | 19007 | .sse, .float, .float_combine, .win_i128 => { |
| 19005 | 19008 | const ret_sse_reg = registerAlias( |
| 19006 | 19009 | abi.getCAbiSseReturnRegs(resolved_cc)[ret_sse_reg_i], |
| 19007 | @intCast(ret_ty.abiSize(pt)), | |
| 19010 | @intCast(ret_ty.abiSize(zcu)), | |
| 19008 | 19011 | ); |
| 19009 | 19012 | ret_sse_reg_i += 1; |
| 19010 | 19013 | |
| ... | ... | @@ -19047,7 +19050,7 @@ fn resolveCallingConventionValues( |
| 19047 | 19050 | |
| 19048 | 19051 | // Input params |
| 19049 | 19052 | for (param_types, result.args) |ty, *arg| { |
| 19050 | assert(ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 19053 | assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 19051 | 19054 | switch (resolved_cc) { |
| 19052 | 19055 | .SysV => {}, |
| 19053 | 19056 | .Win64 => { |
| ... | ... | @@ -19061,8 +19064,8 @@ fn resolveCallingConventionValues( |
| 19061 | 19064 | var arg_mcv_i: usize = 0; |
| 19062 | 19065 | |
| 19063 | 19066 | const classes = switch (resolved_cc) { |
| 19064 | .SysV => mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .arg), .none), | |
| 19065 | .Win64 => &.{abi.classifyWindows(ty, pt)}, | |
| 19067 | .SysV => mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.*, .arg), .none), | |
| 19068 | .Win64 => &.{abi.classifyWindows(ty, zcu)}, | |
| 19066 | 19069 | else => unreachable, |
| 19067 | 19070 | }; |
| 19068 | 19071 | for (classes) |class| switch (class) { |
| ... | ... | @@ -19072,7 +19075,7 @@ fn resolveCallingConventionValues( |
| 19072 | 19075 | |
| 19073 | 19076 | const param_int_reg = registerAlias( |
| 19074 | 19077 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i], |
| 19075 | @intCast(@min(ty.abiSize(pt), 8)), | |
| 19078 | @intCast(@min(ty.abiSize(zcu), 8)), | |
| 19076 | 19079 | ); |
| 19077 | 19080 | param_int_reg_i += 1; |
| 19078 | 19081 | |
| ... | ... | @@ -19085,7 +19088,7 @@ fn resolveCallingConventionValues( |
| 19085 | 19088 | |
| 19086 | 19089 | const param_sse_reg = registerAlias( |
| 19087 | 19090 | abi.getCAbiSseParamRegs(resolved_cc)[param_sse_reg_i], |
| 19088 | @intCast(ty.abiSize(pt)), | |
| 19091 | @intCast(ty.abiSize(zcu)), | |
| 19089 | 19092 | ); |
| 19090 | 19093 | param_sse_reg_i += 1; |
| 19091 | 19094 | |
| ... | ... | @@ -19098,7 +19101,7 @@ fn resolveCallingConventionValues( |
| 19098 | 19101 | .x87, .x87up, .complex_x87, .memory => break, |
| 19099 | 19102 | else => unreachable, |
| 19100 | 19103 | }, |
| 19101 | .Win64 => if (ty.abiSize(pt) > 8) { | |
| 19104 | .Win64 => if (ty.abiSize(zcu) > 8) { | |
| 19102 | 19105 | const param_int_reg = |
| 19103 | 19106 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64(); |
| 19104 | 19107 | param_int_reg_i += 1; |
| ... | ... | @@ -19117,10 +19120,10 @@ fn resolveCallingConventionValues( |
| 19117 | 19120 | param_int_reg_i = param_int_regs_len; |
| 19118 | 19121 | |
| 19119 | 19122 | const frame_elem_align = 8; |
| 19120 | const frame_elems_len = ty.vectorLen(mod) - remaining_param_int_regs; | |
| 19123 | const frame_elems_len = ty.vectorLen(zcu) - remaining_param_int_regs; | |
| 19121 | 19124 | const frame_elem_size = mem.alignForward( |
| 19122 | 19125 | u64, |
| 19123 | ty.childType(mod).abiSize(pt), | |
| 19126 | ty.childType(zcu).abiSize(zcu), | |
| 19124 | 19127 | frame_elem_align, |
| 19125 | 19128 | ); |
| 19126 | 19129 | const frame_size: u31 = @intCast(frame_elems_len * frame_elem_size); |
| ... | ... | @@ -19144,9 +19147,9 @@ fn resolveCallingConventionValues( |
| 19144 | 19147 | continue; |
| 19145 | 19148 | } |
| 19146 | 19149 | |
| 19147 | const param_size: u31 = @intCast(ty.abiSize(pt)); | |
| 19150 | const param_size: u31 = @intCast(ty.abiSize(zcu)); | |
| 19148 | 19151 | const param_align: u31 = |
| 19149 | @intCast(@max(ty.abiAlignment(pt).toByteUnits().?, 8)); | |
| 19152 | @intCast(@max(ty.abiAlignment(zcu).toByteUnits().?, 8)); | |
| 19150 | 19153 | result.stack_byte_count = |
| 19151 | 19154 | mem.alignForward(u31, result.stack_byte_count, param_align); |
| 19152 | 19155 | arg.* = .{ .load_frame = .{ |
| ... | ... | @@ -19164,13 +19167,13 @@ fn resolveCallingConventionValues( |
| 19164 | 19167 | result.stack_align = .@"16"; |
| 19165 | 19168 | |
| 19166 | 19169 | // Return values |
| 19167 | if (ret_ty.zigTypeTag(mod) == .NoReturn) { | |
| 19170 | if (ret_ty.zigTypeTag(zcu) == .NoReturn) { | |
| 19168 | 19171 | result.return_value = InstTracking.init(.unreach); |
| 19169 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 19172 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 19170 | 19173 | result.return_value = InstTracking.init(.none); |
| 19171 | 19174 | } else { |
| 19172 | 19175 | const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0]; |
| 19173 | const ret_ty_size: u31 = @intCast(ret_ty.abiSize(pt)); | |
| 19176 | const ret_ty_size: u31 = @intCast(ret_ty.abiSize(zcu)); | |
| 19174 | 19177 | if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) { |
| 19175 | 19178 | const aliased_reg = registerAlias(ret_reg, ret_ty_size); |
| 19176 | 19179 | result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none }; |
| ... | ... | @@ -19185,12 +19188,12 @@ fn resolveCallingConventionValues( |
| 19185 | 19188 | |
| 19186 | 19189 | // Input params |
| 19187 | 19190 | for (param_types, result.args) |ty, *arg| { |
| 19188 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 19191 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 19189 | 19192 | arg.* = .none; |
| 19190 | 19193 | continue; |
| 19191 | 19194 | } |
| 19192 | const param_size: u31 = @intCast(ty.abiSize(pt)); | |
| 19193 | const param_align: u31 = @intCast(ty.abiAlignment(pt).toByteUnits().?); | |
| 19195 | const param_size: u31 = @intCast(ty.abiSize(zcu)); | |
| 19196 | const param_align: u31 = @intCast(ty.abiAlignment(zcu).toByteUnits().?); | |
| 19194 | 19197 | result.stack_byte_count = |
| 19195 | 19198 | mem.alignForward(u31, result.stack_byte_count, param_align); |
| 19196 | 19199 | arg.* = .{ .load_frame = .{ |
| ... | ... | @@ -19276,25 +19279,26 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 19276 | 19279 | |
| 19277 | 19280 | fn memSize(self: *Self, ty: Type) Memory.Size { |
| 19278 | 19281 | const pt = self.pt; |
| 19279 | const mod = pt.zcu; | |
| 19280 | return switch (ty.zigTypeTag(mod)) { | |
| 19282 | const zcu = pt.zcu; | |
| 19283 | return switch (ty.zigTypeTag(zcu)) { | |
| 19281 | 19284 | .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)), |
| 19282 | else => Memory.Size.fromSize(@intCast(ty.abiSize(pt))), | |
| 19285 | else => Memory.Size.fromSize(@intCast(ty.abiSize(zcu))), | |
| 19283 | 19286 | }; |
| 19284 | 19287 | } |
| 19285 | 19288 | |
| 19286 | 19289 | fn splitType(self: *Self, ty: Type) ![2]Type { |
| 19287 | 19290 | const pt = self.pt; |
| 19288 | const classes = mem.sliceTo(&abi.classifySystemV(ty, pt, self.target.*, .other), .none); | |
| 19291 | const zcu = pt.zcu; | |
| 19292 | const classes = mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.*, .other), .none); | |
| 19289 | 19293 | var parts: [2]Type = undefined; |
| 19290 | 19294 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { |
| 19291 | 19295 | part.* = switch (class) { |
| 19292 | 19296 | .integer => switch (part_i) { |
| 19293 | 19297 | 0 => Type.u64, |
| 19294 | 19298 | 1 => part: { |
| 19295 | const elem_size = ty.abiAlignment(pt).minStrict(.@"8").toByteUnits().?; | |
| 19299 | const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?; | |
| 19296 | 19300 | const elem_ty = try pt.intType(.unsigned, @intCast(elem_size * 8)); |
| 19297 | break :part switch (@divExact(ty.abiSize(pt) - 8, elem_size)) { | |
| 19301 | break :part switch (@divExact(ty.abiSize(zcu) - 8, elem_size)) { | |
| 19298 | 19302 | 1 => elem_ty, |
| 19299 | 19303 | else => |len| try pt.arrayType(.{ .len = len, .child = elem_ty.toIntern() }), |
| 19300 | 19304 | }; |
| ... | ... | @@ -19306,7 +19310,7 @@ fn splitType(self: *Self, ty: Type) ![2]Type { |
| 19306 | 19310 | .sse => Type.f64, |
| 19307 | 19311 | else => break, |
| 19308 | 19312 | }; |
| 19309 | } else if (parts[0].abiSize(pt) + parts[1].abiSize(pt) == ty.abiSize(pt)) return parts; | |
| 19313 | } else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts; | |
| 19310 | 19314 | return self.fail("TODO implement splitType for {}", .{ty.fmt(pt)}); |
| 19311 | 19315 | } |
| 19312 | 19316 | |
| ... | ... | @@ -19314,10 +19318,10 @@ fn splitType(self: *Self, ty: Type) ![2]Type { |
| 19314 | 19318 | /// Clobbers any remaining bits. |
| 19315 | 19319 | fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 19316 | 19320 | const pt = self.pt; |
| 19317 | const mod = pt.zcu; | |
| 19318 | const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{ | |
| 19321 | const zcu = pt.zcu; | |
| 19322 | const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ | |
| 19319 | 19323 | .signedness = .unsigned, |
| 19320 | .bits = @intCast(ty.bitSize(pt)), | |
| 19324 | .bits = @intCast(ty.bitSize(zcu)), | |
| 19321 | 19325 | }; |
| 19322 | 19326 | const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return; |
| 19323 | 19327 | try self.spillEflagsIfOccupied(); |
| ... | ... | @@ -19362,9 +19366,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 19362 | 19366 | |
| 19363 | 19367 | fn regBitSize(self: *Self, ty: Type) u64 { |
| 19364 | 19368 | const pt = self.pt; |
| 19365 | const mod = pt.zcu; | |
| 19366 | const abi_size = ty.abiSize(pt); | |
| 19367 | return switch (ty.zigTypeTag(mod)) { | |
| 19369 | const zcu = pt.zcu; | |
| 19370 | const abi_size = ty.abiSize(zcu); | |
| 19371 | return switch (ty.zigTypeTag(zcu)) { | |
| 19368 | 19372 | else => switch (abi_size) { |
| 19369 | 19373 | 1 => 8, |
| 19370 | 19374 | 2 => 16, |
| ... | ... | @@ -19381,7 +19385,7 @@ fn regBitSize(self: *Self, ty: Type) u64 { |
| 19381 | 19385 | } |
| 19382 | 19386 | |
| 19383 | 19387 | fn regExtraBits(self: *Self, ty: Type) u64 { |
| 19384 | return self.regBitSize(ty) - ty.bitSize(self.pt); | |
| 19388 | return self.regBitSize(ty) - ty.bitSize(self.pt.zcu); | |
| 19385 | 19389 | } |
| 19386 | 19390 | |
| 19387 | 19391 | fn hasFeature(self: *Self, feature: Target.x86.Feature) bool { |
| ... | ... | @@ -19396,14 +19400,14 @@ fn hasAllFeatures(self: *Self, features: anytype) bool { |
| 19396 | 19400 | |
| 19397 | 19401 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 19398 | 19402 | const pt = self.pt; |
| 19399 | const mod = pt.zcu; | |
| 19400 | return self.air.typeOf(inst, &mod.intern_pool); | |
| 19403 | const zcu = pt.zcu; | |
| 19404 | return self.air.typeOf(inst, &zcu.intern_pool); | |
| 19401 | 19405 | } |
| 19402 | 19406 | |
| 19403 | 19407 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 19404 | 19408 | const pt = self.pt; |
| 19405 | const mod = pt.zcu; | |
| 19406 | return self.air.typeOfIndex(inst, &mod.intern_pool); | |
| 19409 | const zcu = pt.zcu; | |
| 19410 | return self.air.typeOfIndex(inst, &zcu.intern_pool); | |
| 19407 | 19411 | } |
| 19408 | 19412 | |
| 19409 | 19413 | fn intCompilerRtAbiName(int_bits: u32) u8 { |
| ... | ... | @@ -19455,17 +19459,17 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 { |
| 19455 | 19459 | |
| 19456 | 19460 | fn promoteInt(self: *Self, ty: Type) Type { |
| 19457 | 19461 | const pt = self.pt; |
| 19458 | const mod = pt.zcu; | |
| 19462 | const zcu = pt.zcu; | |
| 19459 | 19463 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { |
| 19460 | 19464 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, |
| 19461 | else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty, | |
| 19465 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty, | |
| 19462 | 19466 | }; |
| 19463 | 19467 | for ([_]Type{ |
| 19464 | 19468 | Type.c_int, Type.c_uint, |
| 19465 | 19469 | Type.c_long, Type.c_ulong, |
| 19466 | 19470 | Type.c_longlong, Type.c_ulonglong, |
| 19467 | 19471 | }) |promote_ty| { |
| 19468 | const promote_info = promote_ty.intInfo(mod); | |
| 19472 | const promote_info = promote_ty.intInfo(zcu); | |
| 19469 | 19473 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; |
| 19470 | 19474 | if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and |
| 19471 | 19475 | promote_info.signedness == .signed) <= promote_info.bits) return promote_ty; |
src/arch/x86_64/abi.zig+35-35| ... | ... | @@ -44,7 +44,7 @@ pub const Class = enum { |
| 44 | 44 | } |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | pub fn classifyWindows(ty: Type, pt: Zcu.PerThread) Class { | |
| 47 | pub fn classifyWindows(ty: Type, zcu: *Zcu) Class { | |
| 48 | 48 | // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 |
| 49 | 49 | // "There's a strict one-to-one correspondence between a function call's arguments |
| 50 | 50 | // and the registers used for those arguments. Any argument that doesn't fit in 8 |
| ... | ... | @@ -53,7 +53,7 @@ pub fn classifyWindows(ty: Type, pt: Zcu.PerThread) Class { |
| 53 | 53 | // "All floating point operations are done using the 16 XMM registers." |
| 54 | 54 | // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed |
| 55 | 55 | // as if they were integers of the same size." |
| 56 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 56 | switch (ty.zigTypeTag(zcu)) { | |
| 57 | 57 | .Pointer, |
| 58 | 58 | .Int, |
| 59 | 59 | .Bool, |
| ... | ... | @@ -68,12 +68,12 @@ pub fn classifyWindows(ty: Type, pt: Zcu.PerThread) Class { |
| 68 | 68 | .ErrorUnion, |
| 69 | 69 | .AnyFrame, |
| 70 | 70 | .Frame, |
| 71 | => switch (ty.abiSize(pt)) { | |
| 71 | => switch (ty.abiSize(zcu)) { | |
| 72 | 72 | 0 => unreachable, |
| 73 | 73 | 1, 2, 4, 8 => return .integer, |
| 74 | else => switch (ty.zigTypeTag(pt.zcu)) { | |
| 74 | else => switch (ty.zigTypeTag(zcu)) { | |
| 75 | 75 | .Int => return .win_i128, |
| 76 | .Struct, .Union => if (ty.containerLayout(pt.zcu) == .@"packed") { | |
| 76 | .Struct, .Union => if (ty.containerLayout(zcu) == .@"packed") { | |
| 77 | 77 | return .win_i128; |
| 78 | 78 | } else { |
| 79 | 79 | return .memory; |
| ... | ... | @@ -100,14 +100,14 @@ pub const Context = enum { ret, arg, field, other }; |
| 100 | 100 | |
| 101 | 101 | /// There are a maximum of 8 possible return slots. Returned values are in |
| 102 | 102 | /// the beginning of the array; unused slots are filled with .none. |
| 103 | pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Context) [8]Class { | |
| 103 | pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8]Class { | |
| 104 | 104 | const memory_class = [_]Class{ |
| 105 | 105 | .memory, .none, .none, .none, |
| 106 | 106 | .none, .none, .none, .none, |
| 107 | 107 | }; |
| 108 | 108 | var result = [1]Class{.none} ** 8; |
| 109 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 110 | .Pointer => switch (ty.ptrSize(pt.zcu)) { | |
| 109 | switch (ty.zigTypeTag(zcu)) { | |
| 110 | .Pointer => switch (ty.ptrSize(zcu)) { | |
| 111 | 111 | .Slice => { |
| 112 | 112 | result[0] = .integer; |
| 113 | 113 | result[1] = .integer; |
| ... | ... | @@ -119,7 +119,7 @@ pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Con |
| 119 | 119 | }, |
| 120 | 120 | }, |
| 121 | 121 | .Int, .Enum, .ErrorSet => { |
| 122 | const bits = ty.intInfo(pt.zcu).bits; | |
| 122 | const bits = ty.intInfo(zcu).bits; | |
| 123 | 123 | if (bits <= 64) { |
| 124 | 124 | result[0] = .integer; |
| 125 | 125 | return result; |
| ... | ... | @@ -185,8 +185,8 @@ pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Con |
| 185 | 185 | else => unreachable, |
| 186 | 186 | }, |
| 187 | 187 | .Vector => { |
| 188 | const elem_ty = ty.childType(pt.zcu); | |
| 189 | const bits = elem_ty.bitSize(pt) * ty.arrayLen(pt.zcu); | |
| 188 | const elem_ty = ty.childType(zcu); | |
| 189 | const bits = elem_ty.bitSize(zcu) * ty.arrayLen(zcu); | |
| 190 | 190 | if (elem_ty.toIntern() == .bool_type) { |
| 191 | 191 | if (bits <= 32) return .{ |
| 192 | 192 | .integer, .none, .none, .none, |
| ... | ... | @@ -250,7 +250,7 @@ pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Con |
| 250 | 250 | return memory_class; |
| 251 | 251 | }, |
| 252 | 252 | .Optional => { |
| 253 | if (ty.isPtrLikeOptional(pt.zcu)) { | |
| 253 | if (ty.isPtrLikeOptional(zcu)) { | |
| 254 | 254 | result[0] = .integer; |
| 255 | 255 | return result; |
| 256 | 256 | } |
| ... | ... | @@ -261,8 +261,8 @@ pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Con |
| 261 | 261 | // it contains unaligned fields, it has class MEMORY" |
| 262 | 262 | // "If the size of the aggregate exceeds a single eightbyte, each is classified |
| 263 | 263 | // separately.". |
| 264 | const ty_size = ty.abiSize(pt); | |
| 265 | switch (ty.containerLayout(pt.zcu)) { | |
| 264 | const ty_size = ty.abiSize(zcu); | |
| 265 | switch (ty.containerLayout(zcu)) { | |
| 266 | 266 | .auto, .@"extern" => {}, |
| 267 | 267 | .@"packed" => { |
| 268 | 268 | assert(ty_size <= 16); |
| ... | ... | @@ -274,10 +274,10 @@ pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Con |
| 274 | 274 | if (ty_size > 64) |
| 275 | 275 | return memory_class; |
| 276 | 276 | |
| 277 | _ = if (pt.zcu.typeToStruct(ty)) |loaded_struct| | |
| 278 | classifySystemVStruct(&result, 0, loaded_struct, pt, target) | |
| 279 | else if (pt.zcu.typeToUnion(ty)) |loaded_union| | |
| 280 | classifySystemVUnion(&result, 0, loaded_union, pt, target) | |
| 277 | _ = if (zcu.typeToStruct(ty)) |loaded_struct| | |
| 278 | classifySystemVStruct(&result, 0, loaded_struct, zcu, target) | |
| 279 | else if (zcu.typeToUnion(ty)) |loaded_union| | |
| 280 | classifySystemVUnion(&result, 0, loaded_union, zcu, target) | |
| 281 | 281 | else |
| 282 | 282 | unreachable; |
| 283 | 283 | |
| ... | ... | @@ -306,7 +306,7 @@ pub fn classifySystemV(ty: Type, pt: Zcu.PerThread, target: std.Target, ctx: Con |
| 306 | 306 | return result; |
| 307 | 307 | }, |
| 308 | 308 | .Array => { |
| 309 | const ty_size = ty.abiSize(pt); | |
| 309 | const ty_size = ty.abiSize(zcu); | |
| 310 | 310 | if (ty_size <= 8) { |
| 311 | 311 | result[0] = .integer; |
| 312 | 312 | return result; |
| ... | ... | @@ -326,10 +326,10 @@ fn classifySystemVStruct( |
| 326 | 326 | result: *[8]Class, |
| 327 | 327 | starting_byte_offset: u64, |
| 328 | 328 | loaded_struct: InternPool.LoadedStructType, |
| 329 | pt: Zcu.PerThread, | |
| 329 | zcu: *Zcu, | |
| 330 | 330 | target: std.Target, |
| 331 | 331 | ) u64 { |
| 332 | const ip = &pt.zcu.intern_pool; | |
| 332 | const ip = &zcu.intern_pool; | |
| 333 | 333 | var byte_offset = starting_byte_offset; |
| 334 | 334 | var field_it = loaded_struct.iterateRuntimeOrder(ip); |
| 335 | 335 | while (field_it.next()) |field_index| { |
| ... | ... | @@ -338,29 +338,29 @@ fn classifySystemVStruct( |
| 338 | 338 | byte_offset = std.mem.alignForward( |
| 339 | 339 | u64, |
| 340 | 340 | byte_offset, |
| 341 | field_align.toByteUnits() orelse field_ty.abiAlignment(pt).toByteUnits().?, | |
| 341 | field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?, | |
| 342 | 342 | ); |
| 343 | if (pt.zcu.typeToStruct(field_ty)) |field_loaded_struct| { | |
| 343 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { | |
| 344 | 344 | switch (field_loaded_struct.layout) { |
| 345 | 345 | .auto, .@"extern" => { |
| 346 | byte_offset = classifySystemVStruct(result, byte_offset, field_loaded_struct, pt, target); | |
| 346 | byte_offset = classifySystemVStruct(result, byte_offset, field_loaded_struct, zcu, target); | |
| 347 | 347 | continue; |
| 348 | 348 | }, |
| 349 | 349 | .@"packed" => {}, |
| 350 | 350 | } |
| 351 | } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| { | |
| 351 | } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| { | |
| 352 | 352 | switch (field_loaded_union.flagsUnordered(ip).layout) { |
| 353 | 353 | .auto, .@"extern" => { |
| 354 | byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, pt, target); | |
| 354 | byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target); | |
| 355 | 355 | continue; |
| 356 | 356 | }, |
| 357 | 357 | .@"packed" => {}, |
| 358 | 358 | } |
| 359 | 359 | } |
| 360 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, pt, target, .field), .none); | |
| 360 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .field), .none); | |
| 361 | 361 | for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| |
| 362 | 362 | result_class.* = result_class.combineSystemV(field_class); |
| 363 | byte_offset += field_ty.abiSize(pt); | |
| 363 | byte_offset += field_ty.abiSize(zcu); | |
| 364 | 364 | } |
| 365 | 365 | const final_byte_offset = starting_byte_offset + loaded_struct.sizeUnordered(ip); |
| 366 | 366 | std.debug.assert(final_byte_offset == std.mem.alignForward( |
| ... | ... | @@ -375,30 +375,30 @@ fn classifySystemVUnion( |
| 375 | 375 | result: *[8]Class, |
| 376 | 376 | starting_byte_offset: u64, |
| 377 | 377 | loaded_union: InternPool.LoadedUnionType, |
| 378 | pt: Zcu.PerThread, | |
| 378 | zcu: *Zcu, | |
| 379 | 379 | target: std.Target, |
| 380 | 380 | ) u64 { |
| 381 | const ip = &pt.zcu.intern_pool; | |
| 381 | const ip = &zcu.intern_pool; | |
| 382 | 382 | for (0..loaded_union.field_types.len) |field_index| { |
| 383 | 383 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 384 | if (pt.zcu.typeToStruct(field_ty)) |field_loaded_struct| { | |
| 384 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { | |
| 385 | 385 | switch (field_loaded_struct.layout) { |
| 386 | 386 | .auto, .@"extern" => { |
| 387 | _ = classifySystemVStruct(result, starting_byte_offset, field_loaded_struct, pt, target); | |
| 387 | _ = classifySystemVStruct(result, starting_byte_offset, field_loaded_struct, zcu, target); | |
| 388 | 388 | continue; |
| 389 | 389 | }, |
| 390 | 390 | .@"packed" => {}, |
| 391 | 391 | } |
| 392 | } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| { | |
| 392 | } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| { | |
| 393 | 393 | switch (field_loaded_union.flagsUnordered(ip).layout) { |
| 394 | 394 | .auto, .@"extern" => { |
| 395 | _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, pt, target); | |
| 395 | _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target); | |
| 396 | 396 | continue; |
| 397 | 397 | }, |
| 398 | 398 | .@"packed" => {}, |
| 399 | 399 | } |
| 400 | 400 | } |
| 401 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, pt, target, .field), .none); | |
| 401 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .field), .none); | |
| 402 | 402 | for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| |
| 403 | 403 | result_class.* = result_class.combineSystemV(field_class); |
| 404 | 404 | } |
src/codegen.zig+59-58| ... | ... | @@ -198,17 +198,17 @@ pub fn generateSymbol( |
| 198 | 198 | const tracy = trace(@src()); |
| 199 | 199 | defer tracy.end(); |
| 200 | 200 | |
| 201 | const mod = pt.zcu; | |
| 202 | const ip = &mod.intern_pool; | |
| 203 | const ty = val.typeOf(mod); | |
| 201 | const zcu = pt.zcu; | |
| 202 | const ip = &zcu.intern_pool; | |
| 203 | const ty = val.typeOf(zcu); | |
| 204 | 204 | |
| 205 | const target = mod.getTarget(); | |
| 205 | const target = zcu.getTarget(); | |
| 206 | 206 | const endian = target.cpu.arch.endian(); |
| 207 | 207 | |
| 208 | 208 | log.debug("generateSymbol: val = {}", .{val.fmtValue(pt)}); |
| 209 | 209 | |
| 210 | if (val.isUndefDeep(mod)) { | |
| 211 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; | |
| 210 | if (val.isUndefDeep(zcu)) { | |
| 211 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 212 | 212 | try code.appendNTimes(0xaa, abi_size); |
| 213 | 213 | return .ok; |
| 214 | 214 | } |
| ... | ... | @@ -254,9 +254,9 @@ pub fn generateSymbol( |
| 254 | 254 | .empty_enum_value, |
| 255 | 255 | => unreachable, // non-runtime values |
| 256 | 256 | .int => { |
| 257 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; | |
| 257 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 258 | 258 | var space: Value.BigIntSpace = undefined; |
| 259 | const int_val = val.toBigInt(&space, pt); | |
| 259 | const int_val = val.toBigInt(&space, zcu); | |
| 260 | 260 | int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian); |
| 261 | 261 | }, |
| 262 | 262 | .err => |err| { |
| ... | ... | @@ -264,20 +264,20 @@ pub fn generateSymbol( |
| 264 | 264 | try code.writer().writeInt(u16, @intCast(int), endian); |
| 265 | 265 | }, |
| 266 | 266 | .error_union => |error_union| { |
| 267 | const payload_ty = ty.errorUnionPayload(mod); | |
| 267 | const payload_ty = ty.errorUnionPayload(zcu); | |
| 268 | 268 | const err_val: u16 = switch (error_union.val) { |
| 269 | 269 | .err_name => |err_name| @intCast(try pt.getErrorValue(err_name)), |
| 270 | 270 | .payload => 0, |
| 271 | 271 | }; |
| 272 | 272 | |
| 273 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 273 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 274 | 274 | try code.writer().writeInt(u16, err_val, endian); |
| 275 | 275 | return .ok; |
| 276 | 276 | } |
| 277 | 277 | |
| 278 | const payload_align = payload_ty.abiAlignment(pt); | |
| 279 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 280 | const abi_align = ty.abiAlignment(pt); | |
| 278 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 279 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 280 | const abi_align = ty.abiAlignment(zcu); | |
| 281 | 281 | |
| 282 | 282 | // error value first when its type is larger than the error union's payload |
| 283 | 283 | if (error_align.order(payload_align) == .gt) { |
| ... | ... | @@ -317,7 +317,7 @@ pub fn generateSymbol( |
| 317 | 317 | } |
| 318 | 318 | }, |
| 319 | 319 | .enum_tag => |enum_tag| { |
| 320 | const int_tag_ty = ty.intTagType(mod); | |
| 320 | const int_tag_ty = ty.intTagType(zcu); | |
| 321 | 321 | switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) { |
| 322 | 322 | .ok => {}, |
| 323 | 323 | .fail => |em| return .{ .fail = em }, |
| ... | ... | @@ -329,7 +329,7 @@ pub fn generateSymbol( |
| 329 | 329 | .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)), |
| 330 | 330 | .f80 => |f80_val| { |
| 331 | 331 | writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10)); |
| 332 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; | |
| 332 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 333 | 333 | try code.appendNTimes(0, abi_size - 10); |
| 334 | 334 | }, |
| 335 | 335 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), |
| ... | ... | @@ -349,11 +349,11 @@ pub fn generateSymbol( |
| 349 | 349 | } |
| 350 | 350 | }, |
| 351 | 351 | .opt => { |
| 352 | const payload_type = ty.optionalChild(mod); | |
| 353 | const payload_val = val.optionalValue(mod); | |
| 354 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; | |
| 352 | const payload_type = ty.optionalChild(zcu); | |
| 353 | const payload_val = val.optionalValue(zcu); | |
| 354 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 355 | 355 | |
| 356 | if (ty.optionalReprIsPayload(mod)) { | |
| 356 | if (ty.optionalReprIsPayload(zcu)) { | |
| 357 | 357 | if (payload_val) |value| { |
| 358 | 358 | switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) { |
| 359 | 359 | .ok => {}, |
| ... | ... | @@ -363,8 +363,8 @@ pub fn generateSymbol( |
| 363 | 363 | try code.appendNTimes(0, abi_size); |
| 364 | 364 | } |
| 365 | 365 | } else { |
| 366 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(pt)) orelse return error.Overflow) - 1; | |
| 367 | if (payload_type.hasRuntimeBits(pt)) { | |
| 366 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(zcu)) orelse return error.Overflow) - 1; | |
| 367 | if (payload_type.hasRuntimeBits(zcu)) { | |
| 368 | 368 | const value = payload_val orelse Value.fromInterned(try pt.intern(.{ |
| 369 | 369 | .undef = payload_type.toIntern(), |
| 370 | 370 | })); |
| ... | ... | @@ -398,7 +398,7 @@ pub fn generateSymbol( |
| 398 | 398 | }, |
| 399 | 399 | }, |
| 400 | 400 | .vector_type => |vector_type| { |
| 401 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; | |
| 401 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 402 | 402 | if (vector_type.child == .bool_type) { |
| 403 | 403 | const bytes = try code.addManyAsSlice(abi_size); |
| 404 | 404 | @memset(bytes, 0xaa); |
| ... | ... | @@ -458,7 +458,7 @@ pub fn generateSymbol( |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | 460 | const padding = abi_size - |
| 461 | (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(pt) * vector_type.len) orelse | |
| 461 | (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse | |
| 462 | 462 | return error.Overflow); |
| 463 | 463 | if (padding > 0) try code.appendNTimes(0, padding); |
| 464 | 464 | } |
| ... | ... | @@ -471,7 +471,7 @@ pub fn generateSymbol( |
| 471 | 471 | 0.., |
| 472 | 472 | ) |field_ty, comptime_val, index| { |
| 473 | 473 | if (comptime_val != .none) continue; |
| 474 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | |
| 474 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | |
| 475 | 475 | |
| 476 | 476 | const field_val = switch (aggregate.storage) { |
| 477 | 477 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| ... | ... | @@ -489,7 +489,7 @@ pub fn generateSymbol( |
| 489 | 489 | const unpadded_field_end = code.items.len - struct_begin; |
| 490 | 490 | |
| 491 | 491 | // Pad struct members if required |
| 492 | const padded_field_end = ty.structFieldOffset(index + 1, pt); | |
| 492 | const padded_field_end = ty.structFieldOffset(index + 1, zcu); | |
| 493 | 493 | const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse |
| 494 | 494 | return error.Overflow; |
| 495 | 495 | |
| ... | ... | @@ -502,7 +502,7 @@ pub fn generateSymbol( |
| 502 | 502 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 503 | 503 | switch (struct_type.layout) { |
| 504 | 504 | .@"packed" => { |
| 505 | const abi_size = math.cast(usize, ty.abiSize(pt)) orelse return error.Overflow; | |
| 505 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 506 | 506 | const current_pos = code.items.len; |
| 507 | 507 | try code.appendNTimes(0, abi_size); |
| 508 | 508 | var bits: u16 = 0; |
| ... | ... | @@ -519,8 +519,8 @@ pub fn generateSymbol( |
| 519 | 519 | |
| 520 | 520 | // pointer may point to a decl which must be marked used |
| 521 | 521 | // but can also result in a relocation. Therefore we handle those separately. |
| 522 | if (Type.fromInterned(field_ty).zigTypeTag(mod) == .Pointer) { | |
| 523 | const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(pt)) orelse | |
| 522 | if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .Pointer) { | |
| 523 | const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(zcu)) orelse | |
| 524 | 524 | return error.Overflow; |
| 525 | 525 | var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); |
| 526 | 526 | defer tmp_list.deinit(); |
| ... | ... | @@ -531,7 +531,7 @@ pub fn generateSymbol( |
| 531 | 531 | } else { |
| 532 | 532 | Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable; |
| 533 | 533 | } |
| 534 | bits += @intCast(Type.fromInterned(field_ty).bitSize(pt)); | |
| 534 | bits += @intCast(Type.fromInterned(field_ty).bitSize(zcu)); | |
| 535 | 535 | } |
| 536 | 536 | }, |
| 537 | 537 | .auto, .@"extern" => { |
| ... | ... | @@ -542,7 +542,7 @@ pub fn generateSymbol( |
| 542 | 542 | var it = struct_type.iterateRuntimeOrder(ip); |
| 543 | 543 | while (it.next()) |field_index| { |
| 544 | 544 | const field_ty = field_types[field_index]; |
| 545 | if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | |
| 545 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | |
| 546 | 546 | |
| 547 | 547 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 548 | 548 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| ... | ... | @@ -580,7 +580,7 @@ pub fn generateSymbol( |
| 580 | 580 | else => unreachable, |
| 581 | 581 | }, |
| 582 | 582 | .un => |un| { |
| 583 | const layout = ty.unionGetLayout(pt); | |
| 583 | const layout = ty.unionGetLayout(zcu); | |
| 584 | 584 | |
| 585 | 585 | if (layout.payload_size == 0) { |
| 586 | 586 | return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info); |
| ... | ... | @@ -594,11 +594,11 @@ pub fn generateSymbol( |
| 594 | 594 | } |
| 595 | 595 | } |
| 596 | 596 | |
| 597 | const union_obj = mod.typeToUnion(ty).?; | |
| 597 | const union_obj = zcu.typeToUnion(ty).?; | |
| 598 | 598 | if (un.tag != .none) { |
| 599 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; | |
| 599 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?; | |
| 600 | 600 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 601 | if (!field_ty.hasRuntimeBits(pt)) { | |
| 601 | if (!field_ty.hasRuntimeBits(zcu)) { | |
| 602 | 602 | try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); |
| 603 | 603 | } else { |
| 604 | 604 | switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { |
| ... | ... | @@ -606,7 +606,7 @@ pub fn generateSymbol( |
| 606 | 606 | .fail => |em| return Result{ .fail = em }, |
| 607 | 607 | } |
| 608 | 608 | |
| 609 | const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(pt)) orelse return error.Overflow; | |
| 609 | const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow; | |
| 610 | 610 | if (padding > 0) { |
| 611 | 611 | try code.appendNTimes(0, padding); |
| 612 | 612 | } |
| ... | ... | @@ -661,7 +661,7 @@ fn lowerPtr( |
| 661 | 661 | reloc_info, |
| 662 | 662 | offset + errUnionPayloadOffset( |
| 663 | 663 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu), |
| 664 | pt, | |
| 664 | zcu, | |
| 665 | 665 | ), |
| 666 | 666 | ), |
| 667 | 667 | .opt_payload => |opt_ptr| try lowerPtr( |
| ... | ... | @@ -687,7 +687,7 @@ fn lowerPtr( |
| 687 | 687 | }; |
| 688 | 688 | }, |
| 689 | 689 | .Struct, .Union => switch (base_ty.containerLayout(zcu)) { |
| 690 | .auto => base_ty.structFieldOffset(@intCast(field.index), pt), | |
| 690 | .auto => base_ty.structFieldOffset(@intCast(field.index), zcu), | |
| 691 | 691 | .@"extern", .@"packed" => unreachable, |
| 692 | 692 | }, |
| 693 | 693 | else => unreachable, |
| ... | ... | @@ -713,15 +713,16 @@ fn lowerUavRef( |
| 713 | 713 | offset: u64, |
| 714 | 714 | ) CodeGenError!Result { |
| 715 | 715 | _ = debug_output; |
| 716 | const ip = &pt.zcu.intern_pool; | |
| 716 | const zcu = pt.zcu; | |
| 717 | const ip = &zcu.intern_pool; | |
| 717 | 718 | const target = lf.comp.root_mod.resolved_target.result; |
| 718 | 719 | |
| 719 | 720 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 720 | 721 | const uav_val = uav.val; |
| 721 | 722 | const uav_ty = Type.fromInterned(ip.typeOf(uav_val)); |
| 722 | 723 | log.debug("lowerUavRef: ty = {}", .{uav_ty.fmt(pt)}); |
| 723 | const is_fn_body = uav_ty.zigTypeTag(pt.zcu) == .Fn; | |
| 724 | if (!is_fn_body and !uav_ty.hasRuntimeBits(pt)) { | |
| 724 | const is_fn_body = uav_ty.zigTypeTag(zcu) == .Fn; | |
| 725 | if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) { | |
| 725 | 726 | try code.appendNTimes(0xaa, ptr_width_bytes); |
| 726 | 727 | return Result.ok; |
| 727 | 728 | } |
| ... | ... | @@ -768,7 +769,7 @@ fn lowerNavRef( |
| 768 | 769 | const ptr_width = target.ptrBitWidth(); |
| 769 | 770 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); |
| 770 | 771 | const is_fn_body = nav_ty.zigTypeTag(zcu) == .Fn; |
| 771 | if (!is_fn_body and !nav_ty.hasRuntimeBits(pt)) { | |
| 772 | if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) { | |
| 772 | 773 | try code.appendNTimes(0xaa, @divExact(ptr_width, 8)); |
| 773 | 774 | return Result.ok; |
| 774 | 775 | } |
| ... | ... | @@ -860,7 +861,7 @@ fn genNavRef( |
| 860 | 861 | const ty = val.typeOf(zcu); |
| 861 | 862 | log.debug("genNavRef: val = {}", .{val.fmtValue(pt)}); |
| 862 | 863 | |
| 863 | if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 864 | if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 864 | 865 | const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) { |
| 865 | 866 | 1 => 0xaa, |
| 866 | 867 | 2 => 0xaaaa, |
| ... | ... | @@ -994,8 +995,8 @@ pub fn genTypedValue( |
| 994 | 995 | const info = ty.intInfo(zcu); |
| 995 | 996 | if (info.bits <= target.ptrBitWidth()) { |
| 996 | 997 | const unsigned: u64 = switch (info.signedness) { |
| 997 | .signed => @bitCast(val.toSignedInt(pt)), | |
| 998 | .unsigned => val.toUnsignedInt(pt), | |
| 998 | .signed => @bitCast(val.toSignedInt(zcu)), | |
| 999 | .unsigned => val.toUnsignedInt(zcu), | |
| 999 | 1000 | }; |
| 1000 | 1001 | return .{ .mcv = .{ .immediate = unsigned } }; |
| 1001 | 1002 | } |
| ... | ... | @@ -1012,7 +1013,7 @@ pub fn genTypedValue( |
| 1012 | 1013 | val.optionalValue(zcu) orelse return .{ .mcv = .{ .immediate = 0 } }, |
| 1013 | 1014 | target, |
| 1014 | 1015 | ); |
| 1015 | } else if (ty.abiSize(pt) == 1) { | |
| 1016 | } else if (ty.abiSize(zcu) == 1) { | |
| 1016 | 1017 | return .{ .mcv = .{ .immediate = @intFromBool(!val.isNull(zcu)) } }; |
| 1017 | 1018 | } |
| 1018 | 1019 | }, |
| ... | ... | @@ -1034,7 +1035,7 @@ pub fn genTypedValue( |
| 1034 | 1035 | .ErrorUnion => { |
| 1035 | 1036 | const err_type = ty.errorUnionSet(zcu); |
| 1036 | 1037 | const payload_type = ty.errorUnionPayload(zcu); |
| 1037 | if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1038 | if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1038 | 1039 | // We use the error type directly as the type. |
| 1039 | 1040 | const err_int_ty = try pt.errorIntType(); |
| 1040 | 1041 | switch (ip.indexToKey(val.toIntern()).error_union.val) { |
| ... | ... | @@ -1074,23 +1075,23 @@ pub fn genTypedValue( |
| 1074 | 1075 | return lf.lowerUav(pt, val.toIntern(), .none, src_loc); |
| 1075 | 1076 | } |
| 1076 | 1077 | |
| 1077 | pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { | |
| 1078 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; | |
| 1079 | const payload_align = payload_ty.abiAlignment(pt); | |
| 1080 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 1081 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1078 | pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 { | |
| 1079 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0; | |
| 1080 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 1081 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 1082 | if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1082 | 1083 | return 0; |
| 1083 | 1084 | } else { |
| 1084 | return payload_align.forward(Type.anyerror.abiSize(pt)); | |
| 1085 | return payload_align.forward(Type.anyerror.abiSize(zcu)); | |
| 1085 | 1086 | } |
| 1086 | 1087 | } |
| 1087 | 1088 | |
| 1088 | pub fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { | |
| 1089 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return 0; | |
| 1090 | const payload_align = payload_ty.abiAlignment(pt); | |
| 1091 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 1092 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1093 | return error_align.forward(payload_ty.abiSize(pt)); | |
| 1089 | pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 { | |
| 1090 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0; | |
| 1091 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 1092 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 1093 | if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1094 | return error_align.forward(payload_ty.abiSize(zcu)); | |
| 1094 | 1095 | } else { |
| 1095 | 1096 | return 0; |
| 1096 | 1097 | } |
src/codegen/c.zig+121-116| ... | ... | @@ -334,7 +334,7 @@ pub const Function = struct { |
| 334 | 334 | const writer = f.object.codeHeaderWriter(); |
| 335 | 335 | const decl_c_value = try f.allocLocalValue(.{ |
| 336 | 336 | .ctype = try f.ctypeFromType(ty, .complete), |
| 337 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt)), | |
| 337 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt.zcu)), | |
| 338 | 338 | }); |
| 339 | 339 | const gpa = f.object.dg.gpa; |
| 340 | 340 | try f.allocs.put(gpa, decl_c_value.new_local, false); |
| ... | ... | @@ -372,7 +372,7 @@ pub const Function = struct { |
| 372 | 372 | fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue { |
| 373 | 373 | return f.allocAlignedLocal(inst, .{ |
| 374 | 374 | .ctype = try f.ctypeFromType(ty, .complete), |
| 375 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.pt)), | |
| 375 | .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.pt.zcu)), | |
| 376 | 376 | }); |
| 377 | 377 | } |
| 378 | 378 | |
| ... | ... | @@ -648,7 +648,7 @@ pub const DeclGen = struct { |
| 648 | 648 | |
| 649 | 649 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 650 | 650 | const ptr_ty = Type.fromInterned(uav.orig_ty); |
| 651 | if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(pt)) { | |
| 651 | if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) { | |
| 652 | 652 | return dg.writeCValue(writer, .{ .undef = ptr_ty }); |
| 653 | 653 | } |
| 654 | 654 | |
| ... | ... | @@ -688,7 +688,7 @@ pub const DeclGen = struct { |
| 688 | 688 | // alignment. If there is already an entry, keep the greater alignment. |
| 689 | 689 | const explicit_alignment = ptr_type.flags.alignment; |
| 690 | 690 | if (explicit_alignment != .none) { |
| 691 | const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(pt); | |
| 691 | const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(zcu); | |
| 692 | 692 | if (explicit_alignment.order(abi_alignment).compare(.gt)) { |
| 693 | 693 | const aligned_gop = try dg.aligned_uavs.getOrPut(dg.gpa, uav.val); |
| 694 | 694 | aligned_gop.value_ptr.* = if (aligned_gop.found_existing) |
| ... | ... | @@ -722,7 +722,7 @@ pub const DeclGen = struct { |
| 722 | 722 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 723 | 723 | const nav_ty = Type.fromInterned(ip.getNav(owner_nav).typeOf(ip)); |
| 724 | 724 | const ptr_ty = try pt.navPtrType(owner_nav); |
| 725 | if (!nav_ty.isFnOrHasRuntimeBits(pt)) { | |
| 725 | if (!nav_ty.isFnOrHasRuntimeBits(zcu)) { | |
| 726 | 726 | return dg.writeCValue(writer, .{ .undef = ptr_ty }); |
| 727 | 727 | } |
| 728 | 728 | |
| ... | ... | @@ -805,7 +805,7 @@ pub const DeclGen = struct { |
| 805 | 805 | } |
| 806 | 806 | }, |
| 807 | 807 | |
| 808 | .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(pt)) { | |
| 808 | .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) { | |
| 809 | 809 | // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer. |
| 810 | 810 | const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete); |
| 811 | 811 | try writer.writeByte('('); |
| ... | ... | @@ -923,7 +923,7 @@ pub const DeclGen = struct { |
| 923 | 923 | try writer.writeAll("(("); |
| 924 | 924 | try dg.renderCType(writer, ctype); |
| 925 | 925 | try writer.print("){x})", .{try dg.fmtIntLiteral( |
| 926 | try pt.intValue(Type.usize, val.toUnsignedInt(pt)), | |
| 926 | try pt.intValue(Type.usize, val.toUnsignedInt(zcu)), | |
| 927 | 927 | .Other, |
| 928 | 928 | )}); |
| 929 | 929 | }, |
| ... | ... | @@ -970,7 +970,7 @@ pub const DeclGen = struct { |
| 970 | 970 | .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location), |
| 971 | 971 | .float => { |
| 972 | 972 | const bits = ty.floatBits(target.*); |
| 973 | const f128_val = val.toFloat(f128, pt); | |
| 973 | const f128_val = val.toFloat(f128, zcu); | |
| 974 | 974 | |
| 975 | 975 | // All unsigned ints matching float types are pre-allocated. |
| 976 | 976 | const repr_ty = pt.intType(.unsigned, bits) catch unreachable; |
| ... | ... | @@ -984,10 +984,10 @@ pub const DeclGen = struct { |
| 984 | 984 | }; |
| 985 | 985 | |
| 986 | 986 | switch (bits) { |
| 987 | 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, pt)))), | |
| 988 | 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, pt)))), | |
| 989 | 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, pt)))), | |
| 990 | 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, pt)))), | |
| 987 | 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))), | |
| 988 | 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))), | |
| 989 | 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))), | |
| 990 | 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))), | |
| 991 | 991 | 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))), |
| 992 | 992 | else => unreachable, |
| 993 | 993 | } |
| ... | ... | @@ -998,10 +998,10 @@ pub const DeclGen = struct { |
| 998 | 998 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 999 | 999 | try writer.writeByte('('); |
| 1000 | 1000 | switch (bits) { |
| 1001 | 16 => try writer.print("{x}", .{val.toFloat(f16, pt)}), | |
| 1002 | 32 => try writer.print("{x}", .{val.toFloat(f32, pt)}), | |
| 1003 | 64 => try writer.print("{x}", .{val.toFloat(f64, pt)}), | |
| 1004 | 80 => try writer.print("{x}", .{val.toFloat(f80, pt)}), | |
| 1001 | 16 => try writer.print("{x}", .{val.toFloat(f16, zcu)}), | |
| 1002 | 32 => try writer.print("{x}", .{val.toFloat(f32, zcu)}), | |
| 1003 | 64 => try writer.print("{x}", .{val.toFloat(f64, zcu)}), | |
| 1004 | 80 => try writer.print("{x}", .{val.toFloat(f80, zcu)}), | |
| 1005 | 1005 | 128 => try writer.print("{x}", .{f128_val}), |
| 1006 | 1006 | else => unreachable, |
| 1007 | 1007 | } |
| ... | ... | @@ -1041,10 +1041,10 @@ pub const DeclGen = struct { |
| 1041 | 1041 | if (std.math.isNan(f128_val)) switch (bits) { |
| 1042 | 1042 | // We only actually need to pass the significand, but it will get |
| 1043 | 1043 | // properly masked anyway, so just pass the whole value. |
| 1044 | 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, pt)))}), | |
| 1045 | 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, pt)))}), | |
| 1046 | 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, pt)))}), | |
| 1047 | 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, pt)))}), | |
| 1044 | 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}), | |
| 1045 | 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, zcu)))}), | |
| 1046 | 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}), | |
| 1047 | 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}), | |
| 1048 | 1048 | 128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}), |
| 1049 | 1049 | else => unreachable, |
| 1050 | 1050 | }; |
| ... | ... | @@ -1167,11 +1167,11 @@ pub const DeclGen = struct { |
| 1167 | 1167 | const elem_val_u8: u8 = if (elem_val.isUndef(zcu)) |
| 1168 | 1168 | undefPattern(u8) |
| 1169 | 1169 | else |
| 1170 | @intCast(elem_val.toUnsignedInt(pt)); | |
| 1170 | @intCast(elem_val.toUnsignedInt(zcu)); | |
| 1171 | 1171 | try literal.writeChar(elem_val_u8); |
| 1172 | 1172 | } |
| 1173 | 1173 | if (ai.sentinel) |s| { |
| 1174 | const s_u8: u8 = @intCast(s.toUnsignedInt(pt)); | |
| 1174 | const s_u8: u8 = @intCast(s.toUnsignedInt(zcu)); | |
| 1175 | 1175 | if (s_u8 != 0) try literal.writeChar(s_u8); |
| 1176 | 1176 | } |
| 1177 | 1177 | try literal.end(); |
| ... | ... | @@ -1203,7 +1203,7 @@ pub const DeclGen = struct { |
| 1203 | 1203 | const comptime_val = tuple.values.get(ip)[field_index]; |
| 1204 | 1204 | if (comptime_val != .none) continue; |
| 1205 | 1205 | const field_ty = Type.fromInterned(tuple.types.get(ip)[field_index]); |
| 1206 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1206 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1207 | 1207 | |
| 1208 | 1208 | if (!empty) try writer.writeByte(','); |
| 1209 | 1209 | |
| ... | ... | @@ -1238,7 +1238,7 @@ pub const DeclGen = struct { |
| 1238 | 1238 | var need_comma = false; |
| 1239 | 1239 | while (field_it.next()) |field_index| { |
| 1240 | 1240 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1241 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1241 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1242 | 1242 | |
| 1243 | 1243 | if (need_comma) try writer.writeByte(','); |
| 1244 | 1244 | need_comma = true; |
| ... | ... | @@ -1265,7 +1265,7 @@ pub const DeclGen = struct { |
| 1265 | 1265 | |
| 1266 | 1266 | for (0..loaded_struct.field_types.len) |field_index| { |
| 1267 | 1267 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1268 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1268 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1269 | 1269 | eff_num_fields += 1; |
| 1270 | 1270 | } |
| 1271 | 1271 | |
| ... | ... | @@ -1273,7 +1273,7 @@ pub const DeclGen = struct { |
| 1273 | 1273 | try writer.writeByte('('); |
| 1274 | 1274 | try dg.renderUndefValue(writer, ty, location); |
| 1275 | 1275 | try writer.writeByte(')'); |
| 1276 | } else if (ty.bitSize(pt) > 64) { | |
| 1276 | } else if (ty.bitSize(zcu) > 64) { | |
| 1277 | 1277 | // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off)) |
| 1278 | 1278 | var num_or = eff_num_fields - 1; |
| 1279 | 1279 | while (num_or > 0) : (num_or -= 1) { |
| ... | ... | @@ -1286,7 +1286,7 @@ pub const DeclGen = struct { |
| 1286 | 1286 | var needs_closing_paren = false; |
| 1287 | 1287 | for (0..loaded_struct.field_types.len) |field_index| { |
| 1288 | 1288 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1289 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1289 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1290 | 1290 | |
| 1291 | 1291 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 1292 | 1292 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| ... | ... | @@ -1312,7 +1312,7 @@ pub const DeclGen = struct { |
| 1312 | 1312 | if (needs_closing_paren) try writer.writeByte(')'); |
| 1313 | 1313 | if (eff_index != eff_num_fields - 1) try writer.writeAll(", "); |
| 1314 | 1314 | |
| 1315 | bit_offset += field_ty.bitSize(pt); | |
| 1315 | bit_offset += field_ty.bitSize(zcu); | |
| 1316 | 1316 | needs_closing_paren = true; |
| 1317 | 1317 | eff_index += 1; |
| 1318 | 1318 | } |
| ... | ... | @@ -1322,7 +1322,7 @@ pub const DeclGen = struct { |
| 1322 | 1322 | var empty = true; |
| 1323 | 1323 | for (0..loaded_struct.field_types.len) |field_index| { |
| 1324 | 1324 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1325 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1325 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1326 | 1326 | |
| 1327 | 1327 | if (!empty) try writer.writeAll(" | "); |
| 1328 | 1328 | try writer.writeByte('('); |
| ... | ... | @@ -1346,7 +1346,7 @@ pub const DeclGen = struct { |
| 1346 | 1346 | try dg.renderValue(writer, Value.fromInterned(field_val), .Other); |
| 1347 | 1347 | } |
| 1348 | 1348 | |
| 1349 | bit_offset += field_ty.bitSize(pt); | |
| 1349 | bit_offset += field_ty.bitSize(zcu); | |
| 1350 | 1350 | empty = false; |
| 1351 | 1351 | } |
| 1352 | 1352 | try writer.writeByte(')'); |
| ... | ... | @@ -1396,7 +1396,7 @@ pub const DeclGen = struct { |
| 1396 | 1396 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 1397 | 1397 | const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index]; |
| 1398 | 1398 | if (loaded_union.flagsUnordered(ip).layout == .@"packed") { |
| 1399 | if (field_ty.hasRuntimeBits(pt)) { | |
| 1399 | if (field_ty.hasRuntimeBits(zcu)) { | |
| 1400 | 1400 | if (field_ty.isPtrAtRuntime(zcu)) { |
| 1401 | 1401 | try writer.writeByte('('); |
| 1402 | 1402 | try dg.renderCType(writer, ctype); |
| ... | ... | @@ -1427,7 +1427,7 @@ pub const DeclGen = struct { |
| 1427 | 1427 | ), |
| 1428 | 1428 | .payload => { |
| 1429 | 1429 | try writer.writeByte('{'); |
| 1430 | if (field_ty.hasRuntimeBits(pt)) { | |
| 1430 | if (field_ty.hasRuntimeBits(zcu)) { | |
| 1431 | 1431 | try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))}); |
| 1432 | 1432 | try dg.renderValue( |
| 1433 | 1433 | writer, |
| ... | ... | @@ -1439,7 +1439,7 @@ pub const DeclGen = struct { |
| 1439 | 1439 | const inner_field_ty = Type.fromInterned( |
| 1440 | 1440 | loaded_union.field_types.get(ip)[inner_field_index], |
| 1441 | 1441 | ); |
| 1442 | if (!inner_field_ty.hasRuntimeBits(pt)) continue; | |
| 1442 | if (!inner_field_ty.hasRuntimeBits(zcu)) continue; | |
| 1443 | 1443 | try dg.renderUndefValue(writer, inner_field_ty, initializer_type); |
| 1444 | 1444 | break; |
| 1445 | 1445 | } |
| ... | ... | @@ -1588,7 +1588,7 @@ pub const DeclGen = struct { |
| 1588 | 1588 | var need_comma = false; |
| 1589 | 1589 | while (field_it.next()) |field_index| { |
| 1590 | 1590 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 1591 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1591 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1592 | 1592 | |
| 1593 | 1593 | if (need_comma) try writer.writeByte(','); |
| 1594 | 1594 | need_comma = true; |
| ... | ... | @@ -1613,7 +1613,7 @@ pub const DeclGen = struct { |
| 1613 | 1613 | for (0..anon_struct_info.types.len) |field_index| { |
| 1614 | 1614 | if (anon_struct_info.values.get(ip)[field_index] != .none) continue; |
| 1615 | 1615 | const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]); |
| 1616 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1616 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1617 | 1617 | |
| 1618 | 1618 | if (need_comma) try writer.writeByte(','); |
| 1619 | 1619 | need_comma = true; |
| ... | ... | @@ -1651,7 +1651,7 @@ pub const DeclGen = struct { |
| 1651 | 1651 | const inner_field_ty = Type.fromInterned( |
| 1652 | 1652 | loaded_union.field_types.get(ip)[inner_field_index], |
| 1653 | 1653 | ); |
| 1654 | if (!inner_field_ty.hasRuntimeBits(pt)) continue; | |
| 1654 | if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue; | |
| 1655 | 1655 | try dg.renderUndefValue( |
| 1656 | 1656 | writer, |
| 1657 | 1657 | inner_field_ty, |
| ... | ... | @@ -1902,7 +1902,8 @@ pub const DeclGen = struct { |
| 1902 | 1902 | }; |
| 1903 | 1903 | fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool { |
| 1904 | 1904 | const pt = dg.pt; |
| 1905 | const dest_bits = dest_ty.bitSize(pt); | |
| 1905 | const zcu = pt.zcu; | |
| 1906 | const dest_bits = dest_ty.bitSize(zcu); | |
| 1906 | 1907 | const dest_int_info = dest_ty.intInfo(pt.zcu); |
| 1907 | 1908 | |
| 1908 | 1909 | const src_is_ptr = src_ty.isPtrAtRuntime(pt.zcu); |
| ... | ... | @@ -1911,7 +1912,7 @@ pub const DeclGen = struct { |
| 1911 | 1912 | .signed => Type.isize, |
| 1912 | 1913 | } else src_ty; |
| 1913 | 1914 | |
| 1914 | const src_bits = src_eff_ty.bitSize(pt); | |
| 1915 | const src_bits = src_eff_ty.bitSize(zcu); | |
| 1915 | 1916 | const src_int_info = if (src_eff_ty.isAbiInt(pt.zcu)) src_eff_ty.intInfo(pt.zcu) else null; |
| 1916 | 1917 | if (dest_bits <= 64 and src_bits <= 64) { |
| 1917 | 1918 | const needs_cast = src_int_info == null or |
| ... | ... | @@ -1943,7 +1944,7 @@ pub const DeclGen = struct { |
| 1943 | 1944 | ) !void { |
| 1944 | 1945 | const pt = dg.pt; |
| 1945 | 1946 | const zcu = pt.zcu; |
| 1946 | const dest_bits = dest_ty.bitSize(pt); | |
| 1947 | const dest_bits = dest_ty.bitSize(zcu); | |
| 1947 | 1948 | const dest_int_info = dest_ty.intInfo(zcu); |
| 1948 | 1949 | |
| 1949 | 1950 | const src_is_ptr = src_ty.isPtrAtRuntime(zcu); |
| ... | ... | @@ -1952,7 +1953,7 @@ pub const DeclGen = struct { |
| 1952 | 1953 | .signed => Type.isize, |
| 1953 | 1954 | } else src_ty; |
| 1954 | 1955 | |
| 1955 | const src_bits = src_eff_ty.bitSize(pt); | |
| 1956 | const src_bits = src_eff_ty.bitSize(zcu); | |
| 1956 | 1957 | const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null; |
| 1957 | 1958 | if (dest_bits <= 64 and src_bits <= 64) { |
| 1958 | 1959 | const needs_cast = src_int_info == null or |
| ... | ... | @@ -2033,7 +2034,7 @@ pub const DeclGen = struct { |
| 2033 | 2034 | qualifiers, |
| 2034 | 2035 | CType.AlignAs.fromAlignment(.{ |
| 2035 | 2036 | .@"align" = alignment, |
| 2036 | .abi = ty.abiAlignment(dg.pt), | |
| 2037 | .abi = ty.abiAlignment(dg.pt.zcu), | |
| 2037 | 2038 | }), |
| 2038 | 2039 | ); |
| 2039 | 2040 | } |
| ... | ... | @@ -2239,9 +2240,10 @@ pub const DeclGen = struct { |
| 2239 | 2240 | } |
| 2240 | 2241 | |
| 2241 | 2242 | const pt = dg.pt; |
| 2242 | const int_info = if (ty.isAbiInt(pt.zcu)) ty.intInfo(pt.zcu) else std.builtin.Type.Int{ | |
| 2243 | const zcu = pt.zcu; | |
| 2244 | const int_info = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else std.builtin.Type.Int{ | |
| 2243 | 2245 | .signedness = .unsigned, |
| 2244 | .bits = @as(u16, @intCast(ty.bitSize(pt))), | |
| 2246 | .bits = @as(u16, @intCast(ty.bitSize(zcu))), | |
| 2245 | 2247 | }; |
| 2246 | 2248 | |
| 2247 | 2249 | if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); |
| ... | ... | @@ -2891,7 +2893,7 @@ pub fn genDecl(o: *Object) !void { |
| 2891 | 2893 | const nav = ip.getNav(o.dg.pass.nav); |
| 2892 | 2894 | const nav_ty = Type.fromInterned(nav.typeOf(ip)); |
| 2893 | 2895 | |
| 2894 | if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return; | |
| 2896 | if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return; | |
| 2895 | 2897 | switch (ip.indexToKey(nav.status.resolved.val)) { |
| 2896 | 2898 | .@"extern" => |@"extern"| { |
| 2897 | 2899 | if (!ip.isFunctionType(nav_ty.toIntern())) return o.dg.renderFwdDecl(o.dg.pass.nav, .{ |
| ... | ... | @@ -3420,10 +3422,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 3420 | 3422 | } |
| 3421 | 3423 | |
| 3422 | 3424 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3423 | const pt = f.object.dg.pt; | |
| 3425 | const zcu = f.object.dg.pt.zcu; | |
| 3424 | 3426 | const inst_ty = f.typeOfIndex(inst); |
| 3425 | 3427 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3426 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3428 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3427 | 3429 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3428 | 3430 | return .none; |
| 3429 | 3431 | } |
| ... | ... | @@ -3453,7 +3455,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3453 | 3455 | |
| 3454 | 3456 | const inst_ty = f.typeOfIndex(inst); |
| 3455 | 3457 | const ptr_ty = f.typeOf(bin_op.lhs); |
| 3456 | const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(pt); | |
| 3458 | const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(zcu); | |
| 3457 | 3459 | |
| 3458 | 3460 | const ptr = try f.resolveInst(bin_op.lhs); |
| 3459 | 3461 | const index = try f.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3482,10 +3484,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3482 | 3484 | } |
| 3483 | 3485 | |
| 3484 | 3486 | fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3485 | const pt = f.object.dg.pt; | |
| 3487 | const zcu = f.object.dg.pt.zcu; | |
| 3486 | 3488 | const inst_ty = f.typeOfIndex(inst); |
| 3487 | 3489 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3488 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3490 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3489 | 3491 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3490 | 3492 | return .none; |
| 3491 | 3493 | } |
| ... | ... | @@ -3516,7 +3518,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3516 | 3518 | const inst_ty = f.typeOfIndex(inst); |
| 3517 | 3519 | const slice_ty = f.typeOf(bin_op.lhs); |
| 3518 | 3520 | const elem_ty = slice_ty.elemType2(zcu); |
| 3519 | const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 3521 | const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 3520 | 3522 | |
| 3521 | 3523 | const slice = try f.resolveInst(bin_op.lhs); |
| 3522 | 3524 | const index = try f.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3539,10 +3541,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3539 | 3541 | } |
| 3540 | 3542 | |
| 3541 | 3543 | fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3542 | const pt = f.object.dg.pt; | |
| 3544 | const zcu = f.object.dg.pt.zcu; | |
| 3543 | 3545 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3544 | 3546 | const inst_ty = f.typeOfIndex(inst); |
| 3545 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3547 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3546 | 3548 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3547 | 3549 | return .none; |
| 3548 | 3550 | } |
| ... | ... | @@ -3569,13 +3571,13 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3569 | 3571 | const zcu = pt.zcu; |
| 3570 | 3572 | const inst_ty = f.typeOfIndex(inst); |
| 3571 | 3573 | const elem_ty = inst_ty.childType(zcu); |
| 3572 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .{ .undef = inst_ty }; | |
| 3574 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty }; | |
| 3573 | 3575 | |
| 3574 | 3576 | const local = try f.allocLocalValue(.{ |
| 3575 | 3577 | .ctype = try f.ctypeFromType(elem_ty, .complete), |
| 3576 | 3578 | .alignas = CType.AlignAs.fromAlignment(.{ |
| 3577 | 3579 | .@"align" = inst_ty.ptrInfo(zcu).flags.alignment, |
| 3578 | .abi = elem_ty.abiAlignment(pt), | |
| 3580 | .abi = elem_ty.abiAlignment(zcu), | |
| 3579 | 3581 | }), |
| 3580 | 3582 | }); |
| 3581 | 3583 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); |
| ... | ... | @@ -3588,13 +3590,13 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3588 | 3590 | const zcu = pt.zcu; |
| 3589 | 3591 | const inst_ty = f.typeOfIndex(inst); |
| 3590 | 3592 | const elem_ty = inst_ty.childType(zcu); |
| 3591 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .{ .undef = inst_ty }; | |
| 3593 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty }; | |
| 3592 | 3594 | |
| 3593 | 3595 | const local = try f.allocLocalValue(.{ |
| 3594 | 3596 | .ctype = try f.ctypeFromType(elem_ty, .complete), |
| 3595 | 3597 | .alignas = CType.AlignAs.fromAlignment(.{ |
| 3596 | 3598 | .@"align" = inst_ty.ptrInfo(zcu).flags.alignment, |
| 3597 | .abi = elem_ty.abiAlignment(pt), | |
| 3599 | .abi = elem_ty.abiAlignment(zcu), | |
| 3598 | 3600 | }), |
| 3599 | 3601 | }); |
| 3600 | 3602 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local }); |
| ... | ... | @@ -3636,7 +3638,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3636 | 3638 | const ptr_info = ptr_scalar_ty.ptrInfo(zcu); |
| 3637 | 3639 | const src_ty = Type.fromInterned(ptr_info.child); |
| 3638 | 3640 | |
| 3639 | if (!src_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3641 | if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3640 | 3642 | try reap(f, inst, &.{ty_op.operand}); |
| 3641 | 3643 | return .none; |
| 3642 | 3644 | } |
| ... | ... | @@ -3646,7 +3648,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3646 | 3648 | try reap(f, inst, &.{ty_op.operand}); |
| 3647 | 3649 | |
| 3648 | 3650 | const is_aligned = if (ptr_info.flags.alignment != .none) |
| 3649 | ptr_info.flags.alignment.order(src_ty.abiAlignment(pt)).compare(.gte) | |
| 3651 | ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte) | |
| 3650 | 3652 | else |
| 3651 | 3653 | true; |
| 3652 | 3654 | const is_array = lowersToArray(src_ty, pt); |
| ... | ... | @@ -3674,7 +3676,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3674 | 3676 | const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1)); |
| 3675 | 3677 | const bit_offset_val = try pt.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset); |
| 3676 | 3678 | |
| 3677 | const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(pt)))); | |
| 3679 | const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu)))); | |
| 3678 | 3680 | |
| 3679 | 3681 | try f.writeCValue(writer, local, .Other); |
| 3680 | 3682 | try v.elem(f, writer); |
| ... | ... | @@ -3685,9 +3687,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3685 | 3687 | try writer.writeAll("(("); |
| 3686 | 3688 | try f.renderType(writer, field_ty); |
| 3687 | 3689 | try writer.writeByte(')'); |
| 3688 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(pt) > 64; | |
| 3690 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64; | |
| 3689 | 3691 | if (cant_cast) { |
| 3690 | if (field_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | |
| 3692 | if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | |
| 3691 | 3693 | try writer.writeAll("zig_lo_"); |
| 3692 | 3694 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3693 | 3695 | try writer.writeByte('('); |
| ... | ... | @@ -3735,7 +3737,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3735 | 3737 | const ret_val = if (is_array) ret_val: { |
| 3736 | 3738 | const array_local = try f.allocAlignedLocal(inst, .{ |
| 3737 | 3739 | .ctype = ret_ctype, |
| 3738 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(pt)), | |
| 3740 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)), | |
| 3739 | 3741 | }); |
| 3740 | 3742 | try writer.writeAll("memcpy("); |
| 3741 | 3743 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); |
| ... | ... | @@ -3926,7 +3928,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3926 | 3928 | } |
| 3927 | 3929 | |
| 3928 | 3930 | const is_aligned = if (ptr_info.flags.alignment != .none) |
| 3929 | ptr_info.flags.alignment.order(src_ty.abiAlignment(pt)).compare(.gte) | |
| 3931 | ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte) | |
| 3930 | 3932 | else |
| 3931 | 3933 | true; |
| 3932 | 3934 | const is_array = lowersToArray(Type.fromInterned(ptr_info.child), pt); |
| ... | ... | @@ -3976,7 +3978,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3976 | 3978 | const bit_offset_ty = try pt.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1)); |
| 3977 | 3979 | const bit_offset_val = try pt.intValue(bit_offset_ty, ptr_info.packed_offset.bit_offset); |
| 3978 | 3980 | |
| 3979 | const src_bits = src_ty.bitSize(pt); | |
| 3981 | const src_bits = src_ty.bitSize(zcu); | |
| 3980 | 3982 | |
| 3981 | 3983 | const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb; |
| 3982 | 3984 | var stack align(@alignOf(ExpectedContents)) = |
| ... | ... | @@ -4006,9 +4008,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 4006 | 4008 | try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)}); |
| 4007 | 4009 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 4008 | 4010 | try writer.writeByte('('); |
| 4009 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(pt) > 64; | |
| 4011 | const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64; | |
| 4010 | 4012 | if (cant_cast) { |
| 4011 | if (src_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | |
| 4013 | if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | |
| 4012 | 4014 | try writer.writeAll("zig_make_"); |
| 4013 | 4015 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 4014 | 4016 | try writer.writeAll("(0, "); |
| ... | ... | @@ -4130,7 +4132,7 @@ fn airBinOp( |
| 4130 | 4132 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4131 | 4133 | const operand_ty = f.typeOf(bin_op.lhs); |
| 4132 | 4134 | const scalar_ty = operand_ty.scalarType(zcu); |
| 4133 | if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(pt) > 64) or scalar_ty.isRuntimeFloat()) | |
| 4135 | if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat()) | |
| 4134 | 4136 | return try airBinBuiltinCall(f, inst, operation, info); |
| 4135 | 4137 | |
| 4136 | 4138 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | ... | @@ -4169,7 +4171,7 @@ fn airCmpOp( |
| 4169 | 4171 | const lhs_ty = f.typeOf(data.lhs); |
| 4170 | 4172 | const scalar_ty = lhs_ty.scalarType(zcu); |
| 4171 | 4173 | |
| 4172 | const scalar_bits = scalar_ty.bitSize(pt); | |
| 4174 | const scalar_bits = scalar_ty.bitSize(zcu); | |
| 4173 | 4175 | if (scalar_ty.isInt(zcu) and scalar_bits > 64) |
| 4174 | 4176 | return airCmpBuiltinCall( |
| 4175 | 4177 | f, |
| ... | ... | @@ -4219,7 +4221,7 @@ fn airEquality( |
| 4219 | 4221 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4220 | 4222 | |
| 4221 | 4223 | const operand_ty = f.typeOf(bin_op.lhs); |
| 4222 | const operand_bits = operand_ty.bitSize(pt); | |
| 4224 | const operand_bits = operand_ty.bitSize(zcu); | |
| 4223 | 4225 | if (operand_ty.isAbiInt(zcu) and operand_bits > 64) |
| 4224 | 4226 | return airCmpBuiltinCall( |
| 4225 | 4227 | f, |
| ... | ... | @@ -4312,7 +4314,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 4312 | 4314 | const inst_ty = f.typeOfIndex(inst); |
| 4313 | 4315 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 4314 | 4316 | const elem_ty = inst_scalar_ty.elemType2(zcu); |
| 4315 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return f.moveCValue(inst, inst_ty, lhs); | |
| 4317 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs); | |
| 4316 | 4318 | const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete); |
| 4317 | 4319 | |
| 4318 | 4320 | const local = try f.allocLocal(inst, inst_ty); |
| ... | ... | @@ -4351,7 +4353,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 4351 | 4353 | const inst_ty = f.typeOfIndex(inst); |
| 4352 | 4354 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 4353 | 4355 | |
| 4354 | if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(pt) > 64) or inst_scalar_ty.isRuntimeFloat()) | |
| 4356 | if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64) or inst_scalar_ty.isRuntimeFloat()) | |
| 4355 | 4357 | return try airBinBuiltinCall(f, inst, operation, .none); |
| 4356 | 4358 | |
| 4357 | 4359 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | ... | @@ -4446,7 +4448,7 @@ fn airCall( |
| 4446 | 4448 | if (!arg_ctype.eql(try f.ctypeFromType(arg_ty, .complete))) { |
| 4447 | 4449 | const array_local = try f.allocAlignedLocal(inst, .{ |
| 4448 | 4450 | .ctype = arg_ctype, |
| 4449 | .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(pt)), | |
| 4451 | .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)), | |
| 4450 | 4452 | }); |
| 4451 | 4453 | try writer.writeAll("memcpy("); |
| 4452 | 4454 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); |
| ... | ... | @@ -4493,7 +4495,7 @@ fn airCall( |
| 4493 | 4495 | } else { |
| 4494 | 4496 | const local = try f.allocAlignedLocal(inst, .{ |
| 4495 | 4497 | .ctype = ret_ctype, |
| 4496 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(pt)), | |
| 4498 | .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)), | |
| 4497 | 4499 | }); |
| 4498 | 4500 | try f.writeCValue(writer, local, .Other); |
| 4499 | 4501 | try writer.writeAll(" = "); |
| ... | ... | @@ -4618,7 +4620,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) |
| 4618 | 4620 | const writer = f.object.writer(); |
| 4619 | 4621 | |
| 4620 | 4622 | const inst_ty = f.typeOfIndex(inst); |
| 4621 | const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !f.liveness.isUnused(inst)) | |
| 4623 | const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst)) | |
| 4622 | 4624 | try f.allocLocal(inst, inst_ty) |
| 4623 | 4625 | else |
| 4624 | 4626 | .none; |
| ... | ... | @@ -4681,7 +4683,7 @@ fn lowerTry( |
| 4681 | 4683 | const liveness_condbr = f.liveness.getCondBr(inst); |
| 4682 | 4684 | const writer = f.object.writer(); |
| 4683 | 4685 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 4684 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 4686 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 4685 | 4687 | |
| 4686 | 4688 | if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 4687 | 4689 | try writer.writeAll("if ("); |
| ... | ... | @@ -4820,7 +4822,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 4820 | 4822 | try writer.writeAll(", sizeof("); |
| 4821 | 4823 | try f.renderType( |
| 4822 | 4824 | writer, |
| 4823 | if (dest_ty.abiSize(pt) <= operand_ty.abiSize(pt)) dest_ty else operand_ty, | |
| 4825 | if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty, | |
| 4824 | 4826 | ); |
| 4825 | 4827 | try writer.writeAll("));\n"); |
| 4826 | 4828 | |
| ... | ... | @@ -5030,7 +5032,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5030 | 5032 | try f.object.indent_writer.insertNewline(); |
| 5031 | 5033 | try writer.writeAll("case "); |
| 5032 | 5034 | const item_value = try f.air.value(item, pt); |
| 5033 | if (item_value.?.getUnsignedInt(pt)) |item_int| try writer.print("{}\n", .{ | |
| 5035 | if (item_value.?.getUnsignedInt(zcu)) |item_int| try writer.print("{}\n", .{ | |
| 5034 | 5036 | try f.fmtIntLiteral(try pt.intValue(lowered_condition_ty, item_int)), |
| 5035 | 5037 | }) else { |
| 5036 | 5038 | if (condition_ty.isPtrAtRuntime(zcu)) { |
| ... | ... | @@ -5112,10 +5114,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5112 | 5114 | const result = result: { |
| 5113 | 5115 | const writer = f.object.writer(); |
| 5114 | 5116 | const inst_ty = f.typeOfIndex(inst); |
| 5115 | const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(pt)) local: { | |
| 5117 | const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: { | |
| 5116 | 5118 | const inst_local = try f.allocLocalValue(.{ |
| 5117 | 5119 | .ctype = try f.ctypeFromType(inst_ty, .complete), |
| 5118 | .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(pt)), | |
| 5120 | .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)), | |
| 5119 | 5121 | }); |
| 5120 | 5122 | if (f.wantSafety()) { |
| 5121 | 5123 | try f.writeCValue(writer, inst_local, .Other); |
| ... | ... | @@ -5148,7 +5150,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5148 | 5150 | try writer.writeAll("register "); |
| 5149 | 5151 | const output_local = try f.allocLocalValue(.{ |
| 5150 | 5152 | .ctype = try f.ctypeFromType(output_ty, .complete), |
| 5151 | .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(pt)), | |
| 5153 | .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)), | |
| 5152 | 5154 | }); |
| 5153 | 5155 | try f.allocs.put(gpa, output_local.new_local, false); |
| 5154 | 5156 | try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete); |
| ... | ... | @@ -5183,7 +5185,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5183 | 5185 | if (is_reg) try writer.writeAll("register "); |
| 5184 | 5186 | const input_local = try f.allocLocalValue(.{ |
| 5185 | 5187 | .ctype = try f.ctypeFromType(input_ty, .complete), |
| 5186 | .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(pt)), | |
| 5188 | .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)), | |
| 5187 | 5189 | }); |
| 5188 | 5190 | try f.allocs.put(gpa, input_local.new_local, false); |
| 5189 | 5191 | try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete); |
| ... | ... | @@ -5526,9 +5528,9 @@ fn fieldLocation( |
| 5526 | 5528 | .struct_type => { |
| 5527 | 5529 | const loaded_struct = ip.loadStructType(container_ty.toIntern()); |
| 5528 | 5530 | return switch (loaded_struct.layout) { |
| 5529 | .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 5531 | .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 5530 | 5532 | .begin |
| 5531 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(pt)) | |
| 5533 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) | |
| 5532 | 5534 | .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] } |
| 5533 | 5535 | else |
| 5534 | 5536 | .{ .field = if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | ... | @@ -5542,10 +5544,10 @@ fn fieldLocation( |
| 5542 | 5544 | .begin, |
| 5543 | 5545 | }; |
| 5544 | 5546 | }, |
| 5545 | .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 5547 | .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 5546 | 5548 | .begin |
| 5547 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(pt)) | |
| 5548 | .{ .byte_offset = container_ty.structFieldOffset(field_index, pt) } | |
| 5549 | else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) | |
| 5550 | .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) } | |
| 5549 | 5551 | else |
| 5550 | 5552 | .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name| |
| 5551 | 5553 | .{ .identifier = field_name.toSlice(ip) } |
| ... | ... | @@ -5556,8 +5558,8 @@ fn fieldLocation( |
| 5556 | 5558 | switch (loaded_union.flagsUnordered(ip).layout) { |
| 5557 | 5559 | .auto, .@"extern" => { |
| 5558 | 5560 | const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 5559 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 5560 | return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(pt)) | |
| 5561 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 5562 | return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(zcu)) | |
| 5561 | 5563 | .{ .field = .{ .identifier = "payload" } } |
| 5562 | 5564 | else |
| 5563 | 5565 | .begin; |
| ... | ... | @@ -5706,7 +5708,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5706 | 5708 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; |
| 5707 | 5709 | |
| 5708 | 5710 | const inst_ty = f.typeOfIndex(inst); |
| 5709 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5711 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5710 | 5712 | try reap(f, inst, &.{extra.struct_operand}); |
| 5711 | 5713 | return .none; |
| 5712 | 5714 | } |
| ... | ... | @@ -5738,7 +5740,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5738 | 5740 | inst_ty.intInfo(zcu).signedness |
| 5739 | 5741 | else |
| 5740 | 5742 | .unsigned; |
| 5741 | const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(pt)))); | |
| 5743 | const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu)))); | |
| 5742 | 5744 | |
| 5743 | 5745 | const temp_local = try f.allocLocal(inst, field_int_ty); |
| 5744 | 5746 | try f.writeCValue(writer, temp_local, .Other); |
| ... | ... | @@ -5749,7 +5751,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5749 | 5751 | try writer.writeByte(')'); |
| 5750 | 5752 | const cant_cast = int_info.bits > 64; |
| 5751 | 5753 | if (cant_cast) { |
| 5752 | if (field_int_ty.bitSize(pt) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | |
| 5754 | if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{}); | |
| 5753 | 5755 | try writer.writeAll("zig_lo_"); |
| 5754 | 5756 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); |
| 5755 | 5757 | try writer.writeByte('('); |
| ... | ... | @@ -5857,7 +5859,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5857 | 5859 | const payload_ty = error_union_ty.errorUnionPayload(zcu); |
| 5858 | 5860 | const local = try f.allocLocal(inst, inst_ty); |
| 5859 | 5861 | |
| 5860 | if (!payload_ty.hasRuntimeBits(pt) and operand == .local and operand.local == local.new_local) { | |
| 5862 | if (!payload_ty.hasRuntimeBits(zcu) and operand == .local and operand.local == local.new_local) { | |
| 5861 | 5863 | // The store will be 'x = x'; elide it. |
| 5862 | 5864 | return local; |
| 5863 | 5865 | } |
| ... | ... | @@ -5866,7 +5868,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5866 | 5868 | try f.writeCValue(writer, local, .Other); |
| 5867 | 5869 | try writer.writeAll(" = "); |
| 5868 | 5870 | |
| 5869 | if (!payload_ty.hasRuntimeBits(pt)) | |
| 5871 | if (!payload_ty.hasRuntimeBits(zcu)) | |
| 5870 | 5872 | try f.writeCValue(writer, operand, .Other) |
| 5871 | 5873 | else if (error_ty.errorSetIsEmpty(zcu)) |
| 5872 | 5874 | try writer.print("{}", .{ |
| ... | ... | @@ -5892,7 +5894,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 5892 | 5894 | const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 5893 | 5895 | |
| 5894 | 5896 | const writer = f.object.writer(); |
| 5895 | if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(pt)) { | |
| 5897 | if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) { | |
| 5896 | 5898 | if (!is_ptr) return .none; |
| 5897 | 5899 | |
| 5898 | 5900 | const local = try f.allocLocal(inst, inst_ty); |
| ... | ... | @@ -5963,7 +5965,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5963 | 5965 | |
| 5964 | 5966 | const inst_ty = f.typeOfIndex(inst); |
| 5965 | 5967 | const payload_ty = inst_ty.errorUnionPayload(zcu); |
| 5966 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 5968 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 5967 | 5969 | const err_ty = inst_ty.errorUnionSet(zcu); |
| 5968 | 5970 | const err = try f.resolveInst(ty_op.operand); |
| 5969 | 5971 | try reap(f, inst, &.{ty_op.operand}); |
| ... | ... | @@ -6012,7 +6014,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6012 | 6014 | try reap(f, inst, &.{ty_op.operand}); |
| 6013 | 6015 | |
| 6014 | 6016 | // First, set the non-error value. |
| 6015 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 6017 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 6016 | 6018 | const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete)); |
| 6017 | 6019 | try f.writeCValueDeref(writer, operand); |
| 6018 | 6020 | try a.assign(f, writer); |
| ... | ... | @@ -6064,7 +6066,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6064 | 6066 | const inst_ty = f.typeOfIndex(inst); |
| 6065 | 6067 | const payload_ty = inst_ty.errorUnionPayload(zcu); |
| 6066 | 6068 | const payload = try f.resolveInst(ty_op.operand); |
| 6067 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 6069 | const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 6068 | 6070 | const err_ty = inst_ty.errorUnionSet(zcu); |
| 6069 | 6071 | try reap(f, inst, &.{ty_op.operand}); |
| 6070 | 6072 | |
| ... | ... | @@ -6109,7 +6111,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const |
| 6109 | 6111 | try a.assign(f, writer); |
| 6110 | 6112 | const err_int_ty = try pt.errorIntType(); |
| 6111 | 6113 | if (!error_ty.errorSetIsEmpty(zcu)) |
| 6112 | if (payload_ty.hasRuntimeBits(pt)) | |
| 6114 | if (payload_ty.hasRuntimeBits(zcu)) | |
| 6113 | 6115 | if (is_ptr) |
| 6114 | 6116 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| 6115 | 6117 | else |
| ... | ... | @@ -6430,7 +6432,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 6430 | 6432 | try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value }); |
| 6431 | 6433 | |
| 6432 | 6434 | const repr_ty = if (ty.isRuntimeFloat()) |
| 6433 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable | |
| 6435 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable | |
| 6434 | 6436 | else |
| 6435 | 6437 | ty; |
| 6436 | 6438 | |
| ... | ... | @@ -6534,7 +6536,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6534 | 6536 | const operand_mat = try Materialize.start(f, inst, ty, operand); |
| 6535 | 6537 | try reap(f, inst, &.{ pl_op.operand, extra.operand }); |
| 6536 | 6538 | |
| 6537 | const repr_bits = @as(u16, @intCast(ty.abiSize(pt) * 8)); | |
| 6539 | const repr_bits = @as(u16, @intCast(ty.abiSize(zcu) * 8)); | |
| 6538 | 6540 | const is_float = ty.isRuntimeFloat(); |
| 6539 | 6541 | const is_128 = repr_bits == 128; |
| 6540 | 6542 | const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty; |
| ... | ... | @@ -6585,7 +6587,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6585 | 6587 | const ty = ptr_ty.childType(zcu); |
| 6586 | 6588 | |
| 6587 | 6589 | const repr_ty = if (ty.isRuntimeFloat()) |
| 6588 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable | |
| 6590 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable | |
| 6589 | 6591 | else |
| 6590 | 6592 | ty; |
| 6591 | 6593 | |
| ... | ... | @@ -6626,7 +6628,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa |
| 6626 | 6628 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6627 | 6629 | |
| 6628 | 6630 | const repr_ty = if (ty.isRuntimeFloat()) |
| 6629 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(pt) * 8))) catch unreachable | |
| 6631 | pt.intType(.unsigned, @as(u16, @intCast(ty.abiSize(zcu) * 8))) catch unreachable | |
| 6630 | 6632 | else |
| 6631 | 6633 | ty; |
| 6632 | 6634 | |
| ... | ... | @@ -6666,7 +6668,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6666 | 6668 | const dest_slice = try f.resolveInst(bin_op.lhs); |
| 6667 | 6669 | const value = try f.resolveInst(bin_op.rhs); |
| 6668 | 6670 | const elem_ty = f.typeOf(bin_op.rhs); |
| 6669 | const elem_abi_size = elem_ty.abiSize(pt); | |
| 6671 | const elem_abi_size = elem_ty.abiSize(zcu); | |
| 6670 | 6672 | const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false; |
| 6671 | 6673 | const writer = f.object.writer(); |
| 6672 | 6674 | |
| ... | ... | @@ -6831,7 +6833,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6831 | 6833 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6832 | 6834 | |
| 6833 | 6835 | const union_ty = f.typeOf(bin_op.lhs).childType(zcu); |
| 6834 | const layout = union_ty.unionGetLayout(pt); | |
| 6836 | const layout = union_ty.unionGetLayout(zcu); | |
| 6835 | 6837 | if (layout.tag_size == 0) return .none; |
| 6836 | 6838 | const tag_ty = union_ty.unionTagTypeSafety(zcu).?; |
| 6837 | 6839 | |
| ... | ... | @@ -6846,13 +6848,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6846 | 6848 | |
| 6847 | 6849 | fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6848 | 6850 | const pt = f.object.dg.pt; |
| 6851 | const zcu = pt.zcu; | |
| 6849 | 6852 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6850 | 6853 | |
| 6851 | 6854 | const operand = try f.resolveInst(ty_op.operand); |
| 6852 | 6855 | try reap(f, inst, &.{ty_op.operand}); |
| 6853 | 6856 | |
| 6854 | 6857 | const union_ty = f.typeOf(ty_op.operand); |
| 6855 | const layout = union_ty.unionGetLayout(pt); | |
| 6858 | const layout = union_ty.unionGetLayout(zcu); | |
| 6856 | 6859 | if (layout.tag_size == 0) return .none; |
| 6857 | 6860 | |
| 6858 | 6861 | const inst_ty = f.typeOfIndex(inst); |
| ... | ... | @@ -6960,6 +6963,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6960 | 6963 | |
| 6961 | 6964 | fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6962 | 6965 | const pt = f.object.dg.pt; |
| 6966 | const zcu = pt.zcu; | |
| 6963 | 6967 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6964 | 6968 | const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 6965 | 6969 | |
| ... | ... | @@ -6978,7 +6982,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6978 | 6982 | try f.object.dg.renderValue(writer, try pt.intValue(Type.usize, index), .Other); |
| 6979 | 6983 | try writer.writeAll("] = "); |
| 6980 | 6984 | |
| 6981 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(pt); | |
| 6985 | const mask_elem = (try mask.elemValue(pt, index)).toSignedInt(zcu); | |
| 6982 | 6986 | const src_val = try pt.intValue(Type.usize, @as(u64, @intCast(mask_elem ^ mask_elem >> 63))); |
| 6983 | 6987 | |
| 6984 | 6988 | try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other); |
| ... | ... | @@ -7001,7 +7005,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7001 | 7005 | const operand_ty = f.typeOf(reduce.operand); |
| 7002 | 7006 | const writer = f.object.writer(); |
| 7003 | 7007 | |
| 7004 | const use_operator = scalar_ty.bitSize(pt) <= 64; | |
| 7008 | const use_operator = scalar_ty.bitSize(zcu) <= 64; | |
| 7005 | 7009 | const op: union(enum) { |
| 7006 | 7010 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; |
| 7007 | 7011 | builtin: Func, |
| ... | ... | @@ -7178,7 +7182,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7178 | 7182 | var field_it = loaded_struct.iterateRuntimeOrder(ip); |
| 7179 | 7183 | while (field_it.next()) |field_index| { |
| 7180 | 7184 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 7181 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 7185 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 7182 | 7186 | |
| 7183 | 7187 | const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete)); |
| 7184 | 7188 | try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | ... | @@ -7203,7 +7207,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7203 | 7207 | for (0..elements.len) |field_index| { |
| 7204 | 7208 | if (inst_ty.structFieldIsComptime(field_index, zcu)) continue; |
| 7205 | 7209 | const field_ty = inst_ty.structFieldType(field_index, zcu); |
| 7206 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 7210 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 7207 | 7211 | |
| 7208 | 7212 | if (!empty) { |
| 7209 | 7213 | try writer.writeAll("zig_or_"); |
| ... | ... | @@ -7216,7 +7220,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7216 | 7220 | for (resolved_elements, 0..) |element, field_index| { |
| 7217 | 7221 | if (inst_ty.structFieldIsComptime(field_index, zcu)) continue; |
| 7218 | 7222 | const field_ty = inst_ty.structFieldType(field_index, zcu); |
| 7219 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 7223 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 7220 | 7224 | |
| 7221 | 7225 | if (!empty) try writer.writeAll(", "); |
| 7222 | 7226 | // TODO: Skip this entire shift if val is 0? |
| ... | ... | @@ -7248,7 +7252,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7248 | 7252 | try writer.writeByte(')'); |
| 7249 | 7253 | if (!empty) try writer.writeByte(')'); |
| 7250 | 7254 | |
| 7251 | bit_offset += field_ty.bitSize(pt); | |
| 7255 | bit_offset += field_ty.bitSize(zcu); | |
| 7252 | 7256 | empty = false; |
| 7253 | 7257 | } |
| 7254 | 7258 | try writer.writeAll(";\n"); |
| ... | ... | @@ -7258,7 +7262,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7258 | 7262 | .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| { |
| 7259 | 7263 | if (anon_struct_info.values.get(ip)[field_index] != .none) continue; |
| 7260 | 7264 | const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]); |
| 7261 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 7265 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 7262 | 7266 | |
| 7263 | 7267 | const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete)); |
| 7264 | 7268 | try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name| |
| ... | ... | @@ -7294,7 +7298,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7294 | 7298 | if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload); |
| 7295 | 7299 | |
| 7296 | 7300 | const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: { |
| 7297 | const layout = union_ty.unionGetLayout(pt); | |
| 7301 | const layout = union_ty.unionGetLayout(zcu); | |
| 7298 | 7302 | if (layout.tag_size != 0) { |
| 7299 | 7303 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; |
| 7300 | 7304 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| ... | ... | @@ -7818,7 +7822,7 @@ fn formatIntLiteral( |
| 7818 | 7822 | }; |
| 7819 | 7823 | undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits); |
| 7820 | 7824 | break :blk undef_int.toConst(); |
| 7821 | } else data.val.toBigInt(&int_buf, pt); | |
| 7825 | } else data.val.toBigInt(&int_buf, zcu); | |
| 7822 | 7826 | assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits)); |
| 7823 | 7827 | |
| 7824 | 7828 | const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8); |
| ... | ... | @@ -8062,9 +8066,10 @@ const Vectorize = struct { |
| 8062 | 8066 | }; |
| 8063 | 8067 | |
| 8064 | 8068 | fn lowersToArray(ty: Type, pt: Zcu.PerThread) bool { |
| 8065 | return switch (ty.zigTypeTag(pt.zcu)) { | |
| 8069 | const zcu = pt.zcu; | |
| 8070 | return switch (ty.zigTypeTag(zcu)) { | |
| 8066 | 8071 | .Array, .Vector => return true, |
| 8067 | else => return ty.isAbiInt(pt.zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(pt)))) == null, | |
| 8072 | else => return ty.isAbiInt(zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(zcu)))) == null, | |
| 8068 | 8073 | }; |
| 8069 | 8074 | } |
| 8070 | 8075 |
src/codegen/c/Type.zig+13-12| ... | ... | @@ -1344,6 +1344,7 @@ pub const Pool = struct { |
| 1344 | 1344 | kind: Kind, |
| 1345 | 1345 | ) !CType { |
| 1346 | 1346 | const ip = &pt.zcu.intern_pool; |
| 1347 | const zcu = pt.zcu; | |
| 1347 | 1348 | switch (ty.toIntern()) { |
| 1348 | 1349 | .u0_type, |
| 1349 | 1350 | .i0_type, |
| ... | ... | @@ -1476,7 +1477,7 @@ pub const Pool = struct { |
| 1476 | 1477 | ), |
| 1477 | 1478 | .alignas = AlignAs.fromAlignment(.{ |
| 1478 | 1479 | .@"align" = ptr_info.flags.alignment, |
| 1479 | .abi = Type.fromInterned(ptr_info.child).abiAlignment(pt), | |
| 1480 | .abi = Type.fromInterned(ptr_info.child).abiAlignment(zcu), | |
| 1480 | 1481 | }), |
| 1481 | 1482 | }; |
| 1482 | 1483 | break :elem_ctype if (elem.alignas.abiOrder().compare(.gte)) |
| ... | ... | @@ -1552,7 +1553,7 @@ pub const Pool = struct { |
| 1552 | 1553 | .{ |
| 1553 | 1554 | .name = .{ .index = .array }, |
| 1554 | 1555 | .ctype = array_ctype, |
| 1555 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(pt)), | |
| 1556 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)), | |
| 1556 | 1557 | }, |
| 1557 | 1558 | }; |
| 1558 | 1559 | return pool.fromFields(allocator, .@"struct", &fields, kind); |
| ... | ... | @@ -1578,7 +1579,7 @@ pub const Pool = struct { |
| 1578 | 1579 | .{ |
| 1579 | 1580 | .name = .{ .index = .array }, |
| 1580 | 1581 | .ctype = vector_ctype, |
| 1581 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(pt)), | |
| 1582 | .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)), | |
| 1582 | 1583 | }, |
| 1583 | 1584 | }; |
| 1584 | 1585 | return pool.fromFields(allocator, .@"struct", &fields, kind); |
| ... | ... | @@ -1613,7 +1614,7 @@ pub const Pool = struct { |
| 1613 | 1614 | .name = .{ .index = .payload }, |
| 1614 | 1615 | .ctype = payload_ctype, |
| 1615 | 1616 | .alignas = AlignAs.fromAbiAlignment( |
| 1616 | Type.fromInterned(payload_type).abiAlignment(pt), | |
| 1617 | Type.fromInterned(payload_type).abiAlignment(zcu), | |
| 1617 | 1618 | ), |
| 1618 | 1619 | }, |
| 1619 | 1620 | }; |
| ... | ... | @@ -1649,7 +1650,7 @@ pub const Pool = struct { |
| 1649 | 1650 | .{ |
| 1650 | 1651 | .name = .{ .index = .payload }, |
| 1651 | 1652 | .ctype = payload_ctype, |
| 1652 | .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(pt)), | |
| 1653 | .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(zcu)), | |
| 1653 | 1654 | }, |
| 1654 | 1655 | }; |
| 1655 | 1656 | return pool.fromFields(allocator, .@"struct", &fields, kind); |
| ... | ... | @@ -1663,7 +1664,7 @@ pub const Pool = struct { |
| 1663 | 1664 | .tag = .@"struct", |
| 1664 | 1665 | .name = .{ .index = ip_index }, |
| 1665 | 1666 | }); |
| 1666 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 1667 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 1667 | 1668 | fwd_decl |
| 1668 | 1669 | else |
| 1669 | 1670 | CType.void; |
| ... | ... | @@ -1696,7 +1697,7 @@ pub const Pool = struct { |
| 1696 | 1697 | String.fromUnnamed(@intCast(field_index)); |
| 1697 | 1698 | const field_alignas = AlignAs.fromAlignment(.{ |
| 1698 | 1699 | .@"align" = loaded_struct.fieldAlign(ip, field_index), |
| 1699 | .abi = field_type.abiAlignment(pt), | |
| 1700 | .abi = field_type.abiAlignment(zcu), | |
| 1700 | 1701 | }); |
| 1701 | 1702 | pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{ |
| 1702 | 1703 | .name = field_name.index, |
| ... | ... | @@ -1758,7 +1759,7 @@ pub const Pool = struct { |
| 1758 | 1759 | .name = field_name.index, |
| 1759 | 1760 | .ctype = field_ctype.index, |
| 1760 | 1761 | .flags = .{ .alignas = AlignAs.fromAbiAlignment( |
| 1761 | field_type.abiAlignment(pt), | |
| 1762 | field_type.abiAlignment(zcu), | |
| 1762 | 1763 | ) }, |
| 1763 | 1764 | }); |
| 1764 | 1765 | } |
| ... | ... | @@ -1802,7 +1803,7 @@ pub const Pool = struct { |
| 1802 | 1803 | .tag = if (has_tag) .@"struct" else .@"union", |
| 1803 | 1804 | .name = .{ .index = ip_index }, |
| 1804 | 1805 | }); |
| 1805 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 1806 | if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 1806 | 1807 | fwd_decl |
| 1807 | 1808 | else |
| 1808 | 1809 | CType.void; |
| ... | ... | @@ -1836,7 +1837,7 @@ pub const Pool = struct { |
| 1836 | 1837 | ); |
| 1837 | 1838 | const field_alignas = AlignAs.fromAlignment(.{ |
| 1838 | 1839 | .@"align" = loaded_union.fieldAlign(ip, field_index), |
| 1839 | .abi = field_type.abiAlignment(pt), | |
| 1840 | .abi = field_type.abiAlignment(zcu), | |
| 1840 | 1841 | }); |
| 1841 | 1842 | pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{ |
| 1842 | 1843 | .name = field_name.index, |
| ... | ... | @@ -1881,7 +1882,7 @@ pub const Pool = struct { |
| 1881 | 1882 | struct_fields[struct_fields_len] = .{ |
| 1882 | 1883 | .name = .{ .index = .tag }, |
| 1883 | 1884 | .ctype = tag_ctype, |
| 1884 | .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(pt)), | |
| 1885 | .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)), | |
| 1885 | 1886 | }; |
| 1886 | 1887 | struct_fields_len += 1; |
| 1887 | 1888 | } |
| ... | ... | @@ -1929,7 +1930,7 @@ pub const Pool = struct { |
| 1929 | 1930 | }, |
| 1930 | 1931 | .@"packed" => return pool.fromIntInfo(allocator, .{ |
| 1931 | 1932 | .signedness = .unsigned, |
| 1932 | .bits = @intCast(ty.bitSize(pt)), | |
| 1933 | .bits = @intCast(ty.bitSize(zcu)), | |
| 1933 | 1934 | }, mod, kind), |
| 1934 | 1935 | } |
| 1935 | 1936 | }, |
src/codegen/llvm.zig+840-831| ... | ... | @@ -1001,12 +1001,12 @@ pub const Object = struct { |
| 1001 | 1001 | if (o.error_name_table == .none) return; |
| 1002 | 1002 | |
| 1003 | 1003 | const pt = o.pt; |
| 1004 | const mod = pt.zcu; | |
| 1005 | const ip = &mod.intern_pool; | |
| 1004 | const zcu = pt.zcu; | |
| 1005 | const ip = &zcu.intern_pool; | |
| 1006 | 1006 | |
| 1007 | 1007 | const error_name_list = ip.global_error_set.getNamesFromMainThread(); |
| 1008 | const llvm_errors = try mod.gpa.alloc(Builder.Constant, 1 + error_name_list.len); | |
| 1009 | defer mod.gpa.free(llvm_errors); | |
| 1008 | const llvm_errors = try zcu.gpa.alloc(Builder.Constant, 1 + error_name_list.len); | |
| 1009 | defer zcu.gpa.free(llvm_errors); | |
| 1010 | 1010 | |
| 1011 | 1011 | // TODO: Address space |
| 1012 | 1012 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| ... | ... | @@ -1041,7 +1041,7 @@ pub const Object = struct { |
| 1041 | 1041 | table_variable_index.setMutability(.constant, &o.builder); |
| 1042 | 1042 | table_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 1043 | 1043 | table_variable_index.setAlignment( |
| 1044 | slice_ty.abiAlignment(pt).toLlvm(), | |
| 1044 | slice_ty.abiAlignment(zcu).toLlvm(), | |
| 1045 | 1045 | &o.builder, |
| 1046 | 1046 | ); |
| 1047 | 1047 | |
| ... | ... | @@ -1428,7 +1428,7 @@ pub const Object = struct { |
| 1428 | 1428 | var llvm_arg_i: u32 = 0; |
| 1429 | 1429 | |
| 1430 | 1430 | // This gets the LLVM values from the function and stores them in `ng.args`. |
| 1431 | const sret = firstParamSRet(fn_info, pt, target); | |
| 1431 | const sret = firstParamSRet(fn_info, zcu, target); | |
| 1432 | 1432 | const ret_ptr: Builder.Value = if (sret) param: { |
| 1433 | 1433 | const param = wip.arg(llvm_arg_i); |
| 1434 | 1434 | llvm_arg_i += 1; |
| ... | ... | @@ -1469,8 +1469,8 @@ pub const Object = struct { |
| 1469 | 1469 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 1470 | 1470 | const param = wip.arg(llvm_arg_i); |
| 1471 | 1471 | |
| 1472 | if (isByRef(param_ty, pt)) { | |
| 1473 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1472 | if (isByRef(param_ty, zcu)) { | |
| 1473 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1474 | 1474 | const param_llvm_ty = param.typeOfWip(&wip); |
| 1475 | 1475 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1476 | 1476 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| ... | ... | @@ -1486,12 +1486,12 @@ pub const Object = struct { |
| 1486 | 1486 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1487 | 1487 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1488 | 1488 | const param = wip.arg(llvm_arg_i); |
| 1489 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1489 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1490 | 1490 | |
| 1491 | 1491 | try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty); |
| 1492 | 1492 | llvm_arg_i += 1; |
| 1493 | 1493 | |
| 1494 | if (isByRef(param_ty, pt)) { | |
| 1494 | if (isByRef(param_ty, zcu)) { | |
| 1495 | 1495 | args.appendAssumeCapacity(param); |
| 1496 | 1496 | } else { |
| 1497 | 1497 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); |
| ... | ... | @@ -1501,12 +1501,12 @@ pub const Object = struct { |
| 1501 | 1501 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1502 | 1502 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1503 | 1503 | const param = wip.arg(llvm_arg_i); |
| 1504 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1504 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1505 | 1505 | |
| 1506 | 1506 | try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder); |
| 1507 | 1507 | llvm_arg_i += 1; |
| 1508 | 1508 | |
| 1509 | if (isByRef(param_ty, pt)) { | |
| 1509 | if (isByRef(param_ty, zcu)) { | |
| 1510 | 1510 | args.appendAssumeCapacity(param); |
| 1511 | 1511 | } else { |
| 1512 | 1512 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); |
| ... | ... | @@ -1519,11 +1519,11 @@ pub const Object = struct { |
| 1519 | 1519 | llvm_arg_i += 1; |
| 1520 | 1520 | |
| 1521 | 1521 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1522 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1522 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1523 | 1523 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1524 | 1524 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1525 | 1525 | |
| 1526 | args.appendAssumeCapacity(if (isByRef(param_ty, pt)) | |
| 1526 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | |
| 1527 | 1527 | arg_ptr |
| 1528 | 1528 | else |
| 1529 | 1529 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | ... | @@ -1547,7 +1547,7 @@ pub const Object = struct { |
| 1547 | 1547 | const elem_align = (if (ptr_info.flags.alignment != .none) |
| 1548 | 1548 | @as(InternPool.Alignment, ptr_info.flags.alignment) |
| 1549 | 1549 | else |
| 1550 | Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm(); | |
| 1550 | Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm(); | |
| 1551 | 1551 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); |
| 1552 | 1552 | const ptr_param = wip.arg(llvm_arg_i); |
| 1553 | 1553 | llvm_arg_i += 1; |
| ... | ... | @@ -1564,7 +1564,7 @@ pub const Object = struct { |
| 1564 | 1564 | const field_types = it.types_buffer[0..it.types_len]; |
| 1565 | 1565 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1566 | 1566 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1567 | const param_alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1567 | const param_alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1568 | 1568 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, param_alignment, target); |
| 1569 | 1569 | const llvm_ty = try o.builder.structType(.normal, field_types); |
| 1570 | 1570 | for (0..field_types.len) |field_i| { |
| ... | ... | @@ -1576,7 +1576,7 @@ pub const Object = struct { |
| 1576 | 1576 | _ = try wip.store(.normal, param, field_ptr, alignment); |
| 1577 | 1577 | } |
| 1578 | 1578 | |
| 1579 | const is_by_ref = isByRef(param_ty, pt); | |
| 1579 | const is_by_ref = isByRef(param_ty, zcu); | |
| 1580 | 1580 | args.appendAssumeCapacity(if (is_by_ref) |
| 1581 | 1581 | arg_ptr |
| 1582 | 1582 | else |
| ... | ... | @@ -1594,11 +1594,11 @@ pub const Object = struct { |
| 1594 | 1594 | const param = wip.arg(llvm_arg_i); |
| 1595 | 1595 | llvm_arg_i += 1; |
| 1596 | 1596 | |
| 1597 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1597 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1598 | 1598 | const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target); |
| 1599 | 1599 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1600 | 1600 | |
| 1601 | args.appendAssumeCapacity(if (isByRef(param_ty, pt)) | |
| 1601 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | |
| 1602 | 1602 | arg_ptr |
| 1603 | 1603 | else |
| 1604 | 1604 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | ... | @@ -1609,11 +1609,11 @@ pub const Object = struct { |
| 1609 | 1609 | const param = wip.arg(llvm_arg_i); |
| 1610 | 1610 | llvm_arg_i += 1; |
| 1611 | 1611 | |
| 1612 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 1612 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1613 | 1613 | const arg_ptr = try buildAllocaInner(&wip, param.typeOfWip(&wip), alignment, target); |
| 1614 | 1614 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1615 | 1615 | |
| 1616 | args.appendAssumeCapacity(if (isByRef(param_ty, pt)) | |
| 1616 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | |
| 1617 | 1617 | arg_ptr |
| 1618 | 1618 | else |
| 1619 | 1619 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | ... | @@ -1738,13 +1738,13 @@ pub const Object = struct { |
| 1738 | 1738 | |
| 1739 | 1739 | fn updateExportedValue( |
| 1740 | 1740 | o: *Object, |
| 1741 | mod: *Zcu, | |
| 1741 | zcu: *Zcu, | |
| 1742 | 1742 | exported_value: InternPool.Index, |
| 1743 | 1743 | export_indices: []const u32, |
| 1744 | 1744 | ) link.File.UpdateExportsError!void { |
| 1745 | const gpa = mod.gpa; | |
| 1746 | const ip = &mod.intern_pool; | |
| 1747 | const main_exp_name = try o.builder.strtabString(mod.all_exports.items[export_indices[0]].opts.name.toSlice(ip)); | |
| 1745 | const gpa = zcu.gpa; | |
| 1746 | const ip = &zcu.intern_pool; | |
| 1747 | const main_exp_name = try o.builder.strtabString(zcu.all_exports.items[export_indices[0]].opts.name.toSlice(ip)); | |
| 1748 | 1748 | const global_index = i: { |
| 1749 | 1749 | const gop = try o.uav_map.getOrPut(gpa, exported_value); |
| 1750 | 1750 | if (gop.found_existing) { |
| ... | ... | @@ -1768,18 +1768,18 @@ pub const Object = struct { |
| 1768 | 1768 | try variable_index.setInitializer(init_val, &o.builder); |
| 1769 | 1769 | break :i global_index; |
| 1770 | 1770 | }; |
| 1771 | return updateExportedGlobal(o, mod, global_index, export_indices); | |
| 1771 | return updateExportedGlobal(o, zcu, global_index, export_indices); | |
| 1772 | 1772 | } |
| 1773 | 1773 | |
| 1774 | 1774 | fn updateExportedGlobal( |
| 1775 | 1775 | o: *Object, |
| 1776 | mod: *Zcu, | |
| 1776 | zcu: *Zcu, | |
| 1777 | 1777 | global_index: Builder.Global.Index, |
| 1778 | 1778 | export_indices: []const u32, |
| 1779 | 1779 | ) link.File.UpdateExportsError!void { |
| 1780 | const comp = mod.comp; | |
| 1781 | const ip = &mod.intern_pool; | |
| 1782 | const first_export = mod.all_exports.items[export_indices[0]]; | |
| 1780 | const comp = zcu.comp; | |
| 1781 | const ip = &zcu.intern_pool; | |
| 1782 | const first_export = zcu.all_exports.items[export_indices[0]]; | |
| 1783 | 1783 | |
| 1784 | 1784 | // We will rename this global to have a name matching `first_export`. |
| 1785 | 1785 | // Successive exports become aliases. |
| ... | ... | @@ -1836,7 +1836,7 @@ pub const Object = struct { |
| 1836 | 1836 | // Until then we iterate over existing aliases and make them point |
| 1837 | 1837 | // to the correct decl, or otherwise add a new alias. Old aliases are leaked. |
| 1838 | 1838 | for (export_indices[1..]) |export_idx| { |
| 1839 | const exp = mod.all_exports.items[export_idx]; | |
| 1839 | const exp = zcu.all_exports.items[export_idx]; | |
| 1840 | 1840 | const exp_name = try o.builder.strtabString(exp.opts.name.toSlice(ip)); |
| 1841 | 1841 | if (o.builder.getGlobal(exp_name)) |global| { |
| 1842 | 1842 | switch (global.ptrConst(&o.builder).kind) { |
| ... | ... | @@ -1923,7 +1923,7 @@ pub const Object = struct { |
| 1923 | 1923 | const name = try o.allocTypeName(ty); |
| 1924 | 1924 | defer gpa.free(name); |
| 1925 | 1925 | const builder_name = try o.builder.metadataString(name); |
| 1926 | const debug_bits = ty.abiSize(pt) * 8; // lldb cannot handle non-byte sized types | |
| 1926 | const debug_bits = ty.abiSize(zcu) * 8; // lldb cannot handle non-byte sized types | |
| 1927 | 1927 | const debug_int_type = switch (info.signedness) { |
| 1928 | 1928 | .signed => try o.builder.debugSignedType(builder_name, debug_bits), |
| 1929 | 1929 | .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits), |
| ... | ... | @@ -1932,7 +1932,7 @@ pub const Object = struct { |
| 1932 | 1932 | return debug_int_type; |
| 1933 | 1933 | }, |
| 1934 | 1934 | .Enum => { |
| 1935 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1935 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1936 | 1936 | const debug_enum_type = try o.makeEmptyNamespaceDebugType(ty); |
| 1937 | 1937 | try o.debug_type_map.put(gpa, ty, debug_enum_type); |
| 1938 | 1938 | return debug_enum_type; |
| ... | ... | @@ -1949,7 +1949,7 @@ pub const Object = struct { |
| 1949 | 1949 | for (enum_type.names.get(ip), 0..) |field_name_ip, i| { |
| 1950 | 1950 | var bigint_space: Value.BigIntSpace = undefined; |
| 1951 | 1951 | const bigint = if (enum_type.values.len != 0) |
| 1952 | Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, pt) | |
| 1952 | Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, zcu) | |
| 1953 | 1953 | else |
| 1954 | 1954 | std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); |
| 1955 | 1955 | |
| ... | ... | @@ -1976,8 +1976,8 @@ pub const Object = struct { |
| 1976 | 1976 | scope, |
| 1977 | 1977 | ty.typeDeclSrcLine(zcu).? + 1, // Line |
| 1978 | 1978 | try o.lowerDebugType(int_ty), |
| 1979 | ty.abiSize(pt) * 8, | |
| 1980 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 1979 | ty.abiSize(zcu) * 8, | |
| 1980 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 1981 | 1981 | try o.builder.debugTuple(enumerators), |
| 1982 | 1982 | ); |
| 1983 | 1983 | |
| ... | ... | @@ -2017,10 +2017,10 @@ pub const Object = struct { |
| 2017 | 2017 | ptr_info.flags.is_const or |
| 2018 | 2018 | ptr_info.flags.is_volatile or |
| 2019 | 2019 | ptr_info.flags.size == .Many or ptr_info.flags.size == .C or |
| 2020 | !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(pt)) | |
| 2020 | !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu)) | |
| 2021 | 2021 | { |
| 2022 | 2022 | const bland_ptr_ty = try pt.ptrType(.{ |
| 2023 | .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(pt)) | |
| 2023 | .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu)) | |
| 2024 | 2024 | .anyopaque_type |
| 2025 | 2025 | else |
| 2026 | 2026 | ptr_info.child, |
| ... | ... | @@ -2050,10 +2050,10 @@ pub const Object = struct { |
| 2050 | 2050 | defer gpa.free(name); |
| 2051 | 2051 | const line = 0; |
| 2052 | 2052 | |
| 2053 | const ptr_size = ptr_ty.abiSize(pt); | |
| 2054 | const ptr_align = ptr_ty.abiAlignment(pt); | |
| 2055 | const len_size = len_ty.abiSize(pt); | |
| 2056 | const len_align = len_ty.abiAlignment(pt); | |
| 2053 | const ptr_size = ptr_ty.abiSize(zcu); | |
| 2054 | const ptr_align = ptr_ty.abiAlignment(zcu); | |
| 2055 | const len_size = len_ty.abiSize(zcu); | |
| 2056 | const len_align = len_ty.abiAlignment(zcu); | |
| 2057 | 2057 | |
| 2058 | 2058 | const len_offset = len_align.forward(ptr_size); |
| 2059 | 2059 | |
| ... | ... | @@ -2085,8 +2085,8 @@ pub const Object = struct { |
| 2085 | 2085 | o.debug_compile_unit, // Scope |
| 2086 | 2086 | line, |
| 2087 | 2087 | .none, // Underlying type |
| 2088 | ty.abiSize(pt) * 8, | |
| 2089 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2088 | ty.abiSize(zcu) * 8, | |
| 2089 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2090 | 2090 | try o.builder.debugTuple(&.{ |
| 2091 | 2091 | debug_ptr_type, |
| 2092 | 2092 | debug_len_type, |
| ... | ... | @@ -2114,7 +2114,7 @@ pub const Object = struct { |
| 2114 | 2114 | 0, // Line |
| 2115 | 2115 | debug_elem_ty, |
| 2116 | 2116 | target.ptrBitWidth(), |
| 2117 | (ty.ptrAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2117 | (ty.ptrAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2118 | 2118 | 0, // Offset |
| 2119 | 2119 | ); |
| 2120 | 2120 | |
| ... | ... | @@ -2165,8 +2165,8 @@ pub const Object = struct { |
| 2165 | 2165 | .none, // Scope |
| 2166 | 2166 | 0, // Line |
| 2167 | 2167 | try o.lowerDebugType(ty.childType(zcu)), |
| 2168 | ty.abiSize(pt) * 8, | |
| 2169 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2168 | ty.abiSize(zcu) * 8, | |
| 2169 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2170 | 2170 | try o.builder.debugTuple(&.{ |
| 2171 | 2171 | try o.builder.debugSubrange( |
| 2172 | 2172 | try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), |
| ... | ... | @@ -2208,8 +2208,8 @@ pub const Object = struct { |
| 2208 | 2208 | .none, // Scope |
| 2209 | 2209 | 0, // Line |
| 2210 | 2210 | debug_elem_type, |
| 2211 | ty.abiSize(pt) * 8, | |
| 2212 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2211 | ty.abiSize(zcu) * 8, | |
| 2212 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2213 | 2213 | try o.builder.debugTuple(&.{ |
| 2214 | 2214 | try o.builder.debugSubrange( |
| 2215 | 2215 | try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), |
| ... | ... | @@ -2225,7 +2225,7 @@ pub const Object = struct { |
| 2225 | 2225 | const name = try o.allocTypeName(ty); |
| 2226 | 2226 | defer gpa.free(name); |
| 2227 | 2227 | const child_ty = ty.optionalChild(zcu); |
| 2228 | if (!child_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2228 | if (!child_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2229 | 2229 | const debug_bool_type = try o.builder.debugBoolType( |
| 2230 | 2230 | try o.builder.metadataString(name), |
| 2231 | 2231 | 8, |
| ... | ... | @@ -2252,10 +2252,10 @@ pub const Object = struct { |
| 2252 | 2252 | } |
| 2253 | 2253 | |
| 2254 | 2254 | const non_null_ty = Type.u8; |
| 2255 | const payload_size = child_ty.abiSize(pt); | |
| 2256 | const payload_align = child_ty.abiAlignment(pt); | |
| 2257 | const non_null_size = non_null_ty.abiSize(pt); | |
| 2258 | const non_null_align = non_null_ty.abiAlignment(pt); | |
| 2255 | const payload_size = child_ty.abiSize(zcu); | |
| 2256 | const payload_align = child_ty.abiAlignment(zcu); | |
| 2257 | const non_null_size = non_null_ty.abiSize(zcu); | |
| 2258 | const non_null_align = non_null_ty.abiAlignment(zcu); | |
| 2259 | 2259 | const non_null_offset = non_null_align.forward(payload_size); |
| 2260 | 2260 | |
| 2261 | 2261 | const debug_data_type = try o.builder.debugMemberType( |
| ... | ... | @@ -2286,8 +2286,8 @@ pub const Object = struct { |
| 2286 | 2286 | o.debug_compile_unit, // Scope |
| 2287 | 2287 | 0, // Line |
| 2288 | 2288 | .none, // Underlying type |
| 2289 | ty.abiSize(pt) * 8, | |
| 2290 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2289 | ty.abiSize(zcu) * 8, | |
| 2290 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2291 | 2291 | try o.builder.debugTuple(&.{ |
| 2292 | 2292 | debug_data_type, |
| 2293 | 2293 | debug_some_type, |
| ... | ... | @@ -2304,7 +2304,7 @@ pub const Object = struct { |
| 2304 | 2304 | }, |
| 2305 | 2305 | .ErrorUnion => { |
| 2306 | 2306 | const payload_ty = ty.errorUnionPayload(zcu); |
| 2307 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2307 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2308 | 2308 | // TODO: Maybe remove? |
| 2309 | 2309 | const debug_error_union_type = try o.lowerDebugType(Type.anyerror); |
| 2310 | 2310 | try o.debug_type_map.put(gpa, ty, debug_error_union_type); |
| ... | ... | @@ -2314,10 +2314,10 @@ pub const Object = struct { |
| 2314 | 2314 | const name = try o.allocTypeName(ty); |
| 2315 | 2315 | defer gpa.free(name); |
| 2316 | 2316 | |
| 2317 | const error_size = Type.anyerror.abiSize(pt); | |
| 2318 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 2319 | const payload_size = payload_ty.abiSize(pt); | |
| 2320 | const payload_align = payload_ty.abiAlignment(pt); | |
| 2317 | const error_size = Type.anyerror.abiSize(zcu); | |
| 2318 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 2319 | const payload_size = payload_ty.abiSize(zcu); | |
| 2320 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 2321 | 2321 | |
| 2322 | 2322 | var error_index: u32 = undefined; |
| 2323 | 2323 | var payload_index: u32 = undefined; |
| ... | ... | @@ -2365,8 +2365,8 @@ pub const Object = struct { |
| 2365 | 2365 | o.debug_compile_unit, // Sope |
| 2366 | 2366 | 0, // Line |
| 2367 | 2367 | .none, // Underlying type |
| 2368 | ty.abiSize(pt) * 8, | |
| 2369 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2368 | ty.abiSize(zcu) * 8, | |
| 2369 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2370 | 2370 | try o.builder.debugTuple(&fields), |
| 2371 | 2371 | ); |
| 2372 | 2372 | |
| ... | ... | @@ -2393,8 +2393,8 @@ pub const Object = struct { |
| 2393 | 2393 | const info = Type.fromInterned(backing_int_ty).intInfo(zcu); |
| 2394 | 2394 | const builder_name = try o.builder.metadataString(name); |
| 2395 | 2395 | const debug_int_type = switch (info.signedness) { |
| 2396 | .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(pt) * 8), | |
| 2397 | .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(pt) * 8), | |
| 2396 | .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(zcu) * 8), | |
| 2397 | .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(zcu) * 8), | |
| 2398 | 2398 | }; |
| 2399 | 2399 | try o.debug_type_map.put(gpa, ty, debug_int_type); |
| 2400 | 2400 | return debug_int_type; |
| ... | ... | @@ -2414,10 +2414,10 @@ pub const Object = struct { |
| 2414 | 2414 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| 2415 | 2415 | |
| 2416 | 2416 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 2417 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | |
| 2417 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | |
| 2418 | 2418 | |
| 2419 | const field_size = Type.fromInterned(field_ty).abiSize(pt); | |
| 2420 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); | |
| 2419 | const field_size = Type.fromInterned(field_ty).abiSize(zcu); | |
| 2420 | const field_align = Type.fromInterned(field_ty).abiAlignment(zcu); | |
| 2421 | 2421 | const field_offset = field_align.forward(offset); |
| 2422 | 2422 | offset = field_offset + field_size; |
| 2423 | 2423 | |
| ... | ... | @@ -2445,8 +2445,8 @@ pub const Object = struct { |
| 2445 | 2445 | o.debug_compile_unit, // Scope |
| 2446 | 2446 | 0, // Line |
| 2447 | 2447 | .none, // Underlying type |
| 2448 | ty.abiSize(pt) * 8, | |
| 2449 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2448 | ty.abiSize(zcu) * 8, | |
| 2449 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2450 | 2450 | try o.builder.debugTuple(fields.items), |
| 2451 | 2451 | ); |
| 2452 | 2452 | |
| ... | ... | @@ -2472,7 +2472,7 @@ pub const Object = struct { |
| 2472 | 2472 | else => {}, |
| 2473 | 2473 | } |
| 2474 | 2474 | |
| 2475 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2475 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2476 | 2476 | const debug_struct_type = try o.makeEmptyNamespaceDebugType(ty); |
| 2477 | 2477 | try o.debug_type_map.put(gpa, ty, debug_struct_type); |
| 2478 | 2478 | return debug_struct_type; |
| ... | ... | @@ -2494,14 +2494,14 @@ pub const Object = struct { |
| 2494 | 2494 | var it = struct_type.iterateRuntimeOrder(ip); |
| 2495 | 2495 | while (it.next()) |field_index| { |
| 2496 | 2496 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 2497 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 2498 | const field_size = field_ty.abiSize(pt); | |
| 2497 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 2498 | const field_size = field_ty.abiSize(zcu); | |
| 2499 | 2499 | const field_align = pt.structFieldAlignment( |
| 2500 | 2500 | struct_type.fieldAlign(ip, field_index), |
| 2501 | 2501 | field_ty, |
| 2502 | 2502 | struct_type.layout, |
| 2503 | 2503 | ); |
| 2504 | const field_offset = ty.structFieldOffset(field_index, pt); | |
| 2504 | const field_offset = ty.structFieldOffset(field_index, zcu); | |
| 2505 | 2505 | |
| 2506 | 2506 | const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse |
| 2507 | 2507 | try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); |
| ... | ... | @@ -2524,8 +2524,8 @@ pub const Object = struct { |
| 2524 | 2524 | o.debug_compile_unit, // Scope |
| 2525 | 2525 | 0, // Line |
| 2526 | 2526 | .none, // Underlying type |
| 2527 | ty.abiSize(pt) * 8, | |
| 2528 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2527 | ty.abiSize(zcu) * 8, | |
| 2528 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2529 | 2529 | try o.builder.debugTuple(fields.items), |
| 2530 | 2530 | ); |
| 2531 | 2531 | |
| ... | ... | @@ -2543,7 +2543,7 @@ pub const Object = struct { |
| 2543 | 2543 | |
| 2544 | 2544 | const union_type = ip.loadUnionType(ty.toIntern()); |
| 2545 | 2545 | if (!union_type.haveFieldTypes(ip) or |
| 2546 | !ty.hasRuntimeBitsIgnoreComptime(pt) or | |
| 2546 | !ty.hasRuntimeBitsIgnoreComptime(zcu) or | |
| 2547 | 2547 | !union_type.haveLayout(ip)) |
| 2548 | 2548 | { |
| 2549 | 2549 | const debug_union_type = try o.makeEmptyNamespaceDebugType(ty); |
| ... | ... | @@ -2551,7 +2551,7 @@ pub const Object = struct { |
| 2551 | 2551 | return debug_union_type; |
| 2552 | 2552 | } |
| 2553 | 2553 | |
| 2554 | const layout = pt.getUnionLayout(union_type); | |
| 2554 | const layout = Type.getUnionLayout(union_type, zcu); | |
| 2555 | 2555 | |
| 2556 | 2556 | const debug_fwd_ref = try o.builder.debugForwardReference(); |
| 2557 | 2557 | |
| ... | ... | @@ -2565,8 +2565,8 @@ pub const Object = struct { |
| 2565 | 2565 | o.debug_compile_unit, // Scope |
| 2566 | 2566 | 0, // Line |
| 2567 | 2567 | .none, // Underlying type |
| 2568 | ty.abiSize(pt) * 8, | |
| 2569 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2568 | ty.abiSize(zcu) * 8, | |
| 2569 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2570 | 2570 | try o.builder.debugTuple( |
| 2571 | 2571 | &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))}, |
| 2572 | 2572 | ), |
| ... | ... | @@ -2593,12 +2593,12 @@ pub const Object = struct { |
| 2593 | 2593 | |
| 2594 | 2594 | for (0..tag_type.names.len) |field_index| { |
| 2595 | 2595 | const field_ty = union_type.field_types.get(ip)[field_index]; |
| 2596 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 2596 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 2597 | 2597 | |
| 2598 | const field_size = Type.fromInterned(field_ty).abiSize(pt); | |
| 2598 | const field_size = Type.fromInterned(field_ty).abiSize(zcu); | |
| 2599 | 2599 | const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) { |
| 2600 | 2600 | .@"packed" => .none, |
| 2601 | .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)), | |
| 2601 | .auto, .@"extern" => Type.unionFieldNormalAlignment(union_type, @intCast(field_index), zcu), | |
| 2602 | 2602 | }; |
| 2603 | 2603 | |
| 2604 | 2604 | const field_name = tag_type.names.get(ip)[field_index]; |
| ... | ... | @@ -2627,8 +2627,8 @@ pub const Object = struct { |
| 2627 | 2627 | o.debug_compile_unit, // Scope |
| 2628 | 2628 | 0, // Line |
| 2629 | 2629 | .none, // Underlying type |
| 2630 | ty.abiSize(pt) * 8, | |
| 2631 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2630 | ty.abiSize(zcu) * 8, | |
| 2631 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2632 | 2632 | try o.builder.debugTuple(fields.items), |
| 2633 | 2633 | ); |
| 2634 | 2634 | |
| ... | ... | @@ -2686,8 +2686,8 @@ pub const Object = struct { |
| 2686 | 2686 | o.debug_compile_unit, // Scope |
| 2687 | 2687 | 0, // Line |
| 2688 | 2688 | .none, // Underlying type |
| 2689 | ty.abiSize(pt) * 8, | |
| 2690 | (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, | |
| 2689 | ty.abiSize(zcu) * 8, | |
| 2690 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | |
| 2691 | 2691 | try o.builder.debugTuple(&full_fields), |
| 2692 | 2692 | ); |
| 2693 | 2693 | |
| ... | ... | @@ -2708,8 +2708,8 @@ pub const Object = struct { |
| 2708 | 2708 | try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len); |
| 2709 | 2709 | |
| 2710 | 2710 | // Return type goes first. |
| 2711 | if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(pt)) { | |
| 2712 | const sret = firstParamSRet(fn_info, pt, target); | |
| 2711 | if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 2712 | const sret = firstParamSRet(fn_info, zcu, target); | |
| 2713 | 2713 | const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); |
| 2714 | 2714 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty)); |
| 2715 | 2715 | |
| ... | ... | @@ -2730,9 +2730,9 @@ pub const Object = struct { |
| 2730 | 2730 | |
| 2731 | 2731 | for (0..fn_info.param_types.len) |i| { |
| 2732 | 2732 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]); |
| 2733 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 2733 | if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 2734 | 2734 | |
| 2735 | if (isByRef(param_ty, pt)) { | |
| 2735 | if (isByRef(param_ty, zcu)) { | |
| 2736 | 2736 | const ptr_ty = try pt.singleMutPtrType(param_ty); |
| 2737 | 2737 | debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); |
| 2738 | 2738 | } else { |
| ... | ... | @@ -2842,7 +2842,7 @@ pub const Object = struct { |
| 2842 | 2842 | |
| 2843 | 2843 | const fn_info = zcu.typeToFunc(ty).?; |
| 2844 | 2844 | const target = owner_mod.resolved_target.result; |
| 2845 | const sret = firstParamSRet(fn_info, pt, target); | |
| 2845 | const sret = firstParamSRet(fn_info, zcu, target); | |
| 2846 | 2846 | |
| 2847 | 2847 | const is_extern, const lib_name = switch (ip.indexToKey(val.toIntern())) { |
| 2848 | 2848 | .variable => |variable| .{ false, variable.lib_name }, |
| ... | ... | @@ -2934,14 +2934,14 @@ pub const Object = struct { |
| 2934 | 2934 | .byval => { |
| 2935 | 2935 | const param_index = it.zig_index - 1; |
| 2936 | 2936 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 2937 | if (!isByRef(param_ty, pt)) { | |
| 2937 | if (!isByRef(param_ty, zcu)) { | |
| 2938 | 2938 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 2939 | 2939 | } |
| 2940 | 2940 | }, |
| 2941 | 2941 | .byref => { |
| 2942 | 2942 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 2943 | 2943 | const param_llvm_ty = try o.lowerType(param_ty); |
| 2944 | const alignment = param_ty.abiAlignment(pt); | |
| 2944 | const alignment = param_ty.abiAlignment(zcu); | |
| 2945 | 2945 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty); |
| 2946 | 2946 | }, |
| 2947 | 2947 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| ... | ... | @@ -3042,8 +3042,8 @@ pub const Object = struct { |
| 3042 | 3042 | } |
| 3043 | 3043 | errdefer assert(o.uav_map.remove(uav)); |
| 3044 | 3044 | |
| 3045 | const mod = o.pt.zcu; | |
| 3046 | const decl_ty = mod.intern_pool.typeOf(uav); | |
| 3045 | const zcu = o.pt.zcu; | |
| 3046 | const decl_ty = zcu.intern_pool.typeOf(uav); | |
| 3047 | 3047 | |
| 3048 | 3048 | const variable_index = try o.builder.addVariable( |
| 3049 | 3049 | try o.builder.strtabStringFmt("__anon_{d}", .{@intFromEnum(uav)}), |
| ... | ... | @@ -3106,9 +3106,9 @@ pub const Object = struct { |
| 3106 | 3106 | |
| 3107 | 3107 | fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type { |
| 3108 | 3108 | const pt = o.pt; |
| 3109 | const mod = pt.zcu; | |
| 3110 | const target = mod.getTarget(); | |
| 3111 | const ip = &mod.intern_pool; | |
| 3109 | const zcu = pt.zcu; | |
| 3110 | const target = zcu.getTarget(); | |
| 3111 | const ip = &zcu.intern_pool; | |
| 3112 | 3112 | return switch (t.toIntern()) { |
| 3113 | 3113 | .u0_type, .i0_type => unreachable, |
| 3114 | 3114 | inline .u1_type, |
| ... | ... | @@ -3230,16 +3230,16 @@ pub const Object = struct { |
| 3230 | 3230 | ), |
| 3231 | 3231 | .opt_type => |child_ty| { |
| 3232 | 3232 | // Must stay in sync with `opt_payload` logic in `lowerPtr`. |
| 3233 | if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(pt)) return .i8; | |
| 3233 | if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(zcu)) return .i8; | |
| 3234 | 3234 | |
| 3235 | 3235 | const payload_ty = try o.lowerType(Type.fromInterned(child_ty)); |
| 3236 | if (t.optionalReprIsPayload(mod)) return payload_ty; | |
| 3236 | if (t.optionalReprIsPayload(zcu)) return payload_ty; | |
| 3237 | 3237 | |
| 3238 | 3238 | comptime assert(optional_layout_version == 3); |
| 3239 | 3239 | var fields: [3]Builder.Type = .{ payload_ty, .i8, undefined }; |
| 3240 | 3240 | var fields_len: usize = 2; |
| 3241 | const offset = Type.fromInterned(child_ty).abiSize(pt) + 1; | |
| 3242 | const abi_size = t.abiSize(pt); | |
| 3241 | const offset = Type.fromInterned(child_ty).abiSize(zcu) + 1; | |
| 3242 | const abi_size = t.abiSize(zcu); | |
| 3243 | 3243 | const padding_len = abi_size - offset; |
| 3244 | 3244 | if (padding_len > 0) { |
| 3245 | 3245 | fields[2] = try o.builder.arrayType(padding_len, .i8); |
| ... | ... | @@ -3252,16 +3252,16 @@ pub const Object = struct { |
| 3252 | 3252 | // Must stay in sync with `codegen.errUnionPayloadOffset`. |
| 3253 | 3253 | // See logic in `lowerPtr`. |
| 3254 | 3254 | const error_type = try o.errorIntType(); |
| 3255 | if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(pt)) | |
| 3255 | if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(zcu)) | |
| 3256 | 3256 | return error_type; |
| 3257 | 3257 | const payload_type = try o.lowerType(Type.fromInterned(error_union_type.payload_type)); |
| 3258 | 3258 | const err_int_ty = try o.pt.errorIntType(); |
| 3259 | 3259 | |
| 3260 | const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(pt); | |
| 3261 | const error_align = err_int_ty.abiAlignment(pt); | |
| 3260 | const payload_align = Type.fromInterned(error_union_type.payload_type).abiAlignment(zcu); | |
| 3261 | const error_align = err_int_ty.abiAlignment(zcu); | |
| 3262 | 3262 | |
| 3263 | const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(pt); | |
| 3264 | const error_size = err_int_ty.abiSize(pt); | |
| 3263 | const payload_size = Type.fromInterned(error_union_type.payload_type).abiSize(zcu); | |
| 3264 | const error_size = err_int_ty.abiSize(zcu); | |
| 3265 | 3265 | |
| 3266 | 3266 | var fields: [3]Builder.Type = undefined; |
| 3267 | 3267 | var fields_len: usize = 2; |
| ... | ... | @@ -3320,7 +3320,7 @@ pub const Object = struct { |
| 3320 | 3320 | field_ty, |
| 3321 | 3321 | struct_type.layout, |
| 3322 | 3322 | ); |
| 3323 | const field_ty_align = field_ty.abiAlignment(pt); | |
| 3323 | const field_ty_align = field_ty.abiAlignment(zcu); | |
| 3324 | 3324 | if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed"; |
| 3325 | 3325 | big_align = big_align.max(field_align); |
| 3326 | 3326 | const prev_offset = offset; |
| ... | ... | @@ -3332,7 +3332,7 @@ pub const Object = struct { |
| 3332 | 3332 | try o.builder.arrayType(padding_len, .i8), |
| 3333 | 3333 | ); |
| 3334 | 3334 | |
| 3335 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3335 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3336 | 3336 | // This is a zero-bit field. If there are runtime bits after this field, |
| 3337 | 3337 | // map to the next LLVM field (which we know exists): otherwise, don't |
| 3338 | 3338 | // map the field, indicating it's at the end of the struct. |
| ... | ... | @@ -3351,7 +3351,7 @@ pub const Object = struct { |
| 3351 | 3351 | }, @intCast(llvm_field_types.items.len)); |
| 3352 | 3352 | try llvm_field_types.append(o.gpa, try o.lowerType(field_ty)); |
| 3353 | 3353 | |
| 3354 | offset += field_ty.abiSize(pt); | |
| 3354 | offset += field_ty.abiSize(zcu); | |
| 3355 | 3355 | } |
| 3356 | 3356 | { |
| 3357 | 3357 | const prev_offset = offset; |
| ... | ... | @@ -3384,7 +3384,7 @@ pub const Object = struct { |
| 3384 | 3384 | var offset: u64 = 0; |
| 3385 | 3385 | var big_align: InternPool.Alignment = .none; |
| 3386 | 3386 | |
| 3387 | const struct_size = t.abiSize(pt); | |
| 3387 | const struct_size = t.abiSize(zcu); | |
| 3388 | 3388 | |
| 3389 | 3389 | for ( |
| 3390 | 3390 | anon_struct_type.types.get(ip), |
| ... | ... | @@ -3393,7 +3393,7 @@ pub const Object = struct { |
| 3393 | 3393 | ) |field_ty, field_val, field_index| { |
| 3394 | 3394 | if (field_val != .none) continue; |
| 3395 | 3395 | |
| 3396 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); | |
| 3396 | const field_align = Type.fromInterned(field_ty).abiAlignment(zcu); | |
| 3397 | 3397 | big_align = big_align.max(field_align); |
| 3398 | 3398 | const prev_offset = offset; |
| 3399 | 3399 | offset = field_align.forward(offset); |
| ... | ... | @@ -3403,7 +3403,7 @@ pub const Object = struct { |
| 3403 | 3403 | o.gpa, |
| 3404 | 3404 | try o.builder.arrayType(padding_len, .i8), |
| 3405 | 3405 | ); |
| 3406 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3406 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3407 | 3407 | // This is a zero-bit field. If there are runtime bits after this field, |
| 3408 | 3408 | // map to the next LLVM field (which we know exists): otherwise, don't |
| 3409 | 3409 | // map the field, indicating it's at the end of the struct. |
| ... | ... | @@ -3421,7 +3421,7 @@ pub const Object = struct { |
| 3421 | 3421 | }, @intCast(llvm_field_types.items.len)); |
| 3422 | 3422 | try llvm_field_types.append(o.gpa, try o.lowerType(Type.fromInterned(field_ty))); |
| 3423 | 3423 | |
| 3424 | offset += Type.fromInterned(field_ty).abiSize(pt); | |
| 3424 | offset += Type.fromInterned(field_ty).abiSize(zcu); | |
| 3425 | 3425 | } |
| 3426 | 3426 | { |
| 3427 | 3427 | const prev_offset = offset; |
| ... | ... | @@ -3438,10 +3438,10 @@ pub const Object = struct { |
| 3438 | 3438 | if (o.type_map.get(t.toIntern())) |value| return value; |
| 3439 | 3439 | |
| 3440 | 3440 | const union_obj = ip.loadUnionType(t.toIntern()); |
| 3441 | const layout = pt.getUnionLayout(union_obj); | |
| 3441 | const layout = Type.getUnionLayout(union_obj, zcu); | |
| 3442 | 3442 | |
| 3443 | 3443 | if (union_obj.flagsUnordered(ip).layout == .@"packed") { |
| 3444 | const int_ty = try o.builder.intType(@intCast(t.bitSize(pt))); | |
| 3444 | const int_ty = try o.builder.intType(@intCast(t.bitSize(zcu))); | |
| 3445 | 3445 | try o.type_map.put(o.gpa, t.toIntern(), int_ty); |
| 3446 | 3446 | return int_ty; |
| 3447 | 3447 | } |
| ... | ... | @@ -3547,32 +3547,32 @@ pub const Object = struct { |
| 3547 | 3547 | /// There are other similar cases handled here as well. |
| 3548 | 3548 | fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!Builder.Type { |
| 3549 | 3549 | const pt = o.pt; |
| 3550 | const mod = pt.zcu; | |
| 3551 | const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) { | |
| 3550 | const zcu = pt.zcu; | |
| 3551 | const lower_elem_ty = switch (elem_ty.zigTypeTag(zcu)) { | |
| 3552 | 3552 | .Opaque => true, |
| 3553 | .Fn => !mod.typeToFunc(elem_ty).?.is_generic, | |
| 3554 | .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(pt), | |
| 3555 | else => elem_ty.hasRuntimeBitsIgnoreComptime(pt), | |
| 3553 | .Fn => !zcu.typeToFunc(elem_ty).?.is_generic, | |
| 3554 | .Array => elem_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu), | |
| 3555 | else => elem_ty.hasRuntimeBitsIgnoreComptime(zcu), | |
| 3556 | 3556 | }; |
| 3557 | 3557 | return if (lower_elem_ty) try o.lowerType(elem_ty) else .i8; |
| 3558 | 3558 | } |
| 3559 | 3559 | |
| 3560 | 3560 | fn lowerTypeFn(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 3561 | 3561 | const pt = o.pt; |
| 3562 | const mod = pt.zcu; | |
| 3563 | const ip = &mod.intern_pool; | |
| 3564 | const target = mod.getTarget(); | |
| 3562 | const zcu = pt.zcu; | |
| 3563 | const ip = &zcu.intern_pool; | |
| 3564 | const target = zcu.getTarget(); | |
| 3565 | 3565 | const ret_ty = try lowerFnRetTy(o, fn_info); |
| 3566 | 3566 | |
| 3567 | 3567 | var llvm_params = std.ArrayListUnmanaged(Builder.Type){}; |
| 3568 | 3568 | defer llvm_params.deinit(o.gpa); |
| 3569 | 3569 | |
| 3570 | if (firstParamSRet(fn_info, pt, target)) { | |
| 3570 | if (firstParamSRet(fn_info, zcu, target)) { | |
| 3571 | 3571 | try llvm_params.append(o.gpa, .ptr); |
| 3572 | 3572 | } |
| 3573 | 3573 | |
| 3574 | if (Type.fromInterned(fn_info.return_type).isError(mod) and | |
| 3575 | mod.comp.config.any_error_tracing) | |
| 3574 | if (Type.fromInterned(fn_info.return_type).isError(zcu) and | |
| 3575 | zcu.comp.config.any_error_tracing) | |
| 3576 | 3576 | { |
| 3577 | 3577 | const ptr_ty = try pt.singleMutPtrType(try o.getStackTraceType()); |
| 3578 | 3578 | try llvm_params.append(o.gpa, try o.lowerType(ptr_ty)); |
| ... | ... | @@ -3591,13 +3591,13 @@ pub const Object = struct { |
| 3591 | 3591 | .abi_sized_int => { |
| 3592 | 3592 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 3593 | 3593 | try llvm_params.append(o.gpa, try o.builder.intType( |
| 3594 | @intCast(param_ty.abiSize(pt) * 8), | |
| 3594 | @intCast(param_ty.abiSize(zcu) * 8), | |
| 3595 | 3595 | )); |
| 3596 | 3596 | }, |
| 3597 | 3597 | .slice => { |
| 3598 | 3598 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 3599 | 3599 | try llvm_params.appendSlice(o.gpa, &.{ |
| 3600 | try o.builder.ptrType(toLlvmAddressSpace(param_ty.ptrAddressSpace(mod), target)), | |
| 3600 | try o.builder.ptrType(toLlvmAddressSpace(param_ty.ptrAddressSpace(zcu), target)), | |
| 3601 | 3601 | try o.lowerType(Type.usize), |
| 3602 | 3602 | }); |
| 3603 | 3603 | }, |
| ... | ... | @@ -3609,7 +3609,7 @@ pub const Object = struct { |
| 3609 | 3609 | }, |
| 3610 | 3610 | .float_array => |count| { |
| 3611 | 3611 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 3612 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?); | |
| 3612 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?); | |
| 3613 | 3613 | try llvm_params.append(o.gpa, try o.builder.arrayType(count, float_ty)); |
| 3614 | 3614 | }, |
| 3615 | 3615 | .i32_array, .i64_array => |arr_len| { |
| ... | ... | @@ -3630,14 +3630,14 @@ pub const Object = struct { |
| 3630 | 3630 | |
| 3631 | 3631 | fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant { |
| 3632 | 3632 | const pt = o.pt; |
| 3633 | const mod = pt.zcu; | |
| 3634 | const ip = &mod.intern_pool; | |
| 3635 | const target = mod.getTarget(); | |
| 3633 | const zcu = pt.zcu; | |
| 3634 | const ip = &zcu.intern_pool; | |
| 3635 | const target = zcu.getTarget(); | |
| 3636 | 3636 | |
| 3637 | 3637 | const val = Value.fromInterned(arg_val); |
| 3638 | 3638 | const val_key = ip.indexToKey(val.toIntern()); |
| 3639 | 3639 | |
| 3640 | if (val.isUndefDeep(mod)) return o.builder.undefConst(llvm_int_ty); | |
| 3640 | if (val.isUndefDeep(zcu)) return o.builder.undefConst(llvm_int_ty); | |
| 3641 | 3641 | |
| 3642 | 3642 | const ty = Type.fromInterned(val_key.typeOf()); |
| 3643 | 3643 | switch (val_key) { |
| ... | ... | @@ -3661,7 +3661,7 @@ pub const Object = struct { |
| 3661 | 3661 | var running_int = try o.builder.intConst(llvm_int_ty, 0); |
| 3662 | 3662 | var running_bits: u16 = 0; |
| 3663 | 3663 | for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| { |
| 3664 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 3664 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 3665 | 3665 | |
| 3666 | 3666 | const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits); |
| 3667 | 3667 | const field_val = try o.lowerValueToInt(llvm_int_ty, (try val.fieldValue(pt, field_index)).toIntern()); |
| ... | ... | @@ -3669,7 +3669,7 @@ pub const Object = struct { |
| 3669 | 3669 | |
| 3670 | 3670 | running_int = try o.builder.binConst(.xor, running_int, shifted); |
| 3671 | 3671 | |
| 3672 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt)); | |
| 3672 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu)); | |
| 3673 | 3673 | running_bits += ty_bit_size; |
| 3674 | 3674 | } |
| 3675 | 3675 | return running_int; |
| ... | ... | @@ -3678,10 +3678,10 @@ pub const Object = struct { |
| 3678 | 3678 | else => unreachable, |
| 3679 | 3679 | }, |
| 3680 | 3680 | .un => |un| { |
| 3681 | const layout = ty.unionGetLayout(pt); | |
| 3681 | const layout = ty.unionGetLayout(zcu); | |
| 3682 | 3682 | if (layout.payload_size == 0) return o.lowerValue(un.tag); |
| 3683 | 3683 | |
| 3684 | const union_obj = mod.typeToUnion(ty).?; | |
| 3684 | const union_obj = zcu.typeToUnion(ty).?; | |
| 3685 | 3685 | const container_layout = union_obj.flagsUnordered(ip).layout; |
| 3686 | 3686 | |
| 3687 | 3687 | assert(container_layout == .@"packed"); |
| ... | ... | @@ -3694,9 +3694,9 @@ pub const Object = struct { |
| 3694 | 3694 | need_unnamed = true; |
| 3695 | 3695 | return union_val; |
| 3696 | 3696 | } |
| 3697 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | |
| 3697 | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | |
| 3698 | 3698 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 3699 | if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(llvm_int_ty, 0); | |
| 3699 | if (!field_ty.hasRuntimeBits(zcu)) return o.builder.intConst(llvm_int_ty, 0); | |
| 3700 | 3700 | return o.lowerValueToInt(llvm_int_ty, un.val); |
| 3701 | 3701 | }, |
| 3702 | 3702 | .simple_value => |simple_value| switch (simple_value) { |
| ... | ... | @@ -3710,7 +3710,7 @@ pub const Object = struct { |
| 3710 | 3710 | .opt => {}, // pointer like optional expected |
| 3711 | 3711 | else => unreachable, |
| 3712 | 3712 | } |
| 3713 | const bits = ty.bitSize(pt); | |
| 3713 | const bits = ty.bitSize(zcu); | |
| 3714 | 3714 | const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8); |
| 3715 | 3715 | |
| 3716 | 3716 | var stack = std.heap.stackFallback(32, o.gpa); |
| ... | ... | @@ -3743,14 +3743,14 @@ pub const Object = struct { |
| 3743 | 3743 | |
| 3744 | 3744 | fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant { |
| 3745 | 3745 | const pt = o.pt; |
| 3746 | const mod = pt.zcu; | |
| 3747 | const ip = &mod.intern_pool; | |
| 3748 | const target = mod.getTarget(); | |
| 3746 | const zcu = pt.zcu; | |
| 3747 | const ip = &zcu.intern_pool; | |
| 3748 | const target = zcu.getTarget(); | |
| 3749 | 3749 | |
| 3750 | 3750 | const val = Value.fromInterned(arg_val); |
| 3751 | 3751 | const val_key = ip.indexToKey(val.toIntern()); |
| 3752 | 3752 | |
| 3753 | if (val.isUndefDeep(mod)) { | |
| 3753 | if (val.isUndefDeep(zcu)) { | |
| 3754 | 3754 | return o.builder.undefConst(try o.lowerType(Type.fromInterned(val_key.typeOf()))); |
| 3755 | 3755 | } |
| 3756 | 3756 | |
| ... | ... | @@ -3800,7 +3800,7 @@ pub const Object = struct { |
| 3800 | 3800 | }, |
| 3801 | 3801 | .int => { |
| 3802 | 3802 | var bigint_space: Value.BigIntSpace = undefined; |
| 3803 | const bigint = val.toBigInt(&bigint_space, pt); | |
| 3803 | const bigint = val.toBigInt(&bigint_space, zcu); | |
| 3804 | 3804 | return lowerBigInt(o, ty, bigint); |
| 3805 | 3805 | }, |
| 3806 | 3806 | .err => |err| { |
| ... | ... | @@ -3811,20 +3811,20 @@ pub const Object = struct { |
| 3811 | 3811 | .error_union => |error_union| { |
| 3812 | 3812 | const err_val = switch (error_union.val) { |
| 3813 | 3813 | .err_name => |err_name| try pt.intern(.{ .err = .{ |
| 3814 | .ty = ty.errorUnionSet(mod).toIntern(), | |
| 3814 | .ty = ty.errorUnionSet(zcu).toIntern(), | |
| 3815 | 3815 | .name = err_name, |
| 3816 | 3816 | } }), |
| 3817 | 3817 | .payload => (try pt.intValue(try pt.errorIntType(), 0)).toIntern(), |
| 3818 | 3818 | }; |
| 3819 | 3819 | const err_int_ty = try pt.errorIntType(); |
| 3820 | const payload_type = ty.errorUnionPayload(mod); | |
| 3821 | if (!payload_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3820 | const payload_type = ty.errorUnionPayload(zcu); | |
| 3821 | if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3822 | 3822 | // We use the error type directly as the type. |
| 3823 | 3823 | return o.lowerValue(err_val); |
| 3824 | 3824 | } |
| 3825 | 3825 | |
| 3826 | const payload_align = payload_type.abiAlignment(pt); | |
| 3827 | const error_align = err_int_ty.abiAlignment(pt); | |
| 3826 | const payload_align = payload_type.abiAlignment(zcu); | |
| 3827 | const error_align = err_int_ty.abiAlignment(zcu); | |
| 3828 | 3828 | const llvm_error_value = try o.lowerValue(err_val); |
| 3829 | 3829 | const llvm_payload_value = try o.lowerValue(switch (error_union.val) { |
| 3830 | 3830 | .err_name => try pt.intern(.{ .undef = payload_type.toIntern() }), |
| ... | ... | @@ -3858,16 +3858,16 @@ pub const Object = struct { |
| 3858 | 3858 | .enum_tag => |enum_tag| o.lowerValue(enum_tag.int), |
| 3859 | 3859 | .float => switch (ty.floatBits(target)) { |
| 3860 | 3860 | 16 => if (backendSupportsF16(target)) |
| 3861 | try o.builder.halfConst(val.toFloat(f16, pt)) | |
| 3861 | try o.builder.halfConst(val.toFloat(f16, zcu)) | |
| 3862 | 3862 | else |
| 3863 | try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, pt)))), | |
| 3864 | 32 => try o.builder.floatConst(val.toFloat(f32, pt)), | |
| 3865 | 64 => try o.builder.doubleConst(val.toFloat(f64, pt)), | |
| 3863 | try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, zcu)))), | |
| 3864 | 32 => try o.builder.floatConst(val.toFloat(f32, zcu)), | |
| 3865 | 64 => try o.builder.doubleConst(val.toFloat(f64, zcu)), | |
| 3866 | 3866 | 80 => if (backendSupportsF80(target)) |
| 3867 | try o.builder.x86_fp80Const(val.toFloat(f80, pt)) | |
| 3867 | try o.builder.x86_fp80Const(val.toFloat(f80, zcu)) | |
| 3868 | 3868 | else |
| 3869 | try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, pt)))), | |
| 3870 | 128 => try o.builder.fp128Const(val.toFloat(f128, pt)), | |
| 3869 | try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, zcu)))), | |
| 3870 | 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)), | |
| 3871 | 3871 | else => unreachable, |
| 3872 | 3872 | }, |
| 3873 | 3873 | .ptr => try o.lowerPtr(arg_val, 0), |
| ... | ... | @@ -3877,14 +3877,14 @@ pub const Object = struct { |
| 3877 | 3877 | }), |
| 3878 | 3878 | .opt => |opt| { |
| 3879 | 3879 | comptime assert(optional_layout_version == 3); |
| 3880 | const payload_ty = ty.optionalChild(mod); | |
| 3880 | const payload_ty = ty.optionalChild(zcu); | |
| 3881 | 3881 | |
| 3882 | 3882 | const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none)); |
| 3883 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 3883 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 3884 | 3884 | return non_null_bit; |
| 3885 | 3885 | } |
| 3886 | 3886 | const llvm_ty = try o.lowerType(ty); |
| 3887 | if (ty.optionalReprIsPayload(mod)) return switch (opt.val) { | |
| 3887 | if (ty.optionalReprIsPayload(zcu)) return switch (opt.val) { | |
| 3888 | 3888 | .none => switch (llvm_ty.tag(&o.builder)) { |
| 3889 | 3889 | .integer => try o.builder.intConst(llvm_ty, 0), |
| 3890 | 3890 | .pointer => try o.builder.nullConst(llvm_ty), |
| ... | ... | @@ -3893,7 +3893,7 @@ pub const Object = struct { |
| 3893 | 3893 | }, |
| 3894 | 3894 | else => |payload| try o.lowerValue(payload), |
| 3895 | 3895 | }; |
| 3896 | assert(payload_ty.zigTypeTag(mod) != .Fn); | |
| 3896 | assert(payload_ty.zigTypeTag(zcu) != .Fn); | |
| 3897 | 3897 | |
| 3898 | 3898 | var fields: [3]Builder.Type = undefined; |
| 3899 | 3899 | var vals: [3]Builder.Constant = undefined; |
| ... | ... | @@ -4047,9 +4047,9 @@ pub const Object = struct { |
| 4047 | 4047 | 0.., |
| 4048 | 4048 | ) |field_ty, field_val, field_index| { |
| 4049 | 4049 | if (field_val != .none) continue; |
| 4050 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 4050 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 4051 | 4051 | |
| 4052 | const field_align = Type.fromInterned(field_ty).abiAlignment(pt); | |
| 4052 | const field_align = Type.fromInterned(field_ty).abiAlignment(zcu); | |
| 4053 | 4053 | big_align = big_align.max(field_align); |
| 4054 | 4054 | const prev_offset = offset; |
| 4055 | 4055 | offset = field_align.forward(offset); |
| ... | ... | @@ -4071,7 +4071,7 @@ pub const Object = struct { |
| 4071 | 4071 | need_unnamed = true; |
| 4072 | 4072 | llvm_index += 1; |
| 4073 | 4073 | |
| 4074 | offset += Type.fromInterned(field_ty).abiSize(pt); | |
| 4074 | offset += Type.fromInterned(field_ty).abiSize(zcu); | |
| 4075 | 4075 | } |
| 4076 | 4076 | { |
| 4077 | 4077 | const prev_offset = offset; |
| ... | ... | @@ -4098,7 +4098,7 @@ pub const Object = struct { |
| 4098 | 4098 | if (struct_type.layout == .@"packed") { |
| 4099 | 4099 | comptime assert(Type.packed_struct_layout_version == 2); |
| 4100 | 4100 | |
| 4101 | const bits = ty.bitSize(pt); | |
| 4101 | const bits = ty.bitSize(zcu); | |
| 4102 | 4102 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); |
| 4103 | 4103 | |
| 4104 | 4104 | return o.lowerValueToInt(llvm_int_ty, arg_val); |
| ... | ... | @@ -4147,7 +4147,7 @@ pub const Object = struct { |
| 4147 | 4147 | llvm_index += 1; |
| 4148 | 4148 | } |
| 4149 | 4149 | |
| 4150 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4150 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4151 | 4151 | // This is a zero-bit field - we only needed it for the alignment. |
| 4152 | 4152 | continue; |
| 4153 | 4153 | } |
| ... | ... | @@ -4160,7 +4160,7 @@ pub const Object = struct { |
| 4160 | 4160 | need_unnamed = true; |
| 4161 | 4161 | llvm_index += 1; |
| 4162 | 4162 | |
| 4163 | offset += field_ty.abiSize(pt); | |
| 4163 | offset += field_ty.abiSize(zcu); | |
| 4164 | 4164 | } |
| 4165 | 4165 | { |
| 4166 | 4166 | const prev_offset = offset; |
| ... | ... | @@ -4184,19 +4184,19 @@ pub const Object = struct { |
| 4184 | 4184 | }, |
| 4185 | 4185 | .un => |un| { |
| 4186 | 4186 | const union_ty = try o.lowerType(ty); |
| 4187 | const layout = ty.unionGetLayout(pt); | |
| 4187 | const layout = ty.unionGetLayout(zcu); | |
| 4188 | 4188 | if (layout.payload_size == 0) return o.lowerValue(un.tag); |
| 4189 | 4189 | |
| 4190 | const union_obj = mod.typeToUnion(ty).?; | |
| 4190 | const union_obj = zcu.typeToUnion(ty).?; | |
| 4191 | 4191 | const container_layout = union_obj.flagsUnordered(ip).layout; |
| 4192 | 4192 | |
| 4193 | 4193 | var need_unnamed = false; |
| 4194 | 4194 | const payload = if (un.tag != .none) p: { |
| 4195 | const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | |
| 4195 | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | |
| 4196 | 4196 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 4197 | 4197 | if (container_layout == .@"packed") { |
| 4198 | if (!field_ty.hasRuntimeBits(pt)) return o.builder.intConst(union_ty, 0); | |
| 4199 | const bits = ty.bitSize(pt); | |
| 4198 | if (!field_ty.hasRuntimeBits(zcu)) return o.builder.intConst(union_ty, 0); | |
| 4199 | const bits = ty.bitSize(zcu); | |
| 4200 | 4200 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); |
| 4201 | 4201 | |
| 4202 | 4202 | return o.lowerValueToInt(llvm_int_ty, arg_val); |
| ... | ... | @@ -4208,7 +4208,7 @@ pub const Object = struct { |
| 4208 | 4208 | // must pointer cast to the expected type before accessing the union. |
| 4209 | 4209 | need_unnamed = layout.most_aligned_field != field_index; |
| 4210 | 4210 | |
| 4211 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4211 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4212 | 4212 | const padding_len = layout.payload_size; |
| 4213 | 4213 | break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8)); |
| 4214 | 4214 | } |
| ... | ... | @@ -4217,7 +4217,7 @@ pub const Object = struct { |
| 4217 | 4217 | if (payload_ty != union_ty.structFields(&o.builder)[ |
| 4218 | 4218 | @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)) |
| 4219 | 4219 | ]) need_unnamed = true; |
| 4220 | const field_size = field_ty.abiSize(pt); | |
| 4220 | const field_size = field_ty.abiSize(zcu); | |
| 4221 | 4221 | if (field_size == layout.payload_size) break :p payload; |
| 4222 | 4222 | const padding_len = layout.payload_size - field_size; |
| 4223 | 4223 | const padding_ty = try o.builder.arrayType(padding_len, .i8); |
| ... | ... | @@ -4228,7 +4228,7 @@ pub const Object = struct { |
| 4228 | 4228 | } else p: { |
| 4229 | 4229 | assert(layout.tag_size == 0); |
| 4230 | 4230 | if (container_layout == .@"packed") { |
| 4231 | const bits = ty.bitSize(pt); | |
| 4231 | const bits = ty.bitSize(zcu); | |
| 4232 | 4232 | const llvm_int_ty = try o.builder.intType(@intCast(bits)); |
| 4233 | 4233 | |
| 4234 | 4234 | return o.lowerValueToInt(llvm_int_ty, arg_val); |
| ... | ... | @@ -4275,8 +4275,8 @@ pub const Object = struct { |
| 4275 | 4275 | ty: Type, |
| 4276 | 4276 | bigint: std.math.big.int.Const, |
| 4277 | 4277 | ) Allocator.Error!Builder.Constant { |
| 4278 | const mod = o.pt.zcu; | |
| 4279 | return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint); | |
| 4278 | const zcu = o.pt.zcu; | |
| 4279 | return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(zcu).bits), bigint); | |
| 4280 | 4280 | } |
| 4281 | 4281 | |
| 4282 | 4282 | fn lowerPtr( |
| ... | ... | @@ -4310,7 +4310,7 @@ pub const Object = struct { |
| 4310 | 4310 | eu_ptr, |
| 4311 | 4311 | offset + @import("../codegen.zig").errUnionPayloadOffset( |
| 4312 | 4312 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu), |
| 4313 | pt, | |
| 4313 | zcu, | |
| 4314 | 4314 | ), |
| 4315 | 4315 | ), |
| 4316 | 4316 | .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset), |
| ... | ... | @@ -4326,7 +4326,7 @@ pub const Object = struct { |
| 4326 | 4326 | }; |
| 4327 | 4327 | }, |
| 4328 | 4328 | .Struct, .Union => switch (agg_ty.containerLayout(zcu)) { |
| 4329 | .auto => agg_ty.structFieldOffset(@intCast(field.index), pt), | |
| 4329 | .auto => agg_ty.structFieldOffset(@intCast(field.index), zcu), | |
| 4330 | 4330 | .@"extern", .@"packed" => unreachable, |
| 4331 | 4331 | }, |
| 4332 | 4332 | else => unreachable, |
| ... | ... | @@ -4344,11 +4344,11 @@ pub const Object = struct { |
| 4344 | 4344 | uav: InternPool.Key.Ptr.BaseAddr.Uav, |
| 4345 | 4345 | ) Error!Builder.Constant { |
| 4346 | 4346 | const pt = o.pt; |
| 4347 | const mod = pt.zcu; | |
| 4348 | const ip = &mod.intern_pool; | |
| 4347 | const zcu = pt.zcu; | |
| 4348 | const ip = &zcu.intern_pool; | |
| 4349 | 4349 | const uav_val = uav.val; |
| 4350 | 4350 | const uav_ty = Type.fromInterned(ip.typeOf(uav_val)); |
| 4351 | const target = mod.getTarget(); | |
| 4351 | const target = zcu.getTarget(); | |
| 4352 | 4352 | |
| 4353 | 4353 | switch (ip.indexToKey(uav_val)) { |
| 4354 | 4354 | .func => @panic("TODO"), |
| ... | ... | @@ -4358,15 +4358,15 @@ pub const Object = struct { |
| 4358 | 4358 | |
| 4359 | 4359 | const ptr_ty = Type.fromInterned(uav.orig_ty); |
| 4360 | 4360 | |
| 4361 | const is_fn_body = uav_ty.zigTypeTag(mod) == .Fn; | |
| 4362 | if ((!is_fn_body and !uav_ty.hasRuntimeBits(pt)) or | |
| 4363 | (is_fn_body and mod.typeToFunc(uav_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty); | |
| 4361 | const is_fn_body = uav_ty.zigTypeTag(zcu) == .Fn; | |
| 4362 | if ((!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) or | |
| 4363 | (is_fn_body and zcu.typeToFunc(uav_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty); | |
| 4364 | 4364 | |
| 4365 | 4365 | if (is_fn_body) |
| 4366 | 4366 | @panic("TODO"); |
| 4367 | 4367 | |
| 4368 | const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target); | |
| 4369 | const alignment = ptr_ty.ptrAlignment(pt); | |
| 4368 | const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(zcu), target); | |
| 4369 | const alignment = ptr_ty.ptrAlignment(zcu); | |
| 4370 | 4370 | const llvm_global = (try o.resolveGlobalUav(uav.val, llvm_addr_space, alignment)).ptrConst(&o.builder).global; |
| 4371 | 4371 | |
| 4372 | 4372 | const llvm_val = try o.builder.convConst( |
| ... | ... | @@ -4398,7 +4398,7 @@ pub const Object = struct { |
| 4398 | 4398 | const ptr_ty = try pt.navPtrType(owner_nav_index); |
| 4399 | 4399 | |
| 4400 | 4400 | const is_fn_body = nav_ty.zigTypeTag(zcu) == .Fn; |
| 4401 | if ((!is_fn_body and !nav_ty.hasRuntimeBits(pt)) or | |
| 4401 | if ((!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) or | |
| 4402 | 4402 | (is_fn_body and zcu.typeToFunc(nav_ty).?.is_generic)) |
| 4403 | 4403 | { |
| 4404 | 4404 | return o.lowerPtrToVoid(ptr_ty); |
| ... | ... | @@ -4418,19 +4418,19 @@ pub const Object = struct { |
| 4418 | 4418 | } |
| 4419 | 4419 | |
| 4420 | 4420 | fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant { |
| 4421 | const mod = o.pt.zcu; | |
| 4421 | const zcu = o.pt.zcu; | |
| 4422 | 4422 | // Even though we are pointing at something which has zero bits (e.g. `void`), |
| 4423 | 4423 | // Pointers are defined to have bits. So we must return something here. |
| 4424 | 4424 | // The value cannot be undefined, because we use the `nonnull` annotation |
| 4425 | 4425 | // for non-optional pointers. We also need to respect the alignment, even though |
| 4426 | 4426 | // the address will never be dereferenced. |
| 4427 | const int: u64 = ptr_ty.ptrInfo(mod).flags.alignment.toByteUnits() orelse | |
| 4427 | const int: u64 = ptr_ty.ptrInfo(zcu).flags.alignment.toByteUnits() orelse | |
| 4428 | 4428 | // Note that these 0xaa values are appropriate even in release-optimized builds |
| 4429 | 4429 | // because we need a well-defined value that is not null, and LLVM does not |
| 4430 | 4430 | // have an "undef_but_not_null" attribute. As an example, if this `alloc` AIR |
| 4431 | 4431 | // instruction is followed by a `wrap_optional`, it will return this value |
| 4432 | 4432 | // verbatim, and the result should test as non-null. |
| 4433 | switch (mod.getTarget().ptrBitWidth()) { | |
| 4433 | switch (zcu.getTarget().ptrBitWidth()) { | |
| 4434 | 4434 | 16 => 0xaaaa, |
| 4435 | 4435 | 32 => 0xaaaaaaaa, |
| 4436 | 4436 | 64 => 0xaaaaaaaa_aaaaaaaa, |
| ... | ... | @@ -4447,20 +4447,20 @@ pub const Object = struct { |
| 4447 | 4447 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. |
| 4448 | 4448 | fn getAtomicAbiType(o: *Object, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type { |
| 4449 | 4449 | const pt = o.pt; |
| 4450 | const mod = pt.zcu; | |
| 4451 | const int_ty = switch (ty.zigTypeTag(mod)) { | |
| 4450 | const zcu = pt.zcu; | |
| 4451 | const int_ty = switch (ty.zigTypeTag(zcu)) { | |
| 4452 | 4452 | .Int => ty, |
| 4453 | .Enum => ty.intTagType(mod), | |
| 4453 | .Enum => ty.intTagType(zcu), | |
| 4454 | 4454 | .Float => { |
| 4455 | 4455 | if (!is_rmw_xchg) return .none; |
| 4456 | return o.builder.intType(@intCast(ty.abiSize(pt) * 8)); | |
| 4456 | return o.builder.intType(@intCast(ty.abiSize(zcu) * 8)); | |
| 4457 | 4457 | }, |
| 4458 | 4458 | .Bool => return .i8, |
| 4459 | 4459 | else => return .none, |
| 4460 | 4460 | }; |
| 4461 | const bit_count = int_ty.intInfo(mod).bits; | |
| 4461 | const bit_count = int_ty.intInfo(zcu).bits; | |
| 4462 | 4462 | if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) { |
| 4463 | return o.builder.intType(@intCast(int_ty.abiSize(pt) * 8)); | |
| 4463 | return o.builder.intType(@intCast(int_ty.abiSize(zcu) * 8)); | |
| 4464 | 4464 | } else { |
| 4465 | 4465 | return .none; |
| 4466 | 4466 | } |
| ... | ... | @@ -4475,15 +4475,15 @@ pub const Object = struct { |
| 4475 | 4475 | llvm_arg_i: u32, |
| 4476 | 4476 | ) Allocator.Error!void { |
| 4477 | 4477 | const pt = o.pt; |
| 4478 | const mod = pt.zcu; | |
| 4479 | if (param_ty.isPtrAtRuntime(mod)) { | |
| 4480 | const ptr_info = param_ty.ptrInfo(mod); | |
| 4478 | const zcu = pt.zcu; | |
| 4479 | if (param_ty.isPtrAtRuntime(zcu)) { | |
| 4480 | const ptr_info = param_ty.ptrInfo(zcu); | |
| 4481 | 4481 | if (math.cast(u5, param_index)) |i| { |
| 4482 | 4482 | if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) { |
| 4483 | 4483 | try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder); |
| 4484 | 4484 | } |
| 4485 | 4485 | } |
| 4486 | if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) { | |
| 4486 | if (!param_ty.isPtrLikeOptional(zcu) and !ptr_info.flags.is_allowzero) { | |
| 4487 | 4487 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| 4488 | 4488 | } |
| 4489 | 4489 | if (fn_info.cc == .Interrupt) { |
| ... | ... | @@ -4496,9 +4496,9 @@ pub const Object = struct { |
| 4496 | 4496 | const elem_align = if (ptr_info.flags.alignment != .none) |
| 4497 | 4497 | ptr_info.flags.alignment |
| 4498 | 4498 | else |
| 4499 | Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1"); | |
| 4499 | Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1"); | |
| 4500 | 4500 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder); |
| 4501 | } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) { | |
| 4501 | } else if (ccAbiPromoteInt(fn_info.cc, zcu, param_ty)) |s| switch (s) { | |
| 4502 | 4502 | .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder), |
| 4503 | 4503 | .unsigned => try attributes.addParamAttr(llvm_arg_i, .zeroext, &o.builder), |
| 4504 | 4504 | }; |
| ... | ... | @@ -4814,14 +4814,14 @@ pub const FuncGen = struct { |
| 4814 | 4814 | |
| 4815 | 4815 | fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant { |
| 4816 | 4816 | const o = self.ng.object; |
| 4817 | const pt = o.pt; | |
| 4818 | const ty = val.typeOf(pt.zcu); | |
| 4817 | const zcu = o.pt.zcu; | |
| 4818 | const ty = val.typeOf(zcu); | |
| 4819 | 4819 | const llvm_val = try o.lowerValue(val.toIntern()); |
| 4820 | if (!isByRef(ty, pt)) return llvm_val; | |
| 4820 | if (!isByRef(ty, zcu)) return llvm_val; | |
| 4821 | 4821 | |
| 4822 | 4822 | // We have an LLVM value but we need to create a global constant and |
| 4823 | 4823 | // set the value as its initializer, and then return a pointer to the global. |
| 4824 | const target = pt.zcu.getTarget(); | |
| 4824 | const target = zcu.getTarget(); | |
| 4825 | 4825 | const variable_index = try o.builder.addVariable( |
| 4826 | 4826 | .empty, |
| 4827 | 4827 | llvm_val.typeOf(&o.builder), |
| ... | ... | @@ -4831,7 +4831,7 @@ pub const FuncGen = struct { |
| 4831 | 4831 | variable_index.setLinkage(.private, &o.builder); |
| 4832 | 4832 | variable_index.setMutability(.constant, &o.builder); |
| 4833 | 4833 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 4834 | variable_index.setAlignment(ty.abiAlignment(pt).toLlvm(), &o.builder); | |
| 4834 | variable_index.setAlignment(ty.abiAlignment(zcu).toLlvm(), &o.builder); | |
| 4835 | 4835 | return o.builder.convConst( |
| 4836 | 4836 | variable_index.toConst(&o.builder), |
| 4837 | 4837 | try o.builder.ptrType(toLlvmAddressSpace(.generic, target)), |
| ... | ... | @@ -4852,8 +4852,8 @@ pub const FuncGen = struct { |
| 4852 | 4852 | |
| 4853 | 4853 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { |
| 4854 | 4854 | const o = self.ng.object; |
| 4855 | const mod = o.pt.zcu; | |
| 4856 | const ip = &mod.intern_pool; | |
| 4855 | const zcu = o.pt.zcu; | |
| 4856 | const ip = &zcu.intern_pool; | |
| 4857 | 4857 | const air_tags = self.air.instructions.items(.tag); |
| 4858 | 4858 | for (body, 0..) |inst, i| { |
| 4859 | 4859 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue; |
| ... | ... | @@ -5200,19 +5200,19 @@ pub const FuncGen = struct { |
| 5200 | 5200 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 5201 | 5201 | const o = self.ng.object; |
| 5202 | 5202 | const pt = o.pt; |
| 5203 | const mod = pt.zcu; | |
| 5204 | const ip = &mod.intern_pool; | |
| 5203 | const zcu = pt.zcu; | |
| 5204 | const ip = &zcu.intern_pool; | |
| 5205 | 5205 | const callee_ty = self.typeOf(pl_op.operand); |
| 5206 | const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { | |
| 5206 | const zig_fn_ty = switch (callee_ty.zigTypeTag(zcu)) { | |
| 5207 | 5207 | .Fn => callee_ty, |
| 5208 | .Pointer => callee_ty.childType(mod), | |
| 5208 | .Pointer => callee_ty.childType(zcu), | |
| 5209 | 5209 | else => unreachable, |
| 5210 | 5210 | }; |
| 5211 | const fn_info = mod.typeToFunc(zig_fn_ty).?; | |
| 5211 | const fn_info = zcu.typeToFunc(zig_fn_ty).?; | |
| 5212 | 5212 | const return_type = Type.fromInterned(fn_info.return_type); |
| 5213 | 5213 | const llvm_fn = try self.resolveInst(pl_op.operand); |
| 5214 | const target = mod.getTarget(); | |
| 5215 | const sret = firstParamSRet(fn_info, pt, target); | |
| 5214 | const target = zcu.getTarget(); | |
| 5215 | const sret = firstParamSRet(fn_info, zcu, target); | |
| 5216 | 5216 | |
| 5217 | 5217 | var llvm_args = std.ArrayList(Builder.Value).init(self.gpa); |
| 5218 | 5218 | defer llvm_args.deinit(); |
| ... | ... | @@ -5230,13 +5230,13 @@ pub const FuncGen = struct { |
| 5230 | 5230 | const llvm_ret_ty = try o.lowerType(return_type); |
| 5231 | 5231 | try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder); |
| 5232 | 5232 | |
| 5233 | const alignment = return_type.abiAlignment(pt).toLlvm(); | |
| 5233 | const alignment = return_type.abiAlignment(zcu).toLlvm(); | |
| 5234 | 5234 | const ret_ptr = try self.buildAllocaWorkaround(return_type, alignment); |
| 5235 | 5235 | try llvm_args.append(ret_ptr); |
| 5236 | 5236 | break :blk ret_ptr; |
| 5237 | 5237 | }; |
| 5238 | 5238 | |
| 5239 | const err_return_tracing = return_type.isError(mod) and mod.comp.config.any_error_tracing; | |
| 5239 | const err_return_tracing = return_type.isError(zcu) and zcu.comp.config.any_error_tracing; | |
| 5240 | 5240 | if (err_return_tracing) { |
| 5241 | 5241 | assert(self.err_ret_trace != .none); |
| 5242 | 5242 | try llvm_args.append(self.err_ret_trace); |
| ... | ... | @@ -5250,8 +5250,8 @@ pub const FuncGen = struct { |
| 5250 | 5250 | const param_ty = self.typeOf(arg); |
| 5251 | 5251 | const llvm_arg = try self.resolveInst(arg); |
| 5252 | 5252 | const llvm_param_ty = try o.lowerType(param_ty); |
| 5253 | if (isByRef(param_ty, pt)) { | |
| 5254 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5253 | if (isByRef(param_ty, zcu)) { | |
| 5254 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5255 | 5255 | const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, ""); |
| 5256 | 5256 | try llvm_args.append(loaded); |
| 5257 | 5257 | } else { |
| ... | ... | @@ -5262,10 +5262,10 @@ pub const FuncGen = struct { |
| 5262 | 5262 | const arg = args[it.zig_index - 1]; |
| 5263 | 5263 | const param_ty = self.typeOf(arg); |
| 5264 | 5264 | const llvm_arg = try self.resolveInst(arg); |
| 5265 | if (isByRef(param_ty, pt)) { | |
| 5265 | if (isByRef(param_ty, zcu)) { | |
| 5266 | 5266 | try llvm_args.append(llvm_arg); |
| 5267 | 5267 | } else { |
| 5268 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5268 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5269 | 5269 | const param_llvm_ty = llvm_arg.typeOfWip(&self.wip); |
| 5270 | 5270 | const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment); |
| 5271 | 5271 | _ = try self.wip.store(.normal, llvm_arg, arg_ptr, alignment); |
| ... | ... | @@ -5277,10 +5277,10 @@ pub const FuncGen = struct { |
| 5277 | 5277 | const param_ty = self.typeOf(arg); |
| 5278 | 5278 | const llvm_arg = try self.resolveInst(arg); |
| 5279 | 5279 | |
| 5280 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5280 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5281 | 5281 | const param_llvm_ty = try o.lowerType(param_ty); |
| 5282 | 5282 | const arg_ptr = try self.buildAllocaWorkaround(param_ty, alignment); |
| 5283 | if (isByRef(param_ty, pt)) { | |
| 5283 | if (isByRef(param_ty, zcu)) { | |
| 5284 | 5284 | const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, ""); |
| 5285 | 5285 | _ = try self.wip.store(.normal, loaded, arg_ptr, alignment); |
| 5286 | 5286 | } else { |
| ... | ... | @@ -5292,16 +5292,16 @@ pub const FuncGen = struct { |
| 5292 | 5292 | const arg = args[it.zig_index - 1]; |
| 5293 | 5293 | const param_ty = self.typeOf(arg); |
| 5294 | 5294 | const llvm_arg = try self.resolveInst(arg); |
| 5295 | const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(pt) * 8)); | |
| 5295 | const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(zcu) * 8)); | |
| 5296 | 5296 | |
| 5297 | if (isByRef(param_ty, pt)) { | |
| 5298 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5297 | if (isByRef(param_ty, zcu)) { | |
| 5298 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5299 | 5299 | const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, ""); |
| 5300 | 5300 | try llvm_args.append(loaded); |
| 5301 | 5301 | } else { |
| 5302 | 5302 | // LLVM does not allow bitcasting structs so we must allocate |
| 5303 | 5303 | // a local, store as one type, and then load as another type. |
| 5304 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5304 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5305 | 5305 | const int_ptr = try self.buildAllocaWorkaround(param_ty, alignment); |
| 5306 | 5306 | _ = try self.wip.store(.normal, llvm_arg, int_ptr, alignment); |
| 5307 | 5307 | const loaded = try self.wip.load(.normal, int_llvm_ty, int_ptr, alignment, ""); |
| ... | ... | @@ -5320,9 +5320,9 @@ pub const FuncGen = struct { |
| 5320 | 5320 | const param_ty = self.typeOf(arg); |
| 5321 | 5321 | const llvm_types = it.types_buffer[0..it.types_len]; |
| 5322 | 5322 | const llvm_arg = try self.resolveInst(arg); |
| 5323 | const is_by_ref = isByRef(param_ty, pt); | |
| 5323 | const is_by_ref = isByRef(param_ty, zcu); | |
| 5324 | 5324 | const arg_ptr = if (is_by_ref) llvm_arg else ptr: { |
| 5325 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5325 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5326 | 5326 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); |
| 5327 | 5327 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); |
| 5328 | 5328 | break :ptr ptr; |
| ... | ... | @@ -5348,14 +5348,14 @@ pub const FuncGen = struct { |
| 5348 | 5348 | const arg = args[it.zig_index - 1]; |
| 5349 | 5349 | const arg_ty = self.typeOf(arg); |
| 5350 | 5350 | var llvm_arg = try self.resolveInst(arg); |
| 5351 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); | |
| 5352 | if (!isByRef(arg_ty, pt)) { | |
| 5351 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | |
| 5352 | if (!isByRef(arg_ty, zcu)) { | |
| 5353 | 5353 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); |
| 5354 | 5354 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); |
| 5355 | 5355 | llvm_arg = ptr; |
| 5356 | 5356 | } |
| 5357 | 5357 | |
| 5358 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?); | |
| 5358 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?); | |
| 5359 | 5359 | const array_ty = try o.builder.arrayType(count, float_ty); |
| 5360 | 5360 | |
| 5361 | 5361 | const loaded = try self.wip.load(.normal, array_ty, llvm_arg, alignment, ""); |
| ... | ... | @@ -5366,8 +5366,8 @@ pub const FuncGen = struct { |
| 5366 | 5366 | const arg = args[it.zig_index - 1]; |
| 5367 | 5367 | const arg_ty = self.typeOf(arg); |
| 5368 | 5368 | var llvm_arg = try self.resolveInst(arg); |
| 5369 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); | |
| 5370 | if (!isByRef(arg_ty, pt)) { | |
| 5369 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | |
| 5370 | if (!isByRef(arg_ty, zcu)) { | |
| 5371 | 5371 | const ptr = try self.buildAlloca(llvm_arg.typeOfWip(&self.wip), alignment); |
| 5372 | 5372 | _ = try self.wip.store(.normal, llvm_arg, ptr, alignment); |
| 5373 | 5373 | llvm_arg = ptr; |
| ... | ... | @@ -5389,7 +5389,7 @@ pub const FuncGen = struct { |
| 5389 | 5389 | .byval => { |
| 5390 | 5390 | const param_index = it.zig_index - 1; |
| 5391 | 5391 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 5392 | if (!isByRef(param_ty, pt)) { | |
| 5392 | if (!isByRef(param_ty, zcu)) { | |
| 5393 | 5393 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 5394 | 5394 | } |
| 5395 | 5395 | }, |
| ... | ... | @@ -5397,7 +5397,7 @@ pub const FuncGen = struct { |
| 5397 | 5397 | const param_index = it.zig_index - 1; |
| 5398 | 5398 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 5399 | 5399 | const param_llvm_ty = try o.lowerType(param_ty); |
| 5400 | const alignment = param_ty.abiAlignment(pt).toLlvm(); | |
| 5400 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 5401 | 5401 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 5402 | 5402 | }, |
| 5403 | 5403 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| ... | ... | @@ -5414,7 +5414,7 @@ pub const FuncGen = struct { |
| 5414 | 5414 | .slice => { |
| 5415 | 5415 | assert(!it.byval_attr); |
| 5416 | 5416 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 5417 | const ptr_info = param_ty.ptrInfo(mod); | |
| 5417 | const ptr_info = param_ty.ptrInfo(zcu); | |
| 5418 | 5418 | const llvm_arg_i = it.llvm_index - 2; |
| 5419 | 5419 | |
| 5420 | 5420 | if (math.cast(u5, it.zig_index - 1)) |i| { |
| ... | ... | @@ -5422,7 +5422,7 @@ pub const FuncGen = struct { |
| 5422 | 5422 | try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder); |
| 5423 | 5423 | } |
| 5424 | 5424 | } |
| 5425 | if (param_ty.zigTypeTag(mod) != .Optional) { | |
| 5425 | if (param_ty.zigTypeTag(zcu) != .Optional) { | |
| 5426 | 5426 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| 5427 | 5427 | } |
| 5428 | 5428 | if (ptr_info.flags.is_const) { |
| ... | ... | @@ -5431,7 +5431,7 @@ pub const FuncGen = struct { |
| 5431 | 5431 | const elem_align = (if (ptr_info.flags.alignment != .none) |
| 5432 | 5432 | @as(InternPool.Alignment, ptr_info.flags.alignment) |
| 5433 | 5433 | else |
| 5434 | Type.fromInterned(ptr_info.child).abiAlignment(pt).max(.@"1")).toLlvm(); | |
| 5434 | Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm(); | |
| 5435 | 5435 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); |
| 5436 | 5436 | }, |
| 5437 | 5437 | }; |
| ... | ... | @@ -5456,17 +5456,17 @@ pub const FuncGen = struct { |
| 5456 | 5456 | return .none; |
| 5457 | 5457 | } |
| 5458 | 5458 | |
| 5459 | if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5459 | if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5460 | 5460 | return .none; |
| 5461 | 5461 | } |
| 5462 | 5462 | |
| 5463 | 5463 | const llvm_ret_ty = try o.lowerType(return_type); |
| 5464 | 5464 | if (ret_ptr) |rp| { |
| 5465 | if (isByRef(return_type, pt)) { | |
| 5465 | if (isByRef(return_type, zcu)) { | |
| 5466 | 5466 | return rp; |
| 5467 | 5467 | } else { |
| 5468 | 5468 | // our by-ref status disagrees with sret so we must load. |
| 5469 | const return_alignment = return_type.abiAlignment(pt).toLlvm(); | |
| 5469 | const return_alignment = return_type.abiAlignment(zcu).toLlvm(); | |
| 5470 | 5470 | return self.wip.load(.normal, llvm_ret_ty, rp, return_alignment, ""); |
| 5471 | 5471 | } |
| 5472 | 5472 | } |
| ... | ... | @@ -5477,19 +5477,19 @@ pub const FuncGen = struct { |
| 5477 | 5477 | // In this case the function return type is honoring the calling convention by having |
| 5478 | 5478 | // a different LLVM type than the usual one. We solve this here at the callsite |
| 5479 | 5479 | // by using our canonical type, then loading it if necessary. |
| 5480 | const alignment = return_type.abiAlignment(pt).toLlvm(); | |
| 5480 | const alignment = return_type.abiAlignment(zcu).toLlvm(); | |
| 5481 | 5481 | const rp = try self.buildAlloca(abi_ret_ty, alignment); |
| 5482 | 5482 | _ = try self.wip.store(.normal, call, rp, alignment); |
| 5483 | return if (isByRef(return_type, pt)) | |
| 5483 | return if (isByRef(return_type, zcu)) | |
| 5484 | 5484 | rp |
| 5485 | 5485 | else |
| 5486 | 5486 | try self.wip.load(.normal, llvm_ret_ty, rp, alignment, ""); |
| 5487 | 5487 | } |
| 5488 | 5488 | |
| 5489 | if (isByRef(return_type, pt)) { | |
| 5489 | if (isByRef(return_type, zcu)) { | |
| 5490 | 5490 | // our by-ref status disagrees with sret so we must allocate, store, |
| 5491 | 5491 | // and return the allocation pointer. |
| 5492 | const alignment = return_type.abiAlignment(pt).toLlvm(); | |
| 5492 | const alignment = return_type.abiAlignment(zcu).toLlvm(); | |
| 5493 | 5493 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); |
| 5494 | 5494 | _ = try self.wip.store(.normal, call, rp, alignment); |
| 5495 | 5495 | return rp; |
| ... | ... | @@ -5540,8 +5540,8 @@ pub const FuncGen = struct { |
| 5540 | 5540 | fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 5541 | 5541 | const o = self.ng.object; |
| 5542 | 5542 | const pt = o.pt; |
| 5543 | const mod = pt.zcu; | |
| 5544 | const ip = &mod.intern_pool; | |
| 5543 | const zcu = pt.zcu; | |
| 5544 | const ip = &zcu.intern_pool; | |
| 5545 | 5545 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5546 | 5546 | const ret_ty = self.typeOf(un_op); |
| 5547 | 5547 | |
| ... | ... | @@ -5549,9 +5549,9 @@ pub const FuncGen = struct { |
| 5549 | 5549 | const ptr_ty = try pt.singleMutPtrType(ret_ty); |
| 5550 | 5550 | |
| 5551 | 5551 | const operand = try self.resolveInst(un_op); |
| 5552 | const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(mod) else false; | |
| 5552 | const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(zcu) else false; | |
| 5553 | 5553 | if (val_is_undef and safety) undef: { |
| 5554 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 5554 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 5555 | 5555 | const needs_bitmask = (ptr_info.packed_offset.host_size != 0); |
| 5556 | 5556 | if (needs_bitmask) { |
| 5557 | 5557 | // TODO: only some bits are to be undef, we cannot write with a simple memset. |
| ... | ... | @@ -5559,13 +5559,13 @@ pub const FuncGen = struct { |
| 5559 | 5559 | // https://github.com/ziglang/zig/issues/15337 |
| 5560 | 5560 | break :undef; |
| 5561 | 5561 | } |
| 5562 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt)); | |
| 5562 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(zcu)); | |
| 5563 | 5563 | _ = try self.wip.callMemSet( |
| 5564 | 5564 | self.ret_ptr, |
| 5565 | ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 5565 | ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 5566 | 5566 | try o.builder.intValue(.i8, 0xaa), |
| 5567 | 5567 | len, |
| 5568 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, | |
| 5568 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal, | |
| 5569 | 5569 | ); |
| 5570 | 5570 | const owner_mod = self.ng.ownerModule(); |
| 5571 | 5571 | if (owner_mod.valgrind) { |
| ... | ... | @@ -5588,9 +5588,9 @@ pub const FuncGen = struct { |
| 5588 | 5588 | _ = try self.wip.retVoid(); |
| 5589 | 5589 | return .none; |
| 5590 | 5590 | } |
| 5591 | const fn_info = mod.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?; | |
| 5592 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5593 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | |
| 5591 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?; | |
| 5592 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5593 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { | |
| 5594 | 5594 | // Functions with an empty error set are emitted with an error code |
| 5595 | 5595 | // return type and return zero so they can be function pointers coerced |
| 5596 | 5596 | // to functions that return anyerror. |
| ... | ... | @@ -5603,13 +5603,13 @@ pub const FuncGen = struct { |
| 5603 | 5603 | |
| 5604 | 5604 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); |
| 5605 | 5605 | const operand = try self.resolveInst(un_op); |
| 5606 | const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(mod) else false; | |
| 5607 | const alignment = ret_ty.abiAlignment(pt).toLlvm(); | |
| 5606 | const val_is_undef = if (try self.air.value(un_op, pt)) |val| val.isUndefDeep(zcu) else false; | |
| 5607 | const alignment = ret_ty.abiAlignment(zcu).toLlvm(); | |
| 5608 | 5608 | |
| 5609 | 5609 | if (val_is_undef and safety) { |
| 5610 | 5610 | const llvm_ret_ty = operand.typeOfWip(&self.wip); |
| 5611 | 5611 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); |
| 5612 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(pt)); | |
| 5612 | const len = try o.builder.intValue(try o.lowerType(Type.usize), ret_ty.abiSize(zcu)); | |
| 5613 | 5613 | _ = try self.wip.callMemSet( |
| 5614 | 5614 | rp, |
| 5615 | 5615 | alignment, |
| ... | ... | @@ -5625,7 +5625,7 @@ pub const FuncGen = struct { |
| 5625 | 5625 | return .none; |
| 5626 | 5626 | } |
| 5627 | 5627 | |
| 5628 | if (isByRef(ret_ty, pt)) { | |
| 5628 | if (isByRef(ret_ty, zcu)) { | |
| 5629 | 5629 | // operand is a pointer however self.ret_ptr is null so that means |
| 5630 | 5630 | // we need to return a value. |
| 5631 | 5631 | _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, operand, alignment, "")); |
| ... | ... | @@ -5647,14 +5647,14 @@ pub const FuncGen = struct { |
| 5647 | 5647 | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5648 | 5648 | const o = self.ng.object; |
| 5649 | 5649 | const pt = o.pt; |
| 5650 | const mod = pt.zcu; | |
| 5651 | const ip = &mod.intern_pool; | |
| 5650 | const zcu = pt.zcu; | |
| 5651 | const ip = &zcu.intern_pool; | |
| 5652 | 5652 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5653 | 5653 | const ptr_ty = self.typeOf(un_op); |
| 5654 | const ret_ty = ptr_ty.childType(mod); | |
| 5655 | const fn_info = mod.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?; | |
| 5656 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5657 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | |
| 5654 | const ret_ty = ptr_ty.childType(zcu); | |
| 5655 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?; | |
| 5656 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5657 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { | |
| 5658 | 5658 | // Functions with an empty error set are emitted with an error code |
| 5659 | 5659 | // return type and return zero so they can be function pointers coerced |
| 5660 | 5660 | // to functions that return anyerror. |
| ... | ... | @@ -5670,7 +5670,7 @@ pub const FuncGen = struct { |
| 5670 | 5670 | } |
| 5671 | 5671 | const ptr = try self.resolveInst(un_op); |
| 5672 | 5672 | const abi_ret_ty = try lowerFnRetTy(o, fn_info); |
| 5673 | const alignment = ret_ty.abiAlignment(pt).toLlvm(); | |
| 5673 | const alignment = ret_ty.abiAlignment(zcu).toLlvm(); | |
| 5674 | 5674 | _ = try self.wip.ret(try self.wip.load(.normal, abi_ret_ty, ptr, alignment, "")); |
| 5675 | 5675 | return .none; |
| 5676 | 5676 | } |
| ... | ... | @@ -5688,16 +5688,17 @@ pub const FuncGen = struct { |
| 5688 | 5688 | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5689 | 5689 | const o = self.ng.object; |
| 5690 | 5690 | const pt = o.pt; |
| 5691 | const zcu = pt.zcu; | |
| 5691 | 5692 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5692 | 5693 | const src_list = try self.resolveInst(ty_op.operand); |
| 5693 | 5694 | const va_list_ty = ty_op.ty.toType(); |
| 5694 | 5695 | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5695 | 5696 | |
| 5696 | const result_alignment = va_list_ty.abiAlignment(pt).toLlvm(); | |
| 5697 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); | |
| 5697 | 5698 | const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment); |
| 5698 | 5699 | |
| 5699 | 5700 | _ = try self.wip.callIntrinsic(.normal, .none, .va_copy, &.{}, &.{ dest_list, src_list }, ""); |
| 5700 | return if (isByRef(va_list_ty, pt)) | |
| 5701 | return if (isByRef(va_list_ty, zcu)) | |
| 5701 | 5702 | dest_list |
| 5702 | 5703 | else |
| 5703 | 5704 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); |
| ... | ... | @@ -5714,14 +5715,15 @@ pub const FuncGen = struct { |
| 5714 | 5715 | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5715 | 5716 | const o = self.ng.object; |
| 5716 | 5717 | const pt = o.pt; |
| 5718 | const zcu = pt.zcu; | |
| 5717 | 5719 | const va_list_ty = self.typeOfIndex(inst); |
| 5718 | 5720 | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5719 | 5721 | |
| 5720 | const result_alignment = va_list_ty.abiAlignment(pt).toLlvm(); | |
| 5722 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); | |
| 5721 | 5723 | const dest_list = try self.buildAllocaWorkaround(va_list_ty, result_alignment); |
| 5722 | 5724 | |
| 5723 | 5725 | _ = try self.wip.callIntrinsic(.normal, .none, .va_start, &.{}, &.{dest_list}, ""); |
| 5724 | return if (isByRef(va_list_ty, pt)) | |
| 5726 | return if (isByRef(va_list_ty, zcu)) | |
| 5725 | 5727 | dest_list |
| 5726 | 5728 | else |
| 5727 | 5729 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); |
| ... | ... | @@ -5779,21 +5781,21 @@ pub const FuncGen = struct { |
| 5779 | 5781 | ) Allocator.Error!Builder.Value { |
| 5780 | 5782 | const o = self.ng.object; |
| 5781 | 5783 | const pt = o.pt; |
| 5782 | const mod = pt.zcu; | |
| 5783 | const scalar_ty = operand_ty.scalarType(mod); | |
| 5784 | const int_ty = switch (scalar_ty.zigTypeTag(mod)) { | |
| 5785 | .Enum => scalar_ty.intTagType(mod), | |
| 5784 | const zcu = pt.zcu; | |
| 5785 | const scalar_ty = operand_ty.scalarType(zcu); | |
| 5786 | const int_ty = switch (scalar_ty.zigTypeTag(zcu)) { | |
| 5787 | .Enum => scalar_ty.intTagType(zcu), | |
| 5786 | 5788 | .Int, .Bool, .Pointer, .ErrorSet => scalar_ty, |
| 5787 | 5789 | .Optional => blk: { |
| 5788 | const payload_ty = operand_ty.optionalChild(mod); | |
| 5789 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt) or | |
| 5790 | operand_ty.optionalReprIsPayload(mod)) | |
| 5790 | const payload_ty = operand_ty.optionalChild(zcu); | |
| 5791 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu) or | |
| 5792 | operand_ty.optionalReprIsPayload(zcu)) | |
| 5791 | 5793 | { |
| 5792 | 5794 | break :blk operand_ty; |
| 5793 | 5795 | } |
| 5794 | 5796 | // We need to emit instructions to check for equality/inequality |
| 5795 | 5797 | // of optionals that are not pointers. |
| 5796 | const is_by_ref = isByRef(scalar_ty, pt); | |
| 5798 | const is_by_ref = isByRef(scalar_ty, zcu); | |
| 5797 | 5799 | const opt_llvm_ty = try o.lowerType(scalar_ty); |
| 5798 | 5800 | const lhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, lhs, is_by_ref); |
| 5799 | 5801 | const rhs_non_null = try self.optCmpNull(.ne, opt_llvm_ty, rhs, is_by_ref); |
| ... | ... | @@ -5860,7 +5862,7 @@ pub const FuncGen = struct { |
| 5860 | 5862 | .Float => return self.buildFloatCmp(fast, op, operand_ty, .{ lhs, rhs }), |
| 5861 | 5863 | else => unreachable, |
| 5862 | 5864 | }; |
| 5863 | const is_signed = int_ty.isSignedInt(mod); | |
| 5865 | const is_signed = int_ty.isSignedInt(zcu); | |
| 5864 | 5866 | const cond: Builder.IntegerCondition = switch (op) { |
| 5865 | 5867 | .eq => .eq, |
| 5866 | 5868 | .neq => .ne, |
| ... | ... | @@ -5886,15 +5888,15 @@ pub const FuncGen = struct { |
| 5886 | 5888 | ) !Builder.Value { |
| 5887 | 5889 | const o = self.ng.object; |
| 5888 | 5890 | const pt = o.pt; |
| 5889 | const mod = pt.zcu; | |
| 5891 | const zcu = pt.zcu; | |
| 5890 | 5892 | const inst_ty = self.typeOfIndex(inst); |
| 5891 | 5893 | |
| 5892 | if (inst_ty.isNoReturn(mod)) { | |
| 5894 | if (inst_ty.isNoReturn(zcu)) { | |
| 5893 | 5895 | try self.genBodyDebugScope(maybe_inline_func, body); |
| 5894 | 5896 | return .none; |
| 5895 | 5897 | } |
| 5896 | 5898 | |
| 5897 | const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt); | |
| 5899 | const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu); | |
| 5898 | 5900 | |
| 5899 | 5901 | var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 }; |
| 5900 | 5902 | defer if (have_block_result) breaks.list.deinit(self.gpa); |
| ... | ... | @@ -5918,7 +5920,7 @@ pub const FuncGen = struct { |
| 5918 | 5920 | // a pointer to it. LLVM IR allows the call instruction to use function bodies instead |
| 5919 | 5921 | // of function pointers, however the phi makes it a runtime value and therefore |
| 5920 | 5922 | // the LLVM type has to be wrapped in a pointer. |
| 5921 | if (inst_ty.zigTypeTag(mod) == .Fn or isByRef(inst_ty, pt)) { | |
| 5923 | if (inst_ty.zigTypeTag(zcu) == .Fn or isByRef(inst_ty, zcu)) { | |
| 5922 | 5924 | break :ty .ptr; |
| 5923 | 5925 | } |
| 5924 | 5926 | break :ty raw_llvm_ty; |
| ... | ... | @@ -5936,13 +5938,13 @@ pub const FuncGen = struct { |
| 5936 | 5938 | |
| 5937 | 5939 | fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5938 | 5940 | const o = self.ng.object; |
| 5939 | const pt = o.pt; | |
| 5941 | const zcu = o.pt.zcu; | |
| 5940 | 5942 | const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 5941 | 5943 | const block = self.blocks.get(branch.block_inst).?; |
| 5942 | 5944 | |
| 5943 | 5945 | // Add the values to the lists only if the break provides a value. |
| 5944 | 5946 | const operand_ty = self.typeOf(branch.operand); |
| 5945 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 5947 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5946 | 5948 | const val = try self.resolveInst(branch.operand); |
| 5947 | 5949 | |
| 5948 | 5950 | // For the phi node, we need the basic blocks and the values of the |
| ... | ... | @@ -5977,6 +5979,7 @@ pub const FuncGen = struct { |
| 5977 | 5979 | fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 5978 | 5980 | const o = self.ng.object; |
| 5979 | 5981 | const pt = o.pt; |
| 5982 | const zcu = pt.zcu; | |
| 5980 | 5983 | const inst = body_tail[0]; |
| 5981 | 5984 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5982 | 5985 | const err_union = try self.resolveInst(pl_op.operand); |
| ... | ... | @@ -5984,19 +5987,19 @@ pub const FuncGen = struct { |
| 5984 | 5987 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 5985 | 5988 | const err_union_ty = self.typeOf(pl_op.operand); |
| 5986 | 5989 | const payload_ty = self.typeOfIndex(inst); |
| 5987 | const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false; | |
| 5990 | const can_elide_load = if (isByRef(payload_ty, zcu)) self.canElideLoad(body_tail) else false; | |
| 5988 | 5991 | const is_unused = self.liveness.isUnused(inst); |
| 5989 | 5992 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused); |
| 5990 | 5993 | } |
| 5991 | 5994 | |
| 5992 | 5995 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5993 | 5996 | const o = self.ng.object; |
| 5994 | const mod = o.pt.zcu; | |
| 5997 | const zcu = o.pt.zcu; | |
| 5995 | 5998 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5996 | 5999 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); |
| 5997 | 6000 | const err_union_ptr = try self.resolveInst(extra.data.ptr); |
| 5998 | 6001 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); |
| 5999 | const err_union_ty = self.typeOf(extra.data.ptr).childType(mod); | |
| 6002 | const err_union_ty = self.typeOf(extra.data.ptr).childType(zcu); | |
| 6000 | 6003 | const is_unused = self.liveness.isUnused(inst); |
| 6001 | 6004 | return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused); |
| 6002 | 6005 | } |
| ... | ... | @@ -6012,13 +6015,13 @@ pub const FuncGen = struct { |
| 6012 | 6015 | ) !Builder.Value { |
| 6013 | 6016 | const o = fg.ng.object; |
| 6014 | 6017 | const pt = o.pt; |
| 6015 | const mod = pt.zcu; | |
| 6016 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 6017 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt); | |
| 6018 | const zcu = pt.zcu; | |
| 6019 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 6020 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu); | |
| 6018 | 6021 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 6019 | 6022 | const error_type = try o.errorIntType(); |
| 6020 | 6023 | |
| 6021 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 6024 | if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 6022 | 6025 | const loaded = loaded: { |
| 6023 | 6026 | if (!payload_has_bits) { |
| 6024 | 6027 | // TODO add alignment to this load |
| ... | ... | @@ -6028,7 +6031,7 @@ pub const FuncGen = struct { |
| 6028 | 6031 | err_union; |
| 6029 | 6032 | } |
| 6030 | 6033 | const err_field_index = try errUnionErrorOffset(payload_ty, pt); |
| 6031 | if (operand_is_ptr or isByRef(err_union_ty, pt)) { | |
| 6034 | if (operand_is_ptr or isByRef(err_union_ty, zcu)) { | |
| 6032 | 6035 | const err_field_ptr = |
| 6033 | 6036 | try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, ""); |
| 6034 | 6037 | // TODO add alignment to this load |
| ... | ... | @@ -6059,10 +6062,10 @@ pub const FuncGen = struct { |
| 6059 | 6062 | const offset = try errUnionPayloadOffset(payload_ty, pt); |
| 6060 | 6063 | if (operand_is_ptr) { |
| 6061 | 6064 | return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, ""); |
| 6062 | } else if (isByRef(err_union_ty, pt)) { | |
| 6065 | } else if (isByRef(err_union_ty, zcu)) { | |
| 6063 | 6066 | const payload_ptr = try fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, ""); |
| 6064 | const payload_alignment = payload_ty.abiAlignment(pt).toLlvm(); | |
| 6065 | if (isByRef(payload_ty, pt)) { | |
| 6067 | const payload_alignment = payload_ty.abiAlignment(zcu).toLlvm(); | |
| 6068 | if (isByRef(payload_ty, zcu)) { | |
| 6066 | 6069 | if (can_elide_load) |
| 6067 | 6070 | return payload_ptr; |
| 6068 | 6071 | |
| ... | ... | @@ -6140,7 +6143,7 @@ pub const FuncGen = struct { |
| 6140 | 6143 | |
| 6141 | 6144 | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6142 | 6145 | const o = self.ng.object; |
| 6143 | const mod = o.pt.zcu; | |
| 6146 | const zcu = o.pt.zcu; | |
| 6144 | 6147 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6145 | 6148 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 6146 | 6149 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]); |
| ... | ... | @@ -6156,7 +6159,7 @@ pub const FuncGen = struct { |
| 6156 | 6159 | // would have been emitted already. Also the main loop in genBody can |
| 6157 | 6160 | // be while(true) instead of for(body), which will eliminate 1 branch on |
| 6158 | 6161 | // a hot path. |
| 6159 | if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn(mod)) { | |
| 6162 | if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn(zcu)) { | |
| 6160 | 6163 | _ = try self.wip.br(loop_block); |
| 6161 | 6164 | } |
| 6162 | 6165 | return .none; |
| ... | ... | @@ -6165,15 +6168,15 @@ pub const FuncGen = struct { |
| 6165 | 6168 | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6166 | 6169 | const o = self.ng.object; |
| 6167 | 6170 | const pt = o.pt; |
| 6168 | const mod = pt.zcu; | |
| 6171 | const zcu = pt.zcu; | |
| 6169 | 6172 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6170 | 6173 | const operand_ty = self.typeOf(ty_op.operand); |
| 6171 | const array_ty = operand_ty.childType(mod); | |
| 6174 | const array_ty = operand_ty.childType(zcu); | |
| 6172 | 6175 | const llvm_usize = try o.lowerType(Type.usize); |
| 6173 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(mod)); | |
| 6176 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu)); | |
| 6174 | 6177 | const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst)); |
| 6175 | 6178 | const operand = try self.resolveInst(ty_op.operand); |
| 6176 | if (!array_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 6179 | if (!array_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 6177 | 6180 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); |
| 6178 | 6181 | const ptr = try self.wip.gep(.inbounds, try o.lowerType(array_ty), operand, &.{ |
| 6179 | 6182 | try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0), |
| ... | ... | @@ -6184,17 +6187,17 @@ pub const FuncGen = struct { |
| 6184 | 6187 | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6185 | 6188 | const o = self.ng.object; |
| 6186 | 6189 | const pt = o.pt; |
| 6187 | const mod = pt.zcu; | |
| 6190 | const zcu = pt.zcu; | |
| 6188 | 6191 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6189 | 6192 | |
| 6190 | 6193 | const workaround_operand = try self.resolveInst(ty_op.operand); |
| 6191 | 6194 | const operand_ty = self.typeOf(ty_op.operand); |
| 6192 | const operand_scalar_ty = operand_ty.scalarType(mod); | |
| 6193 | const is_signed_int = operand_scalar_ty.isSignedInt(mod); | |
| 6195 | const operand_scalar_ty = operand_ty.scalarType(zcu); | |
| 6196 | const is_signed_int = operand_scalar_ty.isSignedInt(zcu); | |
| 6194 | 6197 | |
| 6195 | 6198 | const operand = o: { |
| 6196 | 6199 | // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381. |
| 6197 | const bit_size = operand_scalar_ty.bitSize(pt); | |
| 6200 | const bit_size = operand_scalar_ty.bitSize(zcu); | |
| 6198 | 6201 | for ([_]u8{ 8, 16, 32, 64, 128 }) |b| { |
| 6199 | 6202 | if (bit_size < b) { |
| 6200 | 6203 | break :o try self.wip.cast( |
| ... | ... | @@ -6211,9 +6214,9 @@ pub const FuncGen = struct { |
| 6211 | 6214 | }; |
| 6212 | 6215 | |
| 6213 | 6216 | const dest_ty = self.typeOfIndex(inst); |
| 6214 | const dest_scalar_ty = dest_ty.scalarType(mod); | |
| 6217 | const dest_scalar_ty = dest_ty.scalarType(zcu); | |
| 6215 | 6218 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 6216 | const target = mod.getTarget(); | |
| 6219 | const target = zcu.getTarget(); | |
| 6217 | 6220 | |
| 6218 | 6221 | if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv( |
| 6219 | 6222 | if (is_signed_int) .signed else .unsigned, |
| ... | ... | @@ -6222,7 +6225,7 @@ pub const FuncGen = struct { |
| 6222 | 6225 | "", |
| 6223 | 6226 | ); |
| 6224 | 6227 | |
| 6225 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(pt))); | |
| 6228 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(zcu))); | |
| 6226 | 6229 | const rt_int_ty = try o.builder.intType(rt_int_bits); |
| 6227 | 6230 | var extended = try self.wip.conv( |
| 6228 | 6231 | if (is_signed_int) .signed else .unsigned, |
| ... | ... | @@ -6269,29 +6272,29 @@ pub const FuncGen = struct { |
| 6269 | 6272 | |
| 6270 | 6273 | const o = self.ng.object; |
| 6271 | 6274 | const pt = o.pt; |
| 6272 | const mod = pt.zcu; | |
| 6273 | const target = mod.getTarget(); | |
| 6275 | const zcu = pt.zcu; | |
| 6276 | const target = zcu.getTarget(); | |
| 6274 | 6277 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6275 | 6278 | |
| 6276 | 6279 | const operand = try self.resolveInst(ty_op.operand); |
| 6277 | 6280 | const operand_ty = self.typeOf(ty_op.operand); |
| 6278 | const operand_scalar_ty = operand_ty.scalarType(mod); | |
| 6281 | const operand_scalar_ty = operand_ty.scalarType(zcu); | |
| 6279 | 6282 | |
| 6280 | 6283 | const dest_ty = self.typeOfIndex(inst); |
| 6281 | const dest_scalar_ty = dest_ty.scalarType(mod); | |
| 6284 | const dest_scalar_ty = dest_ty.scalarType(zcu); | |
| 6282 | 6285 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 6283 | 6286 | |
| 6284 | 6287 | if (intrinsicsAllowed(operand_scalar_ty, target)) { |
| 6285 | 6288 | // TODO set fast math flag |
| 6286 | 6289 | return self.wip.conv( |
| 6287 | if (dest_scalar_ty.isSignedInt(mod)) .signed else .unsigned, | |
| 6290 | if (dest_scalar_ty.isSignedInt(zcu)) .signed else .unsigned, | |
| 6288 | 6291 | operand, |
| 6289 | 6292 | dest_llvm_ty, |
| 6290 | 6293 | "", |
| 6291 | 6294 | ); |
| 6292 | 6295 | } |
| 6293 | 6296 | |
| 6294 | const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(pt))); | |
| 6297 | const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(zcu))); | |
| 6295 | 6298 | const ret_ty = try o.builder.intType(rt_int_bits); |
| 6296 | 6299 | const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: { |
| 6297 | 6300 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard |
| ... | ... | @@ -6303,7 +6306,7 @@ pub const FuncGen = struct { |
| 6303 | 6306 | const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); |
| 6304 | 6307 | |
| 6305 | 6308 | const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits); |
| 6306 | const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns"; | |
| 6309 | const sign_prefix = if (dest_scalar_ty.isSignedInt(zcu)) "" else "uns"; | |
| 6307 | 6310 | |
| 6308 | 6311 | const fn_name = try o.builder.strtabStringFmt("__fix{s}{s}f{s}i", .{ |
| 6309 | 6312 | sign_prefix, |
| ... | ... | @@ -6330,29 +6333,29 @@ pub const FuncGen = struct { |
| 6330 | 6333 | |
| 6331 | 6334 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| 6332 | 6335 | const o = fg.ng.object; |
| 6333 | const mod = o.pt.zcu; | |
| 6334 | return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr; | |
| 6336 | const zcu = o.pt.zcu; | |
| 6337 | return if (ty.isSlice(zcu)) fg.wip.extractValue(ptr, &.{0}, "") else ptr; | |
| 6335 | 6338 | } |
| 6336 | 6339 | |
| 6337 | 6340 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| 6338 | 6341 | const o = fg.ng.object; |
| 6339 | 6342 | const pt = o.pt; |
| 6340 | const mod = pt.zcu; | |
| 6343 | const zcu = pt.zcu; | |
| 6341 | 6344 | const llvm_usize = try o.lowerType(Type.usize); |
| 6342 | switch (ty.ptrSize(mod)) { | |
| 6345 | switch (ty.ptrSize(zcu)) { | |
| 6343 | 6346 | .Slice => { |
| 6344 | 6347 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); |
| 6345 | const elem_ty = ty.childType(mod); | |
| 6346 | const abi_size = elem_ty.abiSize(pt); | |
| 6348 | const elem_ty = ty.childType(zcu); | |
| 6349 | const abi_size = elem_ty.abiSize(zcu); | |
| 6347 | 6350 | if (abi_size == 1) return len; |
| 6348 | 6351 | const abi_size_llvm_val = try o.builder.intValue(llvm_usize, abi_size); |
| 6349 | 6352 | return fg.wip.bin(.@"mul nuw", len, abi_size_llvm_val, ""); |
| 6350 | 6353 | }, |
| 6351 | 6354 | .One => { |
| 6352 | const array_ty = ty.childType(mod); | |
| 6353 | const elem_ty = array_ty.childType(mod); | |
| 6354 | const abi_size = elem_ty.abiSize(pt); | |
| 6355 | return o.builder.intValue(llvm_usize, array_ty.arrayLen(mod) * abi_size); | |
| 6355 | const array_ty = ty.childType(zcu); | |
| 6356 | const elem_ty = array_ty.childType(zcu); | |
| 6357 | const abi_size = elem_ty.abiSize(zcu); | |
| 6358 | return o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu) * abi_size); | |
| 6356 | 6359 | }, |
| 6357 | 6360 | .Many, .C => unreachable, |
| 6358 | 6361 | } |
| ... | ... | @@ -6366,11 +6369,11 @@ pub const FuncGen = struct { |
| 6366 | 6369 | |
| 6367 | 6370 | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value { |
| 6368 | 6371 | const o = self.ng.object; |
| 6369 | const mod = o.pt.zcu; | |
| 6372 | const zcu = o.pt.zcu; | |
| 6370 | 6373 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6371 | 6374 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 6372 | 6375 | const slice_ptr_ty = self.typeOf(ty_op.operand); |
| 6373 | const slice_llvm_ty = try o.lowerPtrElemTy(slice_ptr_ty.childType(mod)); | |
| 6376 | const slice_llvm_ty = try o.lowerPtrElemTy(slice_ptr_ty.childType(zcu)); | |
| 6374 | 6377 | |
| 6375 | 6378 | return self.wip.gepStruct(slice_llvm_ty, slice_ptr, index, ""); |
| 6376 | 6379 | } |
| ... | ... | @@ -6378,21 +6381,21 @@ pub const FuncGen = struct { |
| 6378 | 6381 | fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6379 | 6382 | const o = self.ng.object; |
| 6380 | 6383 | const pt = o.pt; |
| 6381 | const mod = pt.zcu; | |
| 6384 | const zcu = pt.zcu; | |
| 6382 | 6385 | const inst = body_tail[0]; |
| 6383 | 6386 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6384 | 6387 | const slice_ty = self.typeOf(bin_op.lhs); |
| 6385 | 6388 | const slice = try self.resolveInst(bin_op.lhs); |
| 6386 | 6389 | const index = try self.resolveInst(bin_op.rhs); |
| 6387 | const elem_ty = slice_ty.childType(mod); | |
| 6390 | const elem_ty = slice_ty.childType(zcu); | |
| 6388 | 6391 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); |
| 6389 | 6392 | const base_ptr = try self.wip.extractValue(slice, &.{0}, ""); |
| 6390 | 6393 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); |
| 6391 | if (isByRef(elem_ty, pt)) { | |
| 6394 | if (isByRef(elem_ty, zcu)) { | |
| 6392 | 6395 | if (self.canElideLoad(body_tail)) |
| 6393 | 6396 | return ptr; |
| 6394 | 6397 | |
| 6395 | const elem_alignment = elem_ty.abiAlignment(pt).toLlvm(); | |
| 6398 | const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm(); | |
| 6396 | 6399 | return self.loadByRef(ptr, elem_ty, elem_alignment, .normal); |
| 6397 | 6400 | } |
| 6398 | 6401 | |
| ... | ... | @@ -6401,14 +6404,14 @@ pub const FuncGen = struct { |
| 6401 | 6404 | |
| 6402 | 6405 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6403 | 6406 | const o = self.ng.object; |
| 6404 | const mod = o.pt.zcu; | |
| 6407 | const zcu = o.pt.zcu; | |
| 6405 | 6408 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6406 | 6409 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6407 | 6410 | const slice_ty = self.typeOf(bin_op.lhs); |
| 6408 | 6411 | |
| 6409 | 6412 | const slice = try self.resolveInst(bin_op.lhs); |
| 6410 | 6413 | const index = try self.resolveInst(bin_op.rhs); |
| 6411 | const llvm_elem_ty = try o.lowerPtrElemTy(slice_ty.childType(mod)); | |
| 6414 | const llvm_elem_ty = try o.lowerPtrElemTy(slice_ty.childType(zcu)); | |
| 6412 | 6415 | const base_ptr = try self.wip.extractValue(slice, &.{0}, ""); |
| 6413 | 6416 | return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); |
| 6414 | 6417 | } |
| ... | ... | @@ -6416,7 +6419,7 @@ pub const FuncGen = struct { |
| 6416 | 6419 | fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6417 | 6420 | const o = self.ng.object; |
| 6418 | 6421 | const pt = o.pt; |
| 6419 | const mod = pt.zcu; | |
| 6422 | const zcu = pt.zcu; | |
| 6420 | 6423 | const inst = body_tail[0]; |
| 6421 | 6424 | |
| 6422 | 6425 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -6424,16 +6427,16 @@ pub const FuncGen = struct { |
| 6424 | 6427 | const array_llvm_val = try self.resolveInst(bin_op.lhs); |
| 6425 | 6428 | const rhs = try self.resolveInst(bin_op.rhs); |
| 6426 | 6429 | const array_llvm_ty = try o.lowerType(array_ty); |
| 6427 | const elem_ty = array_ty.childType(mod); | |
| 6428 | if (isByRef(array_ty, pt)) { | |
| 6430 | const elem_ty = array_ty.childType(zcu); | |
| 6431 | if (isByRef(array_ty, zcu)) { | |
| 6429 | 6432 | const indices: [2]Builder.Value = .{ |
| 6430 | 6433 | try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs, |
| 6431 | 6434 | }; |
| 6432 | if (isByRef(elem_ty, pt)) { | |
| 6435 | if (isByRef(elem_ty, zcu)) { | |
| 6433 | 6436 | const elem_ptr = |
| 6434 | 6437 | try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, ""); |
| 6435 | 6438 | if (canElideLoad(self, body_tail)) return elem_ptr; |
| 6436 | const elem_alignment = elem_ty.abiAlignment(pt).toLlvm(); | |
| 6439 | const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm(); | |
| 6437 | 6440 | return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal); |
| 6438 | 6441 | } else { |
| 6439 | 6442 | const elem_ptr = |
| ... | ... | @@ -6449,23 +6452,23 @@ pub const FuncGen = struct { |
| 6449 | 6452 | fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6450 | 6453 | const o = self.ng.object; |
| 6451 | 6454 | const pt = o.pt; |
| 6452 | const mod = pt.zcu; | |
| 6455 | const zcu = pt.zcu; | |
| 6453 | 6456 | const inst = body_tail[0]; |
| 6454 | 6457 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6455 | 6458 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 6456 | const elem_ty = ptr_ty.childType(mod); | |
| 6459 | const elem_ty = ptr_ty.childType(zcu); | |
| 6457 | 6460 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); |
| 6458 | 6461 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 6459 | 6462 | const rhs = try self.resolveInst(bin_op.rhs); |
| 6460 | 6463 | // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch |
| 6461 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(mod)) | |
| 6464 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(zcu)) | |
| 6462 | 6465 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 6463 | 6466 | &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs } |
| 6464 | 6467 | else |
| 6465 | 6468 | &.{rhs}, ""); |
| 6466 | if (isByRef(elem_ty, pt)) { | |
| 6469 | if (isByRef(elem_ty, zcu)) { | |
| 6467 | 6470 | if (self.canElideLoad(body_tail)) return ptr; |
| 6468 | const elem_alignment = elem_ty.abiAlignment(pt).toLlvm(); | |
| 6471 | const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm(); | |
| 6469 | 6472 | return self.loadByRef(ptr, elem_ty, elem_alignment, .normal); |
| 6470 | 6473 | } |
| 6471 | 6474 | |
| ... | ... | @@ -6475,21 +6478,21 @@ pub const FuncGen = struct { |
| 6475 | 6478 | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6476 | 6479 | const o = self.ng.object; |
| 6477 | 6480 | const pt = o.pt; |
| 6478 | const mod = pt.zcu; | |
| 6481 | const zcu = pt.zcu; | |
| 6479 | 6482 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6480 | 6483 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6481 | 6484 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 6482 | const elem_ty = ptr_ty.childType(mod); | |
| 6483 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return self.resolveInst(bin_op.lhs); | |
| 6485 | const elem_ty = ptr_ty.childType(zcu); | |
| 6486 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return self.resolveInst(bin_op.lhs); | |
| 6484 | 6487 | |
| 6485 | 6488 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 6486 | 6489 | const rhs = try self.resolveInst(bin_op.rhs); |
| 6487 | 6490 | |
| 6488 | 6491 | const elem_ptr = ty_pl.ty.toType(); |
| 6489 | if (elem_ptr.ptrInfo(mod).flags.vector_index != .none) return base_ptr; | |
| 6492 | if (elem_ptr.ptrInfo(zcu).flags.vector_index != .none) return base_ptr; | |
| 6490 | 6493 | |
| 6491 | 6494 | const llvm_elem_ty = try o.lowerPtrElemTy(elem_ty); |
| 6492 | return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(mod)) | |
| 6495 | return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(zcu)) | |
| 6493 | 6496 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 6494 | 6497 | &.{ try o.builder.intValue(try o.lowerType(Type.usize), 0), rhs } |
| 6495 | 6498 | else |
| ... | ... | @@ -6518,35 +6521,35 @@ pub const FuncGen = struct { |
| 6518 | 6521 | fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6519 | 6522 | const o = self.ng.object; |
| 6520 | 6523 | const pt = o.pt; |
| 6521 | const mod = pt.zcu; | |
| 6524 | const zcu = pt.zcu; | |
| 6522 | 6525 | const inst = body_tail[0]; |
| 6523 | 6526 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6524 | 6527 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 6525 | 6528 | const struct_ty = self.typeOf(struct_field.struct_operand); |
| 6526 | 6529 | const struct_llvm_val = try self.resolveInst(struct_field.struct_operand); |
| 6527 | 6530 | const field_index = struct_field.field_index; |
| 6528 | const field_ty = struct_ty.structFieldType(field_index, mod); | |
| 6529 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 6531 | const field_ty = struct_ty.structFieldType(field_index, zcu); | |
| 6532 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none; | |
| 6530 | 6533 | |
| 6531 | if (!isByRef(struct_ty, pt)) { | |
| 6532 | assert(!isByRef(field_ty, pt)); | |
| 6533 | switch (struct_ty.zigTypeTag(mod)) { | |
| 6534 | .Struct => switch (struct_ty.containerLayout(mod)) { | |
| 6534 | if (!isByRef(struct_ty, zcu)) { | |
| 6535 | assert(!isByRef(field_ty, zcu)); | |
| 6536 | switch (struct_ty.zigTypeTag(zcu)) { | |
| 6537 | .Struct => switch (struct_ty.containerLayout(zcu)) { | |
| 6535 | 6538 | .@"packed" => { |
| 6536 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 6539 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 6537 | 6540 | const bit_offset = pt.structPackedFieldBitOffset(struct_type, field_index); |
| 6538 | 6541 | const containing_int = struct_llvm_val; |
| 6539 | 6542 | const shift_amt = |
| 6540 | 6543 | try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset); |
| 6541 | 6544 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); |
| 6542 | 6545 | const elem_llvm_ty = try o.lowerType(field_ty); |
| 6543 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | |
| 6544 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); | |
| 6546 | if (field_ty.zigTypeTag(zcu) == .Float or field_ty.zigTypeTag(zcu) == .Vector) { | |
| 6547 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(zcu))); | |
| 6545 | 6548 | const truncated_int = |
| 6546 | 6549 | try self.wip.cast(.trunc, shifted_value, same_size_int, ""); |
| 6547 | 6550 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); |
| 6548 | } else if (field_ty.isPtrAtRuntime(mod)) { | |
| 6549 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); | |
| 6551 | } else if (field_ty.isPtrAtRuntime(zcu)) { | |
| 6552 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(zcu))); | |
| 6550 | 6553 | const truncated_int = |
| 6551 | 6554 | try self.wip.cast(.trunc, shifted_value, same_size_int, ""); |
| 6552 | 6555 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); |
| ... | ... | @@ -6559,16 +6562,16 @@ pub const FuncGen = struct { |
| 6559 | 6562 | }, |
| 6560 | 6563 | }, |
| 6561 | 6564 | .Union => { |
| 6562 | assert(struct_ty.containerLayout(mod) == .@"packed"); | |
| 6565 | assert(struct_ty.containerLayout(zcu) == .@"packed"); | |
| 6563 | 6566 | const containing_int = struct_llvm_val; |
| 6564 | 6567 | const elem_llvm_ty = try o.lowerType(field_ty); |
| 6565 | if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) { | |
| 6566 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); | |
| 6568 | if (field_ty.zigTypeTag(zcu) == .Float or field_ty.zigTypeTag(zcu) == .Vector) { | |
| 6569 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(zcu))); | |
| 6567 | 6570 | const truncated_int = |
| 6568 | 6571 | try self.wip.cast(.trunc, containing_int, same_size_int, ""); |
| 6569 | 6572 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); |
| 6570 | } else if (field_ty.isPtrAtRuntime(mod)) { | |
| 6571 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(pt))); | |
| 6573 | } else if (field_ty.isPtrAtRuntime(zcu)) { | |
| 6574 | const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(zcu))); | |
| 6572 | 6575 | const truncated_int = |
| 6573 | 6576 | try self.wip.cast(.trunc, containing_int, same_size_int, ""); |
| 6574 | 6577 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); |
| ... | ... | @@ -6579,20 +6582,20 @@ pub const FuncGen = struct { |
| 6579 | 6582 | } |
| 6580 | 6583 | } |
| 6581 | 6584 | |
| 6582 | switch (struct_ty.zigTypeTag(mod)) { | |
| 6585 | switch (struct_ty.zigTypeTag(zcu)) { | |
| 6583 | 6586 | .Struct => { |
| 6584 | const layout = struct_ty.containerLayout(mod); | |
| 6587 | const layout = struct_ty.containerLayout(zcu); | |
| 6585 | 6588 | assert(layout != .@"packed"); |
| 6586 | 6589 | const struct_llvm_ty = try o.lowerType(struct_ty); |
| 6587 | 6590 | const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?; |
| 6588 | 6591 | const field_ptr = |
| 6589 | 6592 | try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, ""); |
| 6590 | const alignment = struct_ty.structFieldAlign(field_index, pt); | |
| 6593 | const alignment = struct_ty.structFieldAlign(field_index, zcu); | |
| 6591 | 6594 | const field_ptr_ty = try pt.ptrType(.{ |
| 6592 | 6595 | .child = field_ty.toIntern(), |
| 6593 | 6596 | .flags = .{ .alignment = alignment }, |
| 6594 | 6597 | }); |
| 6595 | if (isByRef(field_ty, pt)) { | |
| 6598 | if (isByRef(field_ty, zcu)) { | |
| 6596 | 6599 | if (canElideLoad(self, body_tail)) |
| 6597 | 6600 | return field_ptr; |
| 6598 | 6601 | |
| ... | ... | @@ -6605,12 +6608,12 @@ pub const FuncGen = struct { |
| 6605 | 6608 | }, |
| 6606 | 6609 | .Union => { |
| 6607 | 6610 | const union_llvm_ty = try o.lowerType(struct_ty); |
| 6608 | const layout = struct_ty.unionGetLayout(pt); | |
| 6611 | const layout = struct_ty.unionGetLayout(zcu); | |
| 6609 | 6612 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); |
| 6610 | 6613 | const field_ptr = |
| 6611 | 6614 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 6612 | 6615 | const payload_alignment = layout.payload_align.toLlvm(); |
| 6613 | if (isByRef(field_ty, pt)) { | |
| 6616 | if (isByRef(field_ty, zcu)) { | |
| 6614 | 6617 | if (canElideLoad(self, body_tail)) return field_ptr; |
| 6615 | 6618 | return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal); |
| 6616 | 6619 | } else { |
| ... | ... | @@ -6624,14 +6627,14 @@ pub const FuncGen = struct { |
| 6624 | 6627 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6625 | 6628 | const o = self.ng.object; |
| 6626 | 6629 | const pt = o.pt; |
| 6627 | const mod = pt.zcu; | |
| 6630 | const zcu = pt.zcu; | |
| 6628 | 6631 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6629 | 6632 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 6630 | 6633 | |
| 6631 | 6634 | const field_ptr = try self.resolveInst(extra.field_ptr); |
| 6632 | 6635 | |
| 6633 | const parent_ty = ty_pl.ty.toType().childType(mod); | |
| 6634 | const field_offset = parent_ty.structFieldOffset(extra.field_index, pt); | |
| 6636 | const parent_ty = ty_pl.ty.toType().childType(zcu); | |
| 6637 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); | |
| 6635 | 6638 | if (field_offset == 0) return field_ptr; |
| 6636 | 6639 | |
| 6637 | 6640 | const res_ty = try o.lowerType(ty_pl.ty.toType()); |
| ... | ... | @@ -6686,7 +6689,7 @@ pub const FuncGen = struct { |
| 6686 | 6689 | |
| 6687 | 6690 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6688 | 6691 | const o = self.ng.object; |
| 6689 | const mod = o.pt.zcu; | |
| 6692 | const zcu = o.pt.zcu; | |
| 6690 | 6693 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6691 | 6694 | const operand = try self.resolveInst(pl_op.operand); |
| 6692 | 6695 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| ... | ... | @@ -6697,7 +6700,7 @@ pub const FuncGen = struct { |
| 6697 | 6700 | self.file, |
| 6698 | 6701 | self.scope, |
| 6699 | 6702 | self.prev_dbg_line, |
| 6700 | try o.lowerDebugType(ptr_ty.childType(mod)), | |
| 6703 | try o.lowerDebugType(ptr_ty.childType(zcu)), | |
| 6701 | 6704 | ); |
| 6702 | 6705 | |
| 6703 | 6706 | _ = try self.wip.callIntrinsic( |
| ... | ... | @@ -6741,9 +6744,9 @@ pub const FuncGen = struct { |
| 6741 | 6744 | try o.lowerDebugType(operand_ty), |
| 6742 | 6745 | ); |
| 6743 | 6746 | |
| 6744 | const pt = o.pt; | |
| 6747 | const zcu = o.pt.zcu; | |
| 6745 | 6748 | const owner_mod = self.ng.ownerModule(); |
| 6746 | if (isByRef(operand_ty, pt)) { | |
| 6749 | if (isByRef(operand_ty, zcu)) { | |
| 6747 | 6750 | _ = try self.wip.callIntrinsic( |
| 6748 | 6751 | .normal, |
| 6749 | 6752 | .none, |
| ... | ... | @@ -6760,7 +6763,7 @@ pub const FuncGen = struct { |
| 6760 | 6763 | // We avoid taking this path for naked functions because there's no guarantee that such |
| 6761 | 6764 | // functions even have a valid stack pointer, making the `alloca` + `store` unsafe. |
| 6762 | 6765 | |
| 6763 | const alignment = operand_ty.abiAlignment(pt).toLlvm(); | |
| 6766 | const alignment = operand_ty.abiAlignment(zcu).toLlvm(); | |
| 6764 | 6767 | const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment); |
| 6765 | 6768 | _ = try self.wip.store(.normal, operand, alloca, alignment); |
| 6766 | 6769 | _ = try self.wip.callIntrinsic( |
| ... | ... | @@ -6832,8 +6835,8 @@ pub const FuncGen = struct { |
| 6832 | 6835 | // if so, the element type itself. |
| 6833 | 6836 | const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count); |
| 6834 | 6837 | const pt = o.pt; |
| 6835 | const mod = pt.zcu; | |
| 6836 | const target = mod.getTarget(); | |
| 6838 | const zcu = pt.zcu; | |
| 6839 | const target = zcu.getTarget(); | |
| 6837 | 6840 | |
| 6838 | 6841 | var llvm_ret_i: usize = 0; |
| 6839 | 6842 | var llvm_param_i: usize = 0; |
| ... | ... | @@ -6860,8 +6863,8 @@ pub const FuncGen = struct { |
| 6860 | 6863 | if (output != .none) { |
| 6861 | 6864 | const output_inst = try self.resolveInst(output); |
| 6862 | 6865 | const output_ty = self.typeOf(output); |
| 6863 | assert(output_ty.zigTypeTag(mod) == .Pointer); | |
| 6864 | const elem_llvm_ty = try o.lowerPtrElemTy(output_ty.childType(mod)); | |
| 6866 | assert(output_ty.zigTypeTag(zcu) == .Pointer); | |
| 6867 | const elem_llvm_ty = try o.lowerPtrElemTy(output_ty.childType(zcu)); | |
| 6865 | 6868 | |
| 6866 | 6869 | switch (constraint[0]) { |
| 6867 | 6870 | '=' => {}, |
| ... | ... | @@ -6932,13 +6935,13 @@ pub const FuncGen = struct { |
| 6932 | 6935 | |
| 6933 | 6936 | const arg_llvm_value = try self.resolveInst(input); |
| 6934 | 6937 | const arg_ty = self.typeOf(input); |
| 6935 | const is_by_ref = isByRef(arg_ty, pt); | |
| 6938 | const is_by_ref = isByRef(arg_ty, zcu); | |
| 6936 | 6939 | if (is_by_ref) { |
| 6937 | 6940 | if (constraintAllowsMemory(constraint)) { |
| 6938 | 6941 | llvm_param_values[llvm_param_i] = arg_llvm_value; |
| 6939 | 6942 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 6940 | 6943 | } else { |
| 6941 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); | |
| 6944 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | |
| 6942 | 6945 | const arg_llvm_ty = try o.lowerType(arg_ty); |
| 6943 | 6946 | const load_inst = |
| 6944 | 6947 | try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); |
| ... | ... | @@ -6950,7 +6953,7 @@ pub const FuncGen = struct { |
| 6950 | 6953 | llvm_param_values[llvm_param_i] = arg_llvm_value; |
| 6951 | 6954 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 6952 | 6955 | } else { |
| 6953 | const alignment = arg_ty.abiAlignment(pt).toLlvm(); | |
| 6956 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | |
| 6954 | 6957 | const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOfWip(&self.wip), alignment); |
| 6955 | 6958 | _ = try self.wip.store(.normal, arg_llvm_value, arg_ptr, alignment); |
| 6956 | 6959 | llvm_param_values[llvm_param_i] = arg_ptr; |
| ... | ... | @@ -6978,7 +6981,7 @@ pub const FuncGen = struct { |
| 6978 | 6981 | // In the case of indirect inputs, LLVM requires the callsite to have |
| 6979 | 6982 | // an elementtype(<ty>) attribute. |
| 6980 | 6983 | llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') |
| 6981 | try o.lowerPtrElemTy(if (is_by_ref) arg_ty else arg_ty.childType(mod)) | |
| 6984 | try o.lowerPtrElemTy(if (is_by_ref) arg_ty else arg_ty.childType(zcu)) | |
| 6982 | 6985 | else |
| 6983 | 6986 | .none; |
| 6984 | 6987 | |
| ... | ... | @@ -6997,12 +7000,12 @@ pub const FuncGen = struct { |
| 6997 | 7000 | if (constraint[0] != '+') continue; |
| 6998 | 7001 | |
| 6999 | 7002 | const rw_ty = self.typeOf(output); |
| 7000 | const llvm_elem_ty = try o.lowerPtrElemTy(rw_ty.childType(mod)); | |
| 7003 | const llvm_elem_ty = try o.lowerPtrElemTy(rw_ty.childType(zcu)); | |
| 7001 | 7004 | if (is_indirect) { |
| 7002 | 7005 | llvm_param_values[llvm_param_i] = llvm_rw_val; |
| 7003 | 7006 | llvm_param_types[llvm_param_i] = llvm_rw_val.typeOfWip(&self.wip); |
| 7004 | 7007 | } else { |
| 7005 | const alignment = rw_ty.abiAlignment(pt).toLlvm(); | |
| 7008 | const alignment = rw_ty.abiAlignment(zcu).toLlvm(); | |
| 7006 | 7009 | const loaded = try self.wip.load(.normal, llvm_elem_ty, llvm_rw_val, alignment, ""); |
| 7007 | 7010 | llvm_param_values[llvm_param_i] = loaded; |
| 7008 | 7011 | llvm_param_types[llvm_param_i] = llvm_elem_ty; |
| ... | ... | @@ -7163,7 +7166,7 @@ pub const FuncGen = struct { |
| 7163 | 7166 | const output_ptr = try self.resolveInst(output); |
| 7164 | 7167 | const output_ptr_ty = self.typeOf(output); |
| 7165 | 7168 | |
| 7166 | const alignment = output_ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 7169 | const alignment = output_ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 7167 | 7170 | _ = try self.wip.store(.normal, output_value, output_ptr, alignment); |
| 7168 | 7171 | } else { |
| 7169 | 7172 | ret_val = output_value; |
| ... | ... | @@ -7182,23 +7185,23 @@ pub const FuncGen = struct { |
| 7182 | 7185 | ) !Builder.Value { |
| 7183 | 7186 | const o = self.ng.object; |
| 7184 | 7187 | const pt = o.pt; |
| 7185 | const mod = pt.zcu; | |
| 7188 | const zcu = pt.zcu; | |
| 7186 | 7189 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 7187 | 7190 | const operand = try self.resolveInst(un_op); |
| 7188 | 7191 | const operand_ty = self.typeOf(un_op); |
| 7189 | const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | |
| 7192 | const optional_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | |
| 7190 | 7193 | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 7191 | const payload_ty = optional_ty.optionalChild(mod); | |
| 7192 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 7194 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 7195 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 7193 | 7196 | const loaded = if (operand_is_ptr) |
| 7194 | 7197 | try self.wip.load(.normal, optional_llvm_ty, operand, .default, "") |
| 7195 | 7198 | else |
| 7196 | 7199 | operand; |
| 7197 | if (payload_ty.isSlice(mod)) { | |
| 7200 | if (payload_ty.isSlice(zcu)) { | |
| 7198 | 7201 | const slice_ptr = try self.wip.extractValue(loaded, &.{0}, ""); |
| 7199 | 7202 | const ptr_ty = try o.builder.ptrType(toLlvmAddressSpace( |
| 7200 | payload_ty.ptrAddressSpace(mod), | |
| 7201 | mod.getTarget(), | |
| 7203 | payload_ty.ptrAddressSpace(zcu), | |
| 7204 | zcu.getTarget(), | |
| 7202 | 7205 | )); |
| 7203 | 7206 | return self.wip.icmp(cond, slice_ptr, try o.builder.nullValue(ptr_ty), ""); |
| 7204 | 7207 | } |
| ... | ... | @@ -7207,7 +7210,7 @@ pub const FuncGen = struct { |
| 7207 | 7210 | |
| 7208 | 7211 | comptime assert(optional_layout_version == 3); |
| 7209 | 7212 | |
| 7210 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7213 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7211 | 7214 | const loaded = if (operand_is_ptr) |
| 7212 | 7215 | try self.wip.load(.normal, optional_llvm_ty, operand, .default, "") |
| 7213 | 7216 | else |
| ... | ... | @@ -7215,7 +7218,7 @@ pub const FuncGen = struct { |
| 7215 | 7218 | return self.wip.icmp(cond, loaded, try o.builder.intValue(.i8, 0), ""); |
| 7216 | 7219 | } |
| 7217 | 7220 | |
| 7218 | const is_by_ref = operand_is_ptr or isByRef(optional_ty, pt); | |
| 7221 | const is_by_ref = operand_is_ptr or isByRef(optional_ty, zcu); | |
| 7219 | 7222 | return self.optCmpNull(cond, optional_llvm_ty, operand, is_by_ref); |
| 7220 | 7223 | } |
| 7221 | 7224 | |
| ... | ... | @@ -7227,16 +7230,16 @@ pub const FuncGen = struct { |
| 7227 | 7230 | ) !Builder.Value { |
| 7228 | 7231 | const o = self.ng.object; |
| 7229 | 7232 | const pt = o.pt; |
| 7230 | const mod = pt.zcu; | |
| 7233 | const zcu = pt.zcu; | |
| 7231 | 7234 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 7232 | 7235 | const operand = try self.resolveInst(un_op); |
| 7233 | 7236 | const operand_ty = self.typeOf(un_op); |
| 7234 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | |
| 7235 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 7237 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | |
| 7238 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 7236 | 7239 | const error_type = try o.errorIntType(); |
| 7237 | 7240 | const zero = try o.builder.intValue(error_type, 0); |
| 7238 | 7241 | |
| 7239 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 7242 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 7240 | 7243 | const val: Builder.Constant = switch (cond) { |
| 7241 | 7244 | .eq => .true, // 0 == 0 |
| 7242 | 7245 | .ne => .false, // 0 != 0 |
| ... | ... | @@ -7245,7 +7248,7 @@ pub const FuncGen = struct { |
| 7245 | 7248 | return val.toValue(); |
| 7246 | 7249 | } |
| 7247 | 7250 | |
| 7248 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7251 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7249 | 7252 | const loaded = if (operand_is_ptr) |
| 7250 | 7253 | try self.wip.load(.normal, try o.lowerType(err_union_ty), operand, .default, "") |
| 7251 | 7254 | else |
| ... | ... | @@ -7255,7 +7258,7 @@ pub const FuncGen = struct { |
| 7255 | 7258 | |
| 7256 | 7259 | const err_field_index = try errUnionErrorOffset(payload_ty, pt); |
| 7257 | 7260 | |
| 7258 | const loaded = if (operand_is_ptr or isByRef(err_union_ty, pt)) loaded: { | |
| 7261 | const loaded = if (operand_is_ptr or isByRef(err_union_ty, zcu)) loaded: { | |
| 7259 | 7262 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7260 | 7263 | const err_field_ptr = |
| 7261 | 7264 | try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, ""); |
| ... | ... | @@ -7267,17 +7270,17 @@ pub const FuncGen = struct { |
| 7267 | 7270 | fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7268 | 7271 | const o = self.ng.object; |
| 7269 | 7272 | const pt = o.pt; |
| 7270 | const mod = pt.zcu; | |
| 7273 | const zcu = pt.zcu; | |
| 7271 | 7274 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7272 | 7275 | const operand = try self.resolveInst(ty_op.operand); |
| 7273 | const optional_ty = self.typeOf(ty_op.operand).childType(mod); | |
| 7274 | const payload_ty = optional_ty.optionalChild(mod); | |
| 7275 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7276 | const optional_ty = self.typeOf(ty_op.operand).childType(zcu); | |
| 7277 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 7278 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7276 | 7279 | // We have a pointer to a zero-bit value and we need to return |
| 7277 | 7280 | // a pointer to a zero-bit value. |
| 7278 | 7281 | return operand; |
| 7279 | 7282 | } |
| 7280 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 7283 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 7281 | 7284 | // The payload and the optional are the same value. |
| 7282 | 7285 | return operand; |
| 7283 | 7286 | } |
| ... | ... | @@ -7289,18 +7292,18 @@ pub const FuncGen = struct { |
| 7289 | 7292 | |
| 7290 | 7293 | const o = self.ng.object; |
| 7291 | 7294 | const pt = o.pt; |
| 7292 | const mod = pt.zcu; | |
| 7295 | const zcu = pt.zcu; | |
| 7293 | 7296 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7294 | 7297 | const operand = try self.resolveInst(ty_op.operand); |
| 7295 | const optional_ty = self.typeOf(ty_op.operand).childType(mod); | |
| 7296 | const payload_ty = optional_ty.optionalChild(mod); | |
| 7298 | const optional_ty = self.typeOf(ty_op.operand).childType(zcu); | |
| 7299 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 7297 | 7300 | const non_null_bit = try o.builder.intValue(.i8, 1); |
| 7298 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7301 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7299 | 7302 | // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. |
| 7300 | 7303 | _ = try self.wip.store(.normal, non_null_bit, operand, .default); |
| 7301 | 7304 | return operand; |
| 7302 | 7305 | } |
| 7303 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 7306 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 7304 | 7307 | // The payload and the optional are the same value. |
| 7305 | 7308 | // Setting to non-null will be done when the payload is set. |
| 7306 | 7309 | return operand; |
| ... | ... | @@ -7321,21 +7324,21 @@ pub const FuncGen = struct { |
| 7321 | 7324 | fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7322 | 7325 | const o = self.ng.object; |
| 7323 | 7326 | const pt = o.pt; |
| 7324 | const mod = pt.zcu; | |
| 7327 | const zcu = pt.zcu; | |
| 7325 | 7328 | const inst = body_tail[0]; |
| 7326 | 7329 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7327 | 7330 | const operand = try self.resolveInst(ty_op.operand); |
| 7328 | 7331 | const optional_ty = self.typeOf(ty_op.operand); |
| 7329 | 7332 | const payload_ty = self.typeOfIndex(inst); |
| 7330 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 7333 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none; | |
| 7331 | 7334 | |
| 7332 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 7335 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 7333 | 7336 | // Payload value is the same as the optional value. |
| 7334 | 7337 | return operand; |
| 7335 | 7338 | } |
| 7336 | 7339 | |
| 7337 | 7340 | const opt_llvm_ty = try o.lowerType(optional_ty); |
| 7338 | const can_elide_load = if (isByRef(payload_ty, pt)) self.canElideLoad(body_tail) else false; | |
| 7341 | const can_elide_load = if (isByRef(payload_ty, zcu)) self.canElideLoad(body_tail) else false; | |
| 7339 | 7342 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); |
| 7340 | 7343 | } |
| 7341 | 7344 | |
| ... | ... | @@ -7346,26 +7349,26 @@ pub const FuncGen = struct { |
| 7346 | 7349 | ) !Builder.Value { |
| 7347 | 7350 | const o = self.ng.object; |
| 7348 | 7351 | const pt = o.pt; |
| 7349 | const mod = pt.zcu; | |
| 7352 | const zcu = pt.zcu; | |
| 7350 | 7353 | const inst = body_tail[0]; |
| 7351 | 7354 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7352 | 7355 | const operand = try self.resolveInst(ty_op.operand); |
| 7353 | 7356 | const operand_ty = self.typeOf(ty_op.operand); |
| 7354 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | |
| 7357 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | |
| 7355 | 7358 | const result_ty = self.typeOfIndex(inst); |
| 7356 | const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty; | |
| 7359 | const payload_ty = if (operand_is_ptr) result_ty.childType(zcu) else result_ty; | |
| 7357 | 7360 | |
| 7358 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7361 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7359 | 7362 | return if (operand_is_ptr) operand else .none; |
| 7360 | 7363 | } |
| 7361 | 7364 | const offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7362 | 7365 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7363 | 7366 | if (operand_is_ptr) { |
| 7364 | 7367 | return self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7365 | } else if (isByRef(err_union_ty, pt)) { | |
| 7366 | const payload_alignment = payload_ty.abiAlignment(pt).toLlvm(); | |
| 7368 | } else if (isByRef(err_union_ty, zcu)) { | |
| 7369 | const payload_alignment = payload_ty.abiAlignment(zcu).toLlvm(); | |
| 7367 | 7370 | const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7368 | if (isByRef(payload_ty, pt)) { | |
| 7371 | if (isByRef(payload_ty, zcu)) { | |
| 7369 | 7372 | if (self.canElideLoad(body_tail)) return payload_ptr; |
| 7370 | 7373 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); |
| 7371 | 7374 | } |
| ... | ... | @@ -7382,13 +7385,13 @@ pub const FuncGen = struct { |
| 7382 | 7385 | ) !Builder.Value { |
| 7383 | 7386 | const o = self.ng.object; |
| 7384 | 7387 | const pt = o.pt; |
| 7385 | const mod = pt.zcu; | |
| 7388 | const zcu = pt.zcu; | |
| 7386 | 7389 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7387 | 7390 | const operand = try self.resolveInst(ty_op.operand); |
| 7388 | 7391 | const operand_ty = self.typeOf(ty_op.operand); |
| 7389 | 7392 | const error_type = try o.errorIntType(); |
| 7390 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; | |
| 7391 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 7393 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | |
| 7394 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 7392 | 7395 | if (operand_is_ptr) { |
| 7393 | 7396 | return operand; |
| 7394 | 7397 | } else { |
| ... | ... | @@ -7396,15 +7399,15 @@ pub const FuncGen = struct { |
| 7396 | 7399 | } |
| 7397 | 7400 | } |
| 7398 | 7401 | |
| 7399 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 7400 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7402 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 7403 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7401 | 7404 | if (!operand_is_ptr) return operand; |
| 7402 | 7405 | return self.wip.load(.normal, error_type, operand, .default, ""); |
| 7403 | 7406 | } |
| 7404 | 7407 | |
| 7405 | 7408 | const offset = try errUnionErrorOffset(payload_ty, pt); |
| 7406 | 7409 | |
| 7407 | if (operand_is_ptr or isByRef(err_union_ty, pt)) { | |
| 7410 | if (operand_is_ptr or isByRef(err_union_ty, zcu)) { | |
| 7408 | 7411 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7409 | 7412 | const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7410 | 7413 | return self.wip.load(.normal, error_type, err_field_ptr, .default, ""); |
| ... | ... | @@ -7416,21 +7419,21 @@ pub const FuncGen = struct { |
| 7416 | 7419 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7417 | 7420 | const o = self.ng.object; |
| 7418 | 7421 | const pt = o.pt; |
| 7419 | const mod = pt.zcu; | |
| 7422 | const zcu = pt.zcu; | |
| 7420 | 7423 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7421 | 7424 | const operand = try self.resolveInst(ty_op.operand); |
| 7422 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); | |
| 7425 | const err_union_ty = self.typeOf(ty_op.operand).childType(zcu); | |
| 7423 | 7426 | |
| 7424 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 7427 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 7425 | 7428 | const non_error_val = try o.builder.intValue(try o.errorIntType(), 0); |
| 7426 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7429 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7427 | 7430 | _ = try self.wip.store(.normal, non_error_val, operand, .default); |
| 7428 | 7431 | return operand; |
| 7429 | 7432 | } |
| 7430 | 7433 | const err_union_llvm_ty = try o.lowerType(err_union_ty); |
| 7431 | 7434 | { |
| 7432 | 7435 | const err_int_ty = try pt.errorIntType(); |
| 7433 | const error_alignment = err_int_ty.abiAlignment(pt).toLlvm(); | |
| 7436 | const error_alignment = err_int_ty.abiAlignment(zcu).toLlvm(); | |
| 7434 | 7437 | const error_offset = try errUnionErrorOffset(payload_ty, pt); |
| 7435 | 7438 | // First set the non-error value. |
| 7436 | 7439 | const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, ""); |
| ... | ... | @@ -7457,7 +7460,7 @@ pub const FuncGen = struct { |
| 7457 | 7460 | fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7458 | 7461 | const o = self.ng.object; |
| 7459 | 7462 | const pt = o.pt; |
| 7460 | const mod = pt.zcu; | |
| 7463 | const zcu = pt.zcu; | |
| 7461 | 7464 | |
| 7462 | 7465 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7463 | 7466 | const struct_ty = ty_pl.ty.toType(); |
| ... | ... | @@ -7468,8 +7471,8 @@ pub const FuncGen = struct { |
| 7468 | 7471 | assert(self.err_ret_trace != .none); |
| 7469 | 7472 | const field_ptr = |
| 7470 | 7473 | try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, ""); |
| 7471 | const field_alignment = struct_ty.structFieldAlign(field_index, pt); | |
| 7472 | const field_ty = struct_ty.structFieldType(field_index, mod); | |
| 7474 | const field_alignment = struct_ty.structFieldAlign(field_index, zcu); | |
| 7475 | const field_ty = struct_ty.structFieldType(field_index, zcu); | |
| 7473 | 7476 | const field_ptr_ty = try pt.ptrType(.{ |
| 7474 | 7477 | .child = field_ty.toIntern(), |
| 7475 | 7478 | .flags = .{ .alignment = field_alignment }, |
| ... | ... | @@ -7503,23 +7506,23 @@ pub const FuncGen = struct { |
| 7503 | 7506 | fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7504 | 7507 | const o = self.ng.object; |
| 7505 | 7508 | const pt = o.pt; |
| 7506 | const mod = pt.zcu; | |
| 7509 | const zcu = pt.zcu; | |
| 7507 | 7510 | const inst = body_tail[0]; |
| 7508 | 7511 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7509 | 7512 | const payload_ty = self.typeOf(ty_op.operand); |
| 7510 | 7513 | const non_null_bit = try o.builder.intValue(.i8, 1); |
| 7511 | 7514 | comptime assert(optional_layout_version == 3); |
| 7512 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return non_null_bit; | |
| 7515 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return non_null_bit; | |
| 7513 | 7516 | const operand = try self.resolveInst(ty_op.operand); |
| 7514 | 7517 | const optional_ty = self.typeOfIndex(inst); |
| 7515 | if (optional_ty.optionalReprIsPayload(mod)) return operand; | |
| 7518 | if (optional_ty.optionalReprIsPayload(zcu)) return operand; | |
| 7516 | 7519 | const llvm_optional_ty = try o.lowerType(optional_ty); |
| 7517 | if (isByRef(optional_ty, pt)) { | |
| 7520 | if (isByRef(optional_ty, zcu)) { | |
| 7518 | 7521 | const directReturn = self.isNextRet(body_tail); |
| 7519 | 7522 | const optional_ptr = if (directReturn) |
| 7520 | 7523 | self.ret_ptr |
| 7521 | 7524 | else brk: { |
| 7522 | const alignment = optional_ty.abiAlignment(pt).toLlvm(); | |
| 7525 | const alignment = optional_ty.abiAlignment(zcu).toLlvm(); | |
| 7523 | 7526 | const optional_ptr = try self.buildAllocaWorkaround(optional_ty, alignment); |
| 7524 | 7527 | break :brk optional_ptr; |
| 7525 | 7528 | }; |
| ... | ... | @@ -7537,12 +7540,13 @@ pub const FuncGen = struct { |
| 7537 | 7540 | fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7538 | 7541 | const o = self.ng.object; |
| 7539 | 7542 | const pt = o.pt; |
| 7543 | const zcu = pt.zcu; | |
| 7540 | 7544 | const inst = body_tail[0]; |
| 7541 | 7545 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7542 | 7546 | const err_un_ty = self.typeOfIndex(inst); |
| 7543 | 7547 | const operand = try self.resolveInst(ty_op.operand); |
| 7544 | 7548 | const payload_ty = self.typeOf(ty_op.operand); |
| 7545 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 7549 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 7546 | 7550 | return operand; |
| 7547 | 7551 | } |
| 7548 | 7552 | const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0); |
| ... | ... | @@ -7550,19 +7554,19 @@ pub const FuncGen = struct { |
| 7550 | 7554 | |
| 7551 | 7555 | const payload_offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7552 | 7556 | const error_offset = try errUnionErrorOffset(payload_ty, pt); |
| 7553 | if (isByRef(err_un_ty, pt)) { | |
| 7557 | if (isByRef(err_un_ty, zcu)) { | |
| 7554 | 7558 | const directReturn = self.isNextRet(body_tail); |
| 7555 | 7559 | const result_ptr = if (directReturn) |
| 7556 | 7560 | self.ret_ptr |
| 7557 | 7561 | else brk: { |
| 7558 | const alignment = err_un_ty.abiAlignment(pt).toLlvm(); | |
| 7562 | const alignment = err_un_ty.abiAlignment(pt.zcu).toLlvm(); | |
| 7559 | 7563 | const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment); |
| 7560 | 7564 | break :brk result_ptr; |
| 7561 | 7565 | }; |
| 7562 | 7566 | |
| 7563 | 7567 | const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, ""); |
| 7564 | 7568 | const err_int_ty = try pt.errorIntType(); |
| 7565 | const error_alignment = err_int_ty.abiAlignment(pt).toLlvm(); | |
| 7569 | const error_alignment = err_int_ty.abiAlignment(pt.zcu).toLlvm(); | |
| 7566 | 7570 | _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment); |
| 7567 | 7571 | const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, ""); |
| 7568 | 7572 | const payload_ptr_ty = try pt.singleMutPtrType(payload_ty); |
| ... | ... | @@ -7578,30 +7582,30 @@ pub const FuncGen = struct { |
| 7578 | 7582 | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 7579 | 7583 | const o = self.ng.object; |
| 7580 | 7584 | const pt = o.pt; |
| 7581 | const mod = pt.zcu; | |
| 7585 | const zcu = pt.zcu; | |
| 7582 | 7586 | const inst = body_tail[0]; |
| 7583 | 7587 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7584 | 7588 | const err_un_ty = self.typeOfIndex(inst); |
| 7585 | const payload_ty = err_un_ty.errorUnionPayload(mod); | |
| 7589 | const payload_ty = err_un_ty.errorUnionPayload(zcu); | |
| 7586 | 7590 | const operand = try self.resolveInst(ty_op.operand); |
| 7587 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return operand; | |
| 7591 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return operand; | |
| 7588 | 7592 | const err_un_llvm_ty = try o.lowerType(err_un_ty); |
| 7589 | 7593 | |
| 7590 | 7594 | const payload_offset = try errUnionPayloadOffset(payload_ty, pt); |
| 7591 | 7595 | const error_offset = try errUnionErrorOffset(payload_ty, pt); |
| 7592 | if (isByRef(err_un_ty, pt)) { | |
| 7596 | if (isByRef(err_un_ty, zcu)) { | |
| 7593 | 7597 | const directReturn = self.isNextRet(body_tail); |
| 7594 | 7598 | const result_ptr = if (directReturn) |
| 7595 | 7599 | self.ret_ptr |
| 7596 | 7600 | else brk: { |
| 7597 | const alignment = err_un_ty.abiAlignment(pt).toLlvm(); | |
| 7601 | const alignment = err_un_ty.abiAlignment(zcu).toLlvm(); | |
| 7598 | 7602 | const result_ptr = try self.buildAllocaWorkaround(err_un_ty, alignment); |
| 7599 | 7603 | break :brk result_ptr; |
| 7600 | 7604 | }; |
| 7601 | 7605 | |
| 7602 | 7606 | const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, ""); |
| 7603 | 7607 | const err_int_ty = try pt.errorIntType(); |
| 7604 | const error_alignment = err_int_ty.abiAlignment(pt).toLlvm(); | |
| 7608 | const error_alignment = err_int_ty.abiAlignment(zcu).toLlvm(); | |
| 7605 | 7609 | _ = try self.wip.store(.normal, operand, err_ptr, error_alignment); |
| 7606 | 7610 | const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, ""); |
| 7607 | 7611 | const payload_ptr_ty = try pt.singleMutPtrType(payload_ty); |
| ... | ... | @@ -7639,7 +7643,7 @@ pub const FuncGen = struct { |
| 7639 | 7643 | fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7640 | 7644 | const o = self.ng.object; |
| 7641 | 7645 | const pt = o.pt; |
| 7642 | const mod = pt.zcu; | |
| 7646 | const zcu = pt.zcu; | |
| 7643 | 7647 | const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; |
| 7644 | 7648 | const extra = self.air.extraData(Air.Bin, data.payload).data; |
| 7645 | 7649 | |
| ... | ... | @@ -7649,9 +7653,9 @@ pub const FuncGen = struct { |
| 7649 | 7653 | const operand = try self.resolveInst(extra.rhs); |
| 7650 | 7654 | |
| 7651 | 7655 | const access_kind: Builder.MemoryAccessKind = |
| 7652 | if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | |
| 7653 | const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod)); | |
| 7654 | const alignment = vector_ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 7656 | if (vector_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | |
| 7657 | const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(zcu)); | |
| 7658 | const alignment = vector_ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 7655 | 7659 | const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, ""); |
| 7656 | 7660 | |
| 7657 | 7661 | const new_vector = try self.wip.insertElement(loaded, operand, index, ""); |
| ... | ... | @@ -7661,18 +7665,18 @@ pub const FuncGen = struct { |
| 7661 | 7665 | |
| 7662 | 7666 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7663 | 7667 | const o = self.ng.object; |
| 7664 | const mod = o.pt.zcu; | |
| 7668 | const zcu = o.pt.zcu; | |
| 7665 | 7669 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7666 | 7670 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7667 | 7671 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7668 | 7672 | const inst_ty = self.typeOfIndex(inst); |
| 7669 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7673 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7670 | 7674 | |
| 7671 | 7675 | if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, .normal, inst_ty, 2, .{ lhs, rhs }); |
| 7672 | 7676 | return self.wip.callIntrinsic( |
| 7673 | 7677 | .normal, |
| 7674 | 7678 | .none, |
| 7675 | if (scalar_ty.isSignedInt(mod)) .smin else .umin, | |
| 7679 | if (scalar_ty.isSignedInt(zcu)) .smin else .umin, | |
| 7676 | 7680 | &.{try o.lowerType(inst_ty)}, |
| 7677 | 7681 | &.{ lhs, rhs }, |
| 7678 | 7682 | "", |
| ... | ... | @@ -7681,18 +7685,18 @@ pub const FuncGen = struct { |
| 7681 | 7685 | |
| 7682 | 7686 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7683 | 7687 | const o = self.ng.object; |
| 7684 | const mod = o.pt.zcu; | |
| 7688 | const zcu = o.pt.zcu; | |
| 7685 | 7689 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7686 | 7690 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7687 | 7691 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7688 | 7692 | const inst_ty = self.typeOfIndex(inst); |
| 7689 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7693 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7690 | 7694 | |
| 7691 | 7695 | if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, .normal, inst_ty, 2, .{ lhs, rhs }); |
| 7692 | 7696 | return self.wip.callIntrinsic( |
| 7693 | 7697 | .normal, |
| 7694 | 7698 | .none, |
| 7695 | if (scalar_ty.isSignedInt(mod)) .smax else .umax, | |
| 7699 | if (scalar_ty.isSignedInt(zcu)) .smax else .umax, | |
| 7696 | 7700 | &.{try o.lowerType(inst_ty)}, |
| 7697 | 7701 | &.{ lhs, rhs }, |
| 7698 | 7702 | "", |
| ... | ... | @@ -7711,15 +7715,15 @@ pub const FuncGen = struct { |
| 7711 | 7715 | |
| 7712 | 7716 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7713 | 7717 | const o = self.ng.object; |
| 7714 | const mod = o.pt.zcu; | |
| 7718 | const zcu = o.pt.zcu; | |
| 7715 | 7719 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7716 | 7720 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7717 | 7721 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7718 | 7722 | const inst_ty = self.typeOfIndex(inst); |
| 7719 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7723 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7720 | 7724 | |
| 7721 | 7725 | if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.add, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7722 | return self.wip.bin(if (scalar_ty.isSignedInt(mod)) .@"add nsw" else .@"add nuw", lhs, rhs, ""); | |
| 7726 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"add nsw" else .@"add nuw", lhs, rhs, ""); | |
| 7723 | 7727 | } |
| 7724 | 7728 | |
| 7725 | 7729 | fn airSafeArithmetic( |
| ... | ... | @@ -7729,15 +7733,15 @@ pub const FuncGen = struct { |
| 7729 | 7733 | unsigned_intrinsic: Builder.Intrinsic, |
| 7730 | 7734 | ) !Builder.Value { |
| 7731 | 7735 | const o = fg.ng.object; |
| 7732 | const mod = o.pt.zcu; | |
| 7736 | const zcu = o.pt.zcu; | |
| 7733 | 7737 | |
| 7734 | 7738 | const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7735 | 7739 | const lhs = try fg.resolveInst(bin_op.lhs); |
| 7736 | 7740 | const rhs = try fg.resolveInst(bin_op.rhs); |
| 7737 | 7741 | const inst_ty = fg.typeOfIndex(inst); |
| 7738 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7742 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7739 | 7743 | |
| 7740 | const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic; | |
| 7744 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; | |
| 7741 | 7745 | const llvm_inst_ty = try o.lowerType(inst_ty); |
| 7742 | 7746 | const results = |
| 7743 | 7747 | try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, ""); |
| ... | ... | @@ -7777,18 +7781,18 @@ pub const FuncGen = struct { |
| 7777 | 7781 | |
| 7778 | 7782 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7779 | 7783 | const o = self.ng.object; |
| 7780 | const mod = o.pt.zcu; | |
| 7784 | const zcu = o.pt.zcu; | |
| 7781 | 7785 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7782 | 7786 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7783 | 7787 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7784 | 7788 | const inst_ty = self.typeOfIndex(inst); |
| 7785 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7789 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7786 | 7790 | |
| 7787 | 7791 | if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{}); |
| 7788 | 7792 | return self.wip.callIntrinsic( |
| 7789 | 7793 | .normal, |
| 7790 | 7794 | .none, |
| 7791 | if (scalar_ty.isSignedInt(mod)) .@"sadd.sat" else .@"uadd.sat", | |
| 7795 | if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat", | |
| 7792 | 7796 | &.{try o.lowerType(inst_ty)}, |
| 7793 | 7797 | &.{ lhs, rhs }, |
| 7794 | 7798 | "", |
| ... | ... | @@ -7797,15 +7801,15 @@ pub const FuncGen = struct { |
| 7797 | 7801 | |
| 7798 | 7802 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7799 | 7803 | const o = self.ng.object; |
| 7800 | const mod = o.pt.zcu; | |
| 7804 | const zcu = o.pt.zcu; | |
| 7801 | 7805 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7802 | 7806 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7803 | 7807 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7804 | 7808 | const inst_ty = self.typeOfIndex(inst); |
| 7805 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7809 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7806 | 7810 | |
| 7807 | 7811 | if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.sub, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7808 | return self.wip.bin(if (scalar_ty.isSignedInt(mod)) .@"sub nsw" else .@"sub nuw", lhs, rhs, ""); | |
| 7812 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"sub nsw" else .@"sub nuw", lhs, rhs, ""); | |
| 7809 | 7813 | } |
| 7810 | 7814 | |
| 7811 | 7815 | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -7818,18 +7822,18 @@ pub const FuncGen = struct { |
| 7818 | 7822 | |
| 7819 | 7823 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7820 | 7824 | const o = self.ng.object; |
| 7821 | const mod = o.pt.zcu; | |
| 7825 | const zcu = o.pt.zcu; | |
| 7822 | 7826 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7823 | 7827 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7824 | 7828 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7825 | 7829 | const inst_ty = self.typeOfIndex(inst); |
| 7826 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7830 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7827 | 7831 | |
| 7828 | 7832 | if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{}); |
| 7829 | 7833 | return self.wip.callIntrinsic( |
| 7830 | 7834 | .normal, |
| 7831 | 7835 | .none, |
| 7832 | if (scalar_ty.isSignedInt(mod)) .@"ssub.sat" else .@"usub.sat", | |
| 7836 | if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat", | |
| 7833 | 7837 | &.{try o.lowerType(inst_ty)}, |
| 7834 | 7838 | &.{ lhs, rhs }, |
| 7835 | 7839 | "", |
| ... | ... | @@ -7838,15 +7842,15 @@ pub const FuncGen = struct { |
| 7838 | 7842 | |
| 7839 | 7843 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7840 | 7844 | const o = self.ng.object; |
| 7841 | const mod = o.pt.zcu; | |
| 7845 | const zcu = o.pt.zcu; | |
| 7842 | 7846 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7843 | 7847 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7844 | 7848 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7845 | 7849 | const inst_ty = self.typeOfIndex(inst); |
| 7846 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7850 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7847 | 7851 | |
| 7848 | 7852 | if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.mul, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7849 | return self.wip.bin(if (scalar_ty.isSignedInt(mod)) .@"mul nsw" else .@"mul nuw", lhs, rhs, ""); | |
| 7853 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"mul nsw" else .@"mul nuw", lhs, rhs, ""); | |
| 7850 | 7854 | } |
| 7851 | 7855 | |
| 7852 | 7856 | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -7859,18 +7863,18 @@ pub const FuncGen = struct { |
| 7859 | 7863 | |
| 7860 | 7864 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7861 | 7865 | const o = self.ng.object; |
| 7862 | const mod = o.pt.zcu; | |
| 7866 | const zcu = o.pt.zcu; | |
| 7863 | 7867 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7864 | 7868 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7865 | 7869 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7866 | 7870 | const inst_ty = self.typeOfIndex(inst); |
| 7867 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7871 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7868 | 7872 | |
| 7869 | 7873 | if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{}); |
| 7870 | 7874 | return self.wip.callIntrinsic( |
| 7871 | 7875 | .normal, |
| 7872 | 7876 | .none, |
| 7873 | if (scalar_ty.isSignedInt(mod)) .@"smul.fix.sat" else .@"umul.fix.sat", | |
| 7877 | if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat", | |
| 7874 | 7878 | &.{try o.lowerType(inst_ty)}, |
| 7875 | 7879 | &.{ lhs, rhs, .@"0" }, |
| 7876 | 7880 | "", |
| ... | ... | @@ -7888,34 +7892,34 @@ pub const FuncGen = struct { |
| 7888 | 7892 | |
| 7889 | 7893 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7890 | 7894 | const o = self.ng.object; |
| 7891 | const mod = o.pt.zcu; | |
| 7895 | const zcu = o.pt.zcu; | |
| 7892 | 7896 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7893 | 7897 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7894 | 7898 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7895 | 7899 | const inst_ty = self.typeOfIndex(inst); |
| 7896 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7900 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7897 | 7901 | |
| 7898 | 7902 | if (scalar_ty.isRuntimeFloat()) { |
| 7899 | 7903 | const result = try self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7900 | 7904 | return self.buildFloatOp(.trunc, fast, inst_ty, 1, .{result}); |
| 7901 | 7905 | } |
| 7902 | return self.wip.bin(if (scalar_ty.isSignedInt(mod)) .sdiv else .udiv, lhs, rhs, ""); | |
| 7906 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .sdiv else .udiv, lhs, rhs, ""); | |
| 7903 | 7907 | } |
| 7904 | 7908 | |
| 7905 | 7909 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7906 | 7910 | const o = self.ng.object; |
| 7907 | const mod = o.pt.zcu; | |
| 7911 | const zcu = o.pt.zcu; | |
| 7908 | 7912 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7909 | 7913 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7910 | 7914 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7911 | 7915 | const inst_ty = self.typeOfIndex(inst); |
| 7912 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7916 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7913 | 7917 | |
| 7914 | 7918 | if (scalar_ty.isRuntimeFloat()) { |
| 7915 | 7919 | const result = try self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7916 | 7920 | return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result}); |
| 7917 | 7921 | } |
| 7918 | if (scalar_ty.isSignedInt(mod)) { | |
| 7922 | if (scalar_ty.isSignedInt(zcu)) { | |
| 7919 | 7923 | const inst_llvm_ty = try o.lowerType(inst_ty); |
| 7920 | 7924 | const bit_size_minus_one = try o.builder.splatValue(inst_llvm_ty, try o.builder.intConst( |
| 7921 | 7925 | inst_llvm_ty.scalarType(&o.builder), |
| ... | ... | @@ -7936,16 +7940,16 @@ pub const FuncGen = struct { |
| 7936 | 7940 | |
| 7937 | 7941 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7938 | 7942 | const o = self.ng.object; |
| 7939 | const mod = o.pt.zcu; | |
| 7943 | const zcu = o.pt.zcu; | |
| 7940 | 7944 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7941 | 7945 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7942 | 7946 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7943 | 7947 | const inst_ty = self.typeOfIndex(inst); |
| 7944 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7948 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7945 | 7949 | |
| 7946 | 7950 | if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7947 | 7951 | return self.wip.bin( |
| 7948 | if (scalar_ty.isSignedInt(mod)) .@"sdiv exact" else .@"udiv exact", | |
| 7952 | if (scalar_ty.isSignedInt(zcu)) .@"sdiv exact" else .@"udiv exact", | |
| 7949 | 7953 | lhs, |
| 7950 | 7954 | rhs, |
| 7951 | 7955 | "", |
| ... | ... | @@ -7954,16 +7958,16 @@ pub const FuncGen = struct { |
| 7954 | 7958 | |
| 7955 | 7959 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7956 | 7960 | const o = self.ng.object; |
| 7957 | const mod = o.pt.zcu; | |
| 7961 | const zcu = o.pt.zcu; | |
| 7958 | 7962 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7959 | 7963 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7960 | 7964 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7961 | 7965 | const inst_ty = self.typeOfIndex(inst); |
| 7962 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7966 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7963 | 7967 | |
| 7964 | 7968 | if (scalar_ty.isRuntimeFloat()) |
| 7965 | 7969 | return self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ lhs, rhs }); |
| 7966 | return self.wip.bin(if (scalar_ty.isSignedInt(mod)) | |
| 7970 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) | |
| 7967 | 7971 | .srem |
| 7968 | 7972 | else |
| 7969 | 7973 | .urem, lhs, rhs, ""); |
| ... | ... | @@ -7971,13 +7975,13 @@ pub const FuncGen = struct { |
| 7971 | 7975 | |
| 7972 | 7976 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 7973 | 7977 | const o = self.ng.object; |
| 7974 | const mod = o.pt.zcu; | |
| 7978 | const zcu = o.pt.zcu; | |
| 7975 | 7979 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7976 | 7980 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7977 | 7981 | const rhs = try self.resolveInst(bin_op.rhs); |
| 7978 | 7982 | const inst_ty = self.typeOfIndex(inst); |
| 7979 | 7983 | const inst_llvm_ty = try o.lowerType(inst_ty); |
| 7980 | const scalar_ty = inst_ty.scalarType(mod); | |
| 7984 | const scalar_ty = inst_ty.scalarType(zcu); | |
| 7981 | 7985 | |
| 7982 | 7986 | if (scalar_ty.isRuntimeFloat()) { |
| 7983 | 7987 | const a = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ lhs, rhs }); |
| ... | ... | @@ -7987,7 +7991,7 @@ pub const FuncGen = struct { |
| 7987 | 7991 | const ltz = try self.buildFloatCmp(fast, .lt, inst_ty, .{ lhs, zero }); |
| 7988 | 7992 | return self.wip.select(fast, ltz, c, a, ""); |
| 7989 | 7993 | } |
| 7990 | if (scalar_ty.isSignedInt(mod)) { | |
| 7994 | if (scalar_ty.isSignedInt(zcu)) { | |
| 7991 | 7995 | const bit_size_minus_one = try o.builder.splatValue(inst_llvm_ty, try o.builder.intConst( |
| 7992 | 7996 | inst_llvm_ty.scalarType(&o.builder), |
| 7993 | 7997 | inst_llvm_ty.scalarBits(&o.builder) - 1, |
| ... | ... | @@ -8007,14 +8011,14 @@ pub const FuncGen = struct { |
| 8007 | 8011 | |
| 8008 | 8012 | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8009 | 8013 | const o = self.ng.object; |
| 8010 | const mod = o.pt.zcu; | |
| 8014 | const zcu = o.pt.zcu; | |
| 8011 | 8015 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8012 | 8016 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8013 | 8017 | const ptr = try self.resolveInst(bin_op.lhs); |
| 8014 | 8018 | const offset = try self.resolveInst(bin_op.rhs); |
| 8015 | 8019 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 8016 | const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(mod)); | |
| 8017 | switch (ptr_ty.ptrSize(mod)) { | |
| 8020 | const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(zcu)); | |
| 8021 | switch (ptr_ty.ptrSize(zcu)) { | |
| 8018 | 8022 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| 8019 | 8023 | .One => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{ |
| 8020 | 8024 | try o.builder.intValue(try o.lowerType(Type.usize), 0), offset, |
| ... | ... | @@ -8029,15 +8033,15 @@ pub const FuncGen = struct { |
| 8029 | 8033 | |
| 8030 | 8034 | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8031 | 8035 | const o = self.ng.object; |
| 8032 | const mod = o.pt.zcu; | |
| 8036 | const zcu = o.pt.zcu; | |
| 8033 | 8037 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8034 | 8038 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8035 | 8039 | const ptr = try self.resolveInst(bin_op.lhs); |
| 8036 | 8040 | const offset = try self.resolveInst(bin_op.rhs); |
| 8037 | 8041 | const negative_offset = try self.wip.neg(offset, ""); |
| 8038 | 8042 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 8039 | const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(mod)); | |
| 8040 | switch (ptr_ty.ptrSize(mod)) { | |
| 8043 | const llvm_elem_ty = try o.lowerPtrElemTy(ptr_ty.childType(zcu)); | |
| 8044 | switch (ptr_ty.ptrSize(zcu)) { | |
| 8041 | 8045 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| 8042 | 8046 | .One => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{ |
| 8043 | 8047 | try o.builder.intValue(try o.lowerType(Type.usize), 0), negative_offset, |
| ... | ... | @@ -8058,7 +8062,7 @@ pub const FuncGen = struct { |
| 8058 | 8062 | ) !Builder.Value { |
| 8059 | 8063 | const o = self.ng.object; |
| 8060 | 8064 | const pt = o.pt; |
| 8061 | const mod = pt.zcu; | |
| 8065 | const zcu = pt.zcu; | |
| 8062 | 8066 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8063 | 8067 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8064 | 8068 | |
| ... | ... | @@ -8066,10 +8070,10 @@ pub const FuncGen = struct { |
| 8066 | 8070 | const rhs = try self.resolveInst(extra.rhs); |
| 8067 | 8071 | |
| 8068 | 8072 | const lhs_ty = self.typeOf(extra.lhs); |
| 8069 | const scalar_ty = lhs_ty.scalarType(mod); | |
| 8073 | const scalar_ty = lhs_ty.scalarType(zcu); | |
| 8070 | 8074 | const inst_ty = self.typeOfIndex(inst); |
| 8071 | 8075 | |
| 8072 | const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic; | |
| 8076 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; | |
| 8073 | 8077 | const llvm_inst_ty = try o.lowerType(inst_ty); |
| 8074 | 8078 | const llvm_lhs_ty = try o.lowerType(lhs_ty); |
| 8075 | 8079 | const results = |
| ... | ... | @@ -8081,8 +8085,8 @@ pub const FuncGen = struct { |
| 8081 | 8085 | const result_index = o.llvmFieldIndex(inst_ty, 0).?; |
| 8082 | 8086 | const overflow_index = o.llvmFieldIndex(inst_ty, 1).?; |
| 8083 | 8087 | |
| 8084 | if (isByRef(inst_ty, pt)) { | |
| 8085 | const result_alignment = inst_ty.abiAlignment(pt).toLlvm(); | |
| 8088 | if (isByRef(inst_ty, zcu)) { | |
| 8089 | const result_alignment = inst_ty.abiAlignment(zcu).toLlvm(); | |
| 8086 | 8090 | const alloca_inst = try self.buildAllocaWorkaround(inst_ty, result_alignment); |
| 8087 | 8091 | { |
| 8088 | 8092 | const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, ""); |
| ... | ... | @@ -8165,9 +8169,9 @@ pub const FuncGen = struct { |
| 8165 | 8169 | params: [2]Builder.Value, |
| 8166 | 8170 | ) !Builder.Value { |
| 8167 | 8171 | const o = self.ng.object; |
| 8168 | const mod = o.pt.zcu; | |
| 8169 | const target = mod.getTarget(); | |
| 8170 | const scalar_ty = ty.scalarType(mod); | |
| 8172 | const zcu = o.pt.zcu; | |
| 8173 | const target = zcu.getTarget(); | |
| 8174 | const scalar_ty = ty.scalarType(zcu); | |
| 8171 | 8175 | const scalar_llvm_ty = try o.lowerType(scalar_ty); |
| 8172 | 8176 | |
| 8173 | 8177 | if (intrinsicsAllowed(scalar_ty, target)) { |
| ... | ... | @@ -8205,8 +8209,8 @@ pub const FuncGen = struct { |
| 8205 | 8209 | .gte => .sge, |
| 8206 | 8210 | }; |
| 8207 | 8211 | |
| 8208 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 8209 | const vec_len = ty.vectorLen(mod); | |
| 8212 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 8213 | const vec_len = ty.vectorLen(zcu); | |
| 8210 | 8214 | const vector_result_ty = try o.builder.vectorType(.normal, vec_len, .i32); |
| 8211 | 8215 | |
| 8212 | 8216 | const init = try o.builder.poisonValue(vector_result_ty); |
| ... | ... | @@ -8271,9 +8275,9 @@ pub const FuncGen = struct { |
| 8271 | 8275 | params: [params_len]Builder.Value, |
| 8272 | 8276 | ) !Builder.Value { |
| 8273 | 8277 | const o = self.ng.object; |
| 8274 | const mod = o.pt.zcu; | |
| 8275 | const target = mod.getTarget(); | |
| 8276 | const scalar_ty = ty.scalarType(mod); | |
| 8278 | const zcu = o.pt.zcu; | |
| 8279 | const target = zcu.getTarget(); | |
| 8280 | const scalar_ty = ty.scalarType(zcu); | |
| 8277 | 8281 | const llvm_ty = try o.lowerType(ty); |
| 8278 | 8282 | |
| 8279 | 8283 | if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) { |
| ... | ... | @@ -8382,9 +8386,9 @@ pub const FuncGen = struct { |
| 8382 | 8386 | ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len], |
| 8383 | 8387 | scalar_llvm_ty, |
| 8384 | 8388 | ); |
| 8385 | if (ty.zigTypeTag(mod) == .Vector) { | |
| 8389 | if (ty.zigTypeTag(zcu) == .Vector) { | |
| 8386 | 8390 | const result = try o.builder.poisonValue(llvm_ty); |
| 8387 | return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod)); | |
| 8391 | return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(zcu)); | |
| 8388 | 8392 | } |
| 8389 | 8393 | |
| 8390 | 8394 | return self.wip.call( |
| ... | ... | @@ -8413,7 +8417,7 @@ pub const FuncGen = struct { |
| 8413 | 8417 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8414 | 8418 | const o = self.ng.object; |
| 8415 | 8419 | const pt = o.pt; |
| 8416 | const mod = pt.zcu; | |
| 8420 | const zcu = pt.zcu; | |
| 8417 | 8421 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 8418 | 8422 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 8419 | 8423 | |
| ... | ... | @@ -8421,7 +8425,7 @@ pub const FuncGen = struct { |
| 8421 | 8425 | const rhs = try self.resolveInst(extra.rhs); |
| 8422 | 8426 | |
| 8423 | 8427 | const lhs_ty = self.typeOf(extra.lhs); |
| 8424 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 8428 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 8425 | 8429 | |
| 8426 | 8430 | const dest_ty = self.typeOfIndex(inst); |
| 8427 | 8431 | const llvm_dest_ty = try o.lowerType(dest_ty); |
| ... | ... | @@ -8429,7 +8433,7 @@ pub const FuncGen = struct { |
| 8429 | 8433 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 8430 | 8434 | |
| 8431 | 8435 | const result = try self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 8432 | const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(mod)) | |
| 8436 | const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) | |
| 8433 | 8437 | .ashr |
| 8434 | 8438 | else |
| 8435 | 8439 | .lshr, result, casted_rhs, ""); |
| ... | ... | @@ -8439,8 +8443,8 @@ pub const FuncGen = struct { |
| 8439 | 8443 | const result_index = o.llvmFieldIndex(dest_ty, 0).?; |
| 8440 | 8444 | const overflow_index = o.llvmFieldIndex(dest_ty, 1).?; |
| 8441 | 8445 | |
| 8442 | if (isByRef(dest_ty, pt)) { | |
| 8443 | const result_alignment = dest_ty.abiAlignment(pt).toLlvm(); | |
| 8446 | if (isByRef(dest_ty, zcu)) { | |
| 8447 | const result_alignment = dest_ty.abiAlignment(zcu).toLlvm(); | |
| 8444 | 8448 | const alloca_inst = try self.buildAllocaWorkaround(dest_ty, result_alignment); |
| 8445 | 8449 | { |
| 8446 | 8450 | const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, ""); |
| ... | ... | @@ -8483,17 +8487,17 @@ pub const FuncGen = struct { |
| 8483 | 8487 | |
| 8484 | 8488 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8485 | 8489 | const o = self.ng.object; |
| 8486 | const mod = o.pt.zcu; | |
| 8490 | const zcu = o.pt.zcu; | |
| 8487 | 8491 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8488 | 8492 | |
| 8489 | 8493 | const lhs = try self.resolveInst(bin_op.lhs); |
| 8490 | 8494 | const rhs = try self.resolveInst(bin_op.rhs); |
| 8491 | 8495 | |
| 8492 | 8496 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 8493 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 8497 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 8494 | 8498 | |
| 8495 | 8499 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 8496 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(mod)) | |
| 8500 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) | |
| 8497 | 8501 | .@"shl nsw" |
| 8498 | 8502 | else |
| 8499 | 8503 | .@"shl nuw", lhs, casted_rhs, ""); |
| ... | ... | @@ -8515,15 +8519,15 @@ pub const FuncGen = struct { |
| 8515 | 8519 | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8516 | 8520 | const o = self.ng.object; |
| 8517 | 8521 | const pt = o.pt; |
| 8518 | const mod = pt.zcu; | |
| 8522 | const zcu = pt.zcu; | |
| 8519 | 8523 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8520 | 8524 | |
| 8521 | 8525 | const lhs = try self.resolveInst(bin_op.lhs); |
| 8522 | 8526 | const rhs = try self.resolveInst(bin_op.rhs); |
| 8523 | 8527 | |
| 8524 | 8528 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 8525 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 8526 | const lhs_bits = lhs_scalar_ty.bitSize(pt); | |
| 8529 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 8530 | const lhs_bits = lhs_scalar_ty.bitSize(zcu); | |
| 8527 | 8531 | |
| 8528 | 8532 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 8529 | 8533 | |
| ... | ... | @@ -8532,7 +8536,7 @@ pub const FuncGen = struct { |
| 8532 | 8536 | const result = try self.wip.callIntrinsic( |
| 8533 | 8537 | .normal, |
| 8534 | 8538 | .none, |
| 8535 | if (lhs_scalar_ty.isSignedInt(mod)) .@"sshl.sat" else .@"ushl.sat", | |
| 8539 | if (lhs_scalar_ty.isSignedInt(zcu)) .@"sshl.sat" else .@"ushl.sat", | |
| 8536 | 8540 | &.{llvm_lhs_ty}, |
| 8537 | 8541 | &.{ lhs, casted_rhs }, |
| 8538 | 8542 | "", |
| ... | ... | @@ -8557,17 +8561,17 @@ pub const FuncGen = struct { |
| 8557 | 8561 | |
| 8558 | 8562 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 8559 | 8563 | const o = self.ng.object; |
| 8560 | const mod = o.pt.zcu; | |
| 8564 | const zcu = o.pt.zcu; | |
| 8561 | 8565 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8562 | 8566 | |
| 8563 | 8567 | const lhs = try self.resolveInst(bin_op.lhs); |
| 8564 | 8568 | const rhs = try self.resolveInst(bin_op.rhs); |
| 8565 | 8569 | |
| 8566 | 8570 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 8567 | const lhs_scalar_ty = lhs_ty.scalarType(mod); | |
| 8571 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | |
| 8568 | 8572 | |
| 8569 | 8573 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 8570 | const is_signed_int = lhs_scalar_ty.isSignedInt(mod); | |
| 8574 | const is_signed_int = lhs_scalar_ty.isSignedInt(zcu); | |
| 8571 | 8575 | |
| 8572 | 8576 | return self.wip.bin(if (is_exact) |
| 8573 | 8577 | if (is_signed_int) .@"ashr exact" else .@"lshr exact" |
| ... | ... | @@ -8576,13 +8580,13 @@ pub const FuncGen = struct { |
| 8576 | 8580 | |
| 8577 | 8581 | fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8578 | 8582 | const o = self.ng.object; |
| 8579 | const mod = o.pt.zcu; | |
| 8583 | const zcu = o.pt.zcu; | |
| 8580 | 8584 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8581 | 8585 | const operand = try self.resolveInst(ty_op.operand); |
| 8582 | 8586 | const operand_ty = self.typeOf(ty_op.operand); |
| 8583 | const scalar_ty = operand_ty.scalarType(mod); | |
| 8587 | const scalar_ty = operand_ty.scalarType(zcu); | |
| 8584 | 8588 | |
| 8585 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 8589 | switch (scalar_ty.zigTypeTag(zcu)) { | |
| 8586 | 8590 | .Int => return self.wip.callIntrinsic( |
| 8587 | 8591 | .normal, |
| 8588 | 8592 | .none, |
| ... | ... | @@ -8598,13 +8602,13 @@ pub const FuncGen = struct { |
| 8598 | 8602 | |
| 8599 | 8603 | fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8600 | 8604 | const o = self.ng.object; |
| 8601 | const mod = o.pt.zcu; | |
| 8605 | const zcu = o.pt.zcu; | |
| 8602 | 8606 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8603 | 8607 | const dest_ty = self.typeOfIndex(inst); |
| 8604 | 8608 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8605 | 8609 | const operand = try self.resolveInst(ty_op.operand); |
| 8606 | 8610 | const operand_ty = self.typeOf(ty_op.operand); |
| 8607 | const operand_info = operand_ty.intInfo(mod); | |
| 8611 | const operand_info = operand_ty.intInfo(zcu); | |
| 8608 | 8612 | |
| 8609 | 8613 | return self.wip.conv(switch (operand_info.signedness) { |
| 8610 | 8614 | .signed => .signed, |
| ... | ... | @@ -8622,12 +8626,12 @@ pub const FuncGen = struct { |
| 8622 | 8626 | |
| 8623 | 8627 | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8624 | 8628 | const o = self.ng.object; |
| 8625 | const mod = o.pt.zcu; | |
| 8629 | const zcu = o.pt.zcu; | |
| 8626 | 8630 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8627 | 8631 | const operand = try self.resolveInst(ty_op.operand); |
| 8628 | 8632 | const operand_ty = self.typeOf(ty_op.operand); |
| 8629 | 8633 | const dest_ty = self.typeOfIndex(inst); |
| 8630 | const target = mod.getTarget(); | |
| 8634 | const target = zcu.getTarget(); | |
| 8631 | 8635 | const dest_bits = dest_ty.floatBits(target); |
| 8632 | 8636 | const src_bits = operand_ty.floatBits(target); |
| 8633 | 8637 | |
| ... | ... | @@ -8656,12 +8660,12 @@ pub const FuncGen = struct { |
| 8656 | 8660 | |
| 8657 | 8661 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8658 | 8662 | const o = self.ng.object; |
| 8659 | const mod = o.pt.zcu; | |
| 8663 | const zcu = o.pt.zcu; | |
| 8660 | 8664 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 8661 | 8665 | const operand = try self.resolveInst(ty_op.operand); |
| 8662 | 8666 | const operand_ty = self.typeOf(ty_op.operand); |
| 8663 | 8667 | const dest_ty = self.typeOfIndex(inst); |
| 8664 | const target = mod.getTarget(); | |
| 8668 | const target = zcu.getTarget(); | |
| 8665 | 8669 | |
| 8666 | 8670 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 8667 | 8671 | return self.wip.cast(.fpext, operand, try o.lowerType(dest_ty), ""); |
| ... | ... | @@ -8669,18 +8673,18 @@ pub const FuncGen = struct { |
| 8669 | 8673 | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 8670 | 8674 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8671 | 8675 | |
| 8672 | const dest_bits = dest_ty.scalarType(mod).floatBits(target); | |
| 8673 | const src_bits = operand_ty.scalarType(mod).floatBits(target); | |
| 8676 | const dest_bits = dest_ty.scalarType(zcu).floatBits(target); | |
| 8677 | const src_bits = operand_ty.scalarType(zcu).floatBits(target); | |
| 8674 | 8678 | const fn_name = try o.builder.strtabStringFmt("__extend{s}f{s}f2", .{ |
| 8675 | 8679 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), |
| 8676 | 8680 | }); |
| 8677 | 8681 | |
| 8678 | 8682 | const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); |
| 8679 | if (dest_ty.isVector(mod)) return self.buildElementwiseCall( | |
| 8683 | if (dest_ty.isVector(zcu)) return self.buildElementwiseCall( | |
| 8680 | 8684 | libc_fn, |
| 8681 | 8685 | &.{operand}, |
| 8682 | 8686 | try o.builder.poisonValue(dest_llvm_ty), |
| 8683 | dest_ty.vectorLen(mod), | |
| 8687 | dest_ty.vectorLen(zcu), | |
| 8684 | 8688 | ); |
| 8685 | 8689 | return self.wip.call( |
| 8686 | 8690 | .normal, |
| ... | ... | @@ -8715,9 +8719,9 @@ pub const FuncGen = struct { |
| 8715 | 8719 | fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value { |
| 8716 | 8720 | const o = self.ng.object; |
| 8717 | 8721 | const pt = o.pt; |
| 8718 | const mod = pt.zcu; | |
| 8719 | const operand_is_ref = isByRef(operand_ty, pt); | |
| 8720 | const result_is_ref = isByRef(inst_ty, pt); | |
| 8722 | const zcu = pt.zcu; | |
| 8723 | const operand_is_ref = isByRef(operand_ty, zcu); | |
| 8724 | const result_is_ref = isByRef(inst_ty, zcu); | |
| 8721 | 8725 | const llvm_dest_ty = try o.lowerType(inst_ty); |
| 8722 | 8726 | |
| 8723 | 8727 | if (operand_is_ref and result_is_ref) { |
| ... | ... | @@ -8731,18 +8735,18 @@ pub const FuncGen = struct { |
| 8731 | 8735 | return self.wip.conv(.unsigned, operand, llvm_dest_ty, ""); |
| 8732 | 8736 | } |
| 8733 | 8737 | |
| 8734 | if (operand_ty.zigTypeTag(mod) == .Int and inst_ty.isPtrAtRuntime(mod)) { | |
| 8738 | if (operand_ty.zigTypeTag(zcu) == .Int and inst_ty.isPtrAtRuntime(zcu)) { | |
| 8735 | 8739 | return self.wip.cast(.inttoptr, operand, llvm_dest_ty, ""); |
| 8736 | 8740 | } |
| 8737 | 8741 | |
| 8738 | if (operand_ty.zigTypeTag(mod) == .Vector and inst_ty.zigTypeTag(mod) == .Array) { | |
| 8739 | const elem_ty = operand_ty.childType(mod); | |
| 8742 | if (operand_ty.zigTypeTag(zcu) == .Vector and inst_ty.zigTypeTag(zcu) == .Array) { | |
| 8743 | const elem_ty = operand_ty.childType(zcu); | |
| 8740 | 8744 | if (!result_is_ref) { |
| 8741 | 8745 | return self.ng.todo("implement bitcast vector to non-ref array", .{}); |
| 8742 | 8746 | } |
| 8743 | const alignment = inst_ty.abiAlignment(pt).toLlvm(); | |
| 8747 | const alignment = inst_ty.abiAlignment(zcu).toLlvm(); | |
| 8744 | 8748 | const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); |
| 8745 | const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8; | |
| 8749 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; | |
| 8746 | 8750 | if (bitcast_ok) { |
| 8747 | 8751 | _ = try self.wip.store(.normal, operand, array_ptr, alignment); |
| 8748 | 8752 | } else { |
| ... | ... | @@ -8750,7 +8754,7 @@ pub const FuncGen = struct { |
| 8750 | 8754 | // a simple bitcast will not work, and we fall back to extractelement. |
| 8751 | 8755 | const llvm_usize = try o.lowerType(Type.usize); |
| 8752 | 8756 | const usize_zero = try o.builder.intValue(llvm_usize, 0); |
| 8753 | const vector_len = operand_ty.arrayLen(mod); | |
| 8757 | const vector_len = operand_ty.arrayLen(zcu); | |
| 8754 | 8758 | var i: u64 = 0; |
| 8755 | 8759 | while (i < vector_len) : (i += 1) { |
| 8756 | 8760 | const elem_ptr = try self.wip.gep(.inbounds, llvm_dest_ty, array_ptr, &.{ |
| ... | ... | @@ -8762,16 +8766,16 @@ pub const FuncGen = struct { |
| 8762 | 8766 | } |
| 8763 | 8767 | } |
| 8764 | 8768 | return array_ptr; |
| 8765 | } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { | |
| 8766 | const elem_ty = operand_ty.childType(mod); | |
| 8769 | } else if (operand_ty.zigTypeTag(zcu) == .Array and inst_ty.zigTypeTag(zcu) == .Vector) { | |
| 8770 | const elem_ty = operand_ty.childType(zcu); | |
| 8767 | 8771 | const llvm_vector_ty = try o.lowerType(inst_ty); |
| 8768 | 8772 | if (!operand_is_ref) return self.ng.todo("implement bitcast non-ref array to vector", .{}); |
| 8769 | 8773 | |
| 8770 | const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8; | |
| 8774 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; | |
| 8771 | 8775 | if (bitcast_ok) { |
| 8772 | 8776 | // The array is aligned to the element's alignment, while the vector might have a completely |
| 8773 | 8777 | // different alignment. This means we need to enforce the alignment of this load. |
| 8774 | const alignment = elem_ty.abiAlignment(pt).toLlvm(); | |
| 8778 | const alignment = elem_ty.abiAlignment(zcu).toLlvm(); | |
| 8775 | 8779 | return self.wip.load(.normal, llvm_vector_ty, operand, alignment, ""); |
| 8776 | 8780 | } else { |
| 8777 | 8781 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| ... | ... | @@ -8780,7 +8784,7 @@ pub const FuncGen = struct { |
| 8780 | 8784 | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 8781 | 8785 | const llvm_usize = try o.lowerType(Type.usize); |
| 8782 | 8786 | const usize_zero = try o.builder.intValue(llvm_usize, 0); |
| 8783 | const vector_len = operand_ty.arrayLen(mod); | |
| 8787 | const vector_len = operand_ty.arrayLen(zcu); | |
| 8784 | 8788 | var vector = try o.builder.poisonValue(llvm_vector_ty); |
| 8785 | 8789 | var i: u64 = 0; |
| 8786 | 8790 | while (i < vector_len) : (i += 1) { |
| ... | ... | @@ -8796,25 +8800,25 @@ pub const FuncGen = struct { |
| 8796 | 8800 | } |
| 8797 | 8801 | |
| 8798 | 8802 | if (operand_is_ref) { |
| 8799 | const alignment = operand_ty.abiAlignment(pt).toLlvm(); | |
| 8803 | const alignment = operand_ty.abiAlignment(zcu).toLlvm(); | |
| 8800 | 8804 | return self.wip.load(.normal, llvm_dest_ty, operand, alignment, ""); |
| 8801 | 8805 | } |
| 8802 | 8806 | |
| 8803 | 8807 | if (result_is_ref) { |
| 8804 | const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm(); | |
| 8808 | const alignment = operand_ty.abiAlignment(zcu).max(inst_ty.abiAlignment(zcu)).toLlvm(); | |
| 8805 | 8809 | const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); |
| 8806 | 8810 | _ = try self.wip.store(.normal, operand, result_ptr, alignment); |
| 8807 | 8811 | return result_ptr; |
| 8808 | 8812 | } |
| 8809 | 8813 | |
| 8810 | 8814 | if (llvm_dest_ty.isStruct(&o.builder) or |
| 8811 | ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and | |
| 8812 | operand_ty.bitSize(pt) != inst_ty.bitSize(pt))) | |
| 8815 | ((operand_ty.zigTypeTag(zcu) == .Vector or inst_ty.zigTypeTag(zcu) == .Vector) and | |
| 8816 | operand_ty.bitSize(zcu) != inst_ty.bitSize(zcu))) | |
| 8813 | 8817 | { |
| 8814 | 8818 | // Both our operand and our result are values, not pointers, |
| 8815 | 8819 | // but LLVM won't let us bitcast struct values or vectors with padding bits. |
| 8816 | 8820 | // Therefore, we store operand to alloca, then load for result. |
| 8817 | const alignment = operand_ty.abiAlignment(pt).max(inst_ty.abiAlignment(pt)).toLlvm(); | |
| 8821 | const alignment = operand_ty.abiAlignment(zcu).max(inst_ty.abiAlignment(zcu)).toLlvm(); | |
| 8818 | 8822 | const result_ptr = try self.buildAllocaWorkaround(inst_ty, alignment); |
| 8819 | 8823 | _ = try self.wip.store(.normal, operand, result_ptr, alignment); |
| 8820 | 8824 | return self.wip.load(.normal, llvm_dest_ty, result_ptr, alignment, ""); |
| ... | ... | @@ -8868,7 +8872,7 @@ pub const FuncGen = struct { |
| 8868 | 8872 | }; |
| 8869 | 8873 | |
| 8870 | 8874 | const mod = self.ng.ownerModule(); |
| 8871 | if (isByRef(inst_ty, pt)) { | |
| 8875 | if (isByRef(inst_ty, zcu)) { | |
| 8872 | 8876 | _ = try self.wip.callIntrinsic( |
| 8873 | 8877 | .normal, |
| 8874 | 8878 | .none, |
| ... | ... | @@ -8882,7 +8886,7 @@ pub const FuncGen = struct { |
| 8882 | 8886 | "", |
| 8883 | 8887 | ); |
| 8884 | 8888 | } else if (mod.optimize_mode == .Debug) { |
| 8885 | const alignment = inst_ty.abiAlignment(pt).toLlvm(); | |
| 8889 | const alignment = inst_ty.abiAlignment(zcu).toLlvm(); | |
| 8886 | 8890 | const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment); |
| 8887 | 8891 | _ = try self.wip.store(.normal, arg_val, alloca, alignment); |
| 8888 | 8892 | _ = try self.wip.callIntrinsic( |
| ... | ... | @@ -8919,28 +8923,28 @@ pub const FuncGen = struct { |
| 8919 | 8923 | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8920 | 8924 | const o = self.ng.object; |
| 8921 | 8925 | const pt = o.pt; |
| 8922 | const mod = pt.zcu; | |
| 8926 | const zcu = pt.zcu; | |
| 8923 | 8927 | const ptr_ty = self.typeOfIndex(inst); |
| 8924 | const pointee_type = ptr_ty.childType(mod); | |
| 8925 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(pt)) | |
| 8928 | const pointee_type = ptr_ty.childType(zcu); | |
| 8929 | if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) | |
| 8926 | 8930 | return (try o.lowerPtrToVoid(ptr_ty)).toValue(); |
| 8927 | 8931 | |
| 8928 | 8932 | //const pointee_llvm_ty = try o.lowerType(pointee_type); |
| 8929 | const alignment = ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 8933 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 8930 | 8934 | return self.buildAllocaWorkaround(pointee_type, alignment); |
| 8931 | 8935 | } |
| 8932 | 8936 | |
| 8933 | 8937 | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8934 | 8938 | const o = self.ng.object; |
| 8935 | 8939 | const pt = o.pt; |
| 8936 | const mod = pt.zcu; | |
| 8940 | const zcu = pt.zcu; | |
| 8937 | 8941 | const ptr_ty = self.typeOfIndex(inst); |
| 8938 | const ret_ty = ptr_ty.childType(mod); | |
| 8939 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) | |
| 8942 | const ret_ty = ptr_ty.childType(zcu); | |
| 8943 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) | |
| 8940 | 8944 | return (try o.lowerPtrToVoid(ptr_ty)).toValue(); |
| 8941 | 8945 | if (self.ret_ptr != .none) return self.ret_ptr; |
| 8942 | 8946 | //const ret_llvm_ty = try o.lowerType(ret_ty); |
| 8943 | const alignment = ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 8947 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 8944 | 8948 | return self.buildAllocaWorkaround(ret_ty, alignment); |
| 8945 | 8949 | } |
| 8946 | 8950 | |
| ... | ... | @@ -8962,19 +8966,19 @@ pub const FuncGen = struct { |
| 8962 | 8966 | alignment: Builder.Alignment, |
| 8963 | 8967 | ) Allocator.Error!Builder.Value { |
| 8964 | 8968 | const o = self.ng.object; |
| 8965 | return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment); | |
| 8969 | return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt.zcu), .i8), alignment); | |
| 8966 | 8970 | } |
| 8967 | 8971 | |
| 8968 | 8972 | fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 8969 | 8973 | const o = self.ng.object; |
| 8970 | 8974 | const pt = o.pt; |
| 8971 | const mod = pt.zcu; | |
| 8975 | const zcu = pt.zcu; | |
| 8972 | 8976 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 8973 | 8977 | const dest_ptr = try self.resolveInst(bin_op.lhs); |
| 8974 | 8978 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 8975 | const operand_ty = ptr_ty.childType(mod); | |
| 8979 | const operand_ty = ptr_ty.childType(zcu); | |
| 8976 | 8980 | |
| 8977 | const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false; | |
| 8981 | const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false; | |
| 8978 | 8982 | if (val_is_undef) { |
| 8979 | 8983 | const owner_mod = self.ng.ownerModule(); |
| 8980 | 8984 | |
| ... | ... | @@ -8991,7 +8995,7 @@ pub const FuncGen = struct { |
| 8991 | 8995 | return .none; |
| 8992 | 8996 | } |
| 8993 | 8997 | |
| 8994 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 8998 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 8995 | 8999 | const needs_bitmask = (ptr_info.packed_offset.host_size != 0); |
| 8996 | 9000 | if (needs_bitmask) { |
| 8997 | 9001 | // TODO: only some bits are to be undef, we cannot write with a simple memset. |
| ... | ... | @@ -9000,13 +9004,13 @@ pub const FuncGen = struct { |
| 9000 | 9004 | return .none; |
| 9001 | 9005 | } |
| 9002 | 9006 | |
| 9003 | const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(pt)); | |
| 9007 | const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(zcu)); | |
| 9004 | 9008 | _ = try self.wip.callMemSet( |
| 9005 | 9009 | dest_ptr, |
| 9006 | ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 9010 | ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 9007 | 9011 | if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8), |
| 9008 | 9012 | len, |
| 9009 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, | |
| 9013 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal, | |
| 9010 | 9014 | ); |
| 9011 | 9015 | if (safety and owner_mod.valgrind) { |
| 9012 | 9016 | try self.valgrindMarkUndef(dest_ptr, len); |
| ... | ... | @@ -9027,8 +9031,8 @@ pub const FuncGen = struct { |
| 9027 | 9031 | /// The first instruction of `body_tail` is the one whose copy we want to elide. |
| 9028 | 9032 | fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool { |
| 9029 | 9033 | const o = fg.ng.object; |
| 9030 | const mod = o.pt.zcu; | |
| 9031 | const ip = &mod.intern_pool; | |
| 9034 | const zcu = o.pt.zcu; | |
| 9035 | const ip = &zcu.intern_pool; | |
| 9032 | 9036 | for (body_tail[1..]) |body_inst| { |
| 9033 | 9037 | switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip)) { |
| 9034 | 9038 | .none => continue, |
| ... | ... | @@ -9044,15 +9048,15 @@ pub const FuncGen = struct { |
| 9044 | 9048 | fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 9045 | 9049 | const o = fg.ng.object; |
| 9046 | 9050 | const pt = o.pt; |
| 9047 | const mod = pt.zcu; | |
| 9051 | const zcu = pt.zcu; | |
| 9048 | 9052 | const inst = body_tail[0]; |
| 9049 | 9053 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9050 | 9054 | const ptr_ty = fg.typeOf(ty_op.operand); |
| 9051 | const ptr_info = ptr_ty.ptrInfo(mod); | |
| 9055 | const ptr_info = ptr_ty.ptrInfo(zcu); | |
| 9052 | 9056 | const ptr = try fg.resolveInst(ty_op.operand); |
| 9053 | 9057 | |
| 9054 | 9058 | elide: { |
| 9055 | if (!isByRef(Type.fromInterned(ptr_info.child), pt)) break :elide; | |
| 9059 | if (!isByRef(Type.fromInterned(ptr_info.child), zcu)) break :elide; | |
| 9056 | 9060 | if (!canElideLoad(fg, body_tail)) break :elide; |
| 9057 | 9061 | return ptr; |
| 9058 | 9062 | } |
| ... | ... | @@ -9105,34 +9109,34 @@ pub const FuncGen = struct { |
| 9105 | 9109 | ) !Builder.Value { |
| 9106 | 9110 | const o = self.ng.object; |
| 9107 | 9111 | const pt = o.pt; |
| 9108 | const mod = pt.zcu; | |
| 9112 | const zcu = pt.zcu; | |
| 9109 | 9113 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 9110 | 9114 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 9111 | 9115 | const ptr = try self.resolveInst(extra.ptr); |
| 9112 | 9116 | const ptr_ty = self.typeOf(extra.ptr); |
| 9113 | 9117 | var expected_value = try self.resolveInst(extra.expected_value); |
| 9114 | 9118 | var new_value = try self.resolveInst(extra.new_value); |
| 9115 | const operand_ty = ptr_ty.childType(mod); | |
| 9119 | const operand_ty = ptr_ty.childType(zcu); | |
| 9116 | 9120 | const llvm_operand_ty = try o.lowerType(operand_ty); |
| 9117 | 9121 | const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false); |
| 9118 | 9122 | if (llvm_abi_ty != .none) { |
| 9119 | 9123 | // operand needs widening and truncating |
| 9120 | 9124 | const signedness: Builder.Function.Instruction.Cast.Signedness = |
| 9121 | if (operand_ty.isSignedInt(mod)) .signed else .unsigned; | |
| 9125 | if (operand_ty.isSignedInt(zcu)) .signed else .unsigned; | |
| 9122 | 9126 | expected_value = try self.wip.conv(signedness, expected_value, llvm_abi_ty, ""); |
| 9123 | 9127 | new_value = try self.wip.conv(signedness, new_value, llvm_abi_ty, ""); |
| 9124 | 9128 | } |
| 9125 | 9129 | |
| 9126 | 9130 | const result = try self.wip.cmpxchg( |
| 9127 | 9131 | kind, |
| 9128 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, | |
| 9132 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal, | |
| 9129 | 9133 | ptr, |
| 9130 | 9134 | expected_value, |
| 9131 | 9135 | new_value, |
| 9132 | 9136 | self.sync_scope, |
| 9133 | 9137 | toLlvmAtomicOrdering(extra.successOrder()), |
| 9134 | 9138 | toLlvmAtomicOrdering(extra.failureOrder()), |
| 9135 | ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 9139 | ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 9136 | 9140 | "", |
| 9137 | 9141 | ); |
| 9138 | 9142 | |
| ... | ... | @@ -9142,7 +9146,7 @@ pub const FuncGen = struct { |
| 9142 | 9146 | if (llvm_abi_ty != .none) payload = try self.wip.cast(.trunc, payload, llvm_operand_ty, ""); |
| 9143 | 9147 | const success_bit = try self.wip.extractValue(result, &.{1}, ""); |
| 9144 | 9148 | |
| 9145 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 9149 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 9146 | 9150 | const zero = try o.builder.zeroInitValue(payload.typeOfWip(&self.wip)); |
| 9147 | 9151 | return self.wip.select(.normal, success_bit, zero, payload, ""); |
| 9148 | 9152 | } |
| ... | ... | @@ -9156,14 +9160,14 @@ pub const FuncGen = struct { |
| 9156 | 9160 | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9157 | 9161 | const o = self.ng.object; |
| 9158 | 9162 | const pt = o.pt; |
| 9159 | const mod = pt.zcu; | |
| 9163 | const zcu = pt.zcu; | |
| 9160 | 9164 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 9161 | 9165 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 9162 | 9166 | const ptr = try self.resolveInst(pl_op.operand); |
| 9163 | 9167 | const ptr_ty = self.typeOf(pl_op.operand); |
| 9164 | const operand_ty = ptr_ty.childType(mod); | |
| 9168 | const operand_ty = ptr_ty.childType(zcu); | |
| 9165 | 9169 | const operand = try self.resolveInst(extra.operand); |
| 9166 | const is_signed_int = operand_ty.isSignedInt(mod); | |
| 9170 | const is_signed_int = operand_ty.isSignedInt(zcu); | |
| 9167 | 9171 | const is_float = operand_ty.isRuntimeFloat(); |
| 9168 | 9172 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); |
| 9169 | 9173 | const ordering = toLlvmAtomicOrdering(extra.ordering()); |
| ... | ... | @@ -9171,8 +9175,8 @@ pub const FuncGen = struct { |
| 9171 | 9175 | const llvm_operand_ty = try o.lowerType(operand_ty); |
| 9172 | 9176 | |
| 9173 | 9177 | const access_kind: Builder.MemoryAccessKind = |
| 9174 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | |
| 9175 | const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 9178 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | |
| 9179 | const ptr_alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 9176 | 9180 | |
| 9177 | 9181 | if (llvm_abi_ty != .none) { |
| 9178 | 9182 | // operand needs widening and truncating or bitcasting. |
| ... | ... | @@ -9220,19 +9224,19 @@ pub const FuncGen = struct { |
| 9220 | 9224 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9221 | 9225 | const o = self.ng.object; |
| 9222 | 9226 | const pt = o.pt; |
| 9223 | const mod = pt.zcu; | |
| 9227 | const zcu = pt.zcu; | |
| 9224 | 9228 | const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| 9225 | 9229 | const ptr = try self.resolveInst(atomic_load.ptr); |
| 9226 | 9230 | const ptr_ty = self.typeOf(atomic_load.ptr); |
| 9227 | const info = ptr_ty.ptrInfo(mod); | |
| 9231 | const info = ptr_ty.ptrInfo(zcu); | |
| 9228 | 9232 | const elem_ty = Type.fromInterned(info.child); |
| 9229 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 9233 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none; | |
| 9230 | 9234 | const ordering = toLlvmAtomicOrdering(atomic_load.order); |
| 9231 | 9235 | const llvm_abi_ty = try o.getAtomicAbiType(elem_ty, false); |
| 9232 | 9236 | const ptr_alignment = (if (info.flags.alignment != .none) |
| 9233 | 9237 | @as(InternPool.Alignment, info.flags.alignment) |
| 9234 | 9238 | else |
| 9235 | Type.fromInterned(info.child).abiAlignment(pt)).toLlvm(); | |
| 9239 | Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm(); | |
| 9236 | 9240 | const access_kind: Builder.MemoryAccessKind = |
| 9237 | 9241 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| 9238 | 9242 | const elem_llvm_ty = try o.lowerType(elem_ty); |
| ... | ... | @@ -9268,11 +9272,11 @@ pub const FuncGen = struct { |
| 9268 | 9272 | ) !Builder.Value { |
| 9269 | 9273 | const o = self.ng.object; |
| 9270 | 9274 | const pt = o.pt; |
| 9271 | const mod = pt.zcu; | |
| 9275 | const zcu = pt.zcu; | |
| 9272 | 9276 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9273 | 9277 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 9274 | const operand_ty = ptr_ty.childType(mod); | |
| 9275 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 9278 | const operand_ty = ptr_ty.childType(zcu); | |
| 9279 | if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .none; | |
| 9276 | 9280 | const ptr = try self.resolveInst(bin_op.lhs); |
| 9277 | 9281 | var element = try self.resolveInst(bin_op.rhs); |
| 9278 | 9282 | const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false); |
| ... | ... | @@ -9280,7 +9284,7 @@ pub const FuncGen = struct { |
| 9280 | 9284 | if (llvm_abi_ty != .none) { |
| 9281 | 9285 | // operand needs widening |
| 9282 | 9286 | element = try self.wip.conv( |
| 9283 | if (operand_ty.isSignedInt(mod)) .signed else .unsigned, | |
| 9287 | if (operand_ty.isSignedInt(zcu)) .signed else .unsigned, | |
| 9284 | 9288 | element, |
| 9285 | 9289 | llvm_abi_ty, |
| 9286 | 9290 | "", |
| ... | ... | @@ -9293,26 +9297,26 @@ pub const FuncGen = struct { |
| 9293 | 9297 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 9294 | 9298 | const o = self.ng.object; |
| 9295 | 9299 | const pt = o.pt; |
| 9296 | const mod = pt.zcu; | |
| 9300 | const zcu = pt.zcu; | |
| 9297 | 9301 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9298 | 9302 | const dest_slice = try self.resolveInst(bin_op.lhs); |
| 9299 | 9303 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 9300 | 9304 | const elem_ty = self.typeOf(bin_op.rhs); |
| 9301 | const dest_ptr_align = ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 9305 | const dest_ptr_align = ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 9302 | 9306 | const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty); |
| 9303 | 9307 | const access_kind: Builder.MemoryAccessKind = |
| 9304 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | |
| 9308 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | |
| 9305 | 9309 | |
| 9306 | 9310 | // Any WebAssembly runtime will trap when the destination pointer is out-of-bounds, regardless |
| 9307 | 9311 | // of the length. This means we need to emit a check where we skip the memset when the length |
| 9308 | 9312 | // is 0 as we allow for undefined pointers in 0-sized slices. |
| 9309 | 9313 | // This logic can be removed once https://github.com/ziglang/zig/issues/16360 is done. |
| 9310 | 9314 | const intrinsic_len0_traps = o.target.isWasm() and |
| 9311 | ptr_ty.isSlice(mod) and | |
| 9315 | ptr_ty.isSlice(zcu) and | |
| 9312 | 9316 | std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory); |
| 9313 | 9317 | |
| 9314 | 9318 | if (try self.air.value(bin_op.rhs, pt)) |elem_val| { |
| 9315 | if (elem_val.isUndefDeep(mod)) { | |
| 9319 | if (elem_val.isUndefDeep(zcu)) { | |
| 9316 | 9320 | // Even if safety is disabled, we still emit a memset to undefined since it conveys |
| 9317 | 9321 | // extra information to LLVM. However, safety makes the difference between using |
| 9318 | 9322 | // 0xaa or actual undefined for the fill byte. |
| ... | ... | @@ -9350,7 +9354,7 @@ pub const FuncGen = struct { |
| 9350 | 9354 | } |
| 9351 | 9355 | |
| 9352 | 9356 | const value = try self.resolveInst(bin_op.rhs); |
| 9353 | const elem_abi_size = elem_ty.abiSize(pt); | |
| 9357 | const elem_abi_size = elem_ty.abiSize(zcu); | |
| 9354 | 9358 | |
| 9355 | 9359 | if (elem_abi_size == 1) { |
| 9356 | 9360 | // In this case we can take advantage of LLVM's intrinsic. |
| ... | ... | @@ -9387,9 +9391,9 @@ pub const FuncGen = struct { |
| 9387 | 9391 | const end_block = try self.wip.block(1, "InlineMemsetEnd"); |
| 9388 | 9392 | |
| 9389 | 9393 | const llvm_usize_ty = try o.lowerType(Type.usize); |
| 9390 | const len = switch (ptr_ty.ptrSize(mod)) { | |
| 9394 | const len = switch (ptr_ty.ptrSize(zcu)) { | |
| 9391 | 9395 | .Slice => try self.wip.extractValue(dest_slice, &.{1}, ""), |
| 9392 | .One => try o.builder.intValue(llvm_usize_ty, ptr_ty.childType(mod).arrayLen(mod)), | |
| 9396 | .One => try o.builder.intValue(llvm_usize_ty, ptr_ty.childType(zcu).arrayLen(zcu)), | |
| 9393 | 9397 | .Many, .C => unreachable, |
| 9394 | 9398 | }; |
| 9395 | 9399 | const elem_llvm_ty = try o.lowerType(elem_ty); |
| ... | ... | @@ -9402,9 +9406,9 @@ pub const FuncGen = struct { |
| 9402 | 9406 | _ = try self.wip.brCond(end, body_block, end_block); |
| 9403 | 9407 | |
| 9404 | 9408 | self.wip.cursor = .{ .block = body_block }; |
| 9405 | const elem_abi_align = elem_ty.abiAlignment(pt); | |
| 9409 | const elem_abi_align = elem_ty.abiAlignment(zcu); | |
| 9406 | 9410 | const it_ptr_align = InternPool.Alignment.fromLlvm(dest_ptr_align).min(elem_abi_align).toLlvm(); |
| 9407 | if (isByRef(elem_ty, pt)) { | |
| 9411 | if (isByRef(elem_ty, zcu)) { | |
| 9408 | 9412 | _ = try self.wip.callMemCpy( |
| 9409 | 9413 | it_ptr.toValue(), |
| 9410 | 9414 | it_ptr_align, |
| ... | ... | @@ -9447,7 +9451,7 @@ pub const FuncGen = struct { |
| 9447 | 9451 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9448 | 9452 | const o = self.ng.object; |
| 9449 | 9453 | const pt = o.pt; |
| 9450 | const mod = pt.zcu; | |
| 9454 | const zcu = pt.zcu; | |
| 9451 | 9455 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9452 | 9456 | const dest_slice = try self.resolveInst(bin_op.lhs); |
| 9453 | 9457 | const dest_ptr_ty = self.typeOf(bin_op.lhs); |
| ... | ... | @@ -9456,8 +9460,8 @@ pub const FuncGen = struct { |
| 9456 | 9460 | const src_ptr = try self.sliceOrArrayPtr(src_slice, src_ptr_ty); |
| 9457 | 9461 | const len = try self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty); |
| 9458 | 9462 | const dest_ptr = try self.sliceOrArrayPtr(dest_slice, dest_ptr_ty); |
| 9459 | const access_kind: Builder.MemoryAccessKind = if (src_ptr_ty.isVolatilePtr(mod) or | |
| 9460 | dest_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal; | |
| 9463 | const access_kind: Builder.MemoryAccessKind = if (src_ptr_ty.isVolatilePtr(zcu) or | |
| 9464 | dest_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | |
| 9461 | 9465 | |
| 9462 | 9466 | // When bulk-memory is enabled, this will be lowered to WebAssembly's memory.copy instruction. |
| 9463 | 9467 | // This instruction will trap on an invalid address, regardless of the length. |
| ... | ... | @@ -9466,7 +9470,7 @@ pub const FuncGen = struct { |
| 9466 | 9470 | // This logic can be removed once https://github.com/ziglang/zig/issues/16360 is done. |
| 9467 | 9471 | if (o.target.isWasm() and |
| 9468 | 9472 | std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory) and |
| 9469 | dest_ptr_ty.isSlice(mod)) | |
| 9473 | dest_ptr_ty.isSlice(zcu)) | |
| 9470 | 9474 | { |
| 9471 | 9475 | const usize_zero = try o.builder.intValue(try o.lowerType(Type.usize), 0); |
| 9472 | 9476 | const cond = try self.cmp(.normal, .neq, Type.usize, len, usize_zero); |
| ... | ... | @@ -9476,9 +9480,9 @@ pub const FuncGen = struct { |
| 9476 | 9480 | self.wip.cursor = .{ .block = memcpy_block }; |
| 9477 | 9481 | _ = try self.wip.callMemCpy( |
| 9478 | 9482 | dest_ptr, |
| 9479 | dest_ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 9483 | dest_ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 9480 | 9484 | src_ptr, |
| 9481 | src_ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 9485 | src_ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 9482 | 9486 | len, |
| 9483 | 9487 | access_kind, |
| 9484 | 9488 | ); |
| ... | ... | @@ -9489,9 +9493,9 @@ pub const FuncGen = struct { |
| 9489 | 9493 | |
| 9490 | 9494 | _ = try self.wip.callMemCpy( |
| 9491 | 9495 | dest_ptr, |
| 9492 | dest_ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 9496 | dest_ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 9493 | 9497 | src_ptr, |
| 9494 | src_ptr_ty.ptrAlignment(pt).toLlvm(), | |
| 9498 | src_ptr_ty.ptrAlignment(zcu).toLlvm(), | |
| 9495 | 9499 | len, |
| 9496 | 9500 | access_kind, |
| 9497 | 9501 | ); |
| ... | ... | @@ -9501,10 +9505,10 @@ pub const FuncGen = struct { |
| 9501 | 9505 | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9502 | 9506 | const o = self.ng.object; |
| 9503 | 9507 | const pt = o.pt; |
| 9504 | const mod = pt.zcu; | |
| 9508 | const zcu = pt.zcu; | |
| 9505 | 9509 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 9506 | const un_ty = self.typeOf(bin_op.lhs).childType(mod); | |
| 9507 | const layout = un_ty.unionGetLayout(pt); | |
| 9510 | const un_ty = self.typeOf(bin_op.lhs).childType(zcu); | |
| 9511 | const layout = un_ty.unionGetLayout(zcu); | |
| 9508 | 9512 | if (layout.tag_size == 0) return .none; |
| 9509 | 9513 | const union_ptr = try self.resolveInst(bin_op.lhs); |
| 9510 | 9514 | const new_tag = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -9523,12 +9527,13 @@ pub const FuncGen = struct { |
| 9523 | 9527 | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9524 | 9528 | const o = self.ng.object; |
| 9525 | 9529 | const pt = o.pt; |
| 9530 | const zcu = pt.zcu; | |
| 9526 | 9531 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9527 | 9532 | const un_ty = self.typeOf(ty_op.operand); |
| 9528 | const layout = un_ty.unionGetLayout(pt); | |
| 9533 | const layout = un_ty.unionGetLayout(zcu); | |
| 9529 | 9534 | if (layout.tag_size == 0) return .none; |
| 9530 | 9535 | const union_handle = try self.resolveInst(ty_op.operand); |
| 9531 | if (isByRef(un_ty, pt)) { | |
| 9536 | if (isByRef(un_ty, zcu)) { | |
| 9532 | 9537 | const llvm_un_ty = try o.lowerType(un_ty); |
| 9533 | 9538 | if (layout.payload_size == 0) |
| 9534 | 9539 | return self.wip.load(.normal, llvm_un_ty, union_handle, .default, ""); |
| ... | ... | @@ -9597,10 +9602,10 @@ pub const FuncGen = struct { |
| 9597 | 9602 | |
| 9598 | 9603 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9599 | 9604 | const o = self.ng.object; |
| 9600 | const mod = o.pt.zcu; | |
| 9605 | const zcu = o.pt.zcu; | |
| 9601 | 9606 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9602 | 9607 | const operand_ty = self.typeOf(ty_op.operand); |
| 9603 | var bits = operand_ty.intInfo(mod).bits; | |
| 9608 | var bits = operand_ty.intInfo(zcu).bits; | |
| 9604 | 9609 | assert(bits % 8 == 0); |
| 9605 | 9610 | |
| 9606 | 9611 | const inst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -9611,8 +9616,8 @@ pub const FuncGen = struct { |
| 9611 | 9616 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte |
| 9612 | 9617 | // The truncated result at the end will be the correct bswap |
| 9613 | 9618 | const scalar_ty = try o.builder.intType(@intCast(bits + 8)); |
| 9614 | if (operand_ty.zigTypeTag(mod) == .Vector) { | |
| 9615 | const vec_len = operand_ty.vectorLen(mod); | |
| 9619 | if (operand_ty.zigTypeTag(zcu) == .Vector) { | |
| 9620 | const vec_len = operand_ty.vectorLen(zcu); | |
| 9616 | 9621 | llvm_operand_ty = try o.builder.vectorType(.normal, vec_len, scalar_ty); |
| 9617 | 9622 | } else llvm_operand_ty = scalar_ty; |
| 9618 | 9623 | |
| ... | ... | @@ -9631,13 +9636,13 @@ pub const FuncGen = struct { |
| 9631 | 9636 | |
| 9632 | 9637 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9633 | 9638 | const o = self.ng.object; |
| 9634 | const mod = o.pt.zcu; | |
| 9635 | const ip = &mod.intern_pool; | |
| 9639 | const zcu = o.pt.zcu; | |
| 9640 | const ip = &zcu.intern_pool; | |
| 9636 | 9641 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9637 | 9642 | const operand = try self.resolveInst(ty_op.operand); |
| 9638 | 9643 | const error_set_ty = ty_op.ty.toType(); |
| 9639 | 9644 | |
| 9640 | const names = error_set_ty.errorSetNames(mod); | |
| 9645 | const names = error_set_ty.errorSetNames(zcu); | |
| 9641 | 9646 | const valid_block = try self.wip.block(@intCast(names.len), "Valid"); |
| 9642 | 9647 | const invalid_block = try self.wip.block(1, "Invalid"); |
| 9643 | 9648 | const end_block = try self.wip.block(2, "End"); |
| ... | ... | @@ -9790,14 +9795,14 @@ pub const FuncGen = struct { |
| 9790 | 9795 | fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9791 | 9796 | const o = self.ng.object; |
| 9792 | 9797 | const pt = o.pt; |
| 9793 | const mod = pt.zcu; | |
| 9798 | const zcu = pt.zcu; | |
| 9794 | 9799 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 9795 | 9800 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 9796 | 9801 | const a = try self.resolveInst(extra.a); |
| 9797 | 9802 | const b = try self.resolveInst(extra.b); |
| 9798 | 9803 | const mask = Value.fromInterned(extra.mask); |
| 9799 | 9804 | const mask_len = extra.mask_len; |
| 9800 | const a_len = self.typeOf(extra.a).vectorLen(mod); | |
| 9805 | const a_len = self.typeOf(extra.a).vectorLen(zcu); | |
| 9801 | 9806 | |
| 9802 | 9807 | // LLVM uses integers larger than the length of the first array to |
| 9803 | 9808 | // index into the second array. This was deemed unnecessarily fragile |
| ... | ... | @@ -9809,10 +9814,10 @@ pub const FuncGen = struct { |
| 9809 | 9814 | |
| 9810 | 9815 | for (values, 0..) |*val, i| { |
| 9811 | 9816 | const elem = try mask.elemValue(pt, i); |
| 9812 | if (elem.isUndef(mod)) { | |
| 9817 | if (elem.isUndef(zcu)) { | |
| 9813 | 9818 | val.* = try o.builder.undefConst(.i32); |
| 9814 | 9819 | } else { |
| 9815 | const int = elem.toSignedInt(pt); | |
| 9820 | const int = elem.toSignedInt(zcu); | |
| 9816 | 9821 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int + a_len); |
| 9817 | 9822 | val.* = try o.builder.intConst(.i32, unsigned); |
| 9818 | 9823 | } |
| ... | ... | @@ -9899,8 +9904,8 @@ pub const FuncGen = struct { |
| 9899 | 9904 | |
| 9900 | 9905 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 9901 | 9906 | const o = self.ng.object; |
| 9902 | const mod = o.pt.zcu; | |
| 9903 | const target = mod.getTarget(); | |
| 9907 | const zcu = o.pt.zcu; | |
| 9908 | const target = zcu.getTarget(); | |
| 9904 | 9909 | |
| 9905 | 9910 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 9906 | 9911 | const operand = try self.resolveInst(reduce.operand); |
| ... | ... | @@ -9916,13 +9921,13 @@ pub const FuncGen = struct { |
| 9916 | 9921 | .Xor => .@"vector.reduce.xor", |
| 9917 | 9922 | else => unreachable, |
| 9918 | 9923 | }, &.{llvm_operand_ty}, &.{operand}, ""), |
| 9919 | .Min, .Max => switch (scalar_ty.zigTypeTag(mod)) { | |
| 9924 | .Min, .Max => switch (scalar_ty.zigTypeTag(zcu)) { | |
| 9920 | 9925 | .Int => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { |
| 9921 | .Min => if (scalar_ty.isSignedInt(mod)) | |
| 9926 | .Min => if (scalar_ty.isSignedInt(zcu)) | |
| 9922 | 9927 | .@"vector.reduce.smin" |
| 9923 | 9928 | else |
| 9924 | 9929 | .@"vector.reduce.umin", |
| 9925 | .Max => if (scalar_ty.isSignedInt(mod)) | |
| 9930 | .Max => if (scalar_ty.isSignedInt(zcu)) | |
| 9926 | 9931 | .@"vector.reduce.smax" |
| 9927 | 9932 | else |
| 9928 | 9933 | .@"vector.reduce.umax", |
| ... | ... | @@ -9936,7 +9941,7 @@ pub const FuncGen = struct { |
| 9936 | 9941 | }, &.{llvm_operand_ty}, &.{operand}, ""), |
| 9937 | 9942 | else => unreachable, |
| 9938 | 9943 | }, |
| 9939 | .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) { | |
| 9944 | .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) { | |
| 9940 | 9945 | .Int => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { |
| 9941 | 9946 | .Add => .@"vector.reduce.add", |
| 9942 | 9947 | .Mul => .@"vector.reduce.mul", |
| ... | ... | @@ -10004,21 +10009,21 @@ pub const FuncGen = struct { |
| 10004 | 10009 | ))), |
| 10005 | 10010 | else => unreachable, |
| 10006 | 10011 | }; |
| 10007 | return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(mod), init_val); | |
| 10012 | return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val); | |
| 10008 | 10013 | } |
| 10009 | 10014 | |
| 10010 | 10015 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10011 | 10016 | const o = self.ng.object; |
| 10012 | 10017 | const pt = o.pt; |
| 10013 | const mod = pt.zcu; | |
| 10014 | const ip = &mod.intern_pool; | |
| 10018 | const zcu = pt.zcu; | |
| 10019 | const ip = &zcu.intern_pool; | |
| 10015 | 10020 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 10016 | 10021 | const result_ty = self.typeOfIndex(inst); |
| 10017 | const len: usize = @intCast(result_ty.arrayLen(mod)); | |
| 10022 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | |
| 10018 | 10023 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]); |
| 10019 | 10024 | const llvm_result_ty = try o.lowerType(result_ty); |
| 10020 | 10025 | |
| 10021 | switch (result_ty.zigTypeTag(mod)) { | |
| 10026 | switch (result_ty.zigTypeTag(zcu)) { | |
| 10022 | 10027 | .Vector => { |
| 10023 | 10028 | var vector = try o.builder.poisonValue(llvm_result_ty); |
| 10024 | 10029 | for (elements, 0..) |elem, i| { |
| ... | ... | @@ -10029,21 +10034,21 @@ pub const FuncGen = struct { |
| 10029 | 10034 | return vector; |
| 10030 | 10035 | }, |
| 10031 | 10036 | .Struct => { |
| 10032 | if (mod.typeToPackedStruct(result_ty)) |struct_type| { | |
| 10037 | if (zcu.typeToPackedStruct(result_ty)) |struct_type| { | |
| 10033 | 10038 | const backing_int_ty = struct_type.backingIntTypeUnordered(ip); |
| 10034 | 10039 | assert(backing_int_ty != .none); |
| 10035 | const big_bits = Type.fromInterned(backing_int_ty).bitSize(pt); | |
| 10040 | const big_bits = Type.fromInterned(backing_int_ty).bitSize(zcu); | |
| 10036 | 10041 | const int_ty = try o.builder.intType(@intCast(big_bits)); |
| 10037 | 10042 | comptime assert(Type.packed_struct_layout_version == 2); |
| 10038 | 10043 | var running_int = try o.builder.intValue(int_ty, 0); |
| 10039 | 10044 | var running_bits: u16 = 0; |
| 10040 | 10045 | for (elements, struct_type.field_types.get(ip)) |elem, field_ty| { |
| 10041 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 10046 | if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 10042 | 10047 | |
| 10043 | 10048 | const non_int_val = try self.resolveInst(elem); |
| 10044 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(pt)); | |
| 10049 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu)); | |
| 10045 | 10050 | const small_int_ty = try o.builder.intType(ty_bit_size); |
| 10046 | const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(mod)) | |
| 10051 | const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(zcu)) | |
| 10047 | 10052 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") |
| 10048 | 10053 | else |
| 10049 | 10054 | try self.wip.cast(.bitcast, non_int_val, small_int_ty, ""); |
| ... | ... | @@ -10057,12 +10062,12 @@ pub const FuncGen = struct { |
| 10057 | 10062 | return running_int; |
| 10058 | 10063 | } |
| 10059 | 10064 | |
| 10060 | assert(result_ty.containerLayout(mod) != .@"packed"); | |
| 10065 | assert(result_ty.containerLayout(zcu) != .@"packed"); | |
| 10061 | 10066 | |
| 10062 | if (isByRef(result_ty, pt)) { | |
| 10067 | if (isByRef(result_ty, zcu)) { | |
| 10063 | 10068 | // TODO in debug builds init to undef so that the padding will be 0xaa |
| 10064 | 10069 | // even if we fully populate the fields. |
| 10065 | const alignment = result_ty.abiAlignment(pt).toLlvm(); | |
| 10070 | const alignment = result_ty.abiAlignment(zcu).toLlvm(); | |
| 10066 | 10071 | const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment); |
| 10067 | 10072 | |
| 10068 | 10073 | for (elements, 0..) |elem, i| { |
| ... | ... | @@ -10075,7 +10080,7 @@ pub const FuncGen = struct { |
| 10075 | 10080 | const field_ptr_ty = try pt.ptrType(.{ |
| 10076 | 10081 | .child = self.typeOf(elem).toIntern(), |
| 10077 | 10082 | .flags = .{ |
| 10078 | .alignment = result_ty.structFieldAlign(i, pt), | |
| 10083 | .alignment = result_ty.structFieldAlign(i, zcu), | |
| 10079 | 10084 | }, |
| 10080 | 10085 | }); |
| 10081 | 10086 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .none); |
| ... | ... | @@ -10095,14 +10100,14 @@ pub const FuncGen = struct { |
| 10095 | 10100 | } |
| 10096 | 10101 | }, |
| 10097 | 10102 | .Array => { |
| 10098 | assert(isByRef(result_ty, pt)); | |
| 10103 | assert(isByRef(result_ty, zcu)); | |
| 10099 | 10104 | |
| 10100 | 10105 | const llvm_usize = try o.lowerType(Type.usize); |
| 10101 | 10106 | const usize_zero = try o.builder.intValue(llvm_usize, 0); |
| 10102 | const alignment = result_ty.abiAlignment(pt).toLlvm(); | |
| 10107 | const alignment = result_ty.abiAlignment(zcu).toLlvm(); | |
| 10103 | 10108 | const alloca_inst = try self.buildAllocaWorkaround(result_ty, alignment); |
| 10104 | 10109 | |
| 10105 | const array_info = result_ty.arrayInfo(mod); | |
| 10110 | const array_info = result_ty.arrayInfo(zcu); | |
| 10106 | 10111 | const elem_ptr_ty = try pt.ptrType(.{ |
| 10107 | 10112 | .child = array_info.elem_type.toIntern(), |
| 10108 | 10113 | }); |
| ... | ... | @@ -10131,22 +10136,22 @@ pub const FuncGen = struct { |
| 10131 | 10136 | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10132 | 10137 | const o = self.ng.object; |
| 10133 | 10138 | const pt = o.pt; |
| 10134 | const mod = pt.zcu; | |
| 10135 | const ip = &mod.intern_pool; | |
| 10139 | const zcu = pt.zcu; | |
| 10140 | const ip = &zcu.intern_pool; | |
| 10136 | 10141 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 10137 | 10142 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 10138 | 10143 | const union_ty = self.typeOfIndex(inst); |
| 10139 | 10144 | const union_llvm_ty = try o.lowerType(union_ty); |
| 10140 | const layout = union_ty.unionGetLayout(pt); | |
| 10141 | const union_obj = mod.typeToUnion(union_ty).?; | |
| 10145 | const layout = union_ty.unionGetLayout(zcu); | |
| 10146 | const union_obj = zcu.typeToUnion(union_ty).?; | |
| 10142 | 10147 | |
| 10143 | 10148 | if (union_obj.flagsUnordered(ip).layout == .@"packed") { |
| 10144 | const big_bits = union_ty.bitSize(pt); | |
| 10149 | const big_bits = union_ty.bitSize(zcu); | |
| 10145 | 10150 | const int_llvm_ty = try o.builder.intType(@intCast(big_bits)); |
| 10146 | 10151 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 10147 | 10152 | const non_int_val = try self.resolveInst(extra.init); |
| 10148 | const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(pt))); | |
| 10149 | const small_int_val = if (field_ty.isPtrAtRuntime(mod)) | |
| 10153 | const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(zcu))); | |
| 10154 | const small_int_val = if (field_ty.isPtrAtRuntime(zcu)) | |
| 10150 | 10155 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") |
| 10151 | 10156 | else |
| 10152 | 10157 | try self.wip.cast(.bitcast, non_int_val, small_int_ty, ""); |
| ... | ... | @@ -10154,9 +10159,9 @@ pub const FuncGen = struct { |
| 10154 | 10159 | } |
| 10155 | 10160 | |
| 10156 | 10161 | const tag_int_val = blk: { |
| 10157 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | |
| 10162 | const tag_ty = union_ty.unionTagTypeHypothetical(zcu); | |
| 10158 | 10163 | const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 10159 | const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?; | |
| 10164 | const enum_field_index = tag_ty.enumFieldIndex(union_field_name, zcu).?; | |
| 10160 | 10165 | const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index); |
| 10161 | 10166 | break :blk try tag_val.intFromEnum(tag_ty, pt); |
| 10162 | 10167 | }; |
| ... | ... | @@ -10164,12 +10169,12 @@ pub const FuncGen = struct { |
| 10164 | 10169 | if (layout.tag_size == 0) { |
| 10165 | 10170 | return .none; |
| 10166 | 10171 | } |
| 10167 | assert(!isByRef(union_ty, pt)); | |
| 10172 | assert(!isByRef(union_ty, zcu)); | |
| 10168 | 10173 | var big_int_space: Value.BigIntSpace = undefined; |
| 10169 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt); | |
| 10174 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, zcu); | |
| 10170 | 10175 | return try o.builder.bigIntValue(union_llvm_ty, tag_big_int); |
| 10171 | 10176 | } |
| 10172 | assert(isByRef(union_ty, pt)); | |
| 10177 | assert(isByRef(union_ty, zcu)); | |
| 10173 | 10178 | // The llvm type of the alloca will be the named LLVM union type, and will not |
| 10174 | 10179 | // necessarily match the format that we need, depending on which tag is active. |
| 10175 | 10180 | // We must construct the correct unnamed struct type here, in order to then set |
| ... | ... | @@ -10179,14 +10184,14 @@ pub const FuncGen = struct { |
| 10179 | 10184 | const llvm_payload = try self.resolveInst(extra.init); |
| 10180 | 10185 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 10181 | 10186 | const field_llvm_ty = try o.lowerType(field_ty); |
| 10182 | const field_size = field_ty.abiSize(pt); | |
| 10183 | const field_align = pt.unionFieldNormalAlignment(union_obj, extra.field_index); | |
| 10187 | const field_size = field_ty.abiSize(zcu); | |
| 10188 | const field_align = Type.unionFieldNormalAlignment(union_obj, extra.field_index, zcu); | |
| 10184 | 10189 | const llvm_usize = try o.lowerType(Type.usize); |
| 10185 | 10190 | const usize_zero = try o.builder.intValue(llvm_usize, 0); |
| 10186 | 10191 | |
| 10187 | 10192 | const llvm_union_ty = t: { |
| 10188 | 10193 | const payload_ty = p: { |
| 10189 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 10194 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 10190 | 10195 | const padding_len = layout.payload_size; |
| 10191 | 10196 | break :p try o.builder.arrayType(padding_len, .i8); |
| 10192 | 10197 | } |
| ... | ... | @@ -10242,9 +10247,9 @@ pub const FuncGen = struct { |
| 10242 | 10247 | const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, ""); |
| 10243 | 10248 | const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty)); |
| 10244 | 10249 | var big_int_space: Value.BigIntSpace = undefined; |
| 10245 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, pt); | |
| 10250 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, zcu); | |
| 10246 | 10251 | const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int); |
| 10247 | const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(pt).toLlvm(); | |
| 10252 | const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(zcu).toLlvm(); | |
| 10248 | 10253 | _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment); |
| 10249 | 10254 | } |
| 10250 | 10255 | |
| ... | ... | @@ -10270,8 +10275,8 @@ pub const FuncGen = struct { |
| 10270 | 10275 | // by the target. |
| 10271 | 10276 | // To work around this, don't emit llvm.prefetch in this case. |
| 10272 | 10277 | // See https://bugs.llvm.org/show_bug.cgi?id=21037 |
| 10273 | const mod = o.pt.zcu; | |
| 10274 | const target = mod.getTarget(); | |
| 10278 | const zcu = o.pt.zcu; | |
| 10279 | const target = zcu.getTarget(); | |
| 10275 | 10280 | switch (prefetch.cache) { |
| 10276 | 10281 | .instruction => switch (target.cpu.arch) { |
| 10277 | 10282 | .x86_64, |
| ... | ... | @@ -10397,7 +10402,7 @@ pub const FuncGen = struct { |
| 10397 | 10402 | variable_index.setMutability(.constant, &o.builder); |
| 10398 | 10403 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 10399 | 10404 | variable_index.setAlignment( |
| 10400 | Type.slice_const_u8_sentinel_0.abiAlignment(pt).toLlvm(), | |
| 10405 | Type.slice_const_u8_sentinel_0.abiAlignment(pt.zcu).toLlvm(), | |
| 10401 | 10406 | &o.builder, |
| 10402 | 10407 | ); |
| 10403 | 10408 | |
| ... | ... | @@ -10436,15 +10441,15 @@ pub const FuncGen = struct { |
| 10436 | 10441 | ) !Builder.Value { |
| 10437 | 10442 | const o = fg.ng.object; |
| 10438 | 10443 | const pt = o.pt; |
| 10439 | const mod = pt.zcu; | |
| 10440 | const payload_ty = opt_ty.optionalChild(mod); | |
| 10444 | const zcu = pt.zcu; | |
| 10445 | const payload_ty = opt_ty.optionalChild(zcu); | |
| 10441 | 10446 | |
| 10442 | if (isByRef(opt_ty, pt)) { | |
| 10447 | if (isByRef(opt_ty, zcu)) { | |
| 10443 | 10448 | // We have a pointer and we need to return a pointer to the first field. |
| 10444 | 10449 | const payload_ptr = try fg.wip.gepStruct(opt_llvm_ty, opt_handle, 0, ""); |
| 10445 | 10450 | |
| 10446 | const payload_alignment = payload_ty.abiAlignment(pt).toLlvm(); | |
| 10447 | if (isByRef(payload_ty, pt)) { | |
| 10451 | const payload_alignment = payload_ty.abiAlignment(zcu).toLlvm(); | |
| 10452 | if (isByRef(payload_ty, zcu)) { | |
| 10448 | 10453 | if (can_elide_load) |
| 10449 | 10454 | return payload_ptr; |
| 10450 | 10455 | |
| ... | ... | @@ -10453,7 +10458,7 @@ pub const FuncGen = struct { |
| 10453 | 10458 | return fg.loadTruncate(.normal, payload_ty, payload_ptr, payload_alignment); |
| 10454 | 10459 | } |
| 10455 | 10460 | |
| 10456 | assert(!isByRef(payload_ty, pt)); | |
| 10461 | assert(!isByRef(payload_ty, zcu)); | |
| 10457 | 10462 | return fg.wip.extractValue(opt_handle, &.{0}, ""); |
| 10458 | 10463 | } |
| 10459 | 10464 | |
| ... | ... | @@ -10465,11 +10470,12 @@ pub const FuncGen = struct { |
| 10465 | 10470 | ) !Builder.Value { |
| 10466 | 10471 | const o = self.ng.object; |
| 10467 | 10472 | const pt = o.pt; |
| 10473 | const zcu = pt.zcu; | |
| 10468 | 10474 | const optional_llvm_ty = try o.lowerType(optional_ty); |
| 10469 | 10475 | const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, ""); |
| 10470 | 10476 | |
| 10471 | if (isByRef(optional_ty, pt)) { | |
| 10472 | const payload_alignment = optional_ty.abiAlignment(pt).toLlvm(); | |
| 10477 | if (isByRef(optional_ty, zcu)) { | |
| 10478 | const payload_alignment = optional_ty.abiAlignment(pt.zcu).toLlvm(); | |
| 10473 | 10479 | const alloca_inst = try self.buildAllocaWorkaround(optional_ty, payload_alignment); |
| 10474 | 10480 | |
| 10475 | 10481 | { |
| ... | ... | @@ -10497,15 +10503,15 @@ pub const FuncGen = struct { |
| 10497 | 10503 | ) !Builder.Value { |
| 10498 | 10504 | const o = self.ng.object; |
| 10499 | 10505 | const pt = o.pt; |
| 10500 | const mod = pt.zcu; | |
| 10501 | const struct_ty = struct_ptr_ty.childType(mod); | |
| 10502 | switch (struct_ty.zigTypeTag(mod)) { | |
| 10503 | .Struct => switch (struct_ty.containerLayout(mod)) { | |
| 10506 | const zcu = pt.zcu; | |
| 10507 | const struct_ty = struct_ptr_ty.childType(zcu); | |
| 10508 | switch (struct_ty.zigTypeTag(zcu)) { | |
| 10509 | .Struct => switch (struct_ty.containerLayout(zcu)) { | |
| 10504 | 10510 | .@"packed" => { |
| 10505 | 10511 | const result_ty = self.typeOfIndex(inst); |
| 10506 | const result_ty_info = result_ty.ptrInfo(mod); | |
| 10507 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); | |
| 10508 | const struct_type = mod.typeToStruct(struct_ty).?; | |
| 10512 | const result_ty_info = result_ty.ptrInfo(zcu); | |
| 10513 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu); | |
| 10514 | const struct_type = zcu.typeToStruct(struct_ty).?; | |
| 10509 | 10515 | |
| 10510 | 10516 | if (result_ty_info.packed_offset.host_size != 0) { |
| 10511 | 10517 | // From LLVM's perspective, a pointer to a packed struct and a pointer |
| ... | ... | @@ -10535,15 +10541,15 @@ pub const FuncGen = struct { |
| 10535 | 10541 | // the struct. |
| 10536 | 10542 | const llvm_index = try o.builder.intValue( |
| 10537 | 10543 | try o.lowerType(Type.usize), |
| 10538 | @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(pt)), | |
| 10544 | @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(zcu)), | |
| 10539 | 10545 | ); |
| 10540 | 10546 | return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, ""); |
| 10541 | 10547 | } |
| 10542 | 10548 | }, |
| 10543 | 10549 | }, |
| 10544 | 10550 | .Union => { |
| 10545 | const layout = struct_ty.unionGetLayout(pt); | |
| 10546 | if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .@"packed") return struct_ptr; | |
| 10551 | const layout = struct_ty.unionGetLayout(zcu); | |
| 10552 | if (layout.payload_size == 0 or struct_ty.containerLayout(zcu) == .@"packed") return struct_ptr; | |
| 10547 | 10553 | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); |
| 10548 | 10554 | const union_llvm_ty = try o.lowerType(struct_ty); |
| 10549 | 10555 | return self.wip.gepStruct(union_llvm_ty, struct_ptr, payload_index, ""); |
| ... | ... | @@ -10566,9 +10572,9 @@ pub const FuncGen = struct { |
| 10566 | 10572 | |
| 10567 | 10573 | const o = fg.ng.object; |
| 10568 | 10574 | const pt = o.pt; |
| 10569 | const mod = pt.zcu; | |
| 10575 | const zcu = pt.zcu; | |
| 10570 | 10576 | const payload_llvm_ty = try o.lowerType(payload_ty); |
| 10571 | const abi_size = payload_ty.abiSize(pt); | |
| 10577 | const abi_size = payload_ty.abiSize(zcu); | |
| 10572 | 10578 | |
| 10573 | 10579 | // llvm bug workarounds: |
| 10574 | 10580 | const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4; |
| ... | ... | @@ -10580,7 +10586,7 @@ pub const FuncGen = struct { |
| 10580 | 10586 | return try fg.wip.load(access_kind, payload_llvm_ty, payload_ptr, payload_alignment, ""); |
| 10581 | 10587 | } |
| 10582 | 10588 | |
| 10583 | const load_llvm_ty = if (payload_ty.isAbiInt(mod)) | |
| 10589 | const load_llvm_ty = if (payload_ty.isAbiInt(zcu)) | |
| 10584 | 10590 | try o.builder.intType(@intCast(abi_size * 8)) |
| 10585 | 10591 | else |
| 10586 | 10592 | payload_llvm_ty; |
| ... | ... | @@ -10588,7 +10594,7 @@ pub const FuncGen = struct { |
| 10588 | 10594 | const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big) |
| 10589 | 10595 | try fg.wip.bin(.lshr, loaded, try o.builder.intValue( |
| 10590 | 10596 | load_llvm_ty, |
| 10591 | (payload_ty.abiSize(pt) - (std.math.divCeil(u64, payload_ty.bitSize(pt), 8) catch unreachable)) * 8, | |
| 10597 | (payload_ty.abiSize(zcu) - (std.math.divCeil(u64, payload_ty.bitSize(zcu), 8) catch unreachable)) * 8, | |
| 10592 | 10598 | ), "") |
| 10593 | 10599 | else |
| 10594 | 10600 | loaded; |
| ... | ... | @@ -10614,9 +10620,10 @@ pub const FuncGen = struct { |
| 10614 | 10620 | const o = fg.ng.object; |
| 10615 | 10621 | const pt = o.pt; |
| 10616 | 10622 | //const pointee_llvm_ty = try o.lowerType(pointee_type); |
| 10617 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(pt)).toLlvm(); | |
| 10623 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment) | |
| 10624 | .max(pointee_type.abiAlignment(pt.zcu)).toLlvm(); | |
| 10618 | 10625 | const result_ptr = try fg.buildAllocaWorkaround(pointee_type, result_align); |
| 10619 | const size_bytes = pointee_type.abiSize(pt); | |
| 10626 | const size_bytes = pointee_type.abiSize(pt.zcu); | |
| 10620 | 10627 | _ = try fg.wip.callMemCpy( |
| 10621 | 10628 | result_ptr, |
| 10622 | 10629 | result_align, |
| ... | ... | @@ -10634,15 +10641,15 @@ pub const FuncGen = struct { |
| 10634 | 10641 | fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 10635 | 10642 | const o = self.ng.object; |
| 10636 | 10643 | const pt = o.pt; |
| 10637 | const mod = pt.zcu; | |
| 10638 | const info = ptr_ty.ptrInfo(mod); | |
| 10644 | const zcu = pt.zcu; | |
| 10645 | const info = ptr_ty.ptrInfo(zcu); | |
| 10639 | 10646 | const elem_ty = Type.fromInterned(info.child); |
| 10640 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) return .none; | |
| 10647 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none; | |
| 10641 | 10648 | |
| 10642 | 10649 | const ptr_alignment = (if (info.flags.alignment != .none) |
| 10643 | 10650 | @as(InternPool.Alignment, info.flags.alignment) |
| 10644 | 10651 | else |
| 10645 | elem_ty.abiAlignment(pt)).toLlvm(); | |
| 10652 | elem_ty.abiAlignment(zcu)).toLlvm(); | |
| 10646 | 10653 | |
| 10647 | 10654 | const access_kind: Builder.MemoryAccessKind = |
| 10648 | 10655 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| ... | ... | @@ -10658,7 +10665,7 @@ pub const FuncGen = struct { |
| 10658 | 10665 | } |
| 10659 | 10666 | |
| 10660 | 10667 | if (info.packed_offset.host_size == 0) { |
| 10661 | if (isByRef(elem_ty, pt)) { | |
| 10668 | if (isByRef(elem_ty, zcu)) { | |
| 10662 | 10669 | return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind); |
| 10663 | 10670 | } |
| 10664 | 10671 | return self.loadTruncate(access_kind, elem_ty, ptr, ptr_alignment); |
| ... | ... | @@ -10668,13 +10675,13 @@ pub const FuncGen = struct { |
| 10668 | 10675 | const containing_int = |
| 10669 | 10676 | try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, ""); |
| 10670 | 10677 | |
| 10671 | const elem_bits = ptr_ty.childType(mod).bitSize(pt); | |
| 10678 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); | |
| 10672 | 10679 | const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset); |
| 10673 | 10680 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); |
| 10674 | 10681 | const elem_llvm_ty = try o.lowerType(elem_ty); |
| 10675 | 10682 | |
| 10676 | if (isByRef(elem_ty, pt)) { | |
| 10677 | const result_align = elem_ty.abiAlignment(pt).toLlvm(); | |
| 10683 | if (isByRef(elem_ty, zcu)) { | |
| 10684 | const result_align = elem_ty.abiAlignment(zcu).toLlvm(); | |
| 10678 | 10685 | const result_ptr = try self.buildAllocaWorkaround(elem_ty, result_align); |
| 10679 | 10686 | |
| 10680 | 10687 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); |
| ... | ... | @@ -10683,13 +10690,13 @@ pub const FuncGen = struct { |
| 10683 | 10690 | return result_ptr; |
| 10684 | 10691 | } |
| 10685 | 10692 | |
| 10686 | if (elem_ty.zigTypeTag(mod) == .Float or elem_ty.zigTypeTag(mod) == .Vector) { | |
| 10693 | if (elem_ty.zigTypeTag(zcu) == .Float or elem_ty.zigTypeTag(zcu) == .Vector) { | |
| 10687 | 10694 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); |
| 10688 | 10695 | const truncated_int = try self.wip.cast(.trunc, shifted_value, same_size_int, ""); |
| 10689 | 10696 | return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, ""); |
| 10690 | 10697 | } |
| 10691 | 10698 | |
| 10692 | if (elem_ty.isPtrAtRuntime(mod)) { | |
| 10699 | if (elem_ty.isPtrAtRuntime(zcu)) { | |
| 10693 | 10700 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); |
| 10694 | 10701 | const truncated_int = try self.wip.cast(.trunc, shifted_value, same_size_int, ""); |
| 10695 | 10702 | return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, ""); |
| ... | ... | @@ -10707,13 +10714,13 @@ pub const FuncGen = struct { |
| 10707 | 10714 | ) !void { |
| 10708 | 10715 | const o = self.ng.object; |
| 10709 | 10716 | const pt = o.pt; |
| 10710 | const mod = pt.zcu; | |
| 10711 | const info = ptr_ty.ptrInfo(mod); | |
| 10717 | const zcu = pt.zcu; | |
| 10718 | const info = ptr_ty.ptrInfo(zcu); | |
| 10712 | 10719 | const elem_ty = Type.fromInterned(info.child); |
| 10713 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 10720 | if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 10714 | 10721 | return; |
| 10715 | 10722 | } |
| 10716 | const ptr_alignment = ptr_ty.ptrAlignment(pt).toLlvm(); | |
| 10723 | const ptr_alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); | |
| 10717 | 10724 | const access_kind: Builder.MemoryAccessKind = |
| 10718 | 10725 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| 10719 | 10726 | |
| ... | ... | @@ -10737,12 +10744,12 @@ pub const FuncGen = struct { |
| 10737 | 10744 | assert(ordering == .none); |
| 10738 | 10745 | const containing_int = |
| 10739 | 10746 | try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, ""); |
| 10740 | const elem_bits = ptr_ty.childType(mod).bitSize(pt); | |
| 10747 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); | |
| 10741 | 10748 | const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset); |
| 10742 | 10749 | // Convert to equally-sized integer type in order to perform the bit |
| 10743 | 10750 | // operations on the value to store |
| 10744 | 10751 | const value_bits_type = try o.builder.intType(@intCast(elem_bits)); |
| 10745 | const value_bits = if (elem_ty.isPtrAtRuntime(mod)) | |
| 10752 | const value_bits = if (elem_ty.isPtrAtRuntime(zcu)) | |
| 10746 | 10753 | try self.wip.cast(.ptrtoint, elem, value_bits_type, "") |
| 10747 | 10754 | else |
| 10748 | 10755 | try self.wip.cast(.bitcast, elem, value_bits_type, ""); |
| ... | ... | @@ -10772,7 +10779,7 @@ pub const FuncGen = struct { |
| 10772 | 10779 | _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment); |
| 10773 | 10780 | return; |
| 10774 | 10781 | } |
| 10775 | if (!isByRef(elem_ty, pt)) { | |
| 10782 | if (!isByRef(elem_ty, zcu)) { | |
| 10776 | 10783 | _ = try self.wip.storeAtomic( |
| 10777 | 10784 | access_kind, |
| 10778 | 10785 | elem, |
| ... | ... | @@ -10788,8 +10795,8 @@ pub const FuncGen = struct { |
| 10788 | 10795 | ptr, |
| 10789 | 10796 | ptr_alignment, |
| 10790 | 10797 | elem, |
| 10791 | elem_ty.abiAlignment(pt).toLlvm(), | |
| 10792 | try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(pt)), | |
| 10798 | elem_ty.abiAlignment(zcu).toLlvm(), | |
| 10799 | try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(zcu)), | |
| 10793 | 10800 | access_kind, |
| 10794 | 10801 | ); |
| 10795 | 10802 | } |
| ... | ... | @@ -10816,12 +10823,12 @@ pub const FuncGen = struct { |
| 10816 | 10823 | ) Allocator.Error!Builder.Value { |
| 10817 | 10824 | const o = fg.ng.object; |
| 10818 | 10825 | const pt = o.pt; |
| 10819 | const mod = pt.zcu; | |
| 10820 | const target = mod.getTarget(); | |
| 10826 | const zcu = pt.zcu; | |
| 10827 | const target = zcu.getTarget(); | |
| 10821 | 10828 | if (!target_util.hasValgrindSupport(target)) return default_value; |
| 10822 | 10829 | |
| 10823 | 10830 | const llvm_usize = try o.lowerType(Type.usize); |
| 10824 | const usize_alignment = Type.usize.abiAlignment(pt).toLlvm(); | |
| 10831 | const usize_alignment = Type.usize.abiAlignment(zcu).toLlvm(); | |
| 10825 | 10832 | |
| 10826 | 10833 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); |
| 10827 | 10834 | const array_ptr = if (fg.valgrind_client_request_array == .none) a: { |
| ... | ... | @@ -10882,14 +10889,14 @@ pub const FuncGen = struct { |
| 10882 | 10889 | |
| 10883 | 10890 | fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type { |
| 10884 | 10891 | const o = fg.ng.object; |
| 10885 | const mod = o.pt.zcu; | |
| 10886 | return fg.air.typeOf(inst, &mod.intern_pool); | |
| 10892 | const zcu = o.pt.zcu; | |
| 10893 | return fg.air.typeOf(inst, &zcu.intern_pool); | |
| 10887 | 10894 | } |
| 10888 | 10895 | |
| 10889 | 10896 | fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type { |
| 10890 | 10897 | const o = fg.ng.object; |
| 10891 | const mod = o.pt.zcu; | |
| 10892 | return fg.air.typeOfIndex(inst, &mod.intern_pool); | |
| 10898 | const zcu = o.pt.zcu; | |
| 10899 | return fg.air.typeOfIndex(inst, &zcu.intern_pool); | |
| 10893 | 10900 | } |
| 10894 | 10901 | }; |
| 10895 | 10902 | |
| ... | ... | @@ -11059,12 +11066,12 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ |
| 11059 | 11066 | }; |
| 11060 | 11067 | } |
| 11061 | 11068 | |
| 11062 | fn returnTypeByRef(pt: Zcu.PerThread, target: std.Target, ty: Type) bool { | |
| 11063 | if (isByRef(ty, pt)) { | |
| 11069 | fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool { | |
| 11070 | if (isByRef(ty, zcu)) { | |
| 11064 | 11071 | return true; |
| 11065 | 11072 | } else if (target.cpu.arch.isX86() and |
| 11066 | 11073 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and |
| 11067 | ty.totalVectorBits(pt) >= 512) | |
| 11074 | ty.totalVectorBits(zcu) >= 512) | |
| 11068 | 11075 | { |
| 11069 | 11076 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns |
| 11070 | 11077 | // "512-bit vector arguments require 'evex512' for AVX512" |
| ... | ... | @@ -11074,38 +11081,38 @@ fn returnTypeByRef(pt: Zcu.PerThread, target: std.Target, ty: Type) bool { |
| 11074 | 11081 | } |
| 11075 | 11082 | } |
| 11076 | 11083 | |
| 11077 | fn firstParamSRet(fn_info: InternPool.Key.FuncType, pt: Zcu.PerThread, target: std.Target) bool { | |
| 11084 | fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Target) bool { | |
| 11078 | 11085 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11079 | if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) return false; | |
| 11086 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false; | |
| 11080 | 11087 | |
| 11081 | 11088 | return switch (fn_info.cc) { |
| 11082 | .Unspecified, .Inline => returnTypeByRef(pt, target, return_type), | |
| 11089 | .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type), | |
| 11083 | 11090 | .C => switch (target.cpu.arch) { |
| 11084 | 11091 | .mips, .mipsel => false, |
| 11085 | .x86 => isByRef(return_type, pt), | |
| 11092 | .x86 => isByRef(return_type, zcu), | |
| 11086 | 11093 | .x86_64 => switch (target.os.tag) { |
| 11087 | .windows => x86_64_abi.classifyWindows(return_type, pt) == .memory, | |
| 11088 | else => firstParamSRetSystemV(return_type, pt, target), | |
| 11094 | .windows => x86_64_abi.classifyWindows(return_type, zcu) == .memory, | |
| 11095 | else => firstParamSRetSystemV(return_type, zcu, target), | |
| 11089 | 11096 | }, |
| 11090 | .wasm32 => wasm_c_abi.classifyType(return_type, pt)[0] == .indirect, | |
| 11091 | .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, pt) == .memory, | |
| 11092 | .arm, .armeb => switch (arm_c_abi.classifyType(return_type, pt, .ret)) { | |
| 11097 | .wasm32 => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect, | |
| 11098 | .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, zcu) == .memory, | |
| 11099 | .arm, .armeb => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { | |
| 11093 | 11100 | .memory, .i64_array => true, |
| 11094 | 11101 | .i32_array => |size| size != 1, |
| 11095 | 11102 | .byval => false, |
| 11096 | 11103 | }, |
| 11097 | .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, pt) == .memory, | |
| 11104 | .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, zcu) == .memory, | |
| 11098 | 11105 | else => false, // TODO investigate C ABI for other architectures |
| 11099 | 11106 | }, |
| 11100 | .SysV => firstParamSRetSystemV(return_type, pt, target), | |
| 11101 | .Win64 => x86_64_abi.classifyWindows(return_type, pt) == .memory, | |
| 11102 | .Stdcall => !isScalar(pt.zcu, return_type), | |
| 11107 | .SysV => firstParamSRetSystemV(return_type, zcu, target), | |
| 11108 | .Win64 => x86_64_abi.classifyWindows(return_type, zcu) == .memory, | |
| 11109 | .Stdcall => !isScalar(zcu, return_type), | |
| 11103 | 11110 | else => false, |
| 11104 | 11111 | }; |
| 11105 | 11112 | } |
| 11106 | 11113 | |
| 11107 | fn firstParamSRetSystemV(ty: Type, pt: Zcu.PerThread, target: std.Target) bool { | |
| 11108 | const class = x86_64_abi.classifySystemV(ty, pt, target, .ret); | |
| 11114 | fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: std.Target) bool { | |
| 11115 | const class = x86_64_abi.classifySystemV(ty, zcu, target, .ret); | |
| 11109 | 11116 | if (class[0] == .memory) return true; |
| 11110 | 11117 | if (class[0] == .x87 and class[2] != .none) return true; |
| 11111 | 11118 | return false; |
| ... | ... | @@ -11116,62 +11123,62 @@ fn firstParamSRetSystemV(ty: Type, pt: Zcu.PerThread, target: std.Target) bool { |
| 11116 | 11123 | /// be effectively bitcasted to the actual return type. |
| 11117 | 11124 | fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11118 | 11125 | const pt = o.pt; |
| 11119 | const mod = pt.zcu; | |
| 11126 | const zcu = pt.zcu; | |
| 11120 | 11127 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11121 | if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 11128 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 11122 | 11129 | // If the return type is an error set or an error union, then we make this |
| 11123 | 11130 | // anyerror return type instead, so that it can be coerced into a function |
| 11124 | 11131 | // pointer type which has anyerror as the return type. |
| 11125 | return if (return_type.isError(mod)) try o.errorIntType() else .void; | |
| 11132 | return if (return_type.isError(zcu)) try o.errorIntType() else .void; | |
| 11126 | 11133 | } |
| 11127 | const target = mod.getTarget(); | |
| 11134 | const target = zcu.getTarget(); | |
| 11128 | 11135 | switch (fn_info.cc) { |
| 11129 | 11136 | .Unspecified, |
| 11130 | 11137 | .Inline, |
| 11131 | => return if (returnTypeByRef(pt, target, return_type)) .void else o.lowerType(return_type), | |
| 11138 | => return if (returnTypeByRef(zcu, target, return_type)) .void else o.lowerType(return_type), | |
| 11132 | 11139 | |
| 11133 | 11140 | .C => { |
| 11134 | 11141 | switch (target.cpu.arch) { |
| 11135 | 11142 | .mips, .mipsel => return o.lowerType(return_type), |
| 11136 | .x86 => return if (isByRef(return_type, pt)) .void else o.lowerType(return_type), | |
| 11143 | .x86 => return if (isByRef(return_type, zcu)) .void else o.lowerType(return_type), | |
| 11137 | 11144 | .x86_64 => switch (target.os.tag) { |
| 11138 | 11145 | .windows => return lowerWin64FnRetTy(o, fn_info), |
| 11139 | 11146 | else => return lowerSystemVFnRetTy(o, fn_info), |
| 11140 | 11147 | }, |
| 11141 | 11148 | .wasm32 => { |
| 11142 | if (isScalar(mod, return_type)) { | |
| 11149 | if (isScalar(zcu, return_type)) { | |
| 11143 | 11150 | return o.lowerType(return_type); |
| 11144 | 11151 | } |
| 11145 | const classes = wasm_c_abi.classifyType(return_type, pt); | |
| 11152 | const classes = wasm_c_abi.classifyType(return_type, zcu); | |
| 11146 | 11153 | if (classes[0] == .indirect or classes[0] == .none) { |
| 11147 | 11154 | return .void; |
| 11148 | 11155 | } |
| 11149 | 11156 | |
| 11150 | 11157 | assert(classes[0] == .direct and classes[1] == .none); |
| 11151 | const scalar_type = wasm_c_abi.scalarType(return_type, pt); | |
| 11152 | return o.builder.intType(@intCast(scalar_type.abiSize(pt) * 8)); | |
| 11158 | const scalar_type = wasm_c_abi.scalarType(return_type, zcu); | |
| 11159 | return o.builder.intType(@intCast(scalar_type.abiSize(zcu) * 8)); | |
| 11153 | 11160 | }, |
| 11154 | 11161 | .aarch64, .aarch64_be => { |
| 11155 | switch (aarch64_c_abi.classifyType(return_type, pt)) { | |
| 11162 | switch (aarch64_c_abi.classifyType(return_type, zcu)) { | |
| 11156 | 11163 | .memory => return .void, |
| 11157 | 11164 | .float_array => return o.lowerType(return_type), |
| 11158 | 11165 | .byval => return o.lowerType(return_type), |
| 11159 | .integer => return o.builder.intType(@intCast(return_type.bitSize(pt))), | |
| 11166 | .integer => return o.builder.intType(@intCast(return_type.bitSize(zcu))), | |
| 11160 | 11167 | .double_integer => return o.builder.arrayType(2, .i64), |
| 11161 | 11168 | } |
| 11162 | 11169 | }, |
| 11163 | 11170 | .arm, .armeb => { |
| 11164 | switch (arm_c_abi.classifyType(return_type, pt, .ret)) { | |
| 11171 | switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { | |
| 11165 | 11172 | .memory, .i64_array => return .void, |
| 11166 | 11173 | .i32_array => |len| return if (len == 1) .i32 else .void, |
| 11167 | 11174 | .byval => return o.lowerType(return_type), |
| 11168 | 11175 | } |
| 11169 | 11176 | }, |
| 11170 | 11177 | .riscv32, .riscv64 => { |
| 11171 | switch (riscv_c_abi.classifyType(return_type, pt)) { | |
| 11178 | switch (riscv_c_abi.classifyType(return_type, zcu)) { | |
| 11172 | 11179 | .memory => return .void, |
| 11173 | 11180 | .integer => { |
| 11174 | return o.builder.intType(@intCast(return_type.bitSize(pt))); | |
| 11181 | return o.builder.intType(@intCast(return_type.bitSize(zcu))); | |
| 11175 | 11182 | }, |
| 11176 | 11183 | .double_integer => { |
| 11177 | 11184 | return o.builder.structType(.normal, &.{ .i64, .i64 }); |
| ... | ... | @@ -11180,9 +11187,9 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11180 | 11187 | .fields => { |
| 11181 | 11188 | var types_len: usize = 0; |
| 11182 | 11189 | var types: [8]Builder.Type = undefined; |
| 11183 | for (0..return_type.structFieldCount(mod)) |field_index| { | |
| 11184 | const field_ty = return_type.structFieldType(field_index, mod); | |
| 11185 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 11190 | for (0..return_type.structFieldCount(zcu)) |field_index| { | |
| 11191 | const field_ty = return_type.structFieldType(field_index, zcu); | |
| 11192 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 11186 | 11193 | types[types_len] = try o.lowerType(field_ty); |
| 11187 | 11194 | types_len += 1; |
| 11188 | 11195 | } |
| ... | ... | @@ -11196,20 +11203,20 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11196 | 11203 | }, |
| 11197 | 11204 | .Win64 => return lowerWin64FnRetTy(o, fn_info), |
| 11198 | 11205 | .SysV => return lowerSystemVFnRetTy(o, fn_info), |
| 11199 | .Stdcall => return if (isScalar(mod, return_type)) o.lowerType(return_type) else .void, | |
| 11206 | .Stdcall => return if (isScalar(zcu, return_type)) o.lowerType(return_type) else .void, | |
| 11200 | 11207 | else => return o.lowerType(return_type), |
| 11201 | 11208 | } |
| 11202 | 11209 | } |
| 11203 | 11210 | |
| 11204 | 11211 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11205 | const pt = o.pt; | |
| 11212 | const zcu = o.pt.zcu; | |
| 11206 | 11213 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11207 | switch (x86_64_abi.classifyWindows(return_type, pt)) { | |
| 11214 | switch (x86_64_abi.classifyWindows(return_type, zcu)) { | |
| 11208 | 11215 | .integer => { |
| 11209 | if (isScalar(pt.zcu, return_type)) { | |
| 11216 | if (isScalar(zcu, return_type)) { | |
| 11210 | 11217 | return o.lowerType(return_type); |
| 11211 | 11218 | } else { |
| 11212 | return o.builder.intType(@intCast(return_type.abiSize(pt) * 8)); | |
| 11219 | return o.builder.intType(@intCast(return_type.abiSize(zcu) * 8)); | |
| 11213 | 11220 | } |
| 11214 | 11221 | }, |
| 11215 | 11222 | .win_i128 => return o.builder.vectorType(.normal, 2, .i64), |
| ... | ... | @@ -11221,14 +11228,14 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err |
| 11221 | 11228 | |
| 11222 | 11229 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { |
| 11223 | 11230 | const pt = o.pt; |
| 11224 | const mod = pt.zcu; | |
| 11225 | const ip = &mod.intern_pool; | |
| 11231 | const zcu = pt.zcu; | |
| 11232 | const ip = &zcu.intern_pool; | |
| 11226 | 11233 | const return_type = Type.fromInterned(fn_info.return_type); |
| 11227 | if (isScalar(mod, return_type)) { | |
| 11234 | if (isScalar(zcu, return_type)) { | |
| 11228 | 11235 | return o.lowerType(return_type); |
| 11229 | 11236 | } |
| 11230 | const target = mod.getTarget(); | |
| 11231 | const classes = x86_64_abi.classifySystemV(return_type, pt, target, .ret); | |
| 11237 | const target = zcu.getTarget(); | |
| 11238 | const classes = x86_64_abi.classifySystemV(return_type, zcu, target, .ret); | |
| 11232 | 11239 | if (classes[0] == .memory) return .void; |
| 11233 | 11240 | var types_index: u32 = 0; |
| 11234 | 11241 | var types_buffer: [8]Builder.Type = undefined; |
| ... | ... | @@ -11345,7 +11352,7 @@ const ParamTypeIterator = struct { |
| 11345 | 11352 | const zcu = pt.zcu; |
| 11346 | 11353 | const target = zcu.getTarget(); |
| 11347 | 11354 | |
| 11348 | if (!ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 11355 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 11349 | 11356 | it.zig_index += 1; |
| 11350 | 11357 | return .no_bits; |
| 11351 | 11358 | } |
| ... | ... | @@ -11358,11 +11365,11 @@ const ParamTypeIterator = struct { |
| 11358 | 11365 | { |
| 11359 | 11366 | it.llvm_index += 1; |
| 11360 | 11367 | return .slice; |
| 11361 | } else if (isByRef(ty, pt)) { | |
| 11368 | } else if (isByRef(ty, zcu)) { | |
| 11362 | 11369 | return .byref; |
| 11363 | 11370 | } else if (target.cpu.arch.isX86() and |
| 11364 | 11371 | !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and |
| 11365 | ty.totalVectorBits(pt) >= 512) | |
| 11372 | ty.totalVectorBits(zcu) >= 512) | |
| 11366 | 11373 | { |
| 11367 | 11374 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns |
| 11368 | 11375 | // "512-bit vector arguments require 'evex512' for AVX512" |
| ... | ... | @@ -11390,7 +11397,7 @@ const ParamTypeIterator = struct { |
| 11390 | 11397 | if (isScalar(zcu, ty)) { |
| 11391 | 11398 | return .byval; |
| 11392 | 11399 | } |
| 11393 | const classes = wasm_c_abi.classifyType(ty, pt); | |
| 11400 | const classes = wasm_c_abi.classifyType(ty, zcu); | |
| 11394 | 11401 | if (classes[0] == .indirect) { |
| 11395 | 11402 | return .byref; |
| 11396 | 11403 | } |
| ... | ... | @@ -11399,7 +11406,7 @@ const ParamTypeIterator = struct { |
| 11399 | 11406 | .aarch64, .aarch64_be => { |
| 11400 | 11407 | it.zig_index += 1; |
| 11401 | 11408 | it.llvm_index += 1; |
| 11402 | switch (aarch64_c_abi.classifyType(ty, pt)) { | |
| 11409 | switch (aarch64_c_abi.classifyType(ty, zcu)) { | |
| 11403 | 11410 | .memory => return .byref_mut, |
| 11404 | 11411 | .float_array => |len| return Lowering{ .float_array = len }, |
| 11405 | 11412 | .byval => return .byval, |
| ... | ... | @@ -11414,7 +11421,7 @@ const ParamTypeIterator = struct { |
| 11414 | 11421 | .arm, .armeb => { |
| 11415 | 11422 | it.zig_index += 1; |
| 11416 | 11423 | it.llvm_index += 1; |
| 11417 | switch (arm_c_abi.classifyType(ty, pt, .arg)) { | |
| 11424 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { | |
| 11418 | 11425 | .memory => { |
| 11419 | 11426 | it.byval_attr = true; |
| 11420 | 11427 | return .byref; |
| ... | ... | @@ -11429,7 +11436,7 @@ const ParamTypeIterator = struct { |
| 11429 | 11436 | it.llvm_index += 1; |
| 11430 | 11437 | if (ty.toIntern() == .f16_type and |
| 11431 | 11438 | !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16; |
| 11432 | switch (riscv_c_abi.classifyType(ty, pt)) { | |
| 11439 | switch (riscv_c_abi.classifyType(ty, zcu)) { | |
| 11433 | 11440 | .memory => return .byref_mut, |
| 11434 | 11441 | .byval => return .byval, |
| 11435 | 11442 | .integer => return .abi_sized_int, |
| ... | ... | @@ -11438,7 +11445,7 @@ const ParamTypeIterator = struct { |
| 11438 | 11445 | it.types_len = 0; |
| 11439 | 11446 | for (0..ty.structFieldCount(zcu)) |field_index| { |
| 11440 | 11447 | const field_ty = ty.structFieldType(field_index, zcu); |
| 11441 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 11448 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 11442 | 11449 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty); |
| 11443 | 11450 | it.types_len += 1; |
| 11444 | 11451 | } |
| ... | ... | @@ -11476,10 +11483,10 @@ const ParamTypeIterator = struct { |
| 11476 | 11483 | } |
| 11477 | 11484 | |
| 11478 | 11485 | fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering { |
| 11479 | const pt = it.object.pt; | |
| 11480 | switch (x86_64_abi.classifyWindows(ty, pt)) { | |
| 11486 | const zcu = it.object.pt.zcu; | |
| 11487 | switch (x86_64_abi.classifyWindows(ty, zcu)) { | |
| 11481 | 11488 | .integer => { |
| 11482 | if (isScalar(pt.zcu, ty)) { | |
| 11489 | if (isScalar(zcu, ty)) { | |
| 11483 | 11490 | it.zig_index += 1; |
| 11484 | 11491 | it.llvm_index += 1; |
| 11485 | 11492 | return .byval; |
| ... | ... | @@ -11509,17 +11516,17 @@ const ParamTypeIterator = struct { |
| 11509 | 11516 | } |
| 11510 | 11517 | |
| 11511 | 11518 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { |
| 11512 | const pt = it.object.pt; | |
| 11513 | const ip = &pt.zcu.intern_pool; | |
| 11514 | const target = pt.zcu.getTarget(); | |
| 11515 | const classes = x86_64_abi.classifySystemV(ty, pt, target, .arg); | |
| 11519 | const zcu = it.object.pt.zcu; | |
| 11520 | const ip = &zcu.intern_pool; | |
| 11521 | const target = zcu.getTarget(); | |
| 11522 | const classes = x86_64_abi.classifySystemV(ty, zcu, target, .arg); | |
| 11516 | 11523 | if (classes[0] == .memory) { |
| 11517 | 11524 | it.zig_index += 1; |
| 11518 | 11525 | it.llvm_index += 1; |
| 11519 | 11526 | it.byval_attr = true; |
| 11520 | 11527 | return .byref; |
| 11521 | 11528 | } |
| 11522 | if (isScalar(pt.zcu, ty)) { | |
| 11529 | if (isScalar(zcu, ty)) { | |
| 11523 | 11530 | it.zig_index += 1; |
| 11524 | 11531 | it.llvm_index += 1; |
| 11525 | 11532 | return .byval; |
| ... | ... | @@ -11620,17 +11627,17 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp |
| 11620 | 11627 | |
| 11621 | 11628 | fn ccAbiPromoteInt( |
| 11622 | 11629 | cc: std.builtin.CallingConvention, |
| 11623 | mod: *Zcu, | |
| 11630 | zcu: *Zcu, | |
| 11624 | 11631 | ty: Type, |
| 11625 | 11632 | ) ?std.builtin.Signedness { |
| 11626 | const target = mod.getTarget(); | |
| 11633 | const target = zcu.getTarget(); | |
| 11627 | 11634 | switch (cc) { |
| 11628 | 11635 | .Unspecified, .Inline, .Async => return null, |
| 11629 | 11636 | else => {}, |
| 11630 | 11637 | } |
| 11631 | const int_info = switch (ty.zigTypeTag(mod)) { | |
| 11632 | .Bool => Type.u1.intInfo(mod), | |
| 11633 | .Int, .Enum, .ErrorSet => ty.intInfo(mod), | |
| 11638 | const int_info = switch (ty.zigTypeTag(zcu)) { | |
| 11639 | .Bool => Type.u1.intInfo(zcu), | |
| 11640 | .Int, .Enum, .ErrorSet => ty.intInfo(zcu), | |
| 11634 | 11641 | else => return null, |
| 11635 | 11642 | }; |
| 11636 | 11643 | return switch (target.os.tag) { |
| ... | ... | @@ -11668,13 +11675,13 @@ fn ccAbiPromoteInt( |
| 11668 | 11675 | |
| 11669 | 11676 | /// This is the one source of truth for whether a type is passed around as an LLVM pointer, |
| 11670 | 11677 | /// or as an LLVM value. |
| 11671 | fn isByRef(ty: Type, pt: Zcu.PerThread) bool { | |
| 11678 | fn isByRef(ty: Type, zcu: *Zcu) bool { | |
| 11672 | 11679 | // For tuples and structs, if there are more than this many non-void |
| 11673 | 11680 | // fields, then we make it byref, otherwise byval. |
| 11674 | 11681 | const max_fields_byval = 0; |
| 11675 | const ip = &pt.zcu.intern_pool; | |
| 11682 | const ip = &zcu.intern_pool; | |
| 11676 | 11683 | |
| 11677 | switch (ty.zigTypeTag(pt.zcu)) { | |
| 11684 | switch (ty.zigTypeTag(zcu)) { | |
| 11678 | 11685 | .Type, |
| 11679 | 11686 | .ComptimeInt, |
| 11680 | 11687 | .ComptimeFloat, |
| ... | ... | @@ -11697,17 +11704,17 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool { |
| 11697 | 11704 | .AnyFrame, |
| 11698 | 11705 | => return false, |
| 11699 | 11706 | |
| 11700 | .Array, .Frame => return ty.hasRuntimeBits(pt), | |
| 11707 | .Array, .Frame => return ty.hasRuntimeBits(zcu), | |
| 11701 | 11708 | .Struct => { |
| 11702 | 11709 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { |
| 11703 | 11710 | .anon_struct_type => |tuple| { |
| 11704 | 11711 | var count: usize = 0; |
| 11705 | 11712 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 11706 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | |
| 11713 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | |
| 11707 | 11714 | |
| 11708 | 11715 | count += 1; |
| 11709 | 11716 | if (count > max_fields_byval) return true; |
| 11710 | if (isByRef(Type.fromInterned(field_ty), pt)) return true; | |
| 11717 | if (isByRef(Type.fromInterned(field_ty), zcu)) return true; | |
| 11711 | 11718 | } |
| 11712 | 11719 | return false; |
| 11713 | 11720 | }, |
| ... | ... | @@ -11725,27 +11732,27 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool { |
| 11725 | 11732 | count += 1; |
| 11726 | 11733 | if (count > max_fields_byval) return true; |
| 11727 | 11734 | const field_ty = Type.fromInterned(field_types[field_index]); |
| 11728 | if (isByRef(field_ty, pt)) return true; | |
| 11735 | if (isByRef(field_ty, zcu)) return true; | |
| 11729 | 11736 | } |
| 11730 | 11737 | return false; |
| 11731 | 11738 | }, |
| 11732 | .Union => switch (ty.containerLayout(pt.zcu)) { | |
| 11739 | .Union => switch (ty.containerLayout(zcu)) { | |
| 11733 | 11740 | .@"packed" => return false, |
| 11734 | else => return ty.hasRuntimeBits(pt), | |
| 11741 | else => return ty.hasRuntimeBits(zcu), | |
| 11735 | 11742 | }, |
| 11736 | 11743 | .ErrorUnion => { |
| 11737 | const payload_ty = ty.errorUnionPayload(pt.zcu); | |
| 11738 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 11744 | const payload_ty = ty.errorUnionPayload(zcu); | |
| 11745 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 11739 | 11746 | return false; |
| 11740 | 11747 | } |
| 11741 | 11748 | return true; |
| 11742 | 11749 | }, |
| 11743 | 11750 | .Optional => { |
| 11744 | const payload_ty = ty.optionalChild(pt.zcu); | |
| 11745 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 11751 | const payload_ty = ty.optionalChild(zcu); | |
| 11752 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 11746 | 11753 | return false; |
| 11747 | 11754 | } |
| 11748 | if (ty.optionalReprIsPayload(pt.zcu)) { | |
| 11755 | if (ty.optionalReprIsPayload(zcu)) { | |
| 11749 | 11756 | return false; |
| 11750 | 11757 | } |
| 11751 | 11758 | return true; |
| ... | ... | @@ -11753,8 +11760,8 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool { |
| 11753 | 11760 | } |
| 11754 | 11761 | } |
| 11755 | 11762 | |
| 11756 | fn isScalar(mod: *Zcu, ty: Type) bool { | |
| 11757 | return switch (ty.zigTypeTag(mod)) { | |
| 11763 | fn isScalar(zcu: *Zcu, ty: Type) bool { | |
| 11764 | return switch (ty.zigTypeTag(zcu)) { | |
| 11758 | 11765 | .Void, |
| 11759 | 11766 | .Bool, |
| 11760 | 11767 | .NoReturn, |
| ... | ... | @@ -11768,8 +11775,8 @@ fn isScalar(mod: *Zcu, ty: Type) bool { |
| 11768 | 11775 | .Vector, |
| 11769 | 11776 | => true, |
| 11770 | 11777 | |
| 11771 | .Struct => ty.containerLayout(mod) == .@"packed", | |
| 11772 | .Union => ty.containerLayout(mod) == .@"packed", | |
| 11778 | .Struct => ty.containerLayout(zcu) == .@"packed", | |
| 11779 | .Union => ty.containerLayout(zcu) == .@"packed", | |
| 11773 | 11780 | else => false, |
| 11774 | 11781 | }; |
| 11775 | 11782 | } |
| ... | ... | @@ -11892,13 +11899,15 @@ fn buildAllocaInner( |
| 11892 | 11899 | } |
| 11893 | 11900 | |
| 11894 | 11901 | fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 { |
| 11902 | const zcu = pt.zcu; | |
| 11895 | 11903 | const err_int_ty = try pt.errorIntType(); |
| 11896 | return @intFromBool(err_int_ty.abiAlignment(pt).compare(.gt, payload_ty.abiAlignment(pt))); | |
| 11904 | return @intFromBool(err_int_ty.abiAlignment(zcu).compare(.gt, payload_ty.abiAlignment(zcu))); | |
| 11897 | 11905 | } |
| 11898 | 11906 | |
| 11899 | 11907 | fn errUnionErrorOffset(payload_ty: Type, pt: Zcu.PerThread) !u1 { |
| 11908 | const zcu = pt.zcu; | |
| 11900 | 11909 | const err_int_ty = try pt.errorIntType(); |
| 11901 | return @intFromBool(err_int_ty.abiAlignment(pt).compare(.lte, payload_ty.abiAlignment(pt))); | |
| 11910 | return @intFromBool(err_int_ty.abiAlignment(zcu).compare(.lte, payload_ty.abiAlignment(zcu))); | |
| 11902 | 11911 | } |
| 11903 | 11912 | |
| 11904 | 11913 | /// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location |
src/codegen/spirv.zig+334-333| ... | ... | @@ -436,16 +436,16 @@ const NavGen = struct { |
| 436 | 436 | /// Fetch the result-id for a previously generated instruction or constant. |
| 437 | 437 | fn resolve(self: *NavGen, inst: Air.Inst.Ref) !IdRef { |
| 438 | 438 | const pt = self.pt; |
| 439 | const mod = pt.zcu; | |
| 439 | const zcu = pt.zcu; | |
| 440 | 440 | if (try self.air.value(inst, pt)) |val| { |
| 441 | 441 | const ty = self.typeOf(inst); |
| 442 | if (ty.zigTypeTag(mod) == .Fn) { | |
| 443 | const fn_nav = switch (mod.intern_pool.indexToKey(val.ip_index)) { | |
| 442 | if (ty.zigTypeTag(zcu) == .Fn) { | |
| 443 | const fn_nav = switch (zcu.intern_pool.indexToKey(val.ip_index)) { | |
| 444 | 444 | .@"extern" => |@"extern"| @"extern".owner_nav, |
| 445 | 445 | .func => |func| func.owner_nav, |
| 446 | 446 | else => unreachable, |
| 447 | 447 | }; |
| 448 | const spv_decl_index = try self.object.resolveNav(mod, fn_nav); | |
| 448 | const spv_decl_index = try self.object.resolveNav(zcu, fn_nav); | |
| 449 | 449 | try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {}); |
| 450 | 450 | return self.spv.declPtr(spv_decl_index).result_id; |
| 451 | 451 | } |
| ... | ... | @@ -459,8 +459,8 @@ const NavGen = struct { |
| 459 | 459 | fn resolveUav(self: *NavGen, val: InternPool.Index) !IdRef { |
| 460 | 460 | // TODO: This cannot be a function at this point, but it should probably be handled anyway. |
| 461 | 461 | |
| 462 | const mod = self.pt.zcu; | |
| 463 | const ty = Type.fromInterned(mod.intern_pool.typeOf(val)); | |
| 462 | const zcu = self.pt.zcu; | |
| 463 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(val)); | |
| 464 | 464 | const decl_ptr_ty_id = try self.ptrType(ty, .Generic); |
| 465 | 465 | |
| 466 | 466 | const spv_decl_index = blk: { |
| ... | ... | @@ -639,15 +639,15 @@ const NavGen = struct { |
| 639 | 639 | |
| 640 | 640 | /// Checks whether the type can be directly translated to SPIR-V vectors |
| 641 | 641 | fn isSpvVector(self: *NavGen, ty: Type) bool { |
| 642 | const mod = self.pt.zcu; | |
| 642 | const zcu = self.pt.zcu; | |
| 643 | 643 | const target = self.getTarget(); |
| 644 | if (ty.zigTypeTag(mod) != .Vector) return false; | |
| 644 | if (ty.zigTypeTag(zcu) != .Vector) return false; | |
| 645 | 645 | |
| 646 | 646 | // TODO: This check must be expanded for types that can be represented |
| 647 | 647 | // as integers (enums / packed structs?) and types that are represented |
| 648 | 648 | // by multiple SPIR-V values. |
| 649 | const scalar_ty = ty.scalarType(mod); | |
| 650 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 649 | const scalar_ty = ty.scalarType(zcu); | |
| 650 | switch (scalar_ty.zigTypeTag(zcu)) { | |
| 651 | 651 | .Bool, |
| 652 | 652 | .Int, |
| 653 | 653 | .Float, |
| ... | ... | @@ -655,24 +655,24 @@ const NavGen = struct { |
| 655 | 655 | else => return false, |
| 656 | 656 | } |
| 657 | 657 | |
| 658 | const elem_ty = ty.childType(mod); | |
| 658 | const elem_ty = ty.childType(zcu); | |
| 659 | 659 | |
| 660 | const len = ty.vectorLen(mod); | |
| 661 | const is_scalar = elem_ty.isNumeric(mod) or elem_ty.toIntern() == .bool_type; | |
| 660 | const len = ty.vectorLen(zcu); | |
| 661 | const is_scalar = elem_ty.isNumeric(zcu) or elem_ty.toIntern() == .bool_type; | |
| 662 | 662 | const spirv_len = len > 1 and len <= 4; |
| 663 | 663 | const opencl_len = if (target.os.tag == .opencl) (len == 8 or len == 16) else false; |
| 664 | 664 | return is_scalar and (spirv_len or opencl_len); |
| 665 | 665 | } |
| 666 | 666 | |
| 667 | 667 | fn arithmeticTypeInfo(self: *NavGen, ty: Type) ArithmeticTypeInfo { |
| 668 | const mod = self.pt.zcu; | |
| 668 | const zcu = self.pt.zcu; | |
| 669 | 669 | const target = self.getTarget(); |
| 670 | var scalar_ty = ty.scalarType(mod); | |
| 671 | if (scalar_ty.zigTypeTag(mod) == .Enum) { | |
| 672 | scalar_ty = scalar_ty.intTagType(mod); | |
| 670 | var scalar_ty = ty.scalarType(zcu); | |
| 671 | if (scalar_ty.zigTypeTag(zcu) == .Enum) { | |
| 672 | scalar_ty = scalar_ty.intTagType(zcu); | |
| 673 | 673 | } |
| 674 | const vector_len = if (ty.isVector(mod)) ty.vectorLen(mod) else null; | |
| 675 | return switch (scalar_ty.zigTypeTag(mod)) { | |
| 674 | const vector_len = if (ty.isVector(zcu)) ty.vectorLen(zcu) else null; | |
| 675 | return switch (scalar_ty.zigTypeTag(zcu)) { | |
| 676 | 676 | .Bool => ArithmeticTypeInfo{ |
| 677 | 677 | .bits = 1, // Doesn't matter for this class. |
| 678 | 678 | .backing_bits = self.backingIntBits(1).?, |
| ... | ... | @@ -688,7 +688,7 @@ const NavGen = struct { |
| 688 | 688 | .class = .float, |
| 689 | 689 | }, |
| 690 | 690 | .Int => blk: { |
| 691 | const int_info = scalar_ty.intInfo(mod); | |
| 691 | const int_info = scalar_ty.intInfo(zcu); | |
| 692 | 692 | // TODO: Maybe it's useful to also return this value. |
| 693 | 693 | const maybe_backing_bits = self.backingIntBits(int_info.bits); |
| 694 | 694 | break :blk ArithmeticTypeInfo{ |
| ... | ... | @@ -741,9 +741,9 @@ const NavGen = struct { |
| 741 | 741 | /// the value to an unsigned int first for Kernels. |
| 742 | 742 | fn constInt(self: *NavGen, ty: Type, value: anytype, repr: Repr) !IdRef { |
| 743 | 743 | // TODO: Cache? |
| 744 | const mod = self.pt.zcu; | |
| 745 | const scalar_ty = ty.scalarType(mod); | |
| 746 | const int_info = scalar_ty.intInfo(mod); | |
| 744 | const zcu = self.pt.zcu; | |
| 745 | const scalar_ty = ty.scalarType(zcu); | |
| 746 | const int_info = scalar_ty.intInfo(zcu); | |
| 747 | 747 | // Use backing bits so that negatives are sign extended |
| 748 | 748 | const backing_bits = self.backingIntBits(int_info.bits).?; // Assertion failure means big int |
| 749 | 749 | |
| ... | ... | @@ -783,11 +783,11 @@ const NavGen = struct { |
| 783 | 783 | else => unreachable, // TODO: Large integer constants |
| 784 | 784 | } |
| 785 | 785 | |
| 786 | if (!ty.isVector(mod)) { | |
| 786 | if (!ty.isVector(zcu)) { | |
| 787 | 787 | return result_id; |
| 788 | 788 | } |
| 789 | 789 | |
| 790 | const n = ty.vectorLen(mod); | |
| 790 | const n = ty.vectorLen(zcu); | |
| 791 | 791 | const ids = try self.gpa.alloc(IdRef, n); |
| 792 | 792 | defer self.gpa.free(ids); |
| 793 | 793 | @memset(ids, result_id); |
| ... | ... | @@ -821,8 +821,8 @@ const NavGen = struct { |
| 821 | 821 | /// Construct a vector at runtime. |
| 822 | 822 | /// ty must be an vector type. |
| 823 | 823 | fn constructVector(self: *NavGen, ty: Type, constituents: []const IdRef) !IdRef { |
| 824 | const mod = self.pt.zcu; | |
| 825 | assert(ty.vectorLen(mod) == constituents.len); | |
| 824 | const zcu = self.pt.zcu; | |
| 825 | assert(ty.vectorLen(zcu) == constituents.len); | |
| 826 | 826 | |
| 827 | 827 | // Note: older versions of the Khronos SPRIV-LLVM translator crash on this instruction |
| 828 | 828 | // because it cannot construct structs which' operands are not constant. |
| ... | ... | @@ -845,8 +845,8 @@ const NavGen = struct { |
| 845 | 845 | /// Construct a vector at runtime with all lanes set to the same value. |
| 846 | 846 | /// ty must be an vector type. |
| 847 | 847 | fn constructVectorSplat(self: *NavGen, ty: Type, constituent: IdRef) !IdRef { |
| 848 | const mod = self.pt.zcu; | |
| 849 | const n = ty.vectorLen(mod); | |
| 848 | const zcu = self.pt.zcu; | |
| 849 | const n = ty.vectorLen(zcu); | |
| 850 | 850 | |
| 851 | 851 | const constituents = try self.gpa.alloc(IdRef, n); |
| 852 | 852 | defer self.gpa.free(constituents); |
| ... | ... | @@ -884,13 +884,13 @@ const NavGen = struct { |
| 884 | 884 | } |
| 885 | 885 | |
| 886 | 886 | const pt = self.pt; |
| 887 | const mod = pt.zcu; | |
| 887 | const zcu = pt.zcu; | |
| 888 | 888 | const target = self.getTarget(); |
| 889 | 889 | const result_ty_id = try self.resolveType(ty, repr); |
| 890 | const ip = &mod.intern_pool; | |
| 890 | const ip = &zcu.intern_pool; | |
| 891 | 891 | |
| 892 | 892 | log.debug("lowering constant: ty = {}, val = {}", .{ ty.fmt(pt), val.fmtValue(pt) }); |
| 893 | if (val.isUndefDeep(mod)) { | |
| 893 | if (val.isUndefDeep(zcu)) { | |
| 894 | 894 | return self.spv.constUndef(result_ty_id); |
| 895 | 895 | } |
| 896 | 896 | |
| ... | ... | @@ -937,17 +937,17 @@ const NavGen = struct { |
| 937 | 937 | .false, .true => break :cache try self.constBool(val.toBool(), repr), |
| 938 | 938 | }, |
| 939 | 939 | .int => { |
| 940 | if (ty.isSignedInt(mod)) { | |
| 941 | break :cache try self.constInt(ty, val.toSignedInt(pt), repr); | |
| 940 | if (ty.isSignedInt(zcu)) { | |
| 941 | break :cache try self.constInt(ty, val.toSignedInt(zcu), repr); | |
| 942 | 942 | } else { |
| 943 | break :cache try self.constInt(ty, val.toUnsignedInt(pt), repr); | |
| 943 | break :cache try self.constInt(ty, val.toUnsignedInt(zcu), repr); | |
| 944 | 944 | } |
| 945 | 945 | }, |
| 946 | 946 | .float => { |
| 947 | 947 | const lit: spec.LiteralContextDependentNumber = switch (ty.floatBits(target)) { |
| 948 | 16 => .{ .uint32 = @as(u16, @bitCast(val.toFloat(f16, pt))) }, | |
| 949 | 32 => .{ .float32 = val.toFloat(f32, pt) }, | |
| 950 | 64 => .{ .float64 = val.toFloat(f64, pt) }, | |
| 948 | 16 => .{ .uint32 = @as(u16, @bitCast(val.toFloat(f16, zcu))) }, | |
| 949 | 32 => .{ .float32 = val.toFloat(f32, zcu) }, | |
| 950 | 64 => .{ .float64 = val.toFloat(f64, zcu) }, | |
| 951 | 951 | 80, 128 => unreachable, // TODO |
| 952 | 952 | else => unreachable, |
| 953 | 953 | }; |
| ... | ... | @@ -968,17 +968,17 @@ const NavGen = struct { |
| 968 | 968 | // allows it. For now, just generate it here regardless. |
| 969 | 969 | const err_int_ty = try pt.errorIntType(); |
| 970 | 970 | const err_ty = switch (error_union.val) { |
| 971 | .err_name => ty.errorUnionSet(mod), | |
| 971 | .err_name => ty.errorUnionSet(zcu), | |
| 972 | 972 | .payload => err_int_ty, |
| 973 | 973 | }; |
| 974 | 974 | const err_val = switch (error_union.val) { |
| 975 | 975 | .err_name => |err_name| Value.fromInterned(try pt.intern(.{ .err = .{ |
| 976 | .ty = ty.errorUnionSet(mod).toIntern(), | |
| 976 | .ty = ty.errorUnionSet(zcu).toIntern(), | |
| 977 | 977 | .name = err_name, |
| 978 | 978 | } })), |
| 979 | 979 | .payload => try pt.intValue(err_int_ty, 0), |
| 980 | 980 | }; |
| 981 | const payload_ty = ty.errorUnionPayload(mod); | |
| 981 | const payload_ty = ty.errorUnionPayload(zcu); | |
| 982 | 982 | const eu_layout = self.errorUnionLayout(payload_ty); |
| 983 | 983 | if (!eu_layout.payload_has_bits) { |
| 984 | 984 | // We use the error type directly as the type. |
| ... | ... | @@ -1006,12 +1006,12 @@ const NavGen = struct { |
| 1006 | 1006 | }, |
| 1007 | 1007 | .enum_tag => { |
| 1008 | 1008 | const int_val = try val.intFromEnum(ty, pt); |
| 1009 | const int_ty = ty.intTagType(mod); | |
| 1009 | const int_ty = ty.intTagType(zcu); | |
| 1010 | 1010 | break :cache try self.constant(int_ty, int_val, repr); |
| 1011 | 1011 | }, |
| 1012 | 1012 | .ptr => return self.constantPtr(val), |
| 1013 | 1013 | .slice => |slice| { |
| 1014 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 1014 | const ptr_ty = ty.slicePtrFieldType(zcu); | |
| 1015 | 1015 | const ptr_id = try self.constantPtr(Value.fromInterned(slice.ptr)); |
| 1016 | 1016 | const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect); |
| 1017 | 1017 | return self.constructStruct( |
| ... | ... | @@ -1021,12 +1021,12 @@ const NavGen = struct { |
| 1021 | 1021 | ); |
| 1022 | 1022 | }, |
| 1023 | 1023 | .opt => { |
| 1024 | const payload_ty = ty.optionalChild(mod); | |
| 1025 | const maybe_payload_val = val.optionalValue(mod); | |
| 1024 | const payload_ty = ty.optionalChild(zcu); | |
| 1025 | const maybe_payload_val = val.optionalValue(zcu); | |
| 1026 | 1026 | |
| 1027 | if (!payload_ty.hasRuntimeBits(pt)) { | |
| 1027 | if (!payload_ty.hasRuntimeBits(zcu)) { | |
| 1028 | 1028 | break :cache try self.constBool(maybe_payload_val != null, .indirect); |
| 1029 | } else if (ty.optionalReprIsPayload(mod)) { | |
| 1029 | } else if (ty.optionalReprIsPayload(zcu)) { | |
| 1030 | 1030 | // Optional representation is a nullable pointer or slice. |
| 1031 | 1031 | if (maybe_payload_val) |payload_val| { |
| 1032 | 1032 | return try self.constant(payload_ty, payload_val, .indirect); |
| ... | ... | @@ -1054,7 +1054,7 @@ const NavGen = struct { |
| 1054 | 1054 | inline .array_type, .vector_type => |array_type, tag| { |
| 1055 | 1055 | const elem_ty = Type.fromInterned(array_type.child); |
| 1056 | 1056 | |
| 1057 | const constituents = try self.gpa.alloc(IdRef, @intCast(ty.arrayLenIncludingSentinel(mod))); | |
| 1057 | const constituents = try self.gpa.alloc(IdRef, @intCast(ty.arrayLenIncludingSentinel(zcu))); | |
| 1058 | 1058 | defer self.gpa.free(constituents); |
| 1059 | 1059 | |
| 1060 | 1060 | const child_repr: Repr = switch (tag) { |
| ... | ... | @@ -1088,7 +1088,7 @@ const NavGen = struct { |
| 1088 | 1088 | } |
| 1089 | 1089 | }, |
| 1090 | 1090 | .struct_type => { |
| 1091 | const struct_type = mod.typeToStruct(ty).?; | |
| 1091 | const struct_type = zcu.typeToStruct(ty).?; | |
| 1092 | 1092 | if (struct_type.layout == .@"packed") { |
| 1093 | 1093 | return self.todo("packed struct constants", .{}); |
| 1094 | 1094 | } |
| ... | ... | @@ -1102,7 +1102,7 @@ const NavGen = struct { |
| 1102 | 1102 | var it = struct_type.iterateRuntimeOrder(ip); |
| 1103 | 1103 | while (it.next()) |field_index| { |
| 1104 | 1104 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 1105 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1105 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1106 | 1106 | // This is a zero-bit field - we only needed it for the alignment. |
| 1107 | 1107 | continue; |
| 1108 | 1108 | } |
| ... | ... | @@ -1121,10 +1121,10 @@ const NavGen = struct { |
| 1121 | 1121 | else => unreachable, |
| 1122 | 1122 | }, |
| 1123 | 1123 | .un => |un| { |
| 1124 | const active_field = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; | |
| 1125 | const union_obj = mod.typeToUnion(ty).?; | |
| 1124 | const active_field = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?; | |
| 1125 | const union_obj = zcu.typeToUnion(ty).?; | |
| 1126 | 1126 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[active_field]); |
| 1127 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 1127 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 1128 | 1128 | try self.constant(field_ty, Value.fromInterned(un.val), .direct) |
| 1129 | 1129 | else |
| 1130 | 1130 | null; |
| ... | ... | @@ -1232,8 +1232,8 @@ const NavGen = struct { |
| 1232 | 1232 | // TODO: Merge this function with constantDeclRef. |
| 1233 | 1233 | |
| 1234 | 1234 | const pt = self.pt; |
| 1235 | const mod = pt.zcu; | |
| 1236 | const ip = &mod.intern_pool; | |
| 1235 | const zcu = pt.zcu; | |
| 1236 | const ip = &zcu.intern_pool; | |
| 1237 | 1237 | const ty_id = try self.resolveType(ty, .direct); |
| 1238 | 1238 | const uav_ty = Type.fromInterned(ip.typeOf(uav.val)); |
| 1239 | 1239 | |
| ... | ... | @@ -1243,14 +1243,14 @@ const NavGen = struct { |
| 1243 | 1243 | else => {}, |
| 1244 | 1244 | } |
| 1245 | 1245 | |
| 1246 | // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; | |
| 1247 | if (!uav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 1246 | // const is_fn_body = decl_ty.zigTypeTag(zcu) == .Fn; | |
| 1247 | if (!uav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1248 | 1248 | // Pointer to nothing - return undefined |
| 1249 | 1249 | return self.spv.constUndef(ty_id); |
| 1250 | 1250 | } |
| 1251 | 1251 | |
| 1252 | 1252 | // Uav refs are always generic. |
| 1253 | assert(ty.ptrAddressSpace(mod) == .generic); | |
| 1253 | assert(ty.ptrAddressSpace(zcu) == .generic); | |
| 1254 | 1254 | const decl_ptr_ty_id = try self.ptrType(uav_ty, .Generic); |
| 1255 | 1255 | const ptr_id = try self.resolveUav(uav.val); |
| 1256 | 1256 | |
| ... | ... | @@ -1270,12 +1270,12 @@ const NavGen = struct { |
| 1270 | 1270 | |
| 1271 | 1271 | fn constantNavRef(self: *NavGen, ty: Type, nav_index: InternPool.Nav.Index) !IdRef { |
| 1272 | 1272 | const pt = self.pt; |
| 1273 | const mod = pt.zcu; | |
| 1274 | const ip = &mod.intern_pool; | |
| 1273 | const zcu = pt.zcu; | |
| 1274 | const ip = &zcu.intern_pool; | |
| 1275 | 1275 | const ty_id = try self.resolveType(ty, .direct); |
| 1276 | 1276 | const nav = ip.getNav(nav_index); |
| 1277 | const nav_val = mod.navValue(nav_index); | |
| 1278 | const nav_ty = nav_val.typeOf(mod); | |
| 1277 | const nav_val = zcu.navValue(nav_index); | |
| 1278 | const nav_ty = nav_val.typeOf(zcu); | |
| 1279 | 1279 | |
| 1280 | 1280 | switch (ip.indexToKey(nav_val.toIntern())) { |
| 1281 | 1281 | .func => { |
| ... | ... | @@ -1287,12 +1287,12 @@ const NavGen = struct { |
| 1287 | 1287 | else => {}, |
| 1288 | 1288 | } |
| 1289 | 1289 | |
| 1290 | if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 1290 | if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1291 | 1291 | // Pointer to nothing - return undefined. |
| 1292 | 1292 | return self.spv.constUndef(ty_id); |
| 1293 | 1293 | } |
| 1294 | 1294 | |
| 1295 | const spv_decl_index = try self.object.resolveNav(mod, nav_index); | |
| 1295 | const spv_decl_index = try self.object.resolveNav(zcu, nav_index); | |
| 1296 | 1296 | const spv_decl = self.spv.declPtr(spv_decl_index); |
| 1297 | 1297 | |
| 1298 | 1298 | const decl_id = switch (spv_decl.kind) { |
| ... | ... | @@ -1452,9 +1452,9 @@ const NavGen = struct { |
| 1452 | 1452 | /// } |
| 1453 | 1453 | /// If any of the fields' size is 0, it will be omitted. |
| 1454 | 1454 | fn resolveUnionType(self: *NavGen, ty: Type) !IdRef { |
| 1455 | const mod = self.pt.zcu; | |
| 1456 | const ip = &mod.intern_pool; | |
| 1457 | const union_obj = mod.typeToUnion(ty).?; | |
| 1455 | const zcu = self.pt.zcu; | |
| 1456 | const ip = &zcu.intern_pool; | |
| 1457 | const union_obj = zcu.typeToUnion(ty).?; | |
| 1458 | 1458 | |
| 1459 | 1459 | if (union_obj.flagsUnordered(ip).layout == .@"packed") { |
| 1460 | 1460 | return self.todo("packed union types", .{}); |
| ... | ... | @@ -1503,12 +1503,12 @@ const NavGen = struct { |
| 1503 | 1503 | } |
| 1504 | 1504 | |
| 1505 | 1505 | fn resolveFnReturnType(self: *NavGen, ret_ty: Type) !IdRef { |
| 1506 | const pt = self.pt; | |
| 1507 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1506 | const zcu = self.pt.zcu; | |
| 1507 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1508 | 1508 | // If the return type is an error set or an error union, then we make this |
| 1509 | 1509 | // anyerror return type instead, so that it can be coerced into a function |
| 1510 | 1510 | // pointer type which has anyerror as the return type. |
| 1511 | if (ret_ty.isError(pt.zcu)) { | |
| 1511 | if (ret_ty.isError(zcu)) { | |
| 1512 | 1512 | return self.resolveType(Type.anyerror, .direct); |
| 1513 | 1513 | } else { |
| 1514 | 1514 | return self.resolveType(Type.void, .direct); |
| ... | ... | @@ -1531,14 +1531,14 @@ const NavGen = struct { |
| 1531 | 1531 | |
| 1532 | 1532 | fn resolveTypeInner(self: *NavGen, ty: Type, repr: Repr) Error!IdRef { |
| 1533 | 1533 | const pt = self.pt; |
| 1534 | const mod = pt.zcu; | |
| 1535 | const ip = &mod.intern_pool; | |
| 1534 | const zcu = pt.zcu; | |
| 1535 | const ip = &zcu.intern_pool; | |
| 1536 | 1536 | log.debug("resolveType: ty = {}", .{ty.fmt(pt)}); |
| 1537 | 1537 | const target = self.getTarget(); |
| 1538 | 1538 | |
| 1539 | 1539 | const section = &self.spv.sections.types_globals_constants; |
| 1540 | 1540 | |
| 1541 | switch (ty.zigTypeTag(mod)) { | |
| 1541 | switch (ty.zigTypeTag(zcu)) { | |
| 1542 | 1542 | .NoReturn => { |
| 1543 | 1543 | assert(repr == .direct); |
| 1544 | 1544 | return try self.spv.voidType(); |
| ... | ... | @@ -1562,7 +1562,7 @@ const NavGen = struct { |
| 1562 | 1562 | .indirect => return try self.resolveType(Type.u1, .indirect), |
| 1563 | 1563 | }, |
| 1564 | 1564 | .Int => { |
| 1565 | const int_info = ty.intInfo(mod); | |
| 1565 | const int_info = ty.intInfo(zcu); | |
| 1566 | 1566 | if (int_info.bits == 0) { |
| 1567 | 1567 | // Some times, the backend will be asked to generate a pointer to i0. OpTypeInt |
| 1568 | 1568 | // with 0 bits is invalid, so return an opaque type in this case. |
| ... | ... | @@ -1577,7 +1577,7 @@ const NavGen = struct { |
| 1577 | 1577 | return try self.intType(int_info.signedness, int_info.bits); |
| 1578 | 1578 | }, |
| 1579 | 1579 | .Enum => { |
| 1580 | const tag_ty = ty.intTagType(mod); | |
| 1580 | const tag_ty = ty.intTagType(zcu); | |
| 1581 | 1581 | return try self.resolveType(tag_ty, repr); |
| 1582 | 1582 | }, |
| 1583 | 1583 | .Float => { |
| ... | ... | @@ -1599,13 +1599,13 @@ const NavGen = struct { |
| 1599 | 1599 | return try self.spv.floatType(bits); |
| 1600 | 1600 | }, |
| 1601 | 1601 | .Array => { |
| 1602 | const elem_ty = ty.childType(mod); | |
| 1602 | const elem_ty = ty.childType(zcu); | |
| 1603 | 1603 | const elem_ty_id = try self.resolveType(elem_ty, .indirect); |
| 1604 | const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(mod)) orelse { | |
| 1605 | return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)}); | |
| 1604 | const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(zcu)) orelse { | |
| 1605 | return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)}); | |
| 1606 | 1606 | }; |
| 1607 | 1607 | |
| 1608 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1608 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1609 | 1609 | // The size of the array would be 0, but that is not allowed in SPIR-V. |
| 1610 | 1610 | // This path can be reached when the backend is asked to generate a pointer to |
| 1611 | 1611 | // an array of some zero-bit type. This should always be an indirect path. |
| ... | ... | @@ -1635,7 +1635,7 @@ const NavGen = struct { |
| 1635 | 1635 | }, |
| 1636 | 1636 | .Fn => switch (repr) { |
| 1637 | 1637 | .direct => { |
| 1638 | const fn_info = mod.typeToFunc(ty).?; | |
| 1638 | const fn_info = zcu.typeToFunc(ty).?; | |
| 1639 | 1639 | |
| 1640 | 1640 | comptime assert(zig_call_abi_ver == 3); |
| 1641 | 1641 | switch (fn_info.cc) { |
| ... | ... | @@ -1653,7 +1653,7 @@ const NavGen = struct { |
| 1653 | 1653 | var param_index: usize = 0; |
| 1654 | 1654 | for (fn_info.param_types.get(ip)) |param_ty_index| { |
| 1655 | 1655 | const param_ty = Type.fromInterned(param_ty_index); |
| 1656 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 1656 | if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 1657 | 1657 | |
| 1658 | 1658 | param_ty_ids[param_index] = try self.resolveType(param_ty, .direct); |
| 1659 | 1659 | param_index += 1; |
| ... | ... | @@ -1677,7 +1677,7 @@ const NavGen = struct { |
| 1677 | 1677 | }, |
| 1678 | 1678 | }, |
| 1679 | 1679 | .Pointer => { |
| 1680 | const ptr_info = ty.ptrInfo(mod); | |
| 1680 | const ptr_info = ty.ptrInfo(zcu); | |
| 1681 | 1681 | |
| 1682 | 1682 | const storage_class = self.spvStorageClass(ptr_info.flags.address_space); |
| 1683 | 1683 | const ptr_ty_id = try self.ptrType(Type.fromInterned(ptr_info.child), storage_class); |
| ... | ... | @@ -1693,9 +1693,9 @@ const NavGen = struct { |
| 1693 | 1693 | ); |
| 1694 | 1694 | }, |
| 1695 | 1695 | .Vector => { |
| 1696 | const elem_ty = ty.childType(mod); | |
| 1696 | const elem_ty = ty.childType(zcu); | |
| 1697 | 1697 | const elem_ty_id = try self.resolveType(elem_ty, repr); |
| 1698 | const len = ty.vectorLen(mod); | |
| 1698 | const len = ty.vectorLen(zcu); | |
| 1699 | 1699 | |
| 1700 | 1700 | if (self.isSpvVector(ty)) { |
| 1701 | 1701 | return try self.spv.vectorType(len, elem_ty_id); |
| ... | ... | @@ -1711,7 +1711,7 @@ const NavGen = struct { |
| 1711 | 1711 | |
| 1712 | 1712 | var member_index: usize = 0; |
| 1713 | 1713 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 1714 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; | |
| 1714 | if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | |
| 1715 | 1715 | |
| 1716 | 1716 | member_types[member_index] = try self.resolveType(Type.fromInterned(field_ty), .indirect); |
| 1717 | 1717 | member_index += 1; |
| ... | ... | @@ -1740,13 +1740,13 @@ const NavGen = struct { |
| 1740 | 1740 | var it = struct_type.iterateRuntimeOrder(ip); |
| 1741 | 1741 | while (it.next()) |field_index| { |
| 1742 | 1742 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 1743 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1743 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1744 | 1744 | // This is a zero-bit field - we only needed it for the alignment. |
| 1745 | 1745 | continue; |
| 1746 | 1746 | } |
| 1747 | 1747 | |
| 1748 | 1748 | const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse |
| 1749 | try ip.getOrPutStringFmt(mod.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); | |
| 1749 | try ip.getOrPutStringFmt(zcu.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); | |
| 1750 | 1750 | try member_types.append(try self.resolveType(field_ty, .indirect)); |
| 1751 | 1751 | try member_names.append(field_name.toSlice(ip)); |
| 1752 | 1752 | } |
| ... | ... | @@ -1758,8 +1758,8 @@ const NavGen = struct { |
| 1758 | 1758 | return result_id; |
| 1759 | 1759 | }, |
| 1760 | 1760 | .Optional => { |
| 1761 | const payload_ty = ty.optionalChild(mod); | |
| 1762 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 1761 | const payload_ty = ty.optionalChild(zcu); | |
| 1762 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 1763 | 1763 | // Just use a bool. |
| 1764 | 1764 | // Note: Always generate the bool with indirect format, to save on some sanity |
| 1765 | 1765 | // Perform the conversion to a direct bool when the field is extracted. |
| ... | ... | @@ -1767,7 +1767,7 @@ const NavGen = struct { |
| 1767 | 1767 | } |
| 1768 | 1768 | |
| 1769 | 1769 | const payload_ty_id = try self.resolveType(payload_ty, .indirect); |
| 1770 | if (ty.optionalReprIsPayload(mod)) { | |
| 1770 | if (ty.optionalReprIsPayload(zcu)) { | |
| 1771 | 1771 | // Optional is actually a pointer or a slice. |
| 1772 | 1772 | return payload_ty_id; |
| 1773 | 1773 | } |
| ... | ... | @@ -1782,7 +1782,7 @@ const NavGen = struct { |
| 1782 | 1782 | .Union => return try self.resolveUnionType(ty), |
| 1783 | 1783 | .ErrorSet => return try self.resolveType(Type.u16, repr), |
| 1784 | 1784 | .ErrorUnion => { |
| 1785 | const payload_ty = ty.errorUnionPayload(mod); | |
| 1785 | const payload_ty = ty.errorUnionPayload(zcu); | |
| 1786 | 1786 | const error_ty_id = try self.resolveType(Type.anyerror, .indirect); |
| 1787 | 1787 | |
| 1788 | 1788 | const eu_layout = self.errorUnionLayout(payload_ty); |
| ... | ... | @@ -1877,13 +1877,14 @@ const NavGen = struct { |
| 1877 | 1877 | |
| 1878 | 1878 | fn errorUnionLayout(self: *NavGen, payload_ty: Type) ErrorUnionLayout { |
| 1879 | 1879 | const pt = self.pt; |
| 1880 | const zcu = pt.zcu; | |
| 1880 | 1881 | |
| 1881 | const error_align = Type.anyerror.abiAlignment(pt); | |
| 1882 | const payload_align = payload_ty.abiAlignment(pt); | |
| 1882 | const error_align = Type.anyerror.abiAlignment(zcu); | |
| 1883 | const payload_align = payload_ty.abiAlignment(zcu); | |
| 1883 | 1884 | |
| 1884 | 1885 | const error_first = error_align.compare(.gt, payload_align); |
| 1885 | 1886 | return .{ |
| 1886 | .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(pt), | |
| 1887 | .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu), | |
| 1887 | 1888 | .error_first = error_first, |
| 1888 | 1889 | }; |
| 1889 | 1890 | } |
| ... | ... | @@ -1908,10 +1909,10 @@ const NavGen = struct { |
| 1908 | 1909 | |
| 1909 | 1910 | fn unionLayout(self: *NavGen, ty: Type) UnionLayout { |
| 1910 | 1911 | const pt = self.pt; |
| 1911 | const mod = pt.zcu; | |
| 1912 | const ip = &mod.intern_pool; | |
| 1913 | const layout = ty.unionGetLayout(pt); | |
| 1914 | const union_obj = mod.typeToUnion(ty).?; | |
| 1912 | const zcu = pt.zcu; | |
| 1913 | const ip = &zcu.intern_pool; | |
| 1914 | const layout = ty.unionGetLayout(zcu); | |
| 1915 | const union_obj = zcu.typeToUnion(ty).?; | |
| 1915 | 1916 | |
| 1916 | 1917 | var union_layout = UnionLayout{ |
| 1917 | 1918 | .has_payload = layout.payload_size != 0, |
| ... | ... | @@ -1931,7 +1932,7 @@ const NavGen = struct { |
| 1931 | 1932 | const most_aligned_field = layout.most_aligned_field; |
| 1932 | 1933 | const most_aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[most_aligned_field]); |
| 1933 | 1934 | union_layout.payload_ty = most_aligned_field_ty; |
| 1934 | union_layout.payload_size = @intCast(most_aligned_field_ty.abiSize(pt)); | |
| 1935 | union_layout.payload_size = @intCast(most_aligned_field_ty.abiSize(zcu)); | |
| 1935 | 1936 | } else { |
| 1936 | 1937 | union_layout.payload_size = 0; |
| 1937 | 1938 | } |
| ... | ... | @@ -1998,12 +1999,12 @@ const NavGen = struct { |
| 1998 | 1999 | } |
| 1999 | 2000 | |
| 2000 | 2001 | fn materialize(self: Temporary, ng: *NavGen) !IdResult { |
| 2001 | const mod = ng.pt.zcu; | |
| 2002 | const zcu = ng.pt.zcu; | |
| 2002 | 2003 | switch (self.value) { |
| 2003 | 2004 | .singleton => |id| return id, |
| 2004 | 2005 | .exploded_vector => |range| { |
| 2005 | assert(self.ty.isVector(mod)); | |
| 2006 | assert(self.ty.vectorLen(mod) == range.len); | |
| 2006 | assert(self.ty.isVector(zcu)); | |
| 2007 | assert(self.ty.vectorLen(zcu) == range.len); | |
| 2007 | 2008 | const consituents = try ng.gpa.alloc(IdRef, range.len); |
| 2008 | 2009 | defer ng.gpa.free(consituents); |
| 2009 | 2010 | for (consituents, 0..range.len) |*id, i| { |
| ... | ... | @@ -2028,18 +2029,18 @@ const NavGen = struct { |
| 2028 | 2029 | /// 'Explode' a temporary into separate elements. This turns a vector |
| 2029 | 2030 | /// into a bag of elements. |
| 2030 | 2031 | fn explode(self: Temporary, ng: *NavGen) !IdRange { |
| 2031 | const mod = ng.pt.zcu; | |
| 2032 | const zcu = ng.pt.zcu; | |
| 2032 | 2033 | |
| 2033 | 2034 | // If the value is a scalar, then this is a no-op. |
| 2034 | if (!self.ty.isVector(mod)) { | |
| 2035 | if (!self.ty.isVector(zcu)) { | |
| 2035 | 2036 | return switch (self.value) { |
| 2036 | 2037 | .singleton => |id| .{ .base = @intFromEnum(id), .len = 1 }, |
| 2037 | 2038 | .exploded_vector => |range| range, |
| 2038 | 2039 | }; |
| 2039 | 2040 | } |
| 2040 | 2041 | |
| 2041 | const ty_id = try ng.resolveType(self.ty.scalarType(mod), .direct); | |
| 2042 | const n = self.ty.vectorLen(mod); | |
| 2042 | const ty_id = try ng.resolveType(self.ty.scalarType(zcu), .direct); | |
| 2043 | const n = self.ty.vectorLen(zcu); | |
| 2043 | 2044 | const results = ng.spv.allocIds(n); |
| 2044 | 2045 | |
| 2045 | 2046 | const id = switch (self.value) { |
| ... | ... | @@ -2087,13 +2088,13 @@ const NavGen = struct { |
| 2087 | 2088 | /// only checks the size, but the source-of-truth is implemented |
| 2088 | 2089 | /// by `isSpvVector()`. |
| 2089 | 2090 | fn fromType(ty: Type, ng: *NavGen) Vectorization { |
| 2090 | const mod = ng.pt.zcu; | |
| 2091 | if (!ty.isVector(mod)) { | |
| 2091 | const zcu = ng.pt.zcu; | |
| 2092 | if (!ty.isVector(zcu)) { | |
| 2092 | 2093 | return .scalar; |
| 2093 | 2094 | } else if (ng.isSpvVector(ty)) { |
| 2094 | return .{ .spv_vectorized = ty.vectorLen(mod) }; | |
| 2095 | return .{ .spv_vectorized = ty.vectorLen(zcu) }; | |
| 2095 | 2096 | } else { |
| 2096 | return .{ .unrolled = ty.vectorLen(mod) }; | |
| 2097 | return .{ .unrolled = ty.vectorLen(zcu) }; | |
| 2097 | 2098 | } |
| 2098 | 2099 | } |
| 2099 | 2100 | |
| ... | ... | @@ -2339,10 +2340,10 @@ const NavGen = struct { |
| 2339 | 2340 | /// This function builds an OpSConvert of OpUConvert depending on the |
| 2340 | 2341 | /// signedness of the types. |
| 2341 | 2342 | fn buildIntConvert(self: *NavGen, dst_ty: Type, src: Temporary) !Temporary { |
| 2342 | const mod = self.pt.zcu; | |
| 2343 | const zcu = self.pt.zcu; | |
| 2343 | 2344 | |
| 2344 | const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct); | |
| 2345 | const src_ty_id = try self.resolveType(src.ty.scalarType(mod), .direct); | |
| 2345 | const dst_ty_id = try self.resolveType(dst_ty.scalarType(zcu), .direct); | |
| 2346 | const src_ty_id = try self.resolveType(src.ty.scalarType(zcu), .direct); | |
| 2346 | 2347 | |
| 2347 | 2348 | const v = self.vectorization(.{ dst_ty, src }); |
| 2348 | 2349 | const result_ty = try v.resultType(self, dst_ty); |
| ... | ... | @@ -2363,7 +2364,7 @@ const NavGen = struct { |
| 2363 | 2364 | const op_result_ty = try v.operationType(self, dst_ty); |
| 2364 | 2365 | const op_result_ty_id = try self.resolveType(op_result_ty, .direct); |
| 2365 | 2366 | |
| 2366 | const opcode: Opcode = if (dst_ty.isSignedInt(mod)) .OpSConvert else .OpUConvert; | |
| 2367 | const opcode: Opcode = if (dst_ty.isSignedInt(zcu)) .OpSConvert else .OpUConvert; | |
| 2367 | 2368 | |
| 2368 | 2369 | const op_src = try v.prepare(self, src); |
| 2369 | 2370 | |
| ... | ... | @@ -2418,7 +2419,7 @@ const NavGen = struct { |
| 2418 | 2419 | } |
| 2419 | 2420 | |
| 2420 | 2421 | fn buildSelect(self: *NavGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary { |
| 2421 | const mod = self.pt.zcu; | |
| 2422 | const zcu = self.pt.zcu; | |
| 2422 | 2423 | |
| 2423 | 2424 | const v = self.vectorization(.{ condition, lhs, rhs }); |
| 2424 | 2425 | const ops = v.operations(); |
| ... | ... | @@ -2428,7 +2429,7 @@ const NavGen = struct { |
| 2428 | 2429 | const op_result_ty_id = try self.resolveType(op_result_ty, .direct); |
| 2429 | 2430 | const result_ty = try v.resultType(self, lhs.ty); |
| 2430 | 2431 | |
| 2431 | assert(condition.ty.scalarType(mod).zigTypeTag(mod) == .Bool); | |
| 2432 | assert(condition.ty.scalarType(zcu).zigTypeTag(zcu) == .Bool); | |
| 2432 | 2433 | |
| 2433 | 2434 | const cond = try v.prepare(self, condition); |
| 2434 | 2435 | const object_1 = try v.prepare(self, lhs); |
| ... | ... | @@ -2764,9 +2765,9 @@ const NavGen = struct { |
| 2764 | 2765 | rhs: Temporary, |
| 2765 | 2766 | ) !struct { Temporary, Temporary } { |
| 2766 | 2767 | const pt = self.pt; |
| 2767 | const mod = pt.zcu; | |
| 2768 | const zcu = pt.zcu; | |
| 2768 | 2769 | const target = self.getTarget(); |
| 2769 | const ip = &mod.intern_pool; | |
| 2770 | const ip = &zcu.intern_pool; | |
| 2770 | 2771 | |
| 2771 | 2772 | const v = lhs.vectorization(self).unify(rhs.vectorization(self)); |
| 2772 | 2773 | const ops = v.operations(); |
| ... | ... | @@ -2814,7 +2815,7 @@ const NavGen = struct { |
| 2814 | 2815 | // where T is maybe vectorized. |
| 2815 | 2816 | const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() }; |
| 2816 | 2817 | const values = [2]InternPool.Index{ .none, .none }; |
| 2817 | const index = try ip.getAnonStructType(mod.gpa, pt.tid, .{ | |
| 2818 | const index = try ip.getAnonStructType(zcu.gpa, pt.tid, .{ | |
| 2818 | 2819 | .types = &types, |
| 2819 | 2820 | .values = &values, |
| 2820 | 2821 | .names = &.{}, |
| ... | ... | @@ -2941,17 +2942,17 @@ const NavGen = struct { |
| 2941 | 2942 | |
| 2942 | 2943 | fn genNav(self: *NavGen) !void { |
| 2943 | 2944 | const pt = self.pt; |
| 2944 | const mod = pt.zcu; | |
| 2945 | const ip = &mod.intern_pool; | |
| 2946 | const spv_decl_index = try self.object.resolveNav(mod, self.owner_nav); | |
| 2945 | const zcu = pt.zcu; | |
| 2946 | const ip = &zcu.intern_pool; | |
| 2947 | const spv_decl_index = try self.object.resolveNav(zcu, self.owner_nav); | |
| 2947 | 2948 | const result_id = self.spv.declPtr(spv_decl_index).result_id; |
| 2948 | 2949 | |
| 2949 | 2950 | const nav = ip.getNav(self.owner_nav); |
| 2950 | const val = mod.navValue(self.owner_nav); | |
| 2951 | const ty = val.typeOf(mod); | |
| 2951 | const val = zcu.navValue(self.owner_nav); | |
| 2952 | const ty = val.typeOf(zcu); | |
| 2952 | 2953 | switch (self.spv.declPtr(spv_decl_index).kind) { |
| 2953 | 2954 | .func => { |
| 2954 | const fn_info = mod.typeToFunc(ty).?; | |
| 2955 | const fn_info = zcu.typeToFunc(ty).?; | |
| 2955 | 2956 | const return_ty_id = try self.resolveFnReturnType(Type.fromInterned(fn_info.return_type)); |
| 2956 | 2957 | |
| 2957 | 2958 | const prototype_ty_id = try self.resolveType(ty, .direct); |
| ... | ... | @@ -2969,7 +2970,7 @@ const NavGen = struct { |
| 2969 | 2970 | try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len); |
| 2970 | 2971 | for (fn_info.param_types.get(ip)) |param_ty_index| { |
| 2971 | 2972 | const param_ty = Type.fromInterned(param_ty_index); |
| 2972 | if (!param_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 2973 | if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 2973 | 2974 | |
| 2974 | 2975 | const param_type_id = try self.resolveType(param_ty, .direct); |
| 2975 | 2976 | const arg_result_id = self.spv.allocId(); |
| ... | ... | @@ -3116,8 +3117,8 @@ const NavGen = struct { |
| 3116 | 3117 | /// Convert representation from indirect (in memory) to direct (in 'register') |
| 3117 | 3118 | /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct). |
| 3118 | 3119 | fn convertToDirect(self: *NavGen, ty: Type, operand_id: IdRef) !IdRef { |
| 3119 | const mod = self.pt.zcu; | |
| 3120 | switch (ty.scalarType(mod).zigTypeTag(mod)) { | |
| 3120 | const zcu = self.pt.zcu; | |
| 3121 | switch (ty.scalarType(zcu).zigTypeTag(zcu)) { | |
| 3121 | 3122 | .Bool => { |
| 3122 | 3123 | const false_id = try self.constBool(false, .indirect); |
| 3123 | 3124 | // The operation below requires inputs in direct representation, but the operand |
| ... | ... | @@ -3142,8 +3143,8 @@ const NavGen = struct { |
| 3142 | 3143 | /// Convert representation from direct (in 'register) to direct (in memory) |
| 3143 | 3144 | /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect). |
| 3144 | 3145 | fn convertToIndirect(self: *NavGen, ty: Type, operand_id: IdRef) !IdRef { |
| 3145 | const mod = self.pt.zcu; | |
| 3146 | switch (ty.scalarType(mod).zigTypeTag(mod)) { | |
| 3146 | const zcu = self.pt.zcu; | |
| 3147 | switch (ty.scalarType(zcu).zigTypeTag(zcu)) { | |
| 3147 | 3148 | .Bool => { |
| 3148 | 3149 | const result = try self.intFromBool(Temporary.init(ty, operand_id)); |
| 3149 | 3150 | return try result.materialize(self); |
| ... | ... | @@ -3219,8 +3220,8 @@ const NavGen = struct { |
| 3219 | 3220 | } |
| 3220 | 3221 | |
| 3221 | 3222 | fn genInst(self: *NavGen, inst: Air.Inst.Index) !void { |
| 3222 | const mod = self.pt.zcu; | |
| 3223 | const ip = &mod.intern_pool; | |
| 3223 | const zcu = self.pt.zcu; | |
| 3224 | const ip = &zcu.intern_pool; | |
| 3224 | 3225 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) |
| 3225 | 3226 | return; |
| 3226 | 3227 | |
| ... | ... | @@ -3399,7 +3400,7 @@ const NavGen = struct { |
| 3399 | 3400 | } |
| 3400 | 3401 | |
| 3401 | 3402 | fn airShift(self: *NavGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef { |
| 3402 | const mod = self.pt.zcu; | |
| 3403 | const zcu = self.pt.zcu; | |
| 3403 | 3404 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3404 | 3405 | |
| 3405 | 3406 | const base = try self.temporary(bin_op.lhs); |
| ... | ... | @@ -3420,7 +3421,7 @@ const NavGen = struct { |
| 3420 | 3421 | // Note: The sign may differ here between the shift and the base type, in case |
| 3421 | 3422 | // of an arithmetic right shift. SPIR-V still expects the same type, |
| 3422 | 3423 | // so in that case we have to cast convert to signed. |
| 3423 | const casted_shift = try self.buildIntConvert(base.ty.scalarType(mod), shift); | |
| 3424 | const casted_shift = try self.buildIntConvert(base.ty.scalarType(zcu), shift); | |
| 3424 | 3425 | |
| 3425 | 3426 | const shifted = switch (info.signedness) { |
| 3426 | 3427 | .unsigned => try self.buildBinary(unsigned, base, casted_shift), |
| ... | ... | @@ -3477,7 +3478,7 @@ const NavGen = struct { |
| 3477 | 3478 | /// All other values are returned unmodified (this makes strange integer |
| 3478 | 3479 | /// wrapping easier to use in generic operations). |
| 3479 | 3480 | fn normalize(self: *NavGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary { |
| 3480 | const mod = self.pt.zcu; | |
| 3481 | const zcu = self.pt.zcu; | |
| 3481 | 3482 | const ty = value.ty; |
| 3482 | 3483 | switch (info.class) { |
| 3483 | 3484 | .integer, .bool, .float => return value, |
| ... | ... | @@ -3485,13 +3486,13 @@ const NavGen = struct { |
| 3485 | 3486 | .strange_integer => switch (info.signedness) { |
| 3486 | 3487 | .unsigned => { |
| 3487 | 3488 | const mask_value = if (info.bits == 64) 0xFFFF_FFFF_FFFF_FFFF else (@as(u64, 1) << @as(u6, @intCast(info.bits))) - 1; |
| 3488 | const mask_id = try self.constInt(ty.scalarType(mod), mask_value, .direct); | |
| 3489 | return try self.buildBinary(.bit_and, value, Temporary.init(ty.scalarType(mod), mask_id)); | |
| 3489 | const mask_id = try self.constInt(ty.scalarType(zcu), mask_value, .direct); | |
| 3490 | return try self.buildBinary(.bit_and, value, Temporary.init(ty.scalarType(zcu), mask_id)); | |
| 3490 | 3491 | }, |
| 3491 | 3492 | .signed => { |
| 3492 | 3493 | // Shift left and right so that we can copy the sight bit that way. |
| 3493 | const shift_amt_id = try self.constInt(ty.scalarType(mod), info.backing_bits - info.bits, .direct); | |
| 3494 | const shift_amt = Temporary.init(ty.scalarType(mod), shift_amt_id); | |
| 3494 | const shift_amt_id = try self.constInt(ty.scalarType(zcu), info.backing_bits - info.bits, .direct); | |
| 3495 | const shift_amt = Temporary.init(ty.scalarType(zcu), shift_amt_id); | |
| 3495 | 3496 | const left = try self.buildBinary(.sll, value, shift_amt); |
| 3496 | 3497 | return try self.buildBinary(.sra, left, shift_amt); |
| 3497 | 3498 | }, |
| ... | ... | @@ -3897,7 +3898,7 @@ const NavGen = struct { |
| 3897 | 3898 | } |
| 3898 | 3899 | |
| 3899 | 3900 | fn airShlOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 3900 | const mod = self.pt.zcu; | |
| 3901 | const zcu = self.pt.zcu; | |
| 3901 | 3902 | |
| 3902 | 3903 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3903 | 3904 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | ... | @@ -3916,7 +3917,7 @@ const NavGen = struct { |
| 3916 | 3917 | |
| 3917 | 3918 | // Sometimes Zig doesn't make both of the arguments the same types here. SPIR-V expects that, |
| 3918 | 3919 | // so just manually upcast it if required. |
| 3919 | const casted_shift = try self.buildIntConvert(base.ty.scalarType(mod), shift); | |
| 3920 | const casted_shift = try self.buildIntConvert(base.ty.scalarType(zcu), shift); | |
| 3920 | 3921 | |
| 3921 | 3922 | const left = try self.buildBinary(.sll, base, casted_shift); |
| 3922 | 3923 | const result = try self.normalize(left, info); |
| ... | ... | @@ -3955,12 +3956,12 @@ const NavGen = struct { |
| 3955 | 3956 | fn airClzCtz(self: *NavGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef { |
| 3956 | 3957 | if (self.liveness.isUnused(inst)) return null; |
| 3957 | 3958 | |
| 3958 | const mod = self.pt.zcu; | |
| 3959 | const zcu = self.pt.zcu; | |
| 3959 | 3960 | const target = self.getTarget(); |
| 3960 | 3961 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3961 | 3962 | const operand = try self.temporary(ty_op.operand); |
| 3962 | 3963 | |
| 3963 | const scalar_result_ty = self.typeOfIndex(inst).scalarType(mod); | |
| 3964 | const scalar_result_ty = self.typeOfIndex(inst).scalarType(zcu); | |
| 3964 | 3965 | |
| 3965 | 3966 | const info = self.arithmeticTypeInfo(operand.ty); |
| 3966 | 3967 | switch (info.class) { |
| ... | ... | @@ -4004,16 +4005,16 @@ const NavGen = struct { |
| 4004 | 4005 | } |
| 4005 | 4006 | |
| 4006 | 4007 | fn airReduce(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4007 | const mod = self.pt.zcu; | |
| 4008 | const zcu = self.pt.zcu; | |
| 4008 | 4009 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 4009 | 4010 | const operand = try self.resolve(reduce.operand); |
| 4010 | 4011 | const operand_ty = self.typeOf(reduce.operand); |
| 4011 | const scalar_ty = operand_ty.scalarType(mod); | |
| 4012 | const scalar_ty = operand_ty.scalarType(zcu); | |
| 4012 | 4013 | const scalar_ty_id = try self.resolveType(scalar_ty, .direct); |
| 4013 | 4014 | |
| 4014 | 4015 | const info = self.arithmeticTypeInfo(operand_ty); |
| 4015 | 4016 | |
| 4016 | const len = operand_ty.vectorLen(mod); | |
| 4017 | const len = operand_ty.vectorLen(zcu); | |
| 4017 | 4018 | |
| 4018 | 4019 | const first = try self.extractVectorComponent(scalar_ty, operand, 0); |
| 4019 | 4020 | |
| ... | ... | @@ -4080,7 +4081,7 @@ const NavGen = struct { |
| 4080 | 4081 | |
| 4081 | 4082 | fn airShuffle(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4082 | 4083 | const pt = self.pt; |
| 4083 | const mod = pt.zcu; | |
| 4084 | const zcu = pt.zcu; | |
| 4084 | 4085 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4085 | 4086 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 4086 | 4087 | const a = try self.resolve(extra.a); |
| ... | ... | @@ -4092,7 +4093,7 @@ const NavGen = struct { |
| 4092 | 4093 | const a_ty = self.typeOf(extra.a); |
| 4093 | 4094 | const b_ty = self.typeOf(extra.b); |
| 4094 | 4095 | |
| 4095 | const scalar_ty = result_ty.scalarType(mod); | |
| 4096 | const scalar_ty = result_ty.scalarType(zcu); | |
| 4096 | 4097 | const scalar_ty_id = try self.resolveType(scalar_ty, .direct); |
| 4097 | 4098 | |
| 4098 | 4099 | // If all of the types are SPIR-V vectors, we can use OpVectorShuffle. |
| ... | ... | @@ -4100,20 +4101,20 @@ const NavGen = struct { |
| 4100 | 4101 | // The SPIR-V shuffle instruction is similar to the Air instruction, except that the elements are |
| 4101 | 4102 | // numbered consecutively instead of using negatives. |
| 4102 | 4103 | |
| 4103 | const components = try self.gpa.alloc(Word, result_ty.vectorLen(mod)); | |
| 4104 | const components = try self.gpa.alloc(Word, result_ty.vectorLen(zcu)); | |
| 4104 | 4105 | defer self.gpa.free(components); |
| 4105 | 4106 | |
| 4106 | const a_len = a_ty.vectorLen(mod); | |
| 4107 | const a_len = a_ty.vectorLen(zcu); | |
| 4107 | 4108 | |
| 4108 | 4109 | for (components, 0..) |*component, i| { |
| 4109 | 4110 | const elem = try mask.elemValue(pt, i); |
| 4110 | if (elem.isUndef(mod)) { | |
| 4111 | if (elem.isUndef(zcu)) { | |
| 4111 | 4112 | // This is explicitly valid for OpVectorShuffle, it indicates undefined. |
| 4112 | 4113 | component.* = 0xFFFF_FFFF; |
| 4113 | 4114 | continue; |
| 4114 | 4115 | } |
| 4115 | 4116 | |
| 4116 | const index = elem.toSignedInt(pt); | |
| 4117 | const index = elem.toSignedInt(zcu); | |
| 4117 | 4118 | if (index >= 0) { |
| 4118 | 4119 | component.* = @intCast(index); |
| 4119 | 4120 | } else { |
| ... | ... | @@ -4134,17 +4135,17 @@ const NavGen = struct { |
| 4134 | 4135 | |
| 4135 | 4136 | // Fall back to manually extracting and inserting components. |
| 4136 | 4137 | |
| 4137 | const components = try self.gpa.alloc(IdRef, result_ty.vectorLen(mod)); | |
| 4138 | const components = try self.gpa.alloc(IdRef, result_ty.vectorLen(zcu)); | |
| 4138 | 4139 | defer self.gpa.free(components); |
| 4139 | 4140 | |
| 4140 | 4141 | for (components, 0..) |*id, i| { |
| 4141 | 4142 | const elem = try mask.elemValue(pt, i); |
| 4142 | if (elem.isUndef(mod)) { | |
| 4143 | if (elem.isUndef(zcu)) { | |
| 4143 | 4144 | id.* = try self.spv.constUndef(scalar_ty_id); |
| 4144 | 4145 | continue; |
| 4145 | 4146 | } |
| 4146 | 4147 | |
| 4147 | const index = elem.toSignedInt(pt); | |
| 4148 | const index = elem.toSignedInt(zcu); | |
| 4148 | 4149 | if (index >= 0) { |
| 4149 | 4150 | id.* = try self.extractVectorComponent(scalar_ty, a, @intCast(index)); |
| 4150 | 4151 | } else { |
| ... | ... | @@ -4218,10 +4219,10 @@ const NavGen = struct { |
| 4218 | 4219 | } |
| 4219 | 4220 | |
| 4220 | 4221 | fn ptrAdd(self: *NavGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef { |
| 4221 | const mod = self.pt.zcu; | |
| 4222 | const zcu = self.pt.zcu; | |
| 4222 | 4223 | const result_ty_id = try self.resolveType(result_ty, .direct); |
| 4223 | 4224 | |
| 4224 | switch (ptr_ty.ptrSize(mod)) { | |
| 4225 | switch (ptr_ty.ptrSize(zcu)) { | |
| 4225 | 4226 | .One => { |
| 4226 | 4227 | // Pointer to array |
| 4227 | 4228 | // TODO: Is this correct? |
| ... | ... | @@ -4275,15 +4276,15 @@ const NavGen = struct { |
| 4275 | 4276 | rhs: Temporary, |
| 4276 | 4277 | ) !Temporary { |
| 4277 | 4278 | const pt = self.pt; |
| 4278 | const mod = pt.zcu; | |
| 4279 | const scalar_ty = lhs.ty.scalarType(mod); | |
| 4280 | const is_vector = lhs.ty.isVector(mod); | |
| 4279 | const zcu = pt.zcu; | |
| 4280 | const scalar_ty = lhs.ty.scalarType(zcu); | |
| 4281 | const is_vector = lhs.ty.isVector(zcu); | |
| 4281 | 4282 | |
| 4282 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 4283 | switch (scalar_ty.zigTypeTag(zcu)) { | |
| 4283 | 4284 | .Int, .Bool, .Float => {}, |
| 4284 | 4285 | .Enum => { |
| 4285 | 4286 | assert(!is_vector); |
| 4286 | const ty = lhs.ty.intTagType(mod); | |
| 4287 | const ty = lhs.ty.intTagType(zcu); | |
| 4287 | 4288 | return try self.cmp(op, lhs.pun(ty), rhs.pun(ty)); |
| 4288 | 4289 | }, |
| 4289 | 4290 | .ErrorSet => { |
| ... | ... | @@ -4321,10 +4322,10 @@ const NavGen = struct { |
| 4321 | 4322 | |
| 4322 | 4323 | const ty = lhs.ty; |
| 4323 | 4324 | |
| 4324 | const payload_ty = ty.optionalChild(mod); | |
| 4325 | if (ty.optionalReprIsPayload(mod)) { | |
| 4326 | assert(payload_ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 4327 | assert(!payload_ty.isSlice(mod)); | |
| 4325 | const payload_ty = ty.optionalChild(zcu); | |
| 4326 | if (ty.optionalReprIsPayload(zcu)) { | |
| 4327 | assert(payload_ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 4328 | assert(!payload_ty.isSlice(zcu)); | |
| 4328 | 4329 | |
| 4329 | 4330 | return try self.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty)); |
| 4330 | 4331 | } |
| ... | ... | @@ -4332,12 +4333,12 @@ const NavGen = struct { |
| 4332 | 4333 | const lhs_id = try lhs.materialize(self); |
| 4333 | 4334 | const rhs_id = try rhs.materialize(self); |
| 4334 | 4335 | |
| 4335 | const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 4336 | const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 4336 | 4337 | try self.extractField(Type.bool, lhs_id, 1) |
| 4337 | 4338 | else |
| 4338 | 4339 | try self.convertToDirect(Type.bool, lhs_id); |
| 4339 | 4340 | |
| 4340 | const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 4341 | const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 4341 | 4342 | try self.extractField(Type.bool, rhs_id, 1) |
| 4342 | 4343 | else |
| 4343 | 4344 | try self.convertToDirect(Type.bool, rhs_id); |
| ... | ... | @@ -4345,7 +4346,7 @@ const NavGen = struct { |
| 4345 | 4346 | const lhs_valid = Temporary.init(Type.bool, lhs_valid_id); |
| 4346 | 4347 | const rhs_valid = Temporary.init(Type.bool, rhs_valid_id); |
| 4347 | 4348 | |
| 4348 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4349 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4349 | 4350 | return try self.cmp(op, lhs_valid, rhs_valid); |
| 4350 | 4351 | } |
| 4351 | 4352 | |
| ... | ... | @@ -4465,7 +4466,7 @@ const NavGen = struct { |
| 4465 | 4466 | src_ty: Type, |
| 4466 | 4467 | src_id: IdRef, |
| 4467 | 4468 | ) !IdRef { |
| 4468 | const mod = self.pt.zcu; | |
| 4469 | const zcu = self.pt.zcu; | |
| 4469 | 4470 | const src_ty_id = try self.resolveType(src_ty, .direct); |
| 4470 | 4471 | const dst_ty_id = try self.resolveType(dst_ty, .direct); |
| 4471 | 4472 | |
| ... | ... | @@ -4477,7 +4478,7 @@ const NavGen = struct { |
| 4477 | 4478 | // TODO: Some more cases are missing here |
| 4478 | 4479 | // See fn bitCast in llvm.zig |
| 4479 | 4480 | |
| 4480 | if (src_ty.zigTypeTag(mod) == .Int and dst_ty.isPtrAtRuntime(mod)) { | |
| 4481 | if (src_ty.zigTypeTag(zcu) == .Int and dst_ty.isPtrAtRuntime(zcu)) { | |
| 4481 | 4482 | const result_id = self.spv.allocId(); |
| 4482 | 4483 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ |
| 4483 | 4484 | .id_result_type = dst_ty_id, |
| ... | ... | @@ -4490,7 +4491,7 @@ const NavGen = struct { |
| 4490 | 4491 | // We can only use OpBitcast for specific conversions: between numerical types, and |
| 4491 | 4492 | // between pointers. If the resolved spir-v types fall into this category then emit OpBitcast, |
| 4492 | 4493 | // otherwise use a temporary and perform a pointer cast. |
| 4493 | const can_bitcast = (src_ty.isNumeric(mod) and dst_ty.isNumeric(mod)) or (src_ty.isPtrAtRuntime(mod) and dst_ty.isPtrAtRuntime(mod)); | |
| 4494 | const can_bitcast = (src_ty.isNumeric(zcu) and dst_ty.isNumeric(zcu)) or (src_ty.isPtrAtRuntime(zcu) and dst_ty.isPtrAtRuntime(zcu)); | |
| 4494 | 4495 | if (can_bitcast) { |
| 4495 | 4496 | const result_id = self.spv.allocId(); |
| 4496 | 4497 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| ... | ... | @@ -4519,7 +4520,7 @@ const NavGen = struct { |
| 4519 | 4520 | // the result here. |
| 4520 | 4521 | // TODO: This detail could cause stuff like @as(*const i1, @ptrCast(&@as(u1, 1))) to break |
| 4521 | 4522 | // should we change the representation of strange integers? |
| 4522 | if (dst_ty.zigTypeTag(mod) == .Int) { | |
| 4523 | if (dst_ty.zigTypeTag(zcu) == .Int) { | |
| 4523 | 4524 | const info = self.arithmeticTypeInfo(dst_ty); |
| 4524 | 4525 | const result = try self.normalize(Temporary.init(dst_ty, result_id), info); |
| 4525 | 4526 | return try result.materialize(self); |
| ... | ... | @@ -4675,19 +4676,19 @@ const NavGen = struct { |
| 4675 | 4676 | |
| 4676 | 4677 | fn airArrayToSlice(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4677 | 4678 | const pt = self.pt; |
| 4678 | const mod = pt.zcu; | |
| 4679 | const zcu = pt.zcu; | |
| 4679 | 4680 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4680 | 4681 | const array_ptr_ty = self.typeOf(ty_op.operand); |
| 4681 | const array_ty = array_ptr_ty.childType(mod); | |
| 4682 | const array_ty = array_ptr_ty.childType(zcu); | |
| 4682 | 4683 | const slice_ty = self.typeOfIndex(inst); |
| 4683 | const elem_ptr_ty = slice_ty.slicePtrFieldType(mod); | |
| 4684 | const elem_ptr_ty = slice_ty.slicePtrFieldType(zcu); | |
| 4684 | 4685 | |
| 4685 | 4686 | const elem_ptr_ty_id = try self.resolveType(elem_ptr_ty, .direct); |
| 4686 | 4687 | |
| 4687 | 4688 | const array_ptr_id = try self.resolve(ty_op.operand); |
| 4688 | const len_id = try self.constInt(Type.usize, array_ty.arrayLen(mod), .direct); | |
| 4689 | const len_id = try self.constInt(Type.usize, array_ty.arrayLen(zcu), .direct); | |
| 4689 | 4690 | |
| 4690 | const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 4691 | const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 4691 | 4692 | // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type. |
| 4692 | 4693 | try self.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id) |
| 4693 | 4694 | else |
| ... | ... | @@ -4720,16 +4721,16 @@ const NavGen = struct { |
| 4720 | 4721 | |
| 4721 | 4722 | fn airAggregateInit(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4722 | 4723 | const pt = self.pt; |
| 4723 | const mod = pt.zcu; | |
| 4724 | const ip = &mod.intern_pool; | |
| 4724 | const zcu = pt.zcu; | |
| 4725 | const ip = &zcu.intern_pool; | |
| 4725 | 4726 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4726 | 4727 | const result_ty = self.typeOfIndex(inst); |
| 4727 | const len: usize = @intCast(result_ty.arrayLen(mod)); | |
| 4728 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | |
| 4728 | 4729 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]); |
| 4729 | 4730 | |
| 4730 | switch (result_ty.zigTypeTag(mod)) { | |
| 4731 | switch (result_ty.zigTypeTag(zcu)) { | |
| 4731 | 4732 | .Struct => { |
| 4732 | if (mod.typeToPackedStruct(result_ty)) |struct_type| { | |
| 4733 | if (zcu.typeToPackedStruct(result_ty)) |struct_type| { | |
| 4733 | 4734 | _ = struct_type; |
| 4734 | 4735 | unreachable; // TODO |
| 4735 | 4736 | } |
| ... | ... | @@ -4744,7 +4745,7 @@ const NavGen = struct { |
| 4744 | 4745 | .anon_struct_type => |tuple| { |
| 4745 | 4746 | for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| { |
| 4746 | 4747 | if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue; |
| 4747 | assert(Type.fromInterned(field_ty).hasRuntimeBits(pt)); | |
| 4748 | assert(Type.fromInterned(field_ty).hasRuntimeBits(zcu)); | |
| 4748 | 4749 | |
| 4749 | 4750 | const id = try self.resolve(element); |
| 4750 | 4751 | types[index] = Type.fromInterned(field_ty); |
| ... | ... | @@ -4759,7 +4760,7 @@ const NavGen = struct { |
| 4759 | 4760 | const field_index = it.next().?; |
| 4760 | 4761 | if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue; |
| 4761 | 4762 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 4762 | assert(field_ty.hasRuntimeBitsIgnoreComptime(pt)); | |
| 4763 | assert(field_ty.hasRuntimeBitsIgnoreComptime(zcu)); | |
| 4763 | 4764 | |
| 4764 | 4765 | const id = try self.resolve(element); |
| 4765 | 4766 | types[index] = field_ty; |
| ... | ... | @@ -4777,7 +4778,7 @@ const NavGen = struct { |
| 4777 | 4778 | ); |
| 4778 | 4779 | }, |
| 4779 | 4780 | .Vector => { |
| 4780 | const n_elems = result_ty.vectorLen(mod); | |
| 4781 | const n_elems = result_ty.vectorLen(zcu); | |
| 4781 | 4782 | const elem_ids = try self.gpa.alloc(IdRef, n_elems); |
| 4782 | 4783 | defer self.gpa.free(elem_ids); |
| 4783 | 4784 | |
| ... | ... | @@ -4788,8 +4789,8 @@ const NavGen = struct { |
| 4788 | 4789 | return try self.constructVector(result_ty, elem_ids); |
| 4789 | 4790 | }, |
| 4790 | 4791 | .Array => { |
| 4791 | const array_info = result_ty.arrayInfo(mod); | |
| 4792 | const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod)); | |
| 4792 | const array_info = result_ty.arrayInfo(zcu); | |
| 4793 | const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(zcu)); | |
| 4793 | 4794 | const elem_ids = try self.gpa.alloc(IdRef, n_elems); |
| 4794 | 4795 | defer self.gpa.free(elem_ids); |
| 4795 | 4796 | |
| ... | ... | @@ -4810,14 +4811,14 @@ const NavGen = struct { |
| 4810 | 4811 | |
| 4811 | 4812 | fn sliceOrArrayLen(self: *NavGen, operand_id: IdRef, ty: Type) !IdRef { |
| 4812 | 4813 | const pt = self.pt; |
| 4813 | const mod = pt.zcu; | |
| 4814 | switch (ty.ptrSize(mod)) { | |
| 4814 | const zcu = pt.zcu; | |
| 4815 | switch (ty.ptrSize(zcu)) { | |
| 4815 | 4816 | .Slice => return self.extractField(Type.usize, operand_id, 1), |
| 4816 | 4817 | .One => { |
| 4817 | const array_ty = ty.childType(mod); | |
| 4818 | const elem_ty = array_ty.childType(mod); | |
| 4819 | const abi_size = elem_ty.abiSize(pt); | |
| 4820 | const size = array_ty.arrayLenIncludingSentinel(mod) * abi_size; | |
| 4818 | const array_ty = ty.childType(zcu); | |
| 4819 | const elem_ty = array_ty.childType(zcu); | |
| 4820 | const abi_size = elem_ty.abiSize(zcu); | |
| 4821 | const size = array_ty.arrayLenIncludingSentinel(zcu) * abi_size; | |
| 4821 | 4822 | return try self.constInt(Type.usize, size, .direct); |
| 4822 | 4823 | }, |
| 4823 | 4824 | .Many, .C => unreachable, |
| ... | ... | @@ -4825,9 +4826,9 @@ const NavGen = struct { |
| 4825 | 4826 | } |
| 4826 | 4827 | |
| 4827 | 4828 | fn sliceOrArrayPtr(self: *NavGen, operand_id: IdRef, ty: Type) !IdRef { |
| 4828 | const mod = self.pt.zcu; | |
| 4829 | if (ty.isSlice(mod)) { | |
| 4830 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 4829 | const zcu = self.pt.zcu; | |
| 4830 | if (ty.isSlice(zcu)) { | |
| 4831 | const ptr_ty = ty.slicePtrFieldType(zcu); | |
| 4831 | 4832 | return self.extractField(ptr_ty, operand_id, 0); |
| 4832 | 4833 | } |
| 4833 | 4834 | return operand_id; |
| ... | ... | @@ -4857,11 +4858,11 @@ const NavGen = struct { |
| 4857 | 4858 | } |
| 4858 | 4859 | |
| 4859 | 4860 | fn airSliceElemPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4860 | const mod = self.pt.zcu; | |
| 4861 | const zcu = self.pt.zcu; | |
| 4861 | 4862 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4862 | 4863 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4863 | 4864 | const slice_ty = self.typeOf(bin_op.lhs); |
| 4864 | if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | |
| 4865 | if (!slice_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) return null; | |
| 4865 | 4866 | |
| 4866 | 4867 | const slice_id = try self.resolve(bin_op.lhs); |
| 4867 | 4868 | const index_id = try self.resolve(bin_op.rhs); |
| ... | ... | @@ -4874,28 +4875,28 @@ const NavGen = struct { |
| 4874 | 4875 | } |
| 4875 | 4876 | |
| 4876 | 4877 | fn airSliceElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4877 | const mod = self.pt.zcu; | |
| 4878 | const zcu = self.pt.zcu; | |
| 4878 | 4879 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4879 | 4880 | const slice_ty = self.typeOf(bin_op.lhs); |
| 4880 | if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | |
| 4881 | if (!slice_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) return null; | |
| 4881 | 4882 | |
| 4882 | 4883 | const slice_id = try self.resolve(bin_op.lhs); |
| 4883 | 4884 | const index_id = try self.resolve(bin_op.rhs); |
| 4884 | 4885 | |
| 4885 | const ptr_ty = slice_ty.slicePtrFieldType(mod); | |
| 4886 | const ptr_ty = slice_ty.slicePtrFieldType(zcu); | |
| 4886 | 4887 | const ptr_ty_id = try self.resolveType(ptr_ty, .direct); |
| 4887 | 4888 | |
| 4888 | 4889 | const slice_ptr = try self.extractField(ptr_ty, slice_id, 0); |
| 4889 | 4890 | const elem_ptr = try self.ptrAccessChain(ptr_ty_id, slice_ptr, index_id, &.{}); |
| 4890 | return try self.load(slice_ty.childType(mod), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(mod) }); | |
| 4891 | return try self.load(slice_ty.childType(zcu), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(zcu) }); | |
| 4891 | 4892 | } |
| 4892 | 4893 | |
| 4893 | 4894 | fn ptrElemPtr(self: *NavGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef { |
| 4894 | const mod = self.pt.zcu; | |
| 4895 | const zcu = self.pt.zcu; | |
| 4895 | 4896 | // Construct new pointer type for the resulting pointer |
| 4896 | const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. | |
| 4897 | const elem_ptr_ty_id = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(mod))); | |
| 4898 | if (ptr_ty.isSinglePointer(mod)) { | |
| 4897 | const elem_ty = ptr_ty.elemType2(zcu); // use elemType() so that we get T for *[N]T. | |
| 4898 | const elem_ptr_ty_id = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(zcu))); | |
| 4899 | if (ptr_ty.isSinglePointer(zcu)) { | |
| 4899 | 4900 | // Pointer-to-array. In this case, the resulting pointer is not of the same type |
| 4900 | 4901 | // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain. |
| 4901 | 4902 | return try self.accessChainId(elem_ptr_ty_id, ptr_id, &.{index_id}); |
| ... | ... | @@ -4907,14 +4908,14 @@ const NavGen = struct { |
| 4907 | 4908 | |
| 4908 | 4909 | fn airPtrElemPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4909 | 4910 | const pt = self.pt; |
| 4910 | const mod = pt.zcu; | |
| 4911 | const zcu = pt.zcu; | |
| 4911 | 4912 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4912 | 4913 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4913 | 4914 | const src_ptr_ty = self.typeOf(bin_op.lhs); |
| 4914 | const elem_ty = src_ptr_ty.childType(mod); | |
| 4915 | const elem_ty = src_ptr_ty.childType(zcu); | |
| 4915 | 4916 | const ptr_id = try self.resolve(bin_op.lhs); |
| 4916 | 4917 | |
| 4917 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 4918 | if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 4918 | 4919 | const dst_ptr_ty = self.typeOfIndex(inst); |
| 4919 | 4920 | return try self.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id); |
| 4920 | 4921 | } |
| ... | ... | @@ -4924,10 +4925,10 @@ const NavGen = struct { |
| 4924 | 4925 | } |
| 4925 | 4926 | |
| 4926 | 4927 | fn airArrayElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4927 | const mod = self.pt.zcu; | |
| 4928 | const zcu = self.pt.zcu; | |
| 4928 | 4929 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4929 | 4930 | const array_ty = self.typeOf(bin_op.lhs); |
| 4930 | const elem_ty = array_ty.childType(mod); | |
| 4931 | const elem_ty = array_ty.childType(zcu); | |
| 4931 | 4932 | const array_id = try self.resolve(bin_op.lhs); |
| 4932 | 4933 | const index_id = try self.resolve(bin_op.rhs); |
| 4933 | 4934 | |
| ... | ... | @@ -4946,7 +4947,7 @@ const NavGen = struct { |
| 4946 | 4947 | // For now, just generate a temporary and use that. |
| 4947 | 4948 | // TODO: This backend probably also should use isByRef from llvm... |
| 4948 | 4949 | |
| 4949 | const is_vector = array_ty.isVector(mod); | |
| 4950 | const is_vector = array_ty.isVector(zcu); | |
| 4950 | 4951 | |
| 4951 | 4952 | const elem_repr: Repr = if (is_vector) .direct else .indirect; |
| 4952 | 4953 | const ptr_array_ty_id = try self.ptrType2(array_ty, .Function, .direct); |
| ... | ... | @@ -4985,26 +4986,26 @@ const NavGen = struct { |
| 4985 | 4986 | } |
| 4986 | 4987 | |
| 4987 | 4988 | fn airPtrElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 4988 | const mod = self.pt.zcu; | |
| 4989 | const zcu = self.pt.zcu; | |
| 4989 | 4990 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4990 | 4991 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 4991 | 4992 | const elem_ty = self.typeOfIndex(inst); |
| 4992 | 4993 | const ptr_id = try self.resolve(bin_op.lhs); |
| 4993 | 4994 | const index_id = try self.resolve(bin_op.rhs); |
| 4994 | 4995 | const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id); |
| 4995 | return try self.load(elem_ty, elem_ptr_id, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) }); | |
| 4996 | return try self.load(elem_ty, elem_ptr_id, .{ .is_volatile = ptr_ty.isVolatilePtr(zcu) }); | |
| 4996 | 4997 | } |
| 4997 | 4998 | |
| 4998 | 4999 | fn airVectorStoreElem(self: *NavGen, inst: Air.Inst.Index) !void { |
| 4999 | const mod = self.pt.zcu; | |
| 5000 | const zcu = self.pt.zcu; | |
| 5000 | 5001 | const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; |
| 5001 | 5002 | const extra = self.air.extraData(Air.Bin, data.payload).data; |
| 5002 | 5003 | |
| 5003 | 5004 | const vector_ptr_ty = self.typeOf(data.vector_ptr); |
| 5004 | const vector_ty = vector_ptr_ty.childType(mod); | |
| 5005 | const scalar_ty = vector_ty.scalarType(mod); | |
| 5005 | const vector_ty = vector_ptr_ty.childType(zcu); | |
| 5006 | const scalar_ty = vector_ty.scalarType(zcu); | |
| 5006 | 5007 | |
| 5007 | const storage_class = self.spvStorageClass(vector_ptr_ty.ptrAddressSpace(mod)); | |
| 5008 | const storage_class = self.spvStorageClass(vector_ptr_ty.ptrAddressSpace(zcu)); | |
| 5008 | 5009 | const scalar_ptr_ty_id = try self.ptrType(scalar_ty, storage_class); |
| 5009 | 5010 | |
| 5010 | 5011 | const vector_ptr = try self.resolve(data.vector_ptr); |
| ... | ... | @@ -5013,30 +5014,30 @@ const NavGen = struct { |
| 5013 | 5014 | |
| 5014 | 5015 | const elem_ptr_id = try self.accessChainId(scalar_ptr_ty_id, vector_ptr, &.{index}); |
| 5015 | 5016 | try self.store(scalar_ty, elem_ptr_id, operand, .{ |
| 5016 | .is_volatile = vector_ptr_ty.isVolatilePtr(mod), | |
| 5017 | .is_volatile = vector_ptr_ty.isVolatilePtr(zcu), | |
| 5017 | 5018 | }); |
| 5018 | 5019 | } |
| 5019 | 5020 | |
| 5020 | 5021 | fn airSetUnionTag(self: *NavGen, inst: Air.Inst.Index) !void { |
| 5021 | const mod = self.pt.zcu; | |
| 5022 | const zcu = self.pt.zcu; | |
| 5022 | 5023 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5023 | 5024 | const un_ptr_ty = self.typeOf(bin_op.lhs); |
| 5024 | const un_ty = un_ptr_ty.childType(mod); | |
| 5025 | const un_ty = un_ptr_ty.childType(zcu); | |
| 5025 | 5026 | const layout = self.unionLayout(un_ty); |
| 5026 | 5027 | |
| 5027 | 5028 | if (layout.tag_size == 0) return; |
| 5028 | 5029 | |
| 5029 | const tag_ty = un_ty.unionTagTypeSafety(mod).?; | |
| 5030 | const tag_ptr_ty_id = try self.ptrType(tag_ty, self.spvStorageClass(un_ptr_ty.ptrAddressSpace(mod))); | |
| 5030 | const tag_ty = un_ty.unionTagTypeSafety(zcu).?; | |
| 5031 | const tag_ptr_ty_id = try self.ptrType(tag_ty, self.spvStorageClass(un_ptr_ty.ptrAddressSpace(zcu))); | |
| 5031 | 5032 | |
| 5032 | 5033 | const union_ptr_id = try self.resolve(bin_op.lhs); |
| 5033 | 5034 | const new_tag_id = try self.resolve(bin_op.rhs); |
| 5034 | 5035 | |
| 5035 | 5036 | if (!layout.has_payload) { |
| 5036 | try self.store(tag_ty, union_ptr_id, new_tag_id, .{ .is_volatile = un_ptr_ty.isVolatilePtr(mod) }); | |
| 5037 | try self.store(tag_ty, union_ptr_id, new_tag_id, .{ .is_volatile = un_ptr_ty.isVolatilePtr(zcu) }); | |
| 5037 | 5038 | } else { |
| 5038 | 5039 | const ptr_id = try self.accessChain(tag_ptr_ty_id, union_ptr_id, &.{layout.tag_index}); |
| 5039 | try self.store(tag_ty, ptr_id, new_tag_id, .{ .is_volatile = un_ptr_ty.isVolatilePtr(mod) }); | |
| 5040 | try self.store(tag_ty, ptr_id, new_tag_id, .{ .is_volatile = un_ptr_ty.isVolatilePtr(zcu) }); | |
| 5040 | 5041 | } |
| 5041 | 5042 | } |
| 5042 | 5043 | |
| ... | ... | @@ -5044,14 +5045,14 @@ const NavGen = struct { |
| 5044 | 5045 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5045 | 5046 | const un_ty = self.typeOf(ty_op.operand); |
| 5046 | 5047 | |
| 5047 | const mod = self.pt.zcu; | |
| 5048 | const zcu = self.pt.zcu; | |
| 5048 | 5049 | const layout = self.unionLayout(un_ty); |
| 5049 | 5050 | if (layout.tag_size == 0) return null; |
| 5050 | 5051 | |
| 5051 | 5052 | const union_handle = try self.resolve(ty_op.operand); |
| 5052 | 5053 | if (!layout.has_payload) return union_handle; |
| 5053 | 5054 | |
| 5054 | const tag_ty = un_ty.unionTagTypeSafety(mod).?; | |
| 5055 | const tag_ty = un_ty.unionTagTypeSafety(zcu).?; | |
| 5055 | 5056 | return try self.extractField(tag_ty, union_handle, layout.tag_index); |
| 5056 | 5057 | } |
| 5057 | 5058 | |
| ... | ... | @@ -5068,9 +5069,9 @@ const NavGen = struct { |
| 5068 | 5069 | // Note: The result here is not cached, because it generates runtime code. |
| 5069 | 5070 | |
| 5070 | 5071 | const pt = self.pt; |
| 5071 | const mod = pt.zcu; | |
| 5072 | const ip = &mod.intern_pool; | |
| 5073 | const union_ty = mod.typeToUnion(ty).?; | |
| 5072 | const zcu = pt.zcu; | |
| 5073 | const ip = &zcu.intern_pool; | |
| 5074 | const union_ty = zcu.typeToUnion(ty).?; | |
| 5074 | 5075 | const tag_ty = Type.fromInterned(union_ty.enum_tag_ty); |
| 5075 | 5076 | |
| 5076 | 5077 | if (union_ty.flagsUnordered(ip).layout == .@"packed") { |
| ... | ... | @@ -5082,7 +5083,7 @@ const NavGen = struct { |
| 5082 | 5083 | const tag_int = if (layout.tag_size != 0) blk: { |
| 5083 | 5084 | const tag_val = try pt.enumValueFieldIndex(tag_ty, active_field); |
| 5084 | 5085 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); |
| 5085 | break :blk tag_int_val.toUnsignedInt(pt); | |
| 5086 | break :blk tag_int_val.toUnsignedInt(zcu); | |
| 5086 | 5087 | } else 0; |
| 5087 | 5088 | |
| 5088 | 5089 | if (!layout.has_payload) { |
| ... | ... | @@ -5099,7 +5100,7 @@ const NavGen = struct { |
| 5099 | 5100 | } |
| 5100 | 5101 | |
| 5101 | 5102 | const payload_ty = Type.fromInterned(union_ty.field_types.get(ip)[active_field]); |
| 5102 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5103 | if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5103 | 5104 | const pl_ptr_ty_id = try self.ptrType(layout.payload_ty, .Function); |
| 5104 | 5105 | const pl_ptr_id = try self.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index}); |
| 5105 | 5106 | const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function); |
| ... | ... | @@ -5123,15 +5124,15 @@ const NavGen = struct { |
| 5123 | 5124 | |
| 5124 | 5125 | fn airUnionInit(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5125 | 5126 | const pt = self.pt; |
| 5126 | const mod = pt.zcu; | |
| 5127 | const ip = &mod.intern_pool; | |
| 5127 | const zcu = pt.zcu; | |
| 5128 | const ip = &zcu.intern_pool; | |
| 5128 | 5129 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5129 | 5130 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 5130 | 5131 | const ty = self.typeOfIndex(inst); |
| 5131 | 5132 | |
| 5132 | const union_obj = mod.typeToUnion(ty).?; | |
| 5133 | const union_obj = zcu.typeToUnion(ty).?; | |
| 5133 | 5134 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 5134 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 5135 | const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 5135 | 5136 | try self.resolve(extra.init) |
| 5136 | 5137 | else |
| 5137 | 5138 | null; |
| ... | ... | @@ -5140,23 +5141,23 @@ const NavGen = struct { |
| 5140 | 5141 | |
| 5141 | 5142 | fn airStructFieldVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5142 | 5143 | const pt = self.pt; |
| 5143 | const mod = pt.zcu; | |
| 5144 | const zcu = pt.zcu; | |
| 5144 | 5145 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5145 | 5146 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 5146 | 5147 | |
| 5147 | 5148 | const object_ty = self.typeOf(struct_field.struct_operand); |
| 5148 | 5149 | const object_id = try self.resolve(struct_field.struct_operand); |
| 5149 | 5150 | const field_index = struct_field.field_index; |
| 5150 | const field_ty = object_ty.structFieldType(field_index, mod); | |
| 5151 | const field_ty = object_ty.structFieldType(field_index, zcu); | |
| 5151 | 5152 | |
| 5152 | if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return null; | |
| 5153 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null; | |
| 5153 | 5154 | |
| 5154 | switch (object_ty.zigTypeTag(mod)) { | |
| 5155 | .Struct => switch (object_ty.containerLayout(mod)) { | |
| 5155 | switch (object_ty.zigTypeTag(zcu)) { | |
| 5156 | .Struct => switch (object_ty.containerLayout(zcu)) { | |
| 5156 | 5157 | .@"packed" => unreachable, // TODO |
| 5157 | 5158 | else => return try self.extractField(field_ty, object_id, field_index), |
| 5158 | 5159 | }, |
| 5159 | .Union => switch (object_ty.containerLayout(mod)) { | |
| 5160 | .Union => switch (object_ty.containerLayout(zcu)) { | |
| 5160 | 5161 | .@"packed" => unreachable, // TODO |
| 5161 | 5162 | else => { |
| 5162 | 5163 | // Store, ptr-elem-ptr, pointer-cast, load |
| ... | ... | @@ -5185,16 +5186,16 @@ const NavGen = struct { |
| 5185 | 5186 | |
| 5186 | 5187 | fn airFieldParentPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5187 | 5188 | const pt = self.pt; |
| 5188 | const mod = pt.zcu; | |
| 5189 | const zcu = pt.zcu; | |
| 5189 | 5190 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5190 | 5191 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5191 | 5192 | |
| 5192 | const parent_ty = ty_pl.ty.toType().childType(mod); | |
| 5193 | const parent_ty = ty_pl.ty.toType().childType(zcu); | |
| 5193 | 5194 | const result_ty_id = try self.resolveType(ty_pl.ty.toType(), .indirect); |
| 5194 | 5195 | |
| 5195 | 5196 | const field_ptr = try self.resolve(extra.field_ptr); |
| 5196 | 5197 | const field_ptr_int = try self.intFromPtr(field_ptr); |
| 5197 | const field_offset = parent_ty.structFieldOffset(extra.field_index, pt); | |
| 5198 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); | |
| 5198 | 5199 | |
| 5199 | 5200 | const base_ptr_int = base_ptr_int: { |
| 5200 | 5201 | if (field_offset == 0) break :base_ptr_int field_ptr_int; |
| ... | ... | @@ -5319,10 +5320,10 @@ const NavGen = struct { |
| 5319 | 5320 | } |
| 5320 | 5321 | |
| 5321 | 5322 | fn airAlloc(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5322 | const mod = self.pt.zcu; | |
| 5323 | const zcu = self.pt.zcu; | |
| 5323 | 5324 | const ptr_ty = self.typeOfIndex(inst); |
| 5324 | assert(ptr_ty.ptrAddressSpace(mod) == .generic); | |
| 5325 | const child_ty = ptr_ty.childType(mod); | |
| 5325 | assert(ptr_ty.ptrAddressSpace(zcu) == .generic); | |
| 5326 | const child_ty = ptr_ty.childType(zcu); | |
| 5326 | 5327 | return try self.alloc(child_ty, .{}); |
| 5327 | 5328 | } |
| 5328 | 5329 | |
| ... | ... | @@ -5494,9 +5495,9 @@ const NavGen = struct { |
| 5494 | 5495 | // ir.Block in a different SPIR-V block. |
| 5495 | 5496 | |
| 5496 | 5497 | const pt = self.pt; |
| 5497 | const mod = pt.zcu; | |
| 5498 | const zcu = pt.zcu; | |
| 5498 | 5499 | const ty = self.typeOfIndex(inst); |
| 5499 | const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(pt); | |
| 5500 | const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu); | |
| 5500 | 5501 | |
| 5501 | 5502 | const cf = switch (self.control_flow) { |
| 5502 | 5503 | .structured => |*cf| cf, |
| ... | ... | @@ -5570,7 +5571,7 @@ const NavGen = struct { |
| 5570 | 5571 | |
| 5571 | 5572 | const sblock = cf.block_stack.getLast(); |
| 5572 | 5573 | |
| 5573 | if (ty.isNoReturn(mod)) { | |
| 5574 | if (ty.isNoReturn(zcu)) { | |
| 5574 | 5575 | // If this block is noreturn, this instruction is the last of a block, |
| 5575 | 5576 | // and we must simply jump to the block's merge unconditionally. |
| 5576 | 5577 | try self.structuredBreak(next_block); |
| ... | ... | @@ -5626,13 +5627,13 @@ const NavGen = struct { |
| 5626 | 5627 | } |
| 5627 | 5628 | |
| 5628 | 5629 | fn airBr(self: *NavGen, inst: Air.Inst.Index) !void { |
| 5629 | const pt = self.pt; | |
| 5630 | const zcu = self.pt.zcu; | |
| 5630 | 5631 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 5631 | 5632 | const operand_ty = self.typeOf(br.operand); |
| 5632 | 5633 | |
| 5633 | 5634 | switch (self.control_flow) { |
| 5634 | 5635 | .structured => |*cf| { |
| 5635 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 5636 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5636 | 5637 | const operand_id = try self.resolve(br.operand); |
| 5637 | 5638 | const block_result_var_id = cf.block_results.get(br.block_inst).?; |
| 5638 | 5639 | try self.store(operand_ty, block_result_var_id, operand_id, .{}); |
| ... | ... | @@ -5643,7 +5644,7 @@ const NavGen = struct { |
| 5643 | 5644 | }, |
| 5644 | 5645 | .unstructured => |cf| { |
| 5645 | 5646 | const block = cf.blocks.get(br.block_inst).?; |
| 5646 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) { | |
| 5647 | if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5647 | 5648 | const operand_id = try self.resolve(br.operand); |
| 5648 | 5649 | // current_block_label should not be undefined here, lest there |
| 5649 | 5650 | // is a br or br_void in the function's body. |
| ... | ... | @@ -5770,35 +5771,35 @@ const NavGen = struct { |
| 5770 | 5771 | } |
| 5771 | 5772 | |
| 5772 | 5773 | fn airLoad(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5773 | const mod = self.pt.zcu; | |
| 5774 | const zcu = self.pt.zcu; | |
| 5774 | 5775 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5775 | 5776 | const ptr_ty = self.typeOf(ty_op.operand); |
| 5776 | 5777 | const elem_ty = self.typeOfIndex(inst); |
| 5777 | 5778 | const operand = try self.resolve(ty_op.operand); |
| 5778 | if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | |
| 5779 | if (!ptr_ty.isVolatilePtr(zcu) and self.liveness.isUnused(inst)) return null; | |
| 5779 | 5780 | |
| 5780 | return try self.load(elem_ty, operand, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) }); | |
| 5781 | return try self.load(elem_ty, operand, .{ .is_volatile = ptr_ty.isVolatilePtr(zcu) }); | |
| 5781 | 5782 | } |
| 5782 | 5783 | |
| 5783 | 5784 | fn airStore(self: *NavGen, inst: Air.Inst.Index) !void { |
| 5784 | const mod = self.pt.zcu; | |
| 5785 | const zcu = self.pt.zcu; | |
| 5785 | 5786 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5786 | 5787 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 5787 | const elem_ty = ptr_ty.childType(mod); | |
| 5788 | const elem_ty = ptr_ty.childType(zcu); | |
| 5788 | 5789 | const ptr = try self.resolve(bin_op.lhs); |
| 5789 | 5790 | const value = try self.resolve(bin_op.rhs); |
| 5790 | 5791 | |
| 5791 | try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) }); | |
| 5792 | try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(zcu) }); | |
| 5792 | 5793 | } |
| 5793 | 5794 | |
| 5794 | 5795 | fn airRet(self: *NavGen, inst: Air.Inst.Index) !void { |
| 5795 | 5796 | const pt = self.pt; |
| 5796 | const mod = pt.zcu; | |
| 5797 | const zcu = pt.zcu; | |
| 5797 | 5798 | const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5798 | 5799 | const ret_ty = self.typeOf(operand); |
| 5799 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5800 | const fn_info = mod.typeToFunc(mod.navValue(self.owner_nav).typeOf(mod)).?; | |
| 5801 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | |
| 5800 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5801 | const fn_info = zcu.typeToFunc(zcu.navValue(self.owner_nav).typeOf(zcu)).?; | |
| 5802 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { | |
| 5802 | 5803 | // Functions with an empty error set are emitted with an error code |
| 5803 | 5804 | // return type and return zero so they can be function pointers coerced |
| 5804 | 5805 | // to functions that return anyerror. |
| ... | ... | @@ -5815,14 +5816,14 @@ const NavGen = struct { |
| 5815 | 5816 | |
| 5816 | 5817 | fn airRetLoad(self: *NavGen, inst: Air.Inst.Index) !void { |
| 5817 | 5818 | const pt = self.pt; |
| 5818 | const mod = pt.zcu; | |
| 5819 | const zcu = pt.zcu; | |
| 5819 | 5820 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5820 | 5821 | const ptr_ty = self.typeOf(un_op); |
| 5821 | const ret_ty = ptr_ty.childType(mod); | |
| 5822 | const ret_ty = ptr_ty.childType(zcu); | |
| 5822 | 5823 | |
| 5823 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 5824 | const fn_info = mod.typeToFunc(mod.navValue(self.owner_nav).typeOf(mod)).?; | |
| 5825 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | |
| 5824 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 5825 | const fn_info = zcu.typeToFunc(zcu.navValue(self.owner_nav).typeOf(zcu)).?; | |
| 5826 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { | |
| 5826 | 5827 | // Functions with an empty error set are emitted with an error code |
| 5827 | 5828 | // return type and return zero so they can be function pointers coerced |
| 5828 | 5829 | // to functions that return anyerror. |
| ... | ... | @@ -5834,14 +5835,14 @@ const NavGen = struct { |
| 5834 | 5835 | } |
| 5835 | 5836 | |
| 5836 | 5837 | const ptr = try self.resolve(un_op); |
| 5837 | const value = try self.load(ret_ty, ptr, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) }); | |
| 5838 | const value = try self.load(ret_ty, ptr, .{ .is_volatile = ptr_ty.isVolatilePtr(zcu) }); | |
| 5838 | 5839 | try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ |
| 5839 | 5840 | .value = value, |
| 5840 | 5841 | }); |
| 5841 | 5842 | } |
| 5842 | 5843 | |
| 5843 | 5844 | fn airTry(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5844 | const mod = self.pt.zcu; | |
| 5845 | const zcu = self.pt.zcu; | |
| 5845 | 5846 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5846 | 5847 | const err_union_id = try self.resolve(pl_op.operand); |
| 5847 | 5848 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| ... | ... | @@ -5854,7 +5855,7 @@ const NavGen = struct { |
| 5854 | 5855 | |
| 5855 | 5856 | const eu_layout = self.errorUnionLayout(payload_ty); |
| 5856 | 5857 | |
| 5857 | if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 5858 | if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 5858 | 5859 | const err_id = if (eu_layout.payload_has_bits) |
| 5859 | 5860 | try self.extractField(Type.anyerror, err_union_id, eu_layout.errorFieldIndex()) |
| 5860 | 5861 | else |
| ... | ... | @@ -5911,18 +5912,18 @@ const NavGen = struct { |
| 5911 | 5912 | } |
| 5912 | 5913 | |
| 5913 | 5914 | fn airErrUnionErr(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5914 | const mod = self.pt.zcu; | |
| 5915 | const zcu = self.pt.zcu; | |
| 5915 | 5916 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5916 | 5917 | const operand_id = try self.resolve(ty_op.operand); |
| 5917 | 5918 | const err_union_ty = self.typeOf(ty_op.operand); |
| 5918 | 5919 | const err_ty_id = try self.resolveType(Type.anyerror, .direct); |
| 5919 | 5920 | |
| 5920 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 5921 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 5921 | 5922 | // No error possible, so just return undefined. |
| 5922 | 5923 | return try self.spv.constUndef(err_ty_id); |
| 5923 | 5924 | } |
| 5924 | 5925 | |
| 5925 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 5926 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 5926 | 5927 | const eu_layout = self.errorUnionLayout(payload_ty); |
| 5927 | 5928 | |
| 5928 | 5929 | if (!eu_layout.payload_has_bits) { |
| ... | ... | @@ -5947,10 +5948,10 @@ const NavGen = struct { |
| 5947 | 5948 | } |
| 5948 | 5949 | |
| 5949 | 5950 | fn airWrapErrUnionErr(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 5950 | const mod = self.pt.zcu; | |
| 5951 | const zcu = self.pt.zcu; | |
| 5951 | 5952 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5952 | 5953 | const err_union_ty = self.typeOfIndex(inst); |
| 5953 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 5954 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 5954 | 5955 | const operand_id = try self.resolve(ty_op.operand); |
| 5955 | 5956 | const eu_layout = self.errorUnionLayout(payload_ty); |
| 5956 | 5957 | |
| ... | ... | @@ -5995,28 +5996,28 @@ const NavGen = struct { |
| 5995 | 5996 | |
| 5996 | 5997 | fn airIsNull(self: *NavGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { |
| 5997 | 5998 | const pt = self.pt; |
| 5998 | const mod = pt.zcu; | |
| 5999 | const zcu = pt.zcu; | |
| 5999 | 6000 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6000 | 6001 | const operand_id = try self.resolve(un_op); |
| 6001 | 6002 | const operand_ty = self.typeOf(un_op); |
| 6002 | const optional_ty = if (is_pointer) operand_ty.childType(mod) else operand_ty; | |
| 6003 | const payload_ty = optional_ty.optionalChild(mod); | |
| 6003 | const optional_ty = if (is_pointer) operand_ty.childType(zcu) else operand_ty; | |
| 6004 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 6004 | 6005 | |
| 6005 | 6006 | const bool_ty_id = try self.resolveType(Type.bool, .direct); |
| 6006 | 6007 | |
| 6007 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 6008 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 6008 | 6009 | // Pointer payload represents nullability: pointer or slice. |
| 6009 | 6010 | const loaded_id = if (is_pointer) |
| 6010 | 6011 | try self.load(optional_ty, operand_id, .{}) |
| 6011 | 6012 | else |
| 6012 | 6013 | operand_id; |
| 6013 | 6014 | |
| 6014 | const ptr_ty = if (payload_ty.isSlice(mod)) | |
| 6015 | payload_ty.slicePtrFieldType(mod) | |
| 6015 | const ptr_ty = if (payload_ty.isSlice(zcu)) | |
| 6016 | payload_ty.slicePtrFieldType(zcu) | |
| 6016 | 6017 | else |
| 6017 | 6018 | payload_ty; |
| 6018 | 6019 | |
| 6019 | const ptr_id = if (payload_ty.isSlice(mod)) | |
| 6020 | const ptr_id = if (payload_ty.isSlice(zcu)) | |
| 6020 | 6021 | try self.extractField(ptr_ty, loaded_id, 0) |
| 6021 | 6022 | else |
| 6022 | 6023 | loaded_id; |
| ... | ... | @@ -6036,8 +6037,8 @@ const NavGen = struct { |
| 6036 | 6037 | |
| 6037 | 6038 | const is_non_null_id = blk: { |
| 6038 | 6039 | if (is_pointer) { |
| 6039 | if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 6040 | const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(mod)); | |
| 6040 | if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 6041 | const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(zcu)); | |
| 6041 | 6042 | const bool_ptr_ty_id = try self.ptrType(Type.bool, storage_class); |
| 6042 | 6043 | const tag_ptr_id = try self.accessChain(bool_ptr_ty_id, operand_id, &.{1}); |
| 6043 | 6044 | break :blk try self.load(Type.bool, tag_ptr_id, .{}); |
| ... | ... | @@ -6046,7 +6047,7 @@ const NavGen = struct { |
| 6046 | 6047 | break :blk try self.load(Type.bool, operand_id, .{}); |
| 6047 | 6048 | } |
| 6048 | 6049 | |
| 6049 | break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(pt)) | |
| 6050 | break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) | |
| 6050 | 6051 | try self.extractField(Type.bool, operand_id, 1) |
| 6051 | 6052 | else |
| 6052 | 6053 | // Optional representation is bool indicating whether the optional is set |
| ... | ... | @@ -6071,16 +6072,16 @@ const NavGen = struct { |
| 6071 | 6072 | } |
| 6072 | 6073 | |
| 6073 | 6074 | fn airIsErr(self: *NavGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { |
| 6074 | const mod = self.pt.zcu; | |
| 6075 | const zcu = self.pt.zcu; | |
| 6075 | 6076 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6076 | 6077 | const operand_id = try self.resolve(un_op); |
| 6077 | 6078 | const err_union_ty = self.typeOf(un_op); |
| 6078 | 6079 | |
| 6079 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { | |
| 6080 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | |
| 6080 | 6081 | return try self.constBool(pred == .is_non_err, .direct); |
| 6081 | 6082 | } |
| 6082 | 6083 | |
| 6083 | const payload_ty = err_union_ty.errorUnionPayload(mod); | |
| 6084 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | |
| 6084 | 6085 | const eu_layout = self.errorUnionLayout(payload_ty); |
| 6085 | 6086 | const bool_ty_id = try self.resolveType(Type.bool, .direct); |
| 6086 | 6087 | |
| ... | ... | @@ -6105,15 +6106,15 @@ const NavGen = struct { |
| 6105 | 6106 | |
| 6106 | 6107 | fn airUnwrapOptional(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 6107 | 6108 | const pt = self.pt; |
| 6108 | const mod = pt.zcu; | |
| 6109 | const zcu = pt.zcu; | |
| 6109 | 6110 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6110 | 6111 | const operand_id = try self.resolve(ty_op.operand); |
| 6111 | 6112 | const optional_ty = self.typeOf(ty_op.operand); |
| 6112 | 6113 | const payload_ty = self.typeOfIndex(inst); |
| 6113 | 6114 | |
| 6114 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) return null; | |
| 6115 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null; | |
| 6115 | 6116 | |
| 6116 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 6117 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 6117 | 6118 | return operand_id; |
| 6118 | 6119 | } |
| 6119 | 6120 | |
| ... | ... | @@ -6122,22 +6123,22 @@ const NavGen = struct { |
| 6122 | 6123 | |
| 6123 | 6124 | fn airUnwrapOptionalPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 6124 | 6125 | const pt = self.pt; |
| 6125 | const mod = pt.zcu; | |
| 6126 | const zcu = pt.zcu; | |
| 6126 | 6127 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6127 | 6128 | const operand_id = try self.resolve(ty_op.operand); |
| 6128 | 6129 | const operand_ty = self.typeOf(ty_op.operand); |
| 6129 | const optional_ty = operand_ty.childType(mod); | |
| 6130 | const payload_ty = optional_ty.optionalChild(mod); | |
| 6130 | const optional_ty = operand_ty.childType(zcu); | |
| 6131 | const payload_ty = optional_ty.optionalChild(zcu); | |
| 6131 | 6132 | const result_ty = self.typeOfIndex(inst); |
| 6132 | 6133 | const result_ty_id = try self.resolveType(result_ty, .direct); |
| 6133 | 6134 | |
| 6134 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 6135 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 6135 | 6136 | // There is no payload, but we still need to return a valid pointer. |
| 6136 | 6137 | // We can just return anything here, so just return a pointer to the operand. |
| 6137 | 6138 | return try self.bitCast(result_ty, operand_ty, operand_id); |
| 6138 | 6139 | } |
| 6139 | 6140 | |
| 6140 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 6141 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 6141 | 6142 | // They are the same value. |
| 6142 | 6143 | return try self.bitCast(result_ty, operand_ty, operand_id); |
| 6143 | 6144 | } |
| ... | ... | @@ -6147,18 +6148,18 @@ const NavGen = struct { |
| 6147 | 6148 | |
| 6148 | 6149 | fn airWrapOptional(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 6149 | 6150 | const pt = self.pt; |
| 6150 | const mod = pt.zcu; | |
| 6151 | const zcu = pt.zcu; | |
| 6151 | 6152 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6152 | 6153 | const payload_ty = self.typeOf(ty_op.operand); |
| 6153 | 6154 | |
| 6154 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) { | |
| 6155 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 6155 | 6156 | return try self.constBool(true, .indirect); |
| 6156 | 6157 | } |
| 6157 | 6158 | |
| 6158 | 6159 | const operand_id = try self.resolve(ty_op.operand); |
| 6159 | 6160 | |
| 6160 | 6161 | const optional_ty = self.typeOfIndex(inst); |
| 6161 | if (optional_ty.optionalReprIsPayload(mod)) { | |
| 6162 | if (optional_ty.optionalReprIsPayload(zcu)) { | |
| 6162 | 6163 | return operand_id; |
| 6163 | 6164 | } |
| 6164 | 6165 | |
| ... | ... | @@ -6170,7 +6171,7 @@ const NavGen = struct { |
| 6170 | 6171 | |
| 6171 | 6172 | fn airSwitchBr(self: *NavGen, inst: Air.Inst.Index) !void { |
| 6172 | 6173 | const pt = self.pt; |
| 6173 | const mod = pt.zcu; | |
| 6174 | const zcu = pt.zcu; | |
| 6174 | 6175 | const target = self.getTarget(); |
| 6175 | 6176 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6176 | 6177 | const cond_ty = self.typeOf(pl_op.operand); |
| ... | ... | @@ -6178,18 +6179,18 @@ const NavGen = struct { |
| 6178 | 6179 | var cond_indirect = try self.convertToIndirect(cond_ty, cond); |
| 6179 | 6180 | const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload); |
| 6180 | 6181 | |
| 6181 | const cond_words: u32 = switch (cond_ty.zigTypeTag(mod)) { | |
| 6182 | const cond_words: u32 = switch (cond_ty.zigTypeTag(zcu)) { | |
| 6182 | 6183 | .Bool, .ErrorSet => 1, |
| 6183 | 6184 | .Int => blk: { |
| 6184 | const bits = cond_ty.intInfo(mod).bits; | |
| 6185 | const bits = cond_ty.intInfo(zcu).bits; | |
| 6185 | 6186 | const backing_bits = self.backingIntBits(bits) orelse { |
| 6186 | 6187 | return self.todo("implement composite int switch", .{}); |
| 6187 | 6188 | }; |
| 6188 | 6189 | break :blk if (backing_bits <= 32) 1 else 2; |
| 6189 | 6190 | }, |
| 6190 | 6191 | .Enum => blk: { |
| 6191 | const int_ty = cond_ty.intTagType(mod); | |
| 6192 | const int_info = int_ty.intInfo(mod); | |
| 6192 | const int_ty = cond_ty.intTagType(zcu); | |
| 6193 | const int_info = int_ty.intInfo(zcu); | |
| 6193 | 6194 | const backing_bits = self.backingIntBits(int_info.bits) orelse { |
| 6194 | 6195 | return self.todo("implement composite int switch", .{}); |
| 6195 | 6196 | }; |
| ... | ... | @@ -6200,7 +6201,7 @@ const NavGen = struct { |
| 6200 | 6201 | break :blk target.ptrBitWidth() / 32; |
| 6201 | 6202 | }, |
| 6202 | 6203 | // TODO: Figure out which types apply here, and work around them as we can only do integers. |
| 6203 | else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag(mod))}), | |
| 6204 | else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag(zcu))}), | |
| 6204 | 6205 | }; |
| 6205 | 6206 | |
| 6206 | 6207 | const num_cases = switch_br.data.cases_len; |
| ... | ... | @@ -6255,14 +6256,14 @@ const NavGen = struct { |
| 6255 | 6256 | |
| 6256 | 6257 | for (items) |item| { |
| 6257 | 6258 | const value = (try self.air.value(item, pt)) orelse unreachable; |
| 6258 | const int_val: u64 = switch (cond_ty.zigTypeTag(mod)) { | |
| 6259 | .Bool, .Int => if (cond_ty.isSignedInt(mod)) @bitCast(value.toSignedInt(pt)) else value.toUnsignedInt(pt), | |
| 6259 | const int_val: u64 = switch (cond_ty.zigTypeTag(zcu)) { | |
| 6260 | .Bool, .Int => if (cond_ty.isSignedInt(zcu)) @bitCast(value.toSignedInt(zcu)) else value.toUnsignedInt(zcu), | |
| 6260 | 6261 | .Enum => blk: { |
| 6261 | 6262 | // TODO: figure out of cond_ty is correct (something with enum literals) |
| 6262 | break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(pt); // TODO: composite integer constants | |
| 6263 | break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(zcu); // TODO: composite integer constants | |
| 6263 | 6264 | }, |
| 6264 | .ErrorSet => value.getErrorInt(mod), | |
| 6265 | .Pointer => value.toUnsignedInt(pt), | |
| 6265 | .ErrorSet => value.getErrorInt(zcu), | |
| 6266 | .Pointer => value.toUnsignedInt(zcu), | |
| 6266 | 6267 | else => unreachable, |
| 6267 | 6268 | }; |
| 6268 | 6269 | const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) { |
| ... | ... | @@ -6343,9 +6344,9 @@ const NavGen = struct { |
| 6343 | 6344 | |
| 6344 | 6345 | fn airDbgStmt(self: *NavGen, inst: Air.Inst.Index) !void { |
| 6345 | 6346 | const pt = self.pt; |
| 6346 | const mod = pt.zcu; | |
| 6347 | const zcu = pt.zcu; | |
| 6347 | 6348 | const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 6348 | const path = mod.navFileScope(self.owner_nav).sub_file_path; | |
| 6349 | const path = zcu.navFileScope(self.owner_nav).sub_file_path; | |
| 6349 | 6350 | try self.func.body.emit(self.spv.gpa, .OpLine, .{ |
| 6350 | 6351 | .file = try self.spv.resolveString(path), |
| 6351 | 6352 | .line = self.base_line + dbg_stmt.line + 1, |
| ... | ... | @@ -6354,12 +6355,12 @@ const NavGen = struct { |
| 6354 | 6355 | } |
| 6355 | 6356 | |
| 6356 | 6357 | fn airDbgInlineBlock(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 6357 | const mod = self.pt.zcu; | |
| 6358 | const zcu = self.pt.zcu; | |
| 6358 | 6359 | const inst_datas = self.air.instructions.items(.data); |
| 6359 | 6360 | const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload); |
| 6360 | 6361 | const old_base_line = self.base_line; |
| 6361 | 6362 | defer self.base_line = old_base_line; |
| 6362 | self.base_line = mod.navSrcLine(mod.funcInfo(extra.data.func).owner_nav); | |
| 6363 | self.base_line = zcu.navSrcLine(zcu.funcInfo(extra.data.func).owner_nav); | |
| 6363 | 6364 | return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); |
| 6364 | 6365 | } |
| 6365 | 6366 | |
| ... | ... | @@ -6371,7 +6372,7 @@ const NavGen = struct { |
| 6371 | 6372 | } |
| 6372 | 6373 | |
| 6373 | 6374 | fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 6374 | const mod = self.pt.zcu; | |
| 6375 | const zcu = self.pt.zcu; | |
| 6375 | 6376 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6376 | 6377 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 6377 | 6378 | |
| ... | ... | @@ -6453,20 +6454,20 @@ const NavGen = struct { |
| 6453 | 6454 | // TODO: Translate proper error locations. |
| 6454 | 6455 | assert(as.errors.items.len != 0); |
| 6455 | 6456 | assert(self.error_msg == null); |
| 6456 | const src_loc = mod.navSrcLoc(self.owner_nav); | |
| 6457 | self.error_msg = try Zcu.ErrorMsg.create(mod.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{}); | |
| 6458 | const notes = try mod.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len); | |
| 6457 | const src_loc = zcu.navSrcLoc(self.owner_nav); | |
| 6458 | self.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{}); | |
| 6459 | const notes = try zcu.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len); | |
| 6459 | 6460 | |
| 6460 | 6461 | // Sub-scope to prevent `return error.CodegenFail` from running the errdefers. |
| 6461 | 6462 | { |
| 6462 | errdefer mod.gpa.free(notes); | |
| 6463 | errdefer zcu.gpa.free(notes); | |
| 6463 | 6464 | var i: usize = 0; |
| 6464 | 6465 | errdefer for (notes[0..i]) |*note| { |
| 6465 | note.deinit(mod.gpa); | |
| 6466 | note.deinit(zcu.gpa); | |
| 6466 | 6467 | }; |
| 6467 | 6468 | |
| 6468 | 6469 | while (i < as.errors.items.len) : (i += 1) { |
| 6469 | notes[i] = try Zcu.ErrorMsg.init(mod.gpa, src_loc, "{s}", .{as.errors.items[i].msg}); | |
| 6470 | notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{as.errors.items[i].msg}); | |
| 6470 | 6471 | } |
| 6471 | 6472 | } |
| 6472 | 6473 | self.error_msg.?.notes = notes; |
| ... | ... | @@ -6503,17 +6504,17 @@ const NavGen = struct { |
| 6503 | 6504 | _ = modifier; |
| 6504 | 6505 | |
| 6505 | 6506 | const pt = self.pt; |
| 6506 | const mod = pt.zcu; | |
| 6507 | const zcu = pt.zcu; | |
| 6507 | 6508 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6508 | 6509 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 6509 | 6510 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 6510 | 6511 | const callee_ty = self.typeOf(pl_op.operand); |
| 6511 | const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { | |
| 6512 | const zig_fn_ty = switch (callee_ty.zigTypeTag(zcu)) { | |
| 6512 | 6513 | .Fn => callee_ty, |
| 6513 | 6514 | .Pointer => return self.fail("cannot call function pointers", .{}), |
| 6514 | 6515 | else => unreachable, |
| 6515 | 6516 | }; |
| 6516 | const fn_info = mod.typeToFunc(zig_fn_ty).?; | |
| 6517 | const fn_info = zcu.typeToFunc(zig_fn_ty).?; | |
| 6517 | 6518 | const return_type = fn_info.return_type; |
| 6518 | 6519 | |
| 6519 | 6520 | const result_type_id = try self.resolveFnReturnType(Type.fromInterned(return_type)); |
| ... | ... | @@ -6529,7 +6530,7 @@ const NavGen = struct { |
| 6529 | 6530 | // before starting to emit OpFunctionCall instructions. Hence the |
| 6530 | 6531 | // temporary params buffer. |
| 6531 | 6532 | const arg_ty = self.typeOf(arg); |
| 6532 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(pt)) continue; | |
| 6533 | if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | |
| 6533 | 6534 | const arg_id = try self.resolve(arg); |
| 6534 | 6535 | |
| 6535 | 6536 | params[n_params] = arg_id; |
| ... | ... | @@ -6547,7 +6548,7 @@ const NavGen = struct { |
| 6547 | 6548 | try self.func.body.emit(self.spv.gpa, .OpUnreachable, {}); |
| 6548 | 6549 | } |
| 6549 | 6550 | |
| 6550 | if (self.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(pt)) { | |
| 6551 | if (self.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(zcu)) { | |
| 6551 | 6552 | return null; |
| 6552 | 6553 | } |
| 6553 | 6554 | |
| ... | ... | @@ -6604,12 +6605,12 @@ const NavGen = struct { |
| 6604 | 6605 | } |
| 6605 | 6606 | |
| 6606 | 6607 | fn typeOf(self: *NavGen, inst: Air.Inst.Ref) Type { |
| 6607 | const mod = self.pt.zcu; | |
| 6608 | return self.air.typeOf(inst, &mod.intern_pool); | |
| 6608 | const zcu = self.pt.zcu; | |
| 6609 | return self.air.typeOf(inst, &zcu.intern_pool); | |
| 6609 | 6610 | } |
| 6610 | 6611 | |
| 6611 | 6612 | fn typeOfIndex(self: *NavGen, inst: Air.Inst.Index) Type { |
| 6612 | const mod = self.pt.zcu; | |
| 6613 | return self.air.typeOfIndex(inst, &mod.intern_pool); | |
| 6613 | const zcu = self.pt.zcu; | |
| 6614 | return self.air.typeOfIndex(inst, &zcu.intern_pool); | |
| 6614 | 6615 | } |
| 6615 | 6616 | }; |
src/link/Coff.zig+4-4| ... | ... | @@ -1259,8 +1259,8 @@ fn updateLazySymbolAtom( |
| 1259 | 1259 | atom_index: Atom.Index, |
| 1260 | 1260 | section_index: u16, |
| 1261 | 1261 | ) !void { |
| 1262 | const mod = pt.zcu; | |
| 1263 | const gpa = mod.gpa; | |
| 1262 | const zcu = pt.zcu; | |
| 1263 | const gpa = zcu.gpa; | |
| 1264 | 1264 | |
| 1265 | 1265 | var required_alignment: InternPool.Alignment = .none; |
| 1266 | 1266 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -1275,7 +1275,7 @@ fn updateLazySymbolAtom( |
| 1275 | 1275 | const atom = self.getAtomPtr(atom_index); |
| 1276 | 1276 | const local_sym_index = atom.getSymbolIndex().?; |
| 1277 | 1277 | |
| 1278 | const src = Type.fromInterned(sym.ty).srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded; | |
| 1278 | const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded; | |
| 1279 | 1279 | const res = try codegen.generateLazySymbol( |
| 1280 | 1280 | &self.base, |
| 1281 | 1281 | pt, |
| ... | ... | @@ -1849,7 +1849,7 @@ pub fn lowerUav( |
| 1849 | 1849 | const gpa = zcu.gpa; |
| 1850 | 1850 | const val = Value.fromInterned(uav); |
| 1851 | 1851 | const uav_alignment = switch (explicit_alignment) { |
| 1852 | .none => val.typeOf(zcu).abiAlignment(pt), | |
| 1852 | .none => val.typeOf(zcu).abiAlignment(zcu), | |
| 1853 | 1853 | else => explicit_alignment, |
| 1854 | 1854 | }; |
| 1855 | 1855 | if (self.uavs.get(uav)) |metadata| { |
src/link/Elf/ZigObject.zig+1-1| ... | ... | @@ -849,7 +849,7 @@ pub fn lowerUav( |
| 849 | 849 | const gpa = zcu.gpa; |
| 850 | 850 | const val = Value.fromInterned(uav); |
| 851 | 851 | const uav_alignment = switch (explicit_alignment) { |
| 852 | .none => val.typeOf(zcu).abiAlignment(pt), | |
| 852 | .none => val.typeOf(zcu).abiAlignment(zcu), | |
| 853 | 853 | else => explicit_alignment, |
| 854 | 854 | }; |
| 855 | 855 | if (self.uavs.get(uav)) |metadata| { |
src/link/MachO/ZigObject.zig+1-1| ... | ... | @@ -688,7 +688,7 @@ pub fn lowerUav( |
| 688 | 688 | const gpa = zcu.gpa; |
| 689 | 689 | const val = Value.fromInterned(uav); |
| 690 | 690 | const uav_alignment = switch (explicit_alignment) { |
| 691 | .none => val.typeOf(zcu).abiAlignment(pt), | |
| 691 | .none => val.typeOf(zcu).abiAlignment(zcu), | |
| 692 | 692 | else => explicit_alignment, |
| 693 | 693 | }; |
| 694 | 694 | if (self.uavs.get(uav)) |metadata| { |
src/link/Wasm/ZigObject.zig+7-7| ... | ... | @@ -487,9 +487,9 @@ fn lowerConst( |
| 487 | 487 | src_loc: Zcu.LazySrcLoc, |
| 488 | 488 | ) !LowerConstResult { |
| 489 | 489 | const gpa = wasm_file.base.comp.gpa; |
| 490 | const mod = wasm_file.base.comp.module.?; | |
| 490 | const zcu = wasm_file.base.comp.module.?; | |
| 491 | 491 | |
| 492 | const ty = val.typeOf(mod); | |
| 492 | const ty = val.typeOf(zcu); | |
| 493 | 493 | |
| 494 | 494 | // Create and initialize a new local symbol and atom |
| 495 | 495 | const sym_index = try zig_object.allocateSymbol(gpa); |
| ... | ... | @@ -499,7 +499,7 @@ fn lowerConst( |
| 499 | 499 | |
| 500 | 500 | const code = code: { |
| 501 | 501 | const atom = wasm_file.getAtomPtr(atom_index); |
| 502 | atom.alignment = ty.abiAlignment(pt); | |
| 502 | atom.alignment = ty.abiAlignment(zcu); | |
| 503 | 503 | const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name }); |
| 504 | 504 | errdefer gpa.free(segment_name); |
| 505 | 505 | zig_object.symbol(sym_index).* = .{ |
| ... | ... | @@ -509,7 +509,7 @@ fn lowerConst( |
| 509 | 509 | .index = try zig_object.createDataSegment( |
| 510 | 510 | gpa, |
| 511 | 511 | segment_name, |
| 512 | ty.abiAlignment(pt), | |
| 512 | ty.abiAlignment(zcu), | |
| 513 | 513 | ), |
| 514 | 514 | .virtual_address = undefined, |
| 515 | 515 | }; |
| ... | ... | @@ -555,7 +555,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm, pt: Zcu.Per |
| 555 | 555 | const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); |
| 556 | 556 | const atom = wasm_file.getAtomPtr(atom_index); |
| 557 | 557 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 558 | atom.alignment = slice_ty.abiAlignment(pt); | |
| 558 | atom.alignment = slice_ty.abiAlignment(pt.zcu); | |
| 559 | 559 | |
| 560 | 560 | const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table"); |
| 561 | 561 | const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_name_table"); |
| ... | ... | @@ -611,7 +611,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per |
| 611 | 611 | // TODO: remove this unreachable entry |
| 612 | 612 | try atom.code.appendNTimes(gpa, 0, 4); |
| 613 | 613 | try atom.code.writer(gpa).writeInt(u32, 0, .little); |
| 614 | atom.size += @intCast(slice_ty.abiSize(pt)); | |
| 614 | atom.size += @intCast(slice_ty.abiSize(pt.zcu)); | |
| 615 | 615 | addend += 1; |
| 616 | 616 | |
| 617 | 617 | try names_atom.code.append(gpa, 0); |
| ... | ... | @@ -632,7 +632,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per |
| 632 | 632 | .offset = offset, |
| 633 | 633 | .addend = @intCast(addend), |
| 634 | 634 | }); |
| 635 | atom.size += @intCast(slice_ty.abiSize(pt)); | |
| 635 | atom.size += @intCast(slice_ty.abiSize(pt.zcu)); | |
| 636 | 636 | addend += len; |
| 637 | 637 | |
| 638 | 638 | // as we updated the error name table, we now store the actual name within the names atom |
src/mutable_value.zig+4-4| ... | ... | @@ -369,7 +369,7 @@ pub const MutableValue = union(enum) { |
| 369 | 369 | .bytes => |b| { |
| 370 | 370 | assert(is_trivial_int); |
| 371 | 371 | assert(field_val.typeOf(zcu).toIntern() == .u8_type); |
| 372 | b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt)); | |
| 372 | b.data[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu)); | |
| 373 | 373 | }, |
| 374 | 374 | .repeated => |r| { |
| 375 | 375 | if (field_val.eqlTrivial(r.child.*)) return; |
| ... | ... | @@ -382,9 +382,9 @@ pub const MutableValue = union(enum) { |
| 382 | 382 | { |
| 383 | 383 | // We can use the `bytes` representation. |
| 384 | 384 | const bytes = try arena.alloc(u8, @intCast(len_inc_sent)); |
| 385 | const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(pt); | |
| 385 | const repeated_byte = Value.fromInterned(r.child.interned).toUnsignedInt(zcu); | |
| 386 | 386 | @memset(bytes, @intCast(repeated_byte)); |
| 387 | bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(pt)); | |
| 387 | bytes[field_idx] = @intCast(Value.fromInterned(field_val.interned).toUnsignedInt(zcu)); | |
| 388 | 388 | mv.* = .{ .bytes = .{ |
| 389 | 389 | .ty = r.ty, |
| 390 | 390 | .data = bytes, |
| ... | ... | @@ -431,7 +431,7 @@ pub const MutableValue = union(enum) { |
| 431 | 431 | } else { |
| 432 | 432 | const bytes = try arena.alloc(u8, a.elems.len); |
| 433 | 433 | for (a.elems, bytes) |elem_val, *b| { |
| 434 | b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(pt)); | |
| 434 | b.* = @intCast(Value.fromInterned(elem_val.interned).toUnsignedInt(zcu)); | |
| 435 | 435 | } |
| 436 | 436 | mv.* = .{ .bytes = .{ |
| 437 | 437 | .ty = a.ty, |
src/print_value.zig+3-3| ... | ... | @@ -95,11 +95,11 @@ pub fn print( |
| 95 | 95 | .int => |int| switch (int.storage) { |
| 96 | 96 | inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}), |
| 97 | 97 | .lazy_align => |ty| if (have_sema) { |
| 98 | const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(pt, .sema)).scalar; | |
| 98 | const a = try Type.fromInterned(ty).abiAlignmentSema(pt); | |
| 99 | 99 | try writer.print("{}", .{a.toByteUnits() orelse 0}); |
| 100 | 100 | } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}), |
| 101 | 101 | .lazy_size => |ty| if (have_sema) { |
| 102 | const s = (try Type.fromInterned(ty).abiSizeAdvanced(pt, .sema)).scalar; | |
| 102 | const s = try Type.fromInterned(ty).abiSizeSema(pt); | |
| 103 | 103 | try writer.print("{}", .{s}); |
| 104 | 104 | } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}), |
| 105 | 105 | }, |
| ... | ... | @@ -245,7 +245,7 @@ fn printAggregate( |
| 245 | 245 | if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str; |
| 246 | 246 | const elem_val = Value.fromInterned(aggregate.storage.values()[0]); |
| 247 | 247 | if (elem_val.isUndef(zcu)) break :one_byte_str; |
| 248 | const byte = elem_val.toUnsignedInt(pt); | |
| 248 | const byte = elem_val.toUnsignedInt(zcu); | |
| 249 | 249 | try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})}); |
| 250 | 250 | if (!is_ref) try writer.writeAll(".*"); |
| 251 | 251 | return; |