| ... | ... | @@ -157,7 +157,7 @@ simd_immediates: std.ArrayList([16]u8) = .empty, |
| 157 | 157 | /// The Target we're emitting (used to call intInfo) |
| 158 | 158 | target: *const std.Target, |
| 159 | 159 | ptr_size: enum { wasm32, wasm64 }, |
| 160 | | pt: Zcu.PerThread, |
| 160 | zcu: *Zcu, |
| 161 | 161 | /// List of MIR Instructions |
| 162 | 162 | mir_instructions: std.MultiArrayList(Mir.Inst), |
| 163 | 163 | /// Contains extra data for MIR |
| ... | ... | @@ -380,7 +380,7 @@ pub fn deinit(cg: *CodeGen) void { |
| 380 | 380 | } |
| 381 | 381 | |
| 382 | 382 | pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) Error { |
| 383 | | const zcu = cg.pt.zcu; |
| 383 | const zcu = cg.zcu; |
| 384 | 384 | const func = zcu.funcInfo(cg.func_index); |
| 385 | 385 | return zcu.codegenFail(func.owner_nav, fmt, args); |
| 386 | 386 | } |
| ... | ... | @@ -395,8 +395,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 395 | 395 | const gop = try cg.values.getOrPut(cg.gpa, ref); |
| 396 | 396 | assert(!gop.found_existing); |
| 397 | 397 | |
| 398 | | const pt = cg.pt; |
| 399 | | const zcu = pt.zcu; |
| 398 | const zcu = cg.zcu; |
| 400 | 399 | const val: Value = .fromInterned(ref.toInterned().?); |
| 401 | 400 | const ty = cg.typeOf(ref); |
| 402 | 401 | if (!ty.hasRuntimeBits(zcu) and !ty.isInt(zcu) and !ty.isError(zcu)) { |
| ... | ... | @@ -420,7 +419,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 420 | 419 | } |
| 421 | 420 | |
| 422 | 421 | fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue { |
| 423 | | const zcu = cg.pt.zcu; |
| 422 | const zcu = cg.zcu; |
| 424 | 423 | const ty = val.typeOf(zcu); |
| 425 | 424 | |
| 426 | 425 | return if (isByRef(ty, zcu, cg.target)) |
| ... | ... | @@ -761,7 +760,7 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 761 | 760 | .float32 => |val| try cg.addFloat32(val), |
| 762 | 761 | .float64 => |val| try cg.addFloat64(val), |
| 763 | 762 | .nav_ref => |nav_ref| { |
| 764 | | const zcu = cg.pt.zcu; |
| 763 | const zcu = cg.zcu; |
| 765 | 764 | const ip = &zcu.intern_pool; |
| 766 | 765 | if (ip.zigTypeTag(ip.getNav(nav_ref.nav_index).resolved.?.type) == .@"fn") { |
| 767 | 766 | assert(nav_ref.offset == 0); |
| ... | ... | @@ -782,7 +781,7 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 782 | 781 | } |
| 783 | 782 | }, |
| 784 | 783 | .uav_ref => |uav| { |
| 785 | | const zcu = cg.pt.zcu; |
| 784 | const zcu = cg.zcu; |
| 786 | 785 | const ip = &zcu.intern_pool; |
| 787 | 786 | assert(!ip.isFunctionType(ip.typeOf(uav.ip_index))); |
| 788 | 787 | const gop = try cg.mir_uavs.getOrPut(cg.gpa, uav.ip_index); |
| ... | ... | @@ -853,7 +852,7 @@ fn releaseLocal(cg: *CodeGen, index: u32) void { |
| 853 | 852 | /// Creates one locals for a given `Type`. |
| 854 | 853 | /// Returns a corresponding `Wvalue` with `local` as active tag |
| 855 | 854 | fn allocLocal(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 856 | | const zcu = cg.pt.zcu; |
| 855 | const zcu = cg.zcu; |
| 857 | 856 | const valtype = typeToValtype(ty, zcu, cg.target); |
| 858 | 857 | const free_list = cg.local_pool.freeList(valtype); |
| 859 | 858 | if (free_list.unwrap()) |index| { |
| ... | ... | @@ -870,7 +869,7 @@ fn allocLocal(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 870 | 869 | /// Ensures a new local will be created. This is useful when it's useful |
| 871 | 870 | /// to use a zero-initialized local. |
| 872 | 871 | fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 873 | | const zcu = cg.pt.zcu; |
| 872 | const zcu = cg.zcu; |
| 874 | 873 | try cg.mir_locals.ensureUnusedCapacity(cg.gpa, 1); |
| 875 | 874 | try cg.local_pool.locals.ensureUnusedCapacity(cg.gpa, 1); |
| 876 | 875 | assert(cg.mir_locals.items.len == cg.local_pool.locals.items.len); |
| ... | ... | @@ -905,7 +904,7 @@ pub fn generate( |
| 905 | 904 | |
| 906 | 905 | var code_gen: CodeGen = .{ |
| 907 | 906 | .gpa = gpa, |
| 908 | | .pt = pt, |
| 907 | .zcu = zcu, |
| 909 | 908 | .air = air.*, |
| 910 | 909 | .liveness = liveness.*.?, |
| 911 | 910 | .owner_nav = cg.owner_nav, |
| ... | ... | @@ -940,7 +939,7 @@ pub fn generate( |
| 940 | 939 | } |
| 941 | 940 | |
| 942 | 941 | fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir { |
| 943 | | const zcu = cg.pt.zcu; |
| 942 | const zcu = cg.zcu; |
| 944 | 943 | cg.wasm_param_count = @intCast(cg.args.len + @intFromBool(cg.return_value != .none) + @intFromBool(cg.varargs != .none)); |
| 945 | 944 | cg.initial_stack_value = try cg.ensureAllocLocal(Type.usize); |
| 946 | 945 | cg.bottom_stack_value = try cg.ensureAllocLocal(Type.usize); |
| ... | ... | @@ -1099,7 +1098,7 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu |
| 1099 | 1098 | return cg.emitWValue(value); |
| 1100 | 1099 | } |
| 1101 | 1100 | |
| 1102 | | const zcu = cg.pt.zcu; |
| 1101 | const zcu = cg.zcu; |
| 1103 | 1102 | |
| 1104 | 1103 | switch (abi.classifyType(ty, zcu, cg.target)) { |
| 1105 | 1104 | .direct => |scalar_ty| { |
| ... | ... | @@ -1148,8 +1147,7 @@ fn restoreStackPointer(cg: *CodeGen) !void { |
| 1148 | 1147 | /// |
| 1149 | 1148 | /// Asserts Type has codegenbits |
| 1150 | 1149 | fn allocStack(cg: *CodeGen, ty: Type) !WValue { |
| 1151 | | const pt = cg.pt; |
| 1152 | | const zcu = pt.zcu; |
| 1150 | const zcu = cg.zcu; |
| 1153 | 1151 | assert(ty.hasRuntimeBits(zcu)); |
| 1154 | 1152 | |
| 1155 | 1153 | const abi_size = std.math.cast(u32, ty.abiSize(zcu)) orelse { |
| ... | ... | @@ -1187,8 +1185,7 @@ fn allocStackBytes(cg: *CodeGen, size: u32, alignment: Alignment) !WValue { |
| 1187 | 1185 | /// This is different from allocStack where this will use the pointer's alignment |
| 1188 | 1186 | /// if it is set, to ensure the stack alignment will be set correctly. |
| 1189 | 1187 | fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue { |
| 1190 | | const pt = cg.pt; |
| 1191 | | const zcu = pt.zcu; |
| 1188 | const zcu = cg.zcu; |
| 1192 | 1189 | const ptr_ty = cg.typeOfIndex(inst); |
| 1193 | 1190 | const pointee_ty = ptr_ty.childType(zcu); |
| 1194 | 1191 | |
| ... | ... | @@ -1338,15 +1335,25 @@ const SimdStoreStrategy = enum { |
| 1338 | 1335 | /// it using a instruction, rather than an unrolled version. |
| 1339 | 1336 | pub fn determineSimdStoreStrategy(ty: Type, zcu: *const Zcu, target: *const std.Target) SimdStoreStrategy { |
| 1340 | 1337 | assert(ty.zigTypeTag(zcu) == .vector); |
| 1341 | | if (ty.bitSize(zcu) != 128) return .unrolled; |
| 1342 | | if (target.cpu.has(.wasm, .relaxed_simd) or target.cpu.has(.wasm, .simd128)) { |
| 1343 | | return .direct; |
| 1344 | | } |
| 1345 | | return .unrolled; |
| 1338 | if (!target.cpu.has(.wasm, .simd128)) return .unrolled; |
| 1339 | return switch (ty.toIntern()) { |
| 1340 | .vector_16_i8_type, |
| 1341 | .vector_16_u8_type, |
| 1342 | .vector_8_i16_type, |
| 1343 | .vector_8_u16_type, |
| 1344 | .vector_4_i32_type, |
| 1345 | .vector_4_u32_type, |
| 1346 | .vector_2_i64_type, |
| 1347 | .vector_2_u64_type, |
| 1348 | .vector_4_f32_type, |
| 1349 | .vector_2_f64_type, |
| 1350 | => .direct, |
| 1351 | else => .unrolled, |
| 1352 | }; |
| 1346 | 1353 | } |
| 1347 | 1354 | |
| 1348 | 1355 | fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1349 | | const zcu = cg.pt.zcu; |
| 1356 | const zcu = cg.zcu; |
| 1350 | 1357 | const air_tags = cg.air.instructions.items(.tag); |
| 1351 | 1358 | return switch (air_tags[@backingInt(inst)]) { |
| 1352 | 1359 | // No soft float legalizations are enabled. |
| ... | ... | @@ -1482,7 +1489,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1482 | 1489 | const rhs = try cg.resolveInst(bin_op.rhs); |
| 1483 | 1490 | const ty = cg.typeOfIndex(inst); |
| 1484 | 1491 | |
| 1485 | | if (ty.zigTypeTag(cg.pt.zcu) == .vector) { |
| 1492 | if (ty.zigTypeTag(cg.zcu) == .vector) { |
| 1486 | 1493 | return cg.fail("TODO: implement AIR op: mul_add for vectors", .{}); |
| 1487 | 1494 | } |
| 1488 | 1495 | |
| ... | ... | @@ -1500,7 +1507,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1500 | 1507 | const rhs = try cg.resolveInst(bin_op.rhs); |
| 1501 | 1508 | const ty = cg.typeOfIndex(inst); |
| 1502 | 1509 | |
| 1503 | | if (ty.zigTypeTag(cg.pt.zcu) == .vector) { |
| 1510 | if (ty.zigTypeTag(cg.zcu) == .vector) { |
| 1504 | 1511 | return cg.fail("TODO: implement AIR op: {s} for vectors", .{@tagName(tag)}); |
| 1505 | 1512 | } |
| 1506 | 1513 | |
| ... | ... | @@ -1545,7 +1552,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1545 | 1552 | defer res_tmp.free(cg); |
| 1546 | 1553 | |
| 1547 | 1554 | const result = try cg.allocStack(cg.typeOfIndex(inst)); |
| 1548 | | const offset: u32 = @intCast(ty.abiSize(cg.pt.zcu)); |
| 1555 | const offset: u32 = @intCast(ty.abiSize(cg.zcu)); |
| 1549 | 1556 | |
| 1550 | 1557 | try cg.store(result, res_tmp, ty, .{}); |
| 1551 | 1558 | try cg.store(result, ov_tmp, .u1, .{ .offset = offset }); |
| ... | ... | @@ -1665,7 +1672,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1665 | 1672 | const src_ty = cg.typeOf(ty_op.operand); |
| 1666 | 1673 | const dest_ty = cg.typeOfIndex(inst); |
| 1667 | 1674 | |
| 1668 | | if (dest_ty.zigTypeTag(cg.pt.zcu) == .vector) { |
| 1675 | if (dest_ty.zigTypeTag(cg.zcu) == .vector) { |
| 1669 | 1676 | return cg.fail("TODO: implement AIR op: {s} for vectors", .{@tagName(tag)}); |
| 1670 | 1677 | } |
| 1671 | 1678 | |
| ... | ... | @@ -1949,7 +1956,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1949 | 1956 | } |
| 1950 | 1957 | |
| 1951 | 1958 | fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 1952 | | const zcu = cg.pt.zcu; |
| 1959 | const zcu = cg.zcu; |
| 1953 | 1960 | const ip = &zcu.intern_pool; |
| 1954 | 1961 | |
| 1955 | 1962 | for (body) |inst| { |
| ... | ... | @@ -1969,7 +1976,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 1969 | 1976 | } |
| 1970 | 1977 | |
| 1971 | 1978 | fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1972 | | const zcu = cg.pt.zcu; |
| 1979 | const zcu = cg.zcu; |
| 1973 | 1980 | const un_op = cg.air.instructions.items(.data)[@backingInt(inst)].un_op; |
| 1974 | 1981 | const operand = try cg.resolveInst(un_op); |
| 1975 | 1982 | const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?; |
| ... | ... | @@ -2009,7 +2016,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2009 | 2016 | } |
| 2010 | 2017 | |
| 2011 | 2018 | fn airRetPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2012 | | const zcu = cg.pt.zcu; |
| 2019 | const zcu = cg.zcu; |
| 2013 | 2020 | const child_type = cg.typeOfIndex(inst).childType(zcu); |
| 2014 | 2021 | |
| 2015 | 2022 | const result = result: { |
| ... | ... | @@ -2029,7 +2036,7 @@ fn airRetPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2029 | 2036 | } |
| 2030 | 2037 | |
| 2031 | 2038 | fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2032 | | const zcu = cg.pt.zcu; |
| 2039 | const zcu = cg.zcu; |
| 2033 | 2040 | const un_op = cg.air.instructions.items(.data)[@backingInt(inst)].un_op; |
| 2034 | 2041 | const operand = try cg.resolveInst(un_op); |
| 2035 | 2042 | const ret_ty = cg.typeOf(un_op).childType(zcu); |
| ... | ... | @@ -2066,8 +2073,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) |
| 2066 | 2073 | const args = call.args; |
| 2067 | 2074 | const ty = cg.typeOf(call.callee); |
| 2068 | 2075 | |
| 2069 | | const pt = cg.pt; |
| 2070 | | const zcu = pt.zcu; |
| 2076 | const zcu = cg.zcu; |
| 2071 | 2077 | const ip = &zcu.intern_pool; |
| 2072 | 2078 | const fn_ty = switch (ty.zigTypeTag(zcu)) { |
| 2073 | 2079 | .@"fn" => ty, |
| ... | ... | @@ -2240,7 +2246,7 @@ fn airVaCopy(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2240 | 2246 | } |
| 2241 | 2247 | |
| 2242 | 2248 | fn airVaArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2243 | | const zcu = cg.pt.zcu; |
| 2249 | const zcu = cg.zcu; |
| 2244 | 2250 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 2245 | 2251 | const operand = try cg.resolveInst(ty_op.operand); |
| 2246 | 2252 | |
| ... | ... | @@ -2312,8 +2318,7 @@ fn airAlloc(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2312 | 2318 | } |
| 2313 | 2319 | |
| 2314 | 2320 | fn airStore(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 2315 | | const pt = cg.pt; |
| 2316 | | const zcu = pt.zcu; |
| 2321 | const zcu = cg.zcu; |
| 2317 | 2322 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 2318 | 2323 | |
| 2319 | 2324 | const lhs = try cg.resolveInst(bin_op.lhs); |
| ... | ... | @@ -2356,8 +2361,7 @@ const MemArg = struct { |
| 2356 | 2361 | |
| 2357 | 2362 | fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, memarg: MemArg) InnerError!void { |
| 2358 | 2363 | assert(!(lhs != .stack and rhs == .stack)); |
| 2359 | | const pt = cg.pt; |
| 2360 | | const zcu = pt.zcu; |
| 2364 | const zcu = cg.zcu; |
| 2361 | 2365 | const abi_size = ty.abiSize(zcu); |
| 2362 | 2366 | |
| 2363 | 2367 | if (!ty.hasRuntimeBits(zcu)) return; |
| ... | ... | @@ -2422,8 +2426,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, memarg: MemArg) Inner |
| 2422 | 2426 | } |
| 2423 | 2427 | |
| 2424 | 2428 | fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2425 | | const pt = cg.pt; |
| 2426 | | const zcu = pt.zcu; |
| 2429 | const zcu = cg.zcu; |
| 2427 | 2430 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 2428 | 2431 | const operand = try cg.resolveInst(ty_op.operand); |
| 2429 | 2432 | const elem_ty = ty_op.ty; |
| ... | ... | @@ -2449,7 +2452,7 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2449 | 2452 | /// Loads an operand from the linear memory section. |
| 2450 | 2453 | /// NOTE: Leaves the value on the stack, if isByRef == false. |
| 2451 | 2454 | fn load(cg: *CodeGen, operand: WValue, ty: Type, memarg: MemArg) InnerError!WValue { |
| 2452 | | const zcu = cg.pt.zcu; |
| 2455 | const zcu = cg.zcu; |
| 2453 | 2456 | |
| 2454 | 2457 | const natural_alignment = ty.abiAlignment(zcu); |
| 2455 | 2458 | // wasm memory instruction alignment is <= access width |
| ... | ... | @@ -2527,8 +2530,7 @@ fn load(cg: *CodeGen, operand: WValue, ty: Type, memarg: MemArg) InnerError!WVal |
| 2527 | 2530 | } |
| 2528 | 2531 | |
| 2529 | 2532 | fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2530 | | const pt = cg.pt; |
| 2531 | | const zcu = pt.zcu; |
| 2533 | const zcu = cg.zcu; |
| 2532 | 2534 | const arg_index = cg.arg_index; |
| 2533 | 2535 | const arg = cg.args[arg_index]; |
| 2534 | 2536 | const cc = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?.cc; |
| ... | ... | @@ -2580,7 +2582,7 @@ const IntType = struct { |
| 2580 | 2582 | // Adapted from x86_64 backend |
| 2581 | 2583 | // Differ from Type.intInfo as it treats pointers/booleans/packed/enums/errors as integer |
| 2582 | 2584 | fn fromType(cg: *CodeGen, ty: Type) IntType { |
| 2583 | | const zcu = cg.pt.zcu; |
| 2585 | const zcu = cg.zcu; |
| 2584 | 2586 | const ip = &zcu.intern_pool; |
| 2585 | 2587 | var ty_index = ty.ip_index; |
| 2586 | 2588 | while (true) switch (ip.indexToKey(ty_index)) { |
| ... | ... | @@ -2589,17 +2591,11 @@ const IntType = struct { |
| 2589 | 2591 | .one, .many, .c => .{ .is_signed = false, .bits = cg.target.ptrBitWidth() }, |
| 2590 | 2592 | .slice => unreachable, |
| 2591 | 2593 | }, |
| 2592 | | .opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBits(zcu)) |
| 2593 | | .{ .is_signed = false, .bits = 1 } |
| 2594 | | else switch (ip.indexToKey(opt_child)) { |
| 2595 | | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 2596 | | .one, .many => switch (ptr_type.flags.is_allowzero) { |
| 2597 | | false => .{ .is_signed = false, .bits = cg.target.ptrBitWidth() }, |
| 2598 | | true => unreachable, |
| 2599 | | }, |
| 2600 | | .slice, .c => unreachable, |
| 2601 | | }, |
| 2602 | | else => unreachable, |
| 2594 | .opt_type => |opt_child| { |
| 2595 | if (!Type.fromInterned(opt_child).hasRuntimeBits(zcu)) |
| 2596 | return .{ .is_signed = false, .bits = 1 }; |
| 2597 | assert(Type.fromInterned(ty_index).optionalReprIsPayload(zcu)); |
| 2598 | ty_index = opt_child; |
| 2603 | 2599 | }, |
| 2604 | 2600 | .error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type) |
| 2605 | 2601 | .hasRuntimeBits(zcu)) .{ .is_signed = false, .bits = zcu.errorSetBits() } else unreachable, |
| ... | ... | @@ -5037,8 +5033,7 @@ fn floatFromInt(cg: *CodeGen, dest_ty: FloatType, src_ty: IntType, operand: WVal |
| 5037 | 5033 | } |
| 5038 | 5034 | |
| 5039 | 5035 | fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerError!WValue { |
| 5040 | | const pt = cg.pt; |
| 5041 | | const zcu = pt.zcu; |
| 5036 | const zcu = cg.zcu; |
| 5042 | 5037 | const ip = &zcu.intern_pool; |
| 5043 | 5038 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 5044 | 5039 | const offset: u64 = prev_offset + ptr.byte_offset; |
| ... | ... | @@ -5052,7 +5047,10 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro |
| 5052 | 5047 | .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } } |
| 5053 | 5048 | else |
| 5054 | 5049 | .{ .imm32 = @intCast(Type.fromInterned(uav.orig_ty).ptrAlignment(zcu).forward(@as(u32, 0xaaaaaaaa))) }, |
| 5055 | | .int => return cg.lowerConstant(try pt.intValue(.usize, offset)), |
| 5050 | .int => return switch (cg.ptr_size) { |
| 5051 | .wasm32 => .{ .imm32 = @intCast(offset) }, |
| 5052 | .wasm64 => .{ .imm64 = offset }, |
| 5053 | }, |
| 5056 | 5054 | .eu_payload => |eu_ptr| try cg.lowerPtr( |
| 5057 | 5055 | eu_ptr, |
| 5058 | 5056 | offset + codegen.errUnionPayloadOffset( |
| ... | ... | @@ -5091,8 +5089,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro |
| 5091 | 5089 | |
| 5092 | 5090 | /// Asserts that `isByRef` returns `false` for `val.typeOf(zcu)`. |
| 5093 | 5091 | fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 5094 | | const pt = cg.pt; |
| 5095 | | const zcu = pt.zcu; |
| 5092 | const zcu = cg.zcu; |
| 5096 | 5093 | const ty = val.typeOf(zcu); |
| 5097 | 5094 | assert(!isByRef(ty, zcu, cg.target)); |
| 5098 | 5095 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -5150,22 +5147,16 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 5150 | 5147 | } |
| 5151 | 5148 | }, |
| 5152 | 5149 | .err => |err| { |
| 5153 | | const int = try pt.getErrorValue(err.name); |
| 5150 | const int = ip.getErrorValueIfExists(err.name).?; |
| 5154 | 5151 | return .{ .imm32 = int }; |
| 5155 | 5152 | }, |
| 5156 | 5153 | .error_union => |error_union| { |
| 5157 | | const err_int_ty = try pt.errorIntType(); |
| 5158 | | const err_val: Value = switch (error_union.val) { |
| 5159 | | .err_name => |err_name| .fromInterned(try pt.intern(.{ .err = .{ |
| 5160 | | .ty = ty.errorUnionSet(zcu).toIntern(), |
| 5161 | | .name = err_name, |
| 5162 | | } })), |
| 5163 | | .payload => try pt.intValue(err_int_ty, 0), |
| 5164 | | }; |
| 5165 | 5154 | const payload_type = ty.errorUnionPayload(zcu); |
| 5166 | 5155 | if (!payload_type.hasRuntimeBits(zcu)) { |
| 5167 | | // We use the error type directly as the type. |
| 5168 | | return cg.lowerConstant(err_val); |
| 5156 | return .{ .imm32 = switch (error_union.val) { |
| 5157 | .err_name => |err_name| ip.getErrorValueIfExists(err_name).?, |
| 5158 | .payload => 0, |
| 5159 | } }; |
| 5169 | 5160 | } |
| 5170 | 5161 | |
| 5171 | 5162 | return cg.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{}); |
| ... | ... | @@ -5188,12 +5179,27 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 5188 | 5179 | } else { |
| 5189 | 5180 | return .{ .imm32 = @intFromBool(!val.isNull(zcu)) }; |
| 5190 | 5181 | }, |
| 5191 | | .aggregate => switch (ip.indexToKey(ty.ip_index)) { |
| 5192 | | .array_type => return cg.fail("Wasm TODO: LowerConstant for {f}", .{ty.fmt(zcu)}), |
| 5193 | | .vector_type => { |
| 5182 | .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) { |
| 5183 | .array_type => unreachable, |
| 5184 | .vector_type => |vector_type| { |
| 5194 | 5185 | assert(determineSimdStoreStrategy(ty, zcu, cg.target) == .direct); |
| 5195 | 5186 | var buf: [16]u8 = undefined; |
| 5196 | | val.writeToMemory(zcu, &buf) catch unreachable; |
| 5187 | const elem_size: usize = @intCast(Type.fromInterned(vector_type.child).abiSize(zcu)); |
| 5188 | for (0..vector_type.len) |i| { |
| 5189 | const dest = buf[i * elem_size ..][0..elem_size]; |
| 5190 | const elem: Value = switch (aggregate.storage) { |
| 5191 | .bytes => |bytes| { |
| 5192 | dest[0] = bytes.at(i, ip); |
| 5193 | continue; |
| 5194 | }, |
| 5195 | .elems => |elems| .fromInterned(elems[i]), |
| 5196 | .repeated_elem => |elem| .fromInterned(elem), |
| 5197 | }; |
| 5198 | elem.writeToMemory(zcu, dest) catch |err| switch (err) { |
| 5199 | error.OutOfMemory => return error.OutOfMemory, |
| 5200 | error.ReinterpretDeclRef, error.IllDefinedMemoryLayout => unreachable, |
| 5201 | }; |
| 5202 | } |
| 5197 | 5203 | return cg.storeSimdImmd(buf); |
| 5198 | 5204 | }, |
| 5199 | 5205 | .struct_type => unreachable, // packed structs use `bitpack` |
| ... | ... | @@ -5214,8 +5220,9 @@ fn storeSimdImmd(cg: *CodeGen, value: [16]u8) !WValue { |
| 5214 | 5220 | } |
| 5215 | 5221 | |
| 5216 | 5222 | fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 5217 | | const zcu = cg.pt.zcu; |
| 5223 | const zcu = cg.zcu; |
| 5218 | 5224 | switch (ty.zigTypeTag(zcu)) { |
| 5225 | .vector => return cg.storeSimdImmd(@splat(0xaa)), |
| 5219 | 5226 | .bool, .error_set => return .{ .imm32 = 0xaaaaaaaa }, |
| 5220 | 5227 | .int, .@"enum" => switch (ty.intInfo(zcu).bits) { |
| 5221 | 5228 | 0...32 => return .{ .imm32 = 0xaaaaaaaa }, |
| ... | ... | @@ -5256,7 +5263,7 @@ fn airBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5256 | 5263 | } |
| 5257 | 5264 | |
| 5258 | 5265 | fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void { |
| 5259 | | const zcu = cg.pt.zcu; |
| 5266 | const zcu = cg.zcu; |
| 5260 | 5267 | |
| 5261 | 5268 | if (block_ty.isNoReturn(zcu)) { |
| 5262 | 5269 | assert(cg.liveness.getBlock(inst).deaths.len == 0); |
| ... | ... | @@ -5365,7 +5372,7 @@ fn airCmp(cg: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) Inne |
| 5365 | 5372 | const lhs = try cg.resolveInst(bin_op.lhs); |
| 5366 | 5373 | const rhs = try cg.resolveInst(bin_op.rhs); |
| 5367 | 5374 | const operand_ty = cg.typeOf(bin_op.lhs); |
| 5368 | | const zcu = cg.pt.zcu; |
| 5375 | const zcu = cg.zcu; |
| 5369 | 5376 | |
| 5370 | 5377 | const type_tag = operand_ty.zigTypeTag(zcu); |
| 5371 | 5378 | |
| ... | ... | @@ -5597,10 +5604,10 @@ fn airCmpLteErrorsLen(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5597 | 5604 | const operand = try cg.resolveInst(un_op); |
| 5598 | 5605 | |
| 5599 | 5606 | try cg.emitWValue(operand); |
| 5600 | | const pt = cg.pt; |
| 5601 | | const err_int_ty = try pt.errorIntType(); |
| 5607 | const zcu = cg.zcu; |
| 5608 | const err_int_ty: IntType = .{ .is_signed = false, .bits = zcu.errorSetBits() }; |
| 5602 | 5609 | try cg.addTag(.errors_len); |
| 5603 | | const result = try cg.intCmp(.fromType(cg, err_int_ty), .lt, .stack, .stack); |
| 5610 | const result = try cg.intCmp(err_int_ty, .lt, .stack, .stack); |
| 5604 | 5611 | |
| 5605 | 5612 | return cg.finishAir(inst, result, &.{un_op}); |
| 5606 | 5613 | } |
| ... | ... | @@ -5656,7 +5663,7 @@ fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5656 | 5663 | } |
| 5657 | 5664 | |
| 5658 | 5665 | fn airNopCast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5659 | | const zcu = cg.pt.zcu; |
| 5666 | const zcu = cg.zcu; |
| 5660 | 5667 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 5661 | 5668 | |
| 5662 | 5669 | const operand_ty = cg.typeOf(ty_op.operand); |
| ... | ... | @@ -5670,7 +5677,7 @@ fn airNopCast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5670 | 5677 | } |
| 5671 | 5678 | |
| 5672 | 5679 | fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5673 | | const zcu = cg.pt.zcu; |
| 5680 | const zcu = cg.zcu; |
| 5674 | 5681 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 5675 | 5682 | |
| 5676 | 5683 | const operand_ty = cg.typeOf(ty_op.operand); |
| ... | ... | @@ -5689,7 +5696,7 @@ fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5689 | 5696 | } |
| 5690 | 5697 | |
| 5691 | 5698 | fn airUnionFromEnum(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5692 | | const zcu = cg.pt.zcu; |
| 5699 | const zcu = cg.zcu; |
| 5693 | 5700 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 5694 | 5701 | |
| 5695 | 5702 | const union_ty = cg.typeOfIndex(inst); |
| ... | ... | @@ -5721,7 +5728,7 @@ const BitcastClass = union(enum) { |
| 5721 | 5728 | }; |
| 5722 | 5729 | |
| 5723 | 5730 | fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass { |
| 5724 | | const zcu = cg.pt.zcu; |
| 5731 | const zcu = cg.zcu; |
| 5725 | 5732 | return switch (ty.zigTypeTag(zcu)) { |
| 5726 | 5733 | .bool, |
| 5727 | 5734 | .int, |
| ... | ... | @@ -5739,7 +5746,7 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass { |
| 5739 | 5746 | fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!WValue { |
| 5740 | 5747 | if (dest_ty.eql(src_ty)) return operand; |
| 5741 | 5748 | |
| 5742 | | const zcu = cg.pt.zcu; |
| 5749 | const zcu = cg.zcu; |
| 5743 | 5750 | const src_class = cg.bitcastClass(src_ty); |
| 5744 | 5751 | const dest_class = cg.bitcastClass(dest_ty); |
| 5745 | 5752 | const src_by_ref = isByRef(src_ty, zcu, cg.target); |
| ... | ... | @@ -5785,7 +5792,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro |
| 5785 | 5792 | .f80, .f128 => unreachable, |
| 5786 | 5793 | }, |
| 5787 | 5794 | .int => {}, |
| 5788 | | .aggregate => unreachable, |
| 5795 | .aggregate => return operand, // both v128 |
| 5789 | 5796 | } |
| 5790 | 5797 | |
| 5791 | 5798 | switch (dest_class) { |
| ... | ... | @@ -5815,7 +5822,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro |
| 5815 | 5822 | } |
| 5816 | 5823 | |
| 5817 | 5824 | fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5818 | | const zcu = cg.pt.zcu; |
| 5825 | const zcu = cg.zcu; |
| 5819 | 5826 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 5820 | 5827 | const extra = cg.air.extraData(Air.StructField, ty_pl.payload); |
| 5821 | 5828 | |
| ... | ... | @@ -5827,7 +5834,7 @@ fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5827 | 5834 | } |
| 5828 | 5835 | |
| 5829 | 5836 | fn airStructFieldPtrIndex(cg: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void { |
| 5830 | | const zcu = cg.pt.zcu; |
| 5837 | const zcu = cg.zcu; |
| 5831 | 5838 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 5832 | 5839 | const struct_ptr = try cg.resolveInst(ty_op.operand); |
| 5833 | 5840 | const struct_ptr_ty = cg.typeOf(ty_op.operand); |
| ... | ... | @@ -5845,8 +5852,7 @@ fn structFieldPtr( |
| 5845 | 5852 | struct_ty: Type, |
| 5846 | 5853 | index: u32, |
| 5847 | 5854 | ) InnerError!WValue { |
| 5848 | | const pt = cg.pt; |
| 5849 | | const zcu = pt.zcu; |
| 5855 | const zcu = cg.zcu; |
| 5850 | 5856 | const result_ty = cg.typeOfIndex(inst); |
| 5851 | 5857 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu); |
| 5852 | 5858 | |
| ... | ... | @@ -5868,8 +5874,7 @@ fn structFieldPtr( |
| 5868 | 5874 | } |
| 5869 | 5875 | |
| 5870 | 5876 | fn airAggFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5871 | | const pt = cg.pt; |
| 5872 | | const zcu = pt.zcu; |
| 5877 | const zcu = cg.zcu; |
| 5873 | 5878 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 5874 | 5879 | const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data; |
| 5875 | 5880 | |
| ... | ... | @@ -5897,8 +5902,7 @@ fn airAggFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5897 | 5902 | |
| 5898 | 5903 | // Both `.switch_br` and `.loop_switch_br` are noreturn. |
| 5899 | 5904 | fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) InnerError!void { |
| 5900 | | const pt = cg.pt; |
| 5901 | | const zcu = pt.zcu; |
| 5905 | const zcu = cg.zcu; |
| 5902 | 5906 | |
| 5903 | 5907 | const switch_br = cg.air.unwrapSwitch(inst); |
| 5904 | 5908 | const target_ty = cg.typeOf(switch_br.operand); |
| ... | ... | @@ -6013,6 +6017,13 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner |
| 6013 | 6017 | if (use_br_table) { |
| 6014 | 6018 | const width = width_maybe.?; |
| 6015 | 6019 | |
| 6020 | if (int_ty.bits > 32) { |
| 6021 | _ = try cg.intCmp(int_ty, .lt, target, try cg.resolveValue(min.?)); |
| 6022 | try cg.addLabel(.br_if, branch_count - 1); |
| 6023 | _ = try cg.intCmp(int_ty, .gt, target, try cg.resolveValue(max.?)); |
| 6024 | try cg.addLabel(.br_if, branch_count - 1); |
| 6025 | } |
| 6026 | |
| 6016 | 6027 | const br_value_original = try cg.intSub(int_ty, target, try cg.resolveValue(min.?)); |
| 6017 | 6028 | _ = try cg.intCast(.u32, int_ty, br_value_original); |
| 6018 | 6029 | |
| ... | ... | @@ -6119,7 +6130,7 @@ fn airSwitchDispatch(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6119 | 6130 | } |
| 6120 | 6131 | |
| 6121 | 6132 | fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void { |
| 6122 | | const zcu = cg.pt.zcu; |
| 6133 | const zcu = cg.zcu; |
| 6123 | 6134 | const un_op = cg.air.instructions.items(.data)[@backingInt(inst)].un_op; |
| 6124 | 6135 | const operand = try cg.resolveInst(un_op); |
| 6125 | 6136 | const err_union_ty = switch (op_kind) { |
| ... | ... | @@ -6158,7 +6169,7 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kind |
| 6158 | 6169 | /// E!T -> T op_is_ptr == false |
| 6159 | 6170 | /// *(E!T) -> *T op_is_prt == true |
| 6160 | 6171 | fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 6161 | | const zcu = cg.pt.zcu; |
| 6172 | const zcu = cg.zcu; |
| 6162 | 6173 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6163 | 6174 | |
| 6164 | 6175 | const operand = try cg.resolveInst(ty_op.operand); |
| ... | ... | @@ -6190,7 +6201,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) |
| 6190 | 6201 | /// *(E!T) -> E op_is_ptr == true |
| 6191 | 6202 | /// NOTE: op_is_ptr will not change return type |
| 6192 | 6203 | fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 6193 | | const zcu = cg.pt.zcu; |
| 6204 | const zcu = cg.zcu; |
| 6194 | 6205 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6195 | 6206 | |
| 6196 | 6207 | const operand = try cg.resolveInst(ty_op.operand); |
| ... | ... | @@ -6215,7 +6226,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I |
| 6215 | 6226 | } |
| 6216 | 6227 | |
| 6217 | 6228 | fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6218 | | const zcu = cg.pt.zcu; |
| 6229 | const zcu = cg.zcu; |
| 6219 | 6230 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6220 | 6231 | |
| 6221 | 6232 | const operand = try cg.resolveInst(ty_op.operand); |
| ... | ... | @@ -6244,7 +6255,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6244 | 6255 | } |
| 6245 | 6256 | |
| 6246 | 6257 | fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6247 | | const zcu = cg.pt.zcu; |
| 6258 | const zcu = cg.zcu; |
| 6248 | 6259 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6249 | 6260 | |
| 6250 | 6261 | const operand = try cg.resolveInst(ty_op.operand); |
| ... | ... | @@ -6284,8 +6295,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kin |
| 6284 | 6295 | /// For a given type and operand, checks if it's considered `null`. |
| 6285 | 6296 | /// NOTE: Leaves the result on the stack |
| 6286 | 6297 | fn isNull(cg: *CodeGen, operand: WValue, op_ty: Type, opcode: std.wasm.Opcode, op_kind: OpKind) InnerError!WValue { |
| 6287 | | const pt = cg.pt; |
| 6288 | | const zcu = pt.zcu; |
| 6298 | const zcu = cg.zcu; |
| 6289 | 6299 | const optional_ty = switch (op_kind) { |
| 6290 | 6300 | .value => op_ty, |
| 6291 | 6301 | .ptr => op_ty.childType(zcu), |
| ... | ... | @@ -6330,7 +6340,7 @@ fn isNull(cg: *CodeGen, operand: WValue, op_ty: Type, opcode: std.wasm.Opcode, o |
| 6330 | 6340 | } |
| 6331 | 6341 | |
| 6332 | 6342 | fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6333 | | const zcu = cg.pt.zcu; |
| 6343 | const zcu = cg.zcu; |
| 6334 | 6344 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6335 | 6345 | const opt_ty = cg.typeOf(ty_op.operand); |
| 6336 | 6346 | const payload_ty = cg.typeOfIndex(inst); |
| ... | ... | @@ -6352,7 +6362,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6352 | 6362 | } |
| 6353 | 6363 | |
| 6354 | 6364 | fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6355 | | const zcu = cg.pt.zcu; |
| 6365 | const zcu = cg.zcu; |
| 6356 | 6366 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6357 | 6367 | const operand = try cg.resolveInst(ty_op.operand); |
| 6358 | 6368 | const opt_ty = cg.typeOf(ty_op.operand).childType(zcu); |
| ... | ... | @@ -6369,8 +6379,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6369 | 6379 | } |
| 6370 | 6380 | |
| 6371 | 6381 | fn airOptionalPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6372 | | const pt = cg.pt; |
| 6373 | | const zcu = pt.zcu; |
| 6382 | const zcu = cg.zcu; |
| 6374 | 6383 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6375 | 6384 | const operand = try cg.resolveInst(ty_op.operand); |
| 6376 | 6385 | const opt_ty = cg.typeOf(ty_op.operand).childType(zcu); |
| ... | ... | @@ -6394,8 +6403,7 @@ fn airOptionalPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 6394 | 6403 | fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6395 | 6404 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6396 | 6405 | const payload_ty = cg.typeOf(ty_op.operand); |
| 6397 | | const pt = cg.pt; |
| 6398 | | const zcu = pt.zcu; |
| 6406 | const zcu = cg.zcu; |
| 6399 | 6407 | |
| 6400 | 6408 | const result = result: { |
| 6401 | 6409 | if (!payload_ty.hasRuntimeBits(zcu)) { |
| ... | ... | @@ -6451,7 +6459,7 @@ fn airSliceLen(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6451 | 6459 | } |
| 6452 | 6460 | |
| 6453 | 6461 | fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6454 | | const zcu = cg.pt.zcu; |
| 6462 | const zcu = cg.zcu; |
| 6455 | 6463 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 6456 | 6464 | |
| 6457 | 6465 | const slice_ty = cg.typeOf(bin_op.lhs); |
| ... | ... | @@ -6472,7 +6480,7 @@ fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6472 | 6480 | } |
| 6473 | 6481 | |
| 6474 | 6482 | fn airSliceElemPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6475 | | const zcu = cg.pt.zcu; |
| 6483 | const zcu = cg.zcu; |
| 6476 | 6484 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 6477 | 6485 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6478 | 6486 | |
| ... | ... | @@ -6507,7 +6515,7 @@ fn sliceLen(cg: *CodeGen, operand: WValue) InnerError!WValue { |
| 6507 | 6515 | } |
| 6508 | 6516 | |
| 6509 | 6517 | fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6510 | | const zcu = cg.pt.zcu; |
| 6518 | const zcu = cg.zcu; |
| 6511 | 6519 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6512 | 6520 | |
| 6513 | 6521 | const operand = try cg.resolveInst(ty_op.operand); |
| ... | ... | @@ -6527,7 +6535,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6527 | 6535 | } |
| 6528 | 6536 | |
| 6529 | 6537 | fn airPtrElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6530 | | const zcu = cg.pt.zcu; |
| 6538 | const zcu = cg.zcu; |
| 6531 | 6539 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 6532 | 6540 | |
| 6533 | 6541 | const ptr_ty = cg.typeOf(bin_op.lhs); |
| ... | ... | @@ -6552,7 +6560,7 @@ fn airPtrElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6552 | 6560 | } |
| 6553 | 6561 | |
| 6554 | 6562 | fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6555 | | const zcu = cg.pt.zcu; |
| 6563 | const zcu = cg.zcu; |
| 6556 | 6564 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 6557 | 6565 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6558 | 6566 | |
| ... | ... | @@ -6577,7 +6585,7 @@ fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6577 | 6585 | } |
| 6578 | 6586 | |
| 6579 | 6587 | fn airPtrBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: PointerOffsetOp) InnerError!void { |
| 6580 | | const zcu = cg.pt.zcu; |
| 6588 | const zcu = cg.zcu; |
| 6581 | 6589 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 6582 | 6590 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6583 | 6591 | |
| ... | ... | @@ -6596,7 +6604,7 @@ fn airPtrBinOp(cg: *CodeGen, inst: Air.Inst.Index, op: PointerOffsetOp) InnerErr |
| 6596 | 6604 | } |
| 6597 | 6605 | |
| 6598 | 6606 | fn airMemset(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 6599 | | const zcu = cg.pt.zcu; |
| 6607 | const zcu = cg.zcu; |
| 6600 | 6608 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 6601 | 6609 | |
| 6602 | 6610 | const ptr = try cg.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6630,7 +6638,7 @@ fn airMemset(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { |
| 6630 | 6638 | /// this to wasm's memset instruction. When the feature is not present, |
| 6631 | 6639 | /// we implement it manually. |
| 6632 | 6640 | fn memset(cg: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void { |
| 6633 | | const zcu = cg.pt.zcu; |
| 6641 | const zcu = cg.zcu; |
| 6634 | 6642 | const abi_size = @as(u32, @intCast(elem_ty.abiSize(zcu))); |
| 6635 | 6643 | const len_known_neq_0 = switch (len) { |
| 6636 | 6644 | .imm32 => |imm| if (imm != 0) true else return, |
| ... | ... | @@ -6750,7 +6758,7 @@ fn memset(cg: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) |
| 6750 | 6758 | } |
| 6751 | 6759 | |
| 6752 | 6760 | fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6753 | | const zcu = cg.pt.zcu; |
| 6761 | const zcu = cg.zcu; |
| 6754 | 6762 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 6755 | 6763 | |
| 6756 | 6764 | const array_ty = cg.typeOf(bin_op.lhs); |
| ... | ... | @@ -6804,7 +6812,7 @@ fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6804 | 6812 | } |
| 6805 | 6813 | |
| 6806 | 6814 | fn airSplat(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6807 | | const zcu = cg.pt.zcu; |
| 6815 | const zcu = cg.zcu; |
| 6808 | 6816 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6809 | 6817 | const operand = try cg.resolveInst(ty_op.operand); |
| 6810 | 6818 | const ty = cg.typeOfIndex(inst); |
| ... | ... | @@ -6875,8 +6883,7 @@ fn airSelect(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6875 | 6883 | } |
| 6876 | 6884 | |
| 6877 | 6885 | fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6878 | | const pt = cg.pt; |
| 6879 | | const zcu = pt.zcu; |
| 6886 | const zcu = cg.zcu; |
| 6880 | 6887 | |
| 6881 | 6888 | const unwrapped = cg.air.unwrapShuffleOne(zcu, inst); |
| 6882 | 6889 | const result_ty = unwrapped.result_ty; |
| ... | ... | @@ -6907,8 +6914,7 @@ fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6907 | 6914 | } |
| 6908 | 6915 | |
| 6909 | 6916 | fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6910 | | const pt = cg.pt; |
| 6911 | | const zcu = pt.zcu; |
| 6917 | const zcu = cg.zcu; |
| 6912 | 6918 | |
| 6913 | 6919 | const unwrapped = cg.air.unwrapShuffleTwo(zcu, inst); |
| 6914 | 6920 | const result_ty = unwrapped.result_ty; |
| ... | ... | @@ -6984,8 +6990,7 @@ fn airReduce(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6984 | 6990 | } |
| 6985 | 6991 | |
| 6986 | 6992 | fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6987 | | const pt = cg.pt; |
| 6988 | | const zcu = pt.zcu; |
| 6993 | const zcu = cg.zcu; |
| 6989 | 6994 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 6990 | 6995 | const result_ty = cg.typeOfIndex(inst); |
| 6991 | 6996 | const len = @as(usize, @intCast(result_ty.arrayLen(zcu))); |
| ... | ... | @@ -6994,31 +6999,59 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6994 | 6999 | const result: WValue = result_value: { |
| 6995 | 7000 | switch (result_ty.zigTypeTag(zcu)) { |
| 6996 | 7001 | .array, .vector => { |
| 6997 | | const result = try cg.allocStack(result_ty); |
| 6998 | 7002 | const elem_ty = result_ty.childType(zcu); |
| 6999 | | const elem_size = elem_ty.abiSize(zcu); |
| 7000 | | const sentinel = result_ty.sentinel(zcu); |
| 7001 | | |
| 7002 | | var offset: u64 = 0; |
| 7003 | | for (elements) |elem| { |
| 7004 | | const elem_val = try cg.resolveInst(elem); |
| 7005 | | try cg.store(result, elem_val, elem_ty, .{ .offset = offset }); |
| 7006 | | offset += elem_size; |
| 7007 | | } |
| 7008 | | if (sentinel) |s| { |
| 7009 | | const val = try cg.resolveValue(s); |
| 7010 | | try cg.store(result, val, elem_ty, .{ .offset = offset }); |
| 7003 | if (isByRef(result_ty, zcu, cg.target)) { |
| 7004 | const result = try cg.allocStack(result_ty); |
| 7005 | const elem_size = elem_ty.abiSize(zcu); |
| 7006 | const sentinel = result_ty.sentinel(zcu); |
| 7007 | |
| 7008 | var offset: u64 = 0; |
| 7009 | for (elements) |elem| { |
| 7010 | const elem_val = try cg.resolveInst(elem); |
| 7011 | try cg.store(result, elem_val, elem_ty, .{ .offset = offset }); |
| 7012 | offset += elem_size; |
| 7013 | } |
| 7014 | if (sentinel) |s| { |
| 7015 | const val = try cg.resolveValue(s); |
| 7016 | try cg.store(result, val, elem_ty, .{ .offset = offset }); |
| 7017 | } |
| 7018 | break :result_value result; |
| 7019 | } else { |
| 7020 | assert(result_ty.zigTypeTag(zcu) == .vector); |
| 7021 | const splat: std.wasm.SimdOpcode, const replace_lane: std.wasm.SimdOpcode = switch (elem_ty.toIntern()) { |
| 7022 | .u8_type, .i8_type => .{ .i8x16_splat, .i8x16_replace_lane }, |
| 7023 | .u16_type, .i16_type => .{ .i16x8_splat, .i16x8_replace_lane }, |
| 7024 | .u32_type, .i32_type => .{ .i32x4_splat, .i32x4_replace_lane }, |
| 7025 | .u64_type, .i64_type => .{ .i64x2_splat, .i64x2_replace_lane }, |
| 7026 | .f32_type => .{ .f32x4_splat, .f32x4_replace_lane }, |
| 7027 | .f64_type => .{ .f64x2_splat, .f64x2_replace_lane }, |
| 7028 | else => unreachable, |
| 7029 | }; |
| 7030 | |
| 7031 | // TODO: find best element to splat, if it is constant dont use splat at all |
| 7032 | try cg.emitWValue(try cg.resolveInst(elements[0])); |
| 7033 | const splat_extra: u32 = @intCast(cg.mir_extra.items.len); |
| 7034 | try cg.mir_extra.append(cg.gpa, @backingInt(splat)); |
| 7035 | try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = splat_extra } }); |
| 7036 | for (elements[1..], 1..) |elem, lane| { |
| 7037 | if (elem == elements[0]) continue; |
| 7038 | try cg.emitWValue(try cg.resolveInst(elem)); |
| 7039 | const extra_index: u32 = @intCast(cg.mir_extra.items.len); |
| 7040 | try cg.mir_extra.appendSlice(cg.gpa, &.{ @backingInt(replace_lane), @intCast(lane) }); |
| 7041 | try cg.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 7042 | } |
| 7043 | break :result_value .stack; |
| 7011 | 7044 | } |
| 7012 | | break :result_value result; |
| 7013 | 7045 | }, |
| 7014 | 7046 | .@"struct" => switch (result_ty.containerLayout(zcu)) { |
| 7015 | 7047 | .@"packed" => unreachable, // legalize .expand_packed_aggregate_init |
| 7016 | 7048 | else => { |
| 7017 | 7049 | const result = try cg.allocStack(result_ty); |
| 7018 | 7050 | for (elements, 0..) |elem, elem_index| { |
| 7019 | | if (try result_ty.structFieldValueComptime(pt, elem_index) != null) continue; |
| 7051 | if (result_ty.structFieldIsComptime(elem_index, zcu)) continue; |
| 7020 | 7052 | |
| 7021 | 7053 | const elem_ty = result_ty.fieldType(elem_index, zcu); |
| 7054 | if (!elem_ty.hasRuntimeBits(zcu)) continue; |
| 7022 | 7055 | const field_offset = result_ty.structFieldOffset(elem_index, zcu); |
| 7023 | 7056 | |
| 7024 | 7057 | const value = try cg.resolveInst(elem); |
| ... | ... | @@ -7038,8 +7071,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7038 | 7071 | } |
| 7039 | 7072 | |
| 7040 | 7073 | fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7041 | | const pt = cg.pt; |
| 7042 | | const zcu = pt.zcu; |
| 7074 | const zcu = cg.zcu; |
| 7043 | 7075 | const ip = &zcu.intern_pool; |
| 7044 | 7076 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 7045 | 7077 | const extra = cg.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| ... | ... | @@ -7051,11 +7083,27 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7051 | 7083 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]); |
| 7052 | 7084 | const field_name = ip.loadEnumType(union_obj.enum_tag_type).field_names.get(ip)[extra.field_index]; |
| 7053 | 7085 | |
| 7054 | | const tag_int = blk: { |
| 7086 | const tag_int: WValue = blk: { |
| 7055 | 7087 | const tag_ty = union_ty.unionTagTypeHypothetical(zcu); |
| 7056 | 7088 | const enum_field_index = tag_ty.enumFieldIndex(field_name, zcu).?; |
| 7057 | | const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index); |
| 7058 | | break :blk try cg.lowerConstant(tag_val); |
| 7089 | const enum_type = ip.loadEnumType(tag_ty.toIntern()); |
| 7090 | const int_ty = Type.fromInterned(enum_type.int_tag_type); |
| 7091 | const int_bits = int_ty.intInfo(zcu).bits; |
| 7092 | if (int_bits > 64) { |
| 7093 | return cg.fail("TODO: union tags > 64 bits", .{}); |
| 7094 | } |
| 7095 | |
| 7096 | if (enum_type.field_values.len == 0) { |
| 7097 | // Auto-numbered fields. |
| 7098 | break :blk switch (int_bits) { |
| 7099 | 0...32 => .{ .imm32 = enum_field_index }, |
| 7100 | 33...64 => .{ .imm64 = enum_field_index }, |
| 7101 | else => unreachable, |
| 7102 | }; |
| 7103 | } |
| 7104 | |
| 7105 | const int_value = enum_type.field_values.get(ip)[enum_field_index]; |
| 7106 | break :blk try cg.lowerConstant(.fromInterned(int_value)); |
| 7059 | 7107 | }; |
| 7060 | 7108 | if (layout.payload_size == 0) { |
| 7061 | 7109 | if (layout.tag_size == 0) { |
| ... | ... | @@ -7116,8 +7164,7 @@ fn airWasmMemoryGrow(cg: *CodeGen, inst: Air.Inst.Index) !void { |
| 7116 | 7164 | } |
| 7117 | 7165 | |
| 7118 | 7166 | fn airSetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7119 | | const pt = cg.pt; |
| 7120 | | const zcu = pt.zcu; |
| 7167 | const zcu = cg.zcu; |
| 7121 | 7168 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 7122 | 7169 | const un_ty = cg.typeOf(bin_op.lhs).childType(zcu); |
| 7123 | 7170 | const tag_ty = cg.typeOf(bin_op.rhs); |
| ... | ... | @@ -7141,7 +7188,7 @@ fn airSetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7141 | 7188 | } |
| 7142 | 7189 | |
| 7143 | 7190 | fn airGetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7144 | | const zcu = cg.pt.zcu; |
| 7191 | const zcu = cg.zcu; |
| 7145 | 7192 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 7146 | 7193 | |
| 7147 | 7194 | const un_ty = cg.typeOf(ty_op.operand); |
| ... | ... | @@ -7161,7 +7208,7 @@ fn airGetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7161 | 7208 | } |
| 7162 | 7209 | |
| 7163 | 7210 | fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7164 | | const zcu = cg.pt.zcu; |
| 7211 | const zcu = cg.zcu; |
| 7165 | 7212 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 7166 | 7213 | |
| 7167 | 7214 | const err_set_ty = cg.typeOf(ty_op.operand).childType(zcu); |
| ... | ... | @@ -7185,8 +7232,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 7185 | 7232 | } |
| 7186 | 7233 | |
| 7187 | 7234 | fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7188 | | const pt = cg.pt; |
| 7189 | | const zcu = pt.zcu; |
| 7235 | const zcu = cg.zcu; |
| 7190 | 7236 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 7191 | 7237 | const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 7192 | 7238 | |
| ... | ... | @@ -7225,7 +7271,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7225 | 7271 | } |
| 7226 | 7272 | |
| 7227 | 7273 | fn sliceOrArrayPtr(cg: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue { |
| 7228 | | const zcu = cg.pt.zcu; |
| 7274 | const zcu = cg.zcu; |
| 7229 | 7275 | if (ptr_ty.isSlice(zcu)) { |
| 7230 | 7276 | return cg.slicePtr(ptr); |
| 7231 | 7277 | } else { |
| ... | ... | @@ -7234,7 +7280,7 @@ fn sliceOrArrayPtr(cg: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue { |
| 7234 | 7280 | } |
| 7235 | 7281 | |
| 7236 | 7282 | fn airMemcpy(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7237 | | const zcu = cg.pt.zcu; |
| 7283 | const zcu = cg.zcu; |
| 7238 | 7284 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 7239 | 7285 | const dst = try cg.resolveInst(bin_op.lhs); |
| 7240 | 7286 | const dst_ty = cg.typeOf(bin_op.lhs); |
| ... | ... | @@ -7268,7 +7314,7 @@ fn airMemcpy(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7268 | 7314 | } |
| 7269 | 7315 | |
| 7270 | 7316 | fn airMemmove(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7271 | | const zcu = cg.pt.zcu; |
| 7317 | const zcu = cg.zcu; |
| 7272 | 7318 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 7273 | 7319 | const dst = try cg.resolveInst(bin_op.lhs); |
| 7274 | 7320 | const dst_ty = cg.typeOf(bin_op.lhs); |
| ... | ... | @@ -7319,9 +7365,9 @@ fn airErrorName(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7319 | 7365 | // |
| 7320 | 7366 | // As the names are global and the slice elements are constant, we do not have |
| 7321 | 7367 | // to make a copy of the ptr+value but can point towards them directly. |
| 7322 | | const pt = cg.pt; |
| 7368 | const zcu = cg.zcu; |
| 7323 | 7369 | const name_ty = Type.slice_const_u8_sentinel_0; |
| 7324 | | const abi_size = name_ty.abiSize(pt.zcu); |
| 7370 | const abi_size = name_ty.abiSize(zcu); |
| 7325 | 7371 | |
| 7326 | 7372 | // Lowers to a i32.const or i64.const with the error table memory address. |
| 7327 | 7373 | cg.error_name_table_ref_count += 1; |
| ... | ... | @@ -7382,7 +7428,7 @@ fn airTry(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7382 | 7428 | } |
| 7383 | 7429 | |
| 7384 | 7430 | fn airTryPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7385 | | const zcu = cg.pt.zcu; |
| 7431 | const zcu = cg.zcu; |
| 7386 | 7432 | const unwrapped_try = cg.air.unwrapTryPtr(inst); |
| 7387 | 7433 | const err_union_ptr = try cg.resolveInst(unwrapped_try.error_union_ptr); |
| 7388 | 7434 | const body = unwrapped_try.else_body; |
| ... | ... | @@ -7405,7 +7451,7 @@ fn lowerTry( |
| 7405 | 7451 | err_union_ty: Type, |
| 7406 | 7452 | operand_is_ptr: bool, |
| 7407 | 7453 | ) InnerError!WValue { |
| 7408 | | const zcu = cg.pt.zcu; |
| 7454 | const zcu = cg.zcu; |
| 7409 | 7455 | const branch_liveness = cg.liveness.getCondBr(inst); |
| 7410 | 7456 | |
| 7411 | 7457 | const pl_ty = err_union_ty.errorUnionPayload(zcu); |
| ... | ... | @@ -7465,7 +7511,7 @@ fn callIntrinsic( |
| 7465 | 7511 | args: []const WValue, |
| 7466 | 7512 | ) InnerError!WValue { |
| 7467 | 7513 | assert(param_types.len == args.len); |
| 7468 | | const zcu = cg.pt.zcu; |
| 7514 | const zcu = cg.zcu; |
| 7469 | 7515 | |
| 7470 | 7516 | // Always pass over C-ABI |
| 7471 | 7517 | |
| ... | ... | @@ -7523,7 +7569,7 @@ fn airIsNamedEnumValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7523 | 7569 | } |
| 7524 | 7570 | |
| 7525 | 7571 | fn airErrorSetHasValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7526 | | const zcu = cg.pt.zcu; |
| 7572 | const zcu = cg.zcu; |
| 7527 | 7573 | const ip = &zcu.intern_pool; |
| 7528 | 7574 | const ty_op = cg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 7529 | 7575 | |
| ... | ... | @@ -7610,7 +7656,7 @@ inline fn useAtomicFeature(cg: *const CodeGen) bool { |
| 7610 | 7656 | } |
| 7611 | 7657 | |
| 7612 | 7658 | fn airCmpxchg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7613 | | const zcu = cg.pt.zcu; |
| 7659 | const zcu = cg.zcu; |
| 7614 | 7660 | const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 7615 | 7661 | const extra = cg.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 7616 | 7662 | |
| ... | ... | @@ -7636,7 +7682,7 @@ fn airCmpxchg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7636 | 7682 | 1 => .i32_atomic_rmw8_cmpxchg_u, |
| 7637 | 7683 | 2 => .i32_atomic_rmw16_cmpxchg_u, |
| 7638 | 7684 | 4 => .i32_atomic_rmw_cmpxchg, |
| 7639 | | 8 => .i32_atomic_rmw_cmpxchg, |
| 7685 | 8 => .i64_atomic_rmw_cmpxchg, |
| 7640 | 7686 | else => |size| return cg.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}), |
| 7641 | 7687 | }, .{ |
| 7642 | 7688 | .offset = ptr_operand.memOffset(), |
| ... | ... | @@ -7688,7 +7734,7 @@ fn airCmpxchg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7688 | 7734 | } |
| 7689 | 7735 | |
| 7690 | 7736 | fn airAtomicLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7691 | | const zcu = cg.pt.zcu; |
| 7737 | const zcu = cg.zcu; |
| 7692 | 7738 | const atomic_load = cg.air.instructions.items(.data)[@backingInt(inst)].atomic_load; |
| 7693 | 7739 | const ptr = try cg.resolveInst(atomic_load.ptr); |
| 7694 | 7740 | const ty = cg.typeOfIndex(inst); |
| ... | ... | @@ -7714,7 +7760,7 @@ fn airAtomicLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7714 | 7760 | } |
| 7715 | 7761 | |
| 7716 | 7762 | fn airAtomicRmw(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7717 | | const zcu = cg.pt.zcu; |
| 7763 | const zcu = cg.zcu; |
| 7718 | 7764 | const pl_op = cg.air.instructions.items(.data)[@backingInt(inst)].pl_op; |
| 7719 | 7765 | const extra = cg.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 7720 | 7766 | |
| ... | ... | @@ -7724,6 +7770,9 @@ fn airAtomicRmw(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7724 | 7770 | const op: std.lang.AtomicRmwOp = extra.op(); |
| 7725 | 7771 | |
| 7726 | 7772 | if (cg.useAtomicFeature()) { |
| 7773 | if (ty.isAnyFloat()) { |
| 7774 | return cg.fail("TODO: atomic rmw on floats", .{}); |
| 7775 | } |
| 7727 | 7776 | const int_ty: IntType = .fromType(cg, ty); |
| 7728 | 7777 | switch (op) { |
| 7729 | 7778 | .Max, |
| ... | ... | @@ -7918,7 +7967,7 @@ fn airAtomicRmw(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7918 | 7967 | } |
| 7919 | 7968 | |
| 7920 | 7969 | fn airAtomicStore(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7921 | | const zcu = cg.pt.zcu; |
| 7970 | const zcu = cg.zcu; |
| 7922 | 7971 | const bin_op = cg.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 7923 | 7972 | |
| 7924 | 7973 | const ptr = try cg.resolveInst(bin_op.lhs); |
| ... | ... | @@ -7954,7 +8003,7 @@ fn airFrameAddress(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7954 | 8003 | |
| 7955 | 8004 | fn airRuntimeNavPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7956 | 8005 | const ty_nav = cg.air.instructions.items(.data)[@backingInt(inst)].ty_nav; |
| 7957 | | const mod = cg.pt.zcu.navFileScope(cg.owner_nav).mod.?; |
| 8006 | const mod = cg.zcu.navFileScope(cg.owner_nav).mod.?; |
| 7958 | 8007 | if (mod.single_threaded) { |
| 7959 | 8008 | const result: WValue = .{ .nav_ref = .{ |
| 7960 | 8009 | .nav_index = ty_nav.nav, |
| ... | ... | @@ -7970,7 +8019,7 @@ fn airAsm(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7970 | 8019 | const outputs = unwrapped_asm.outputs; |
| 7971 | 8020 | const inputs = unwrapped_asm.inputs; |
| 7972 | 8021 | |
| 7973 | | const zcu = cg.pt.zcu; |
| 8022 | const zcu = cg.zcu; |
| 7974 | 8023 | const output_ty = cg.typeOfIndex(inst); |
| 7975 | 8024 | |
| 7976 | 8025 | const result: WValue = if (output_ty.hasRuntimeBits(zcu)) |
| ... | ... | @@ -8037,11 +8086,11 @@ fn airAsm(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 8037 | 8086 | } |
| 8038 | 8087 | |
| 8039 | 8088 | fn typeOf(cg: *CodeGen, inst: Air.Inst.Ref) Type { |
| 8040 | | const zcu = cg.pt.zcu; |
| 8089 | const zcu = cg.zcu; |
| 8041 | 8090 | return cg.air.typeOf(inst, &zcu.intern_pool); |
| 8042 | 8091 | } |
| 8043 | 8092 | |
| 8044 | 8093 | fn typeOfIndex(cg: *CodeGen, inst: Air.Inst.Index) Type { |
| 8045 | | const zcu = cg.pt.zcu; |
| 8094 | const zcu = cg.zcu; |
| 8046 | 8095 | return cg.air.typeOfIndex(inst, &zcu.intern_pool); |
| 8047 | 8096 | } |