authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-26 02:45:48-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-06-26 02:45:48-04:00
logcc2daae47e4fbb7d68e00211d509dd934d2e14b2
treee839501c6d7e37079d0a15a906e6f6dd30a3f4fc
parentdce1999c803dd9d8ceff7fbffa1825af837ee0ed
parent85902115d4fde6120b6cea610cd6f79baede5aaa
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15771 from jacobly0/x86_64-behavior

x86_64: behavior

10 files changed, 398 insertions(+), 352 deletions(-)

lib/std/mem.zig+3-4
......@@ -1832,7 +1832,6 @@ pub fn writeIntSlice(comptime T: type, buffer: []u8, value: T, endian: Endian) v
18321832pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value: anytype, endian: std.builtin.Endian) void {
18331833 const T = @TypeOf(value);
18341834 const uN = std.meta.Int(.unsigned, @bitSizeOf(T));
1835 const Log2N = std.math.Log2Int(T);
18361835
18371836 const bit_shift = @as(u3, @intCast(bit_offset % 8));
18381837 const write_size = (bit_count + bit_shift + 7) / 8;
......@@ -1861,9 +1860,9 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
18611860
18621861 // Write first byte, using a mask to protects bits preceding bit_offset
18631862 const head_mask = @as(u8, 0xff) >> bit_shift;
1864 write_bytes[@as(usize, @intCast(i))] &= ~(head_mask << bit_shift);
1865 write_bytes[@as(usize, @intCast(i))] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & head_mask)) << bit_shift;
1866 remaining >>= @as(Log2N, @intCast(@as(u4, 8) - bit_shift));
1863 write_bytes[@intCast(i)] &= ~(head_mask << bit_shift);
1864 write_bytes[@intCast(i)] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & head_mask)) << bit_shift;
1865 remaining = math.shr(T, remaining, @as(u4, 8) - bit_shift);
18671866 i += delta;
18681867
18691868 // Write bytes[1..bytes.len - 1]
src/arch/x86_64/CodeGen.zig+366-329
......@@ -329,7 +329,7 @@ pub const MCValue = union(enum) {
329329 .load_frame,
330330 .reserved_frame,
331331 => unreachable, // not offsettable
332 .immediate => |imm| .{ .immediate = @as(u64, @bitCast(@as(i64, @bitCast(imm)) +% off)) },
332 .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) },
333333 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },
334334 .register_offset => |reg_off| .{
335335 .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off },
......@@ -606,7 +606,7 @@ const FrameAlloc = struct {
606606 fn init(alloc_abi: struct { size: u64, alignment: u32 }) FrameAlloc {
607607 assert(math.isPowerOfTwo(alloc_abi.alignment));
608608 return .{
609 .abi_size = @as(u31, @intCast(alloc_abi.size)),
609 .abi_size = @intCast(alloc_abi.size),
610610 .abi_align = math.log2_int(u32, alloc_abi.alignment),
611611 .ref_count = 0,
612612 };
......@@ -694,7 +694,7 @@ pub fn generate(
694694 FrameAlloc.init(.{
695695 .size = 0,
696696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|
697 @as(u32, @intCast(set_align_stack.alignment.toByteUnitsOptional().?))
697 @intCast(set_align_stack.alignment.toByteUnitsOptional().?)
698698 else
699699 1,
700700 }),
......@@ -979,7 +979,7 @@ fn fmtTracking(self: *Self) std.fmt.Formatter(formatTracking) {
979979fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
980980 const gpa = self.gpa;
981981 try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
982 const result_index = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len));
982 const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
983983 self.mir_instructions.appendAssumeCapacity(inst);
984984 if (inst.tag != .pseudo or switch (inst.ops) {
985985 else => true,
......@@ -1000,11 +1000,11 @@ fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 {
10001000
10011001fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
10021002 const fields = std.meta.fields(@TypeOf(extra));
1003 const result = @as(u32, @intCast(self.mir_extra.items.len));
1003 const result: u32 = @intCast(self.mir_extra.items.len);
10041004 inline for (fields) |field| {
10051005 self.mir_extra.appendAssumeCapacity(switch (field.type) {
10061006 u32 => @field(extra, field.name),
1007 i32 => @as(u32, @bitCast(@field(extra, field.name))),
1007 i32 => @bitCast(@field(extra, field.name)),
10081008 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
10091009 });
10101010 }
......@@ -1214,8 +1214,8 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void {
12141214 .data = .{ .i = .{
12151215 .fixes = tag[0],
12161216 .i = switch (imm) {
1217 .signed => |s| @as(u32, @bitCast(s)),
1218 .unsigned => |u| @as(u32, @intCast(u)),
1217 .signed => |s| @bitCast(s),
1218 .unsigned => |u| @intCast(u),
12191219 },
12201220 } },
12211221 });
......@@ -1246,8 +1246,8 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:
12461246 .fixes = tag[0],
12471247 .r1 = reg,
12481248 .i = switch (imm) {
1249 .signed => |s| @as(u32, @bitCast(s)),
1250 .unsigned => |u| @as(u32, @intCast(u)),
1249 .signed => |s| @bitCast(s),
1250 .unsigned => |u| @intCast(u),
12511251 },
12521252 } },
12531253 .ri64 => .{ .rx = .{
......@@ -1339,8 +1339,8 @@ fn asmRegisterRegisterImmediate(
13391339 .r1 = reg1,
13401340 .r2 = reg2,
13411341 .i = switch (imm) {
1342 .signed => |s| @as(u32, @bitCast(s)),
1343 .unsigned => |u| @as(u32, @intCast(u)),
1342 .signed => |s| @bitCast(s),
1343 .unsigned => |u| @intCast(u),
13441344 },
13451345 } },
13461346 });
......@@ -1458,7 +1458,7 @@ fn asmRegisterRegisterMemoryImmediate(
14581458 .fixes = tag[0],
14591459 .r1 = reg1,
14601460 .r2 = reg2,
1461 .i = @as(u8, @intCast(imm.unsigned)),
1461 .i = @intCast(imm.unsigned),
14621462 .payload = switch (m) {
14631463 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
14641464 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),
......@@ -1490,8 +1490,8 @@ fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Regist
14901490
14911491fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immediate) !void {
14921492 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
1493 .signed => |s| @as(u32, @bitCast(s)),
1494 .unsigned => |u| @as(u32, @intCast(u)),
1493 .signed => |s| @bitCast(s),
1494 .unsigned => |u| @intCast(u),
14951495 } });
14961496 assert(payload + 1 == switch (m) {
14971497 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
......@@ -1562,7 +1562,7 @@ fn asmMemoryRegisterImmediate(
15621562 .data = .{ .rix = .{
15631563 .fixes = tag[0],
15641564 .r1 = reg,
1565 .i = @as(u8, @intCast(imm.unsigned)),
1565 .i = @intCast(imm.unsigned),
15661566 .payload = switch (m) {
15671567 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
15681568 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),
......@@ -1617,7 +1617,7 @@ fn gen(self: *Self) InnerError!void {
16171617 // Eliding the reloc will cause a miscompilation in this case.
16181618 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
16191619 self.mir_instructions.items(.data)[jmp_reloc].inst.inst =
1620 @as(u32, @intCast(self.mir_instructions.len));
1620 @intCast(self.mir_instructions.len);
16211621 }
16221622
16231623 try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
......@@ -1739,7 +1739,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
17391739
17401740 for (body) |inst| {
17411741 if (builtin.mode == .Debug) {
1742 const mir_inst = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len));
1742 const mir_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len);
17431743 try self.mir_to_air_map.put(self.gpa, mir_inst, inst);
17441744 }
17451745
......@@ -2034,7 +2034,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
20342034
20352035 var data_off: i32 = 0;
20362036 for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, index_usize| {
2037 const index = @as(u32, @intCast(index_usize));
2037 const index: u32 = @intCast(index_usize);
20382038 const tag_name = mod.intern_pool.stringToSlice(enum_ty.enumFields(mod)[index_usize]);
20392039 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
20402040 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
......@@ -2052,7 +2052,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
20522052 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
20532053 try self.performReloc(skip_reloc);
20542054
2055 data_off += @as(i32, @intCast(tag_name.len + 1));
2055 data_off += @intCast(tag_name.len + 1);
20562056 }
20572057
20582058 try self.airTrap();
......@@ -2169,7 +2169,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
21692169 const frame_offset = self.frame_locs.items(.disp);
21702170
21712171 for (stack_frame_order, FrameIndex.named_count..) |*frame_order, frame_index|
2172 frame_order.* = @as(FrameIndex, @enumFromInt(frame_index));
2172 frame_order.* = @enumFromInt(frame_index);
21732173 {
21742174 const SortContext = struct {
21752175 frame_align: @TypeOf(frame_align),
......@@ -2197,7 +2197,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
21972197 }
21982198 }
21992199
2200 var rbp_offset = @as(i32, @intCast(save_reg_list.count() * 8));
2200 var rbp_offset: i32 = @intCast(save_reg_list.count() * 8);
22012201 self.setFrameLoc(.base_ptr, .rbp, &rbp_offset, false);
22022202 self.setFrameLoc(.ret_addr, .rbp, &rbp_offset, false);
22032203 self.setFrameLoc(.args_frame, .rbp, &rbp_offset, false);
......@@ -2212,11 +2212,11 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
22122212 rsp_offset = mem.alignForward(i32, rsp_offset, @as(i32, 1) << needed_align);
22132213 rsp_offset -= stack_frame_align_offset;
22142214 frame_size[@intFromEnum(FrameIndex.call_frame)] =
2215 @as(u31, @intCast(rsp_offset - frame_offset[@intFromEnum(FrameIndex.stack_frame)]));
2215 @intCast(rsp_offset - frame_offset[@intFromEnum(FrameIndex.stack_frame)]);
22162216
22172217 return .{
22182218 .stack_mask = @as(u32, math.maxInt(u32)) << (if (need_align_stack) needed_align else 0),
2219 .stack_adjust = @as(u32, @intCast(rsp_offset - frame_offset[@intFromEnum(FrameIndex.call_frame)])),
2219 .stack_adjust = @intCast(rsp_offset - frame_offset[@intFromEnum(FrameIndex.call_frame)]),
22202220 .save_reg_list = save_reg_list,
22212221 };
22222222}
......@@ -2247,7 +2247,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
22472247 _ = self.free_frame_indices.swapRemoveAt(free_i);
22482248 return frame_index;
22492249 }
2250 const frame_index = @as(FrameIndex, @enumFromInt(self.frame_allocs.len));
2250 const frame_index: FrameIndex = @enumFromInt(self.frame_allocs.len);
22512251 try self.frame_allocs.append(self.gpa, alloc);
22522252 return frame_index;
22532253}
......@@ -2323,7 +2323,7 @@ const State = struct {
23232323
23242324fn initRetroactiveState(self: *Self) State {
23252325 var state: State = undefined;
2326 state.inst_tracking_len = @as(u32, @intCast(self.inst_tracking.count()));
2326 state.inst_tracking_len = @intCast(self.inst_tracking.count());
23272327 state.scope_generation = self.scope_generation;
23282328 return state;
23292329}
......@@ -2394,9 +2394,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt
23942394 self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst);
23952395 }
23962396 {
2397 const reg = RegisterManager.regAtTrackedIndex(
2398 @as(RegisterManager.RegisterBitSet.ShiftInt, @intCast(index)),
2399 );
2397 const reg = RegisterManager.regAtTrackedIndex(@intCast(index));
24002398 self.register_manager.freeReg(reg);
24012399 self.register_manager.getRegAssumeFree(reg, target_maybe_inst);
24022400 }
......@@ -2630,7 +2628,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
26302628
26312629 const dst_ty = self.typeOfIndex(inst);
26322630 const dst_int_info = dst_ty.intInfo(mod);
2633 const abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
2631 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));
26342632
26352633 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;
26362634 const extend = switch (src_int_info.signedness) {
......@@ -2708,9 +2706,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
27082706 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27092707
27102708 const dst_ty = self.typeOfIndex(inst);
2711 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
2709 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
27122710 const src_ty = self.typeOf(ty_op.operand);
2713 const src_abi_size = @as(u32, @intCast(src_ty.abiSize(mod)));
2711 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));
27142712
27152713 const result = result: {
27162714 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -2727,7 +2725,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
27272725 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod));
27282726 const dst_info = dst_ty.childType(mod).intInfo(mod);
27292727 const src_info = src_ty.childType(mod).intInfo(mod);
2730 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_info.bits) {
2728 const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_info.bits) {
27312729 8 => switch (src_info.bits) {
27322730 16 => switch (dst_ty.vectorLen(mod)) {
27332731 1...8 => if (self.hasFeature(.avx)) .{ .vp_b, .ackusw } else .{ .p_b, .ackusw },
......@@ -2750,18 +2748,18 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
27502748 else => null,
27512749 },
27522750 else => null,
2753 })) |tag| tag else return self.fail("TODO implement airTrunc for {}", .{
2751 }) orelse return self.fail("TODO implement airTrunc for {}", .{
27542752 dst_ty.fmt(self.bin_file.options.module.?),
27552753 });
27562754
27572755 const elem_ty = src_ty.childType(mod);
2758 const mask_val = try mod.intValue(elem_ty, @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - dst_info.bits)));
2756 const mask_val = try mod.intValue(elem_ty, @as(u64, math.maxInt(u64)) >> @intCast(64 - dst_info.bits));
27592757
27602758 const splat_ty = try mod.vectorType(.{
2761 .len = @as(u32, @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits))),
2759 .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)),
27622760 .child = elem_ty.ip_index,
27632761 });
2764 const splat_abi_size = @as(u32, @intCast(splat_ty.abiSize(mod)));
2762 const splat_abi_size: u32 = @intCast(splat_ty.abiSize(mod));
27652763
27662764 const splat_val = try mod.intern(.{ .aggregate = .{
27672765 .ty = splat_ty.ip_index,
......@@ -2836,7 +2834,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
28362834 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
28372835 try self.genSetMem(
28382836 .{ .frame = frame_index },
2839 @as(i32, @intCast(ptr_ty.abiSize(mod))),
2837 @intCast(ptr_ty.abiSize(mod)),
28402838 len_ty,
28412839 len,
28422840 );
......@@ -2935,6 +2933,10 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
29352933 const mod = self.bin_file.options.module.?;
29362934 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
29372935 const ty = self.typeOf(bin_op.lhs);
2936 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(
2937 "TODO implement addMulSat for {}",
2938 .{ty.fmt(mod)},
2939 );
29382940
29392941 const lhs_mcv = try self.resolveInst(bin_op.lhs);
29402942 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
......@@ -2966,7 +2968,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
29662968 try self.genSetReg(limit_reg, ty, dst_mcv);
29672969 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
29682970 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{
2969 .immediate = (@as(u64, 1) << @as(u6, @intCast(reg_bits - 1))) - 1,
2971 .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1,
29702972 });
29712973 if (reg_extra_bits > 0) {
29722974 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);
......@@ -2985,7 +2987,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
29852987 break :cc .o;
29862988 } else cc: {
29872989 try self.genSetReg(limit_reg, ty, .{
2988 .immediate = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - ty.bitSize(mod))),
2990 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(mod)),
29892991 });
29902992
29912993 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
......@@ -3014,6 +3016,10 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
30143016 const mod = self.bin_file.options.module.?;
30153017 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
30163018 const ty = self.typeOf(bin_op.lhs);
3019 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(
3020 "TODO implement addMulSat for {}",
3021 .{ty.fmt(mod)},
3022 );
30173023
30183024 const lhs_mcv = try self.resolveInst(bin_op.lhs);
30193025 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
......@@ -3045,7 +3051,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
30453051 try self.genSetReg(limit_reg, ty, dst_mcv);
30463052 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
30473053 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{
3048 .immediate = (@as(u64, 1) << @as(u6, @intCast(reg_bits - 1))) - 1,
3054 .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1,
30493055 });
30503056 if (reg_extra_bits > 0) {
30513057 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);
......@@ -3086,6 +3092,10 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
30863092 const mod = self.bin_file.options.module.?;
30873093 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
30883094 const ty = self.typeOf(bin_op.lhs);
3095 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(
3096 "TODO implement addMulSat for {}",
3097 .{ty.fmt(mod)},
3098 );
30893099
30903100 try self.spillRegisters(&.{ .rax, .rdx });
30913101 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });
......@@ -3116,12 +3126,12 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
31163126 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);
31173127 try self.genShiftBinOpMir(.{ ._, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
31183128 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{
3119 .immediate = (@as(u64, 1) << @as(u6, @intCast(reg_bits - 1))) - 1,
3129 .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1,
31203130 });
31213131 break :cc .o;
31223132 } else cc: {
31233133 try self.genSetReg(limit_reg, ty, .{
3124 .immediate = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - reg_bits)),
3134 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - reg_bits),
31253135 });
31263136 break :cc .c;
31273137 };
......@@ -3174,13 +3184,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
31743184 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
31753185 try self.genSetMem(
31763186 .{ .frame = frame_index },
3177 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),
3187 @intCast(tuple_ty.structFieldOffset(1, mod)),
31783188 Type.u1,
31793189 .{ .eflags = cc },
31803190 );
31813191 try self.genSetMem(
31823192 .{ .frame = frame_index },
3183 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),
3193 @intCast(tuple_ty.structFieldOffset(0, mod)),
31843194 ty,
31853195 partial_mcv,
31863196 );
......@@ -3247,13 +3257,13 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
32473257 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
32483258 try self.genSetMem(
32493259 .{ .frame = frame_index },
3250 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),
3260 @intCast(tuple_ty.structFieldOffset(1, mod)),
32513261 tuple_ty.structFieldType(1, mod),
32523262 .{ .eflags = cc },
32533263 );
32543264 try self.genSetMem(
32553265 .{ .frame = frame_index },
3256 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),
3266 @intCast(tuple_ty.structFieldOffset(0, mod)),
32573267 tuple_ty.structFieldType(0, mod),
32583268 partial_mcv,
32593269 );
......@@ -3321,7 +3331,7 @@ fn genSetFrameTruncatedOverflowCompare(
33213331 );
33223332 }
33233333
3324 const payload_off = @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod)));
3334 const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod));
33253335 if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv);
33263336 try self.genSetMem(
33273337 .{ .frame = frame_index },
......@@ -3331,7 +3341,7 @@ fn genSetFrameTruncatedOverflowCompare(
33313341 );
33323342 try self.genSetMem(
33333343 .{ .frame = frame_index },
3334 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),
3344 @intCast(tuple_ty.structFieldOffset(1, mod)),
33353345 tuple_ty.structFieldType(1, mod),
33363346 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
33373347 );
......@@ -3388,13 +3398,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
33883398 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {
33893399 try self.genSetMem(
33903400 .{ .frame = frame_index },
3391 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),
3401 @intCast(tuple_ty.structFieldOffset(0, mod)),
33923402 tuple_ty.structFieldType(0, mod),
33933403 partial_mcv,
33943404 );
33953405 try self.genSetMem(
33963406 .{ .frame = frame_index },
3397 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),
3407 @intCast(tuple_ty.structFieldOffset(1, mod)),
33983408 tuple_ty.structFieldType(1, mod),
33993409 .{ .immediate = 0 }, // cc being set is impossible
34003410 );
......@@ -3418,7 +3428,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
34183428/// Quotient is saved in .rax and remainder in .rdx.
34193429fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {
34203430 const mod = self.bin_file.options.module.?;
3421 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
3431 const abi_size: u32 = @intCast(ty.abiSize(mod));
34223432 if (abi_size > 8) {
34233433 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});
34243434 }
......@@ -3458,7 +3468,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue
34583468/// Clobbers .rax and .rdx registers.
34593469fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
34603470 const mod = self.bin_file.options.module.?;
3461 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
3471 const abi_size: u32 = @intCast(ty.abiSize(mod));
34623472 const int_info = ty.intInfo(mod);
34633473 const dividend: Register = switch (lhs) {
34643474 .register => |reg| reg,
......@@ -3597,7 +3607,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
35973607 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
35983608
35993609 const pl_ty = dst_ty.childType(mod);
3600 const pl_abi_size = @as(i32, @intCast(pl_ty.abiSize(mod)));
3610 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod));
36013611 try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });
36023612 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
36033613 };
......@@ -3629,17 +3639,12 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
36293639 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
36303640
36313641 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);
3632 if (err_off > 0) {
3633 const shift = @as(u6, @intCast(err_off * 8));
3634 try self.genShiftBinOpMir(
3635 .{ ._r, .sh },
3636 err_union_ty,
3637 result,
3638 .{ .immediate = shift },
3639 );
3640 } else {
3641 try self.truncateRegister(Type.anyerror, result.register);
3642 }
3642 if (err_off > 0) try self.genShiftBinOpMir(
3643 .{ ._r, .sh },
3644 err_union_ty,
3645 result,
3646 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
3647 ) else try self.truncateRegister(Type.anyerror, result.register);
36433648 break :result result;
36443649 },
36453650 .load_frame => |frame_addr| break :result .{ .load_frame = .{
......@@ -3687,17 +3692,12 @@ fn genUnwrapErrorUnionPayloadMir(
36873692 try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union)
36883693 else
36893694 .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) };
3690 if (payload_off > 0) {
3691 const shift = @as(u6, @intCast(payload_off * 8));
3692 try self.genShiftBinOpMir(
3693 .{ ._r, .sh },
3694 err_union_ty,
3695 result_mcv,
3696 .{ .immediate = shift },
3697 );
3698 } else {
3699 try self.truncateRegister(payload_ty, result_mcv.register);
3700 }
3695 if (payload_off > 0) try self.genShiftBinOpMir(
3696 .{ ._r, .sh },
3697 err_union_ty,
3698 result_mcv,
3699 .{ .immediate = @as(u6, @intCast(payload_off * 8)) },
3700 ) else try self.truncateRegister(payload_ty, result_mcv.register);
37013701 break :result result_mcv;
37023702 },
37033703 else => return self.fail("TODO implement genUnwrapErrorUnionPayloadMir for {}", .{err_union}),
......@@ -3729,8 +3729,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
37293729 const eu_ty = src_ty.childType(mod);
37303730 const pl_ty = eu_ty.errorUnionPayload(mod);
37313731 const err_ty = eu_ty.errorUnionSet(mod);
3732 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));
3733 const err_abi_size = @as(u32, @intCast(err_ty.abiSize(mod)));
3732 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
3733 const err_abi_size: u32 = @intCast(err_ty.abiSize(mod));
37343734 try self.asmRegisterMemory(
37353735 .{ ._, .mov },
37363736 registerAlias(dst_reg, err_abi_size),
......@@ -3768,8 +3768,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
37683768
37693769 const eu_ty = src_ty.childType(mod);
37703770 const pl_ty = eu_ty.errorUnionPayload(mod);
3771 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));
3772 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
3771 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3772 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
37733773 try self.asmRegisterMemory(
37743774 .{ ._, .lea },
37753775 registerAlias(dst_reg, dst_abi_size),
......@@ -3795,8 +3795,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
37953795 const eu_ty = src_ty.childType(mod);
37963796 const pl_ty = eu_ty.errorUnionPayload(mod);
37973797 const err_ty = eu_ty.errorUnionSet(mod);
3798 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));
3799 const err_abi_size = @as(u32, @intCast(err_ty.abiSize(mod)));
3798 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
3799 const err_abi_size: u32 = @intCast(err_ty.abiSize(mod));
38003800 try self.asmMemoryImmediate(
38013801 .{ ._, .mov },
38023802 Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{
......@@ -3816,8 +3816,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
38163816 const dst_lock = self.register_manager.lockReg(dst_reg);
38173817 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
38183818
3819 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));
3820 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
3819 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3820 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
38213821 try self.asmRegisterMemory(
38223822 .{ ._, .lea },
38233823 registerAlias(dst_reg, dst_abi_size),
......@@ -3866,7 +3866,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
38663866 try self.genCopy(pl_ty, opt_mcv, pl_mcv);
38673867
38683868 if (!same_repr) {
3869 const pl_abi_size = @as(i32, @intCast(pl_ty.abiSize(mod)));
3869 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod));
38703870 switch (opt_mcv) {
38713871 else => unreachable,
38723872
......@@ -3905,8 +3905,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
39053905 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .{ .immediate = 0 };
39063906
39073907 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3908 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));
3909 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));
3908 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3909 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
39103910 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);
39113911 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });
39123912 break :result .{ .load_frame = .{ .index = frame_index } };
......@@ -3927,8 +3927,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
39273927 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);
39283928
39293929 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3930 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));
3931 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));
3930 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3931 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
39323932 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);
39333933 const operand = try self.resolveInst(ty_op.operand);
39343934 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);
......@@ -3990,7 +3990,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
39903990 const dst_lock = self.register_manager.lockReg(dst_reg);
39913991 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
39923992
3993 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
3993 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
39943994 try self.asmRegisterMemory(
39953995 .{ ._, .lea },
39963996 registerAlias(dst_reg, dst_abi_size),
......@@ -4167,7 +4167,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
41674167 // additional `mov` is needed at the end to get the actual value
41684168
41694169 const elem_ty = ptr_ty.elemType2(mod);
4170 const elem_abi_size = @as(u32, @intCast(elem_ty.abiSize(mod)));
4170 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod));
41714171 const index_ty = self.typeOf(bin_op.rhs);
41724172 const index_mcv = try self.resolveInst(bin_op.rhs);
41734173 const index_lock = switch (index_mcv) {
......@@ -4307,7 +4307,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
43074307 .load_frame => |frame_addr| {
43084308 if (tag_abi_size <= 8) {
43094309 const off: i32 = if (layout.tag_align < layout.payload_align)
4310 @as(i32, @intCast(layout.payload_size))
4310 @intCast(layout.payload_size)
43114311 else
43124312 0;
43134313 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{
......@@ -4319,13 +4319,13 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
43194319 },
43204320 .register => {
43214321 const shift: u6 = if (layout.tag_align < layout.payload_align)
4322 @as(u6, @intCast(layout.payload_size * 8))
4322 @intCast(layout.payload_size * 8)
43234323 else
43244324 0;
43254325 const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand);
43264326 try self.genShiftBinOpMir(.{ ._r, .sh }, Type.usize, result, .{ .immediate = shift });
43274327 break :blk MCValue{
4328 .register = registerAlias(result.register, @as(u32, @intCast(layout.tag_size))),
4328 .register = registerAlias(result.register, @intCast(layout.tag_size)),
43294329 };
43304330 },
43314331 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),
......@@ -4341,6 +4341,9 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
43414341 const result = result: {
43424342 const dst_ty = self.typeOfIndex(inst);
43434343 const src_ty = self.typeOf(ty_op.operand);
4344 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{
4345 src_ty.fmt(mod),
4346 });
43444347
43454348 const src_mcv = try self.resolveInst(ty_op.operand);
43464349 const mat_src_mcv = switch (src_mcv) {
......@@ -4432,7 +4435,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
44324435 try self.genBinOpMir(.{ ._, .xor }, dst_ty, dst_mcv, .{ .immediate = src_bits - 1 });
44334436 } else {
44344437 const imm_reg = try self.copyToTmpRegister(dst_ty, .{
4435 .immediate = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - self.regBitSize(dst_ty))),
4438 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - self.regBitSize(dst_ty)),
44364439 });
44374440 const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg);
44384441 defer self.register_manager.unlockReg(imm_lock);
......@@ -4503,8 +4506,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
45034506 .{ ._, .@"or" },
45044507 wide_ty,
45054508 tmp_mcv,
4506 .{ .immediate = (@as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - extra_bits))) <<
4507 @as(u6, @intCast(src_bits)) },
4509 .{ .immediate = (@as(u64, math.maxInt(u64)) >> @intCast(64 - extra_bits)) <<
4510 @intCast(src_bits) },
45084511 );
45094512 break :masked tmp_mcv;
45104513 } else mat_src_mcv;
......@@ -4521,7 +4524,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
45214524 .{ ._, .@"or" },
45224525 Type.u64,
45234526 dst_mcv,
4524 .{ .immediate = @as(u64, math.maxInt(u64)) << @as(u6, @intCast(src_bits - 64)) },
4527 .{ .immediate = @as(u64, math.maxInt(u64)) << @intCast(src_bits - 64) },
45254528 );
45264529 break :masked dst_mcv;
45274530 } else mat_src_mcv.address().offset(8).deref();
......@@ -4565,7 +4568,9 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
45654568 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
45664569 const result: MCValue = result: {
45674570 const src_ty = self.typeOf(ty_op.operand);
4568 const src_abi_size = @as(u32, @intCast(src_ty.abiSize(mod)));
4571 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));
4572 if (src_ty.zigTypeTag(mod) == .Vector or src_abi_size > 8)
4573 return self.fail("TODO implement airPopcount for {}", .{src_ty.fmt(mod)});
45694574 const src_mcv = try self.resolveInst(ty_op.operand);
45704575
45714576 if (self.hasFeature(.popcnt)) {
......@@ -4590,7 +4595,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
45904595 break :result dst_mcv;
45914596 }
45924597
4593 const mask = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - src_abi_size * 8));
4598 const mask = @as(u64, math.maxInt(u64)) >> @intCast(64 - src_abi_size * 8);
45944599 const imm_0_1 = Immediate.u(mask / 0b1_1);
45954600 const imm_00_11 = Immediate.u(mask / 0b01_01);
45964601 const imm_0000_1111 = Immediate.u(mask / 0b0001_0001);
......@@ -4674,8 +4679,13 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
46744679}
46754680
46764681fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, mem_ok: bool) !MCValue {
4682 const mod = self.bin_file.options.module.?;
46774683 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
46784684
4685 if (src_ty.zigTypeTag(mod) == .Vector or src_ty.abiSize(mod) > 8) return self.fail(
4686 "TODO implement byteSwap for {}",
4687 .{src_ty.fmt(mod)},
4688 );
46794689 const src_bits = self.regBitSize(src_ty);
46804690 const src_lock = switch (src_mcv) {
46814691 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
......@@ -4684,7 +4694,9 @@ fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, m
46844694 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
46854695
46864696 switch (src_bits) {
4687 else => unreachable,
4697 else => return self.fail("TODO implement byteSwap for {}", .{
4698 src_ty.fmt(mod),
4699 }),
46884700 8 => return if ((mem_ok or src_mcv.isRegister()) and
46894701 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
46904702 src_mcv
......@@ -4756,7 +4768,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
47564768 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47574769
47584770 const src_ty = self.typeOf(ty_op.operand);
4759 const src_abi_size = @as(u32, @intCast(src_ty.abiSize(mod)));
4771 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));
47604772 const src_mcv = try self.resolveInst(ty_op.operand);
47614773
47624774 const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, false);
......@@ -4776,7 +4788,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
47764788 else
47774789 undefined;
47784790
4779 const mask = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - src_abi_size * 8));
4791 const mask = @as(u64, math.maxInt(u64)) >> @intCast(64 - src_abi_size * 8);
47804792 const imm_0000_1111 = Immediate.u(mask / 0b0001_0001);
47814793 const imm_00_11 = Immediate.u(mask / 0b01_01);
47824794 const imm_0_1 = Immediate.u(mask / 0b1_1);
......@@ -4874,6 +4886,9 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
48744886 }),
48754887 };
48764888 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);
4889 if (scalar_bits == 80) return self.fail("TODO implement airFloatSign for {}", .{
4890 ty.fmt(mod),
4891 });
48774892
48784893 const src_mcv = try self.resolveInst(un_op);
48794894 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
......@@ -4989,7 +5004,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
49895004 if (!self.hasFeature(.sse4_1))
49905005 return self.fail("TODO implement genRound without sse4_1 feature", .{});
49915006
4992 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
5007 const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
49935008 .Float => switch (ty.floatBits(self.target.*)) {
49945009 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
49955010 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },
......@@ -5016,10 +5031,10 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
50165031 else => null,
50175032 },
50185033 else => unreachable,
5019 })) |tag| tag else return self.fail("TODO implement genRound for {}", .{
5034 }) orelse return self.fail("TODO implement genRound for {}", .{
50205035 ty.fmt(self.bin_file.options.module.?),
50215036 });
5022 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
5037 const abi_size: u32 = @intCast(ty.abiSize(mod));
50235038 const dst_alias = registerAlias(dst_reg, abi_size);
50245039 switch (mir_tag[0]) {
50255040 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
......@@ -5059,7 +5074,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
50595074 const mod = self.bin_file.options.module.?;
50605075 const un_op = self.air.instructions.items(.data)[inst].un_op;
50615076 const ty = self.typeOf(un_op);
5062 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
5077 const abi_size: u32 = @intCast(ty.abiSize(mod));
50635078
50645079 const src_mcv = try self.resolveInst(un_op);
50655080 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
......@@ -5071,7 +5086,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
50715086 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
50725087
50735088 const result: MCValue = result: {
5074 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
5089 const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
50755090 .Float => switch (ty.floatBits(self.target.*)) {
50765091 16 => if (self.hasFeature(.f16c)) {
50775092 const mat_src_reg = if (src_mcv.isRegister())
......@@ -5125,7 +5140,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
51255140 .{ .v_ps, .cvtph2 },
51265141 wide_reg,
51275142 src_mcv.mem(Memory.PtrSize.fromSize(
5128 @as(u32, @intCast(@divExact(wide_reg.bitSize(), 16))),
5143 @intCast(@divExact(wide_reg.bitSize(), 16)),
51295144 )),
51305145 ) else try self.asmRegisterRegister(
51315146 .{ .v_ps, .cvtph2 },
......@@ -5164,7 +5179,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
51645179 else => unreachable,
51655180 },
51665181 else => unreachable,
5167 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{
5182 }) orelse return self.fail("TODO implement airSqrt for {}", .{
51685183 ty.fmt(mod),
51695184 });
51705185 switch (mir_tag[0]) {
......@@ -5257,10 +5272,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
52575272 const ptr_info = ptr_ty.ptrInfo(mod);
52585273
52595274 const val_ty = ptr_info.child.toType();
5260 const val_abi_size = @as(u32, @intCast(val_ty.abiSize(mod)));
5275 const val_abi_size: u32 = @intCast(val_ty.abiSize(mod));
52615276 const limb_abi_size: u32 = @min(val_abi_size, 8);
52625277 const limb_abi_bits = limb_abi_size * 8;
5263 const val_byte_off = @as(i32, @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size));
5278 const val_byte_off: i32 = @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size);
52645279 const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
52655280 const val_extra_bits = self.regExtraBits(val_ty);
52665281
......@@ -5404,9 +5419,10 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
54045419
54055420 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);
54065421 const limb_abi_bits = limb_abi_size * 8;
5422 const limb_ty = try mod.intType(.unsigned, limb_abi_bits);
54075423
54085424 const src_bit_size = src_ty.bitSize(mod);
5409 const src_byte_off = @as(i32, @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size));
5425 const src_byte_off: i32 = @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size);
54105426 const src_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
54115427
54125428 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
......@@ -5423,10 +5439,9 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
54235439 .disp = src_byte_off + limb_i * limb_abi_bits,
54245440 });
54255441
5426 const part_mask = (@as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - part_bit_size))) <<
5427 @as(u6, @intCast(part_bit_off));
5428 const part_mask_not = part_mask ^
5429 (@as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - limb_abi_bits)));
5442 const part_mask = (@as(u64, math.maxInt(u64)) >> @intCast(64 - part_bit_size)) <<
5443 @intCast(part_bit_off);
5444 const part_mask_not = part_mask ^ (@as(u64, math.maxInt(u64)) >> @intCast(64 - limb_abi_bits));
54305445 if (limb_abi_size <= 4) {
54315446 try self.asmMemoryImmediate(.{ ._, .@"and" }, limb_mem, Immediate.u(part_mask_not));
54325447 } else if (math.cast(i32, @as(i64, @bitCast(part_mask_not)))) |small| {
......@@ -5443,23 +5458,23 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
54435458 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
54445459 defer self.register_manager.unlockReg(tmp_lock);
54455460
5446 try self.genSetReg(tmp_reg, src_ty, src_mcv);
5461 try self.genSetReg(tmp_reg, limb_ty, src_mcv);
54475462 switch (limb_i) {
54485463 0 => try self.genShiftBinOpMir(
54495464 .{ ._l, .sh },
5450 src_ty,
5465 limb_ty,
54515466 tmp_mcv,
54525467 .{ .immediate = src_bit_off },
54535468 ),
54545469 1 => try self.genShiftBinOpMir(
54555470 .{ ._r, .sh },
5456 src_ty,
5471 limb_ty,
54575472 tmp_mcv,
54585473 .{ .immediate = limb_abi_bits - src_bit_off },
54595474 ),
54605475 else => unreachable,
54615476 }
5462 try self.genBinOpMir(.{ ._, .@"and" }, src_ty, tmp_mcv, .{ .immediate = part_mask });
5477 try self.genBinOpMir(.{ ._, .@"and" }, limb_ty, tmp_mcv, .{ .immediate = part_mask });
54635478 try self.asmMemoryRegister(
54645479 .{ ._, .@"or" },
54655480 limb_mem,
......@@ -5544,14 +5559,14 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
55445559 const ptr_field_ty = self.typeOfIndex(inst);
55455560 const ptr_container_ty = self.typeOf(operand);
55465561 const container_ty = ptr_container_ty.childType(mod);
5547 const field_offset = @as(i32, @intCast(switch (container_ty.containerLayout(mod)) {
5562 const field_offset: i32 = @intCast(switch (container_ty.containerLayout(mod)) {
55485563 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
55495564 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and
55505565 ptr_field_ty.ptrInfo(mod).packed_offset.host_size == 0)
55515566 container_ty.packedStructFieldByteOffset(index, mod)
55525567 else
55535568 0,
5554 }));
5569 });
55555570
55565571 const src_mcv = try self.resolveInst(operand);
55575572 const dst_mcv = if (switch (src_mcv) {
......@@ -5578,8 +5593,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
55785593 const field_is_gp = field_rc.supersetOf(gp);
55795594
55805595 const src_mcv = try self.resolveInst(operand);
5581 const field_off = switch (container_ty.containerLayout(mod)) {
5582 .Auto, .Extern => @as(u32, @intCast(container_ty.structFieldOffset(index, mod) * 8)),
5596 const field_off: u32 = switch (container_ty.containerLayout(mod)) {
5597 .Auto, .Extern => @intCast(container_ty.structFieldOffset(index, mod) * 8),
55835598 .Packed => if (mod.typeToStruct(container_ty)) |struct_obj|
55845599 struct_obj.packedFieldBitOffset(mod, index)
55855600 else
......@@ -5588,9 +5603,31 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
55885603
55895604 switch (src_mcv) {
55905605 .load_frame => |frame_addr| {
5606 const field_abi_size: u32 = @intCast(field_ty.abiSize(mod));
55915607 if (field_off % 8 == 0) {
55925608 const off_mcv =
5593 src_mcv.address().offset(@as(i32, @intCast(@divExact(field_off, 8)))).deref();
5609 src_mcv.address().offset(@intCast(@divExact(field_off, 8))).deref();
5610
5611 if (field_abi_size <= 8) {
5612 const int_ty = try mod.intType(
5613 if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned,
5614 @intCast(field_ty.bitSize(mod)),
5615 );
5616
5617 const dst_reg =
5618 try self.register_manager.allocReg(if (field_is_gp) inst else null, gp);
5619 const dst_mcv = MCValue{ .register = dst_reg };
5620 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
5621 defer self.register_manager.unlockReg(dst_lock);
5622
5623 try self.genCopy(int_ty, dst_mcv, off_mcv);
5624 if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(int_ty, dst_reg);
5625 break :result if (field_is_gp)
5626 dst_mcv
5627 else
5628 try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv);
5629 }
5630
55945631 if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result off_mcv;
55955632
55965633 const dst_mcv = try self.allocRegOrMem(inst, true);
......@@ -5598,10 +5635,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
55985635 break :result dst_mcv;
55995636 }
56005637
5601 const field_abi_size = @as(u32, @intCast(field_ty.abiSize(mod)));
56025638 const limb_abi_size: u32 = @min(field_abi_size, 8);
56035639 const limb_abi_bits = limb_abi_size * 8;
5604 const field_byte_off = @as(i32, @intCast(field_off / limb_abi_bits * limb_abi_size));
5640 const field_byte_off: i32 = @intCast(field_off / limb_abi_bits * limb_abi_size);
56055641 const field_bit_off = field_off % limb_abi_bits;
56065642
56075643 if (field_abi_size > 8) {
......@@ -5726,7 +5762,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
57265762
57275763 const inst_ty = self.typeOfIndex(inst);
57285764 const parent_ty = inst_ty.childType(mod);
5729 const field_offset = @as(i32, @intCast(parent_ty.structFieldOffset(extra.field_index, mod)));
5765 const field_offset: i32 = @intCast(parent_ty.structFieldOffset(extra.field_index, mod));
57305766
57315767 const src_mcv = try self.resolveInst(extra.field_ptr);
57325768 const dst_mcv = if (src_mcv.isRegisterOffset() and
......@@ -5775,14 +5811,14 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
57755811
57765812 switch (tag) {
57775813 .not => {
5778 const limb_abi_size = @as(u16, @intCast(@min(src_ty.abiSize(mod), 8)));
5814 const limb_abi_size: u16 = @intCast(@min(src_ty.abiSize(mod), 8));
57795815 const int_info = if (src_ty.ip_index == .bool_type)
57805816 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }
57815817 else
57825818 src_ty.intInfo(mod);
57835819 var byte_off: i32 = 0;
57845820 while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) {
5785 const limb_bits = @as(u16, @intCast(@min(int_info.bits - byte_off * 8, limb_abi_size * 8)));
5821 const limb_bits: u16 = @intCast(@min(int_info.bits - byte_off * 8, limb_abi_size * 8));
57865822 const limb_ty = try mod.intType(int_info.signedness, limb_bits);
57875823 const limb_mcv = switch (byte_off) {
57885824 0 => dst_mcv,
......@@ -5790,7 +5826,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
57905826 };
57915827
57925828 if (int_info.signedness == .unsigned and self.regExtraBits(limb_ty) > 0) {
5793 const mask = @as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - limb_bits));
5829 const mask = @as(u64, math.maxInt(u64)) >> @intCast(64 - limb_bits);
57945830 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });
57955831 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);
57965832 }
......@@ -5803,7 +5839,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
58035839
58045840fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
58055841 const mod = self.bin_file.options.module.?;
5806 const abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
5842 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));
58075843 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{
58085844 mir_tag,
58095845 dst_ty.fmt(self.bin_file.options.module.?),
......@@ -5865,7 +5901,7 @@ fn genShiftBinOpMir(
58655901 break :rhs .{ .register = .rcx };
58665902 };
58675903
5868 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
5904 const abi_size: u32 = @intCast(ty.abiSize(mod));
58695905 if (abi_size <= 8) {
58705906 switch (lhs_mcv) {
58715907 .register => |lhs_reg| switch (rhs_mcv) {
......@@ -6085,16 +6121,16 @@ fn genShiftBinOp(
60856121 rhs_ty: Type,
60866122) !MCValue {
60876123 const mod = self.bin_file.options.module.?;
6088 if (lhs_ty.zigTypeTag(mod) == .Vector) {
6089 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
6090 }
6124 if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{
6125 lhs_ty.fmt(mod),
6126 });
60916127
60926128 assert(rhs_ty.abiSize(mod) == 1);
60936129
60946130 const lhs_abi_size = lhs_ty.abiSize(mod);
6095 if (lhs_abi_size > 16) {
6096 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
6097 }
6131 if (lhs_abi_size > 16) return self.fail("TODO implement genShiftBinOp for {}", .{
6132 lhs_ty.fmt(mod),
6133 });
60986134
60996135 try self.register_manager.getReg(.rcx, null);
61006136 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);
......@@ -6150,11 +6186,12 @@ fn genMulDivBinOp(
61506186 rhs: MCValue,
61516187) !MCValue {
61526188 const mod = self.bin_file.options.module.?;
6153 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) {
6154 return self.fail("TODO implement genMulDivBinOp for {}", .{dst_ty.fmtDebug()});
6155 }
6156 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
6157 const src_abi_size = @as(u32, @intCast(src_ty.abiSize(mod)));
6189 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail(
6190 "TODO implement genMulDivBinOp for {}",
6191 .{dst_ty.fmt(mod)},
6192 );
6193 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
6194 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));
61586195 if (switch (tag) {
61596196 else => unreachable,
61606197 .mul, .mul_wrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,
......@@ -6328,7 +6365,13 @@ fn genBinOp(
63286365 const mod = self.bin_file.options.module.?;
63296366 const lhs_ty = self.typeOf(lhs_air);
63306367 const rhs_ty = self.typeOf(rhs_air);
6331 const abi_size = @as(u32, @intCast(lhs_ty.abiSize(mod)));
6368 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));
6369 if ((lhs_ty.scalarType(mod).isRuntimeFloat() and
6370 lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or
6371 lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16))
6372 return self.fail("TODO implement genBinOp for {s} {}", .{
6373 @tagName(air_tag), lhs_ty.fmt(mod),
6374 });
63326375
63336376 const maybe_mask_reg = switch (air_tag) {
63346377 else => null,
......@@ -6339,6 +6382,9 @@ fn genBinOp(
63396382 } else try self.register_manager.allocReg(null, sse),
63406383 abi_size,
63416384 ) else null,
6385 .rem, .mod => return self.fail("TODO implement genBinOp for {s} {}", .{
6386 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6387 }),
63426388 };
63436389 const mask_lock =
63446390 if (maybe_mask_reg) |mask_reg| self.register_manager.lockRegAssumeUnused(mask_reg) else null;
......@@ -6543,7 +6589,7 @@ fn genBinOp(
65436589 Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), switch (mat_src_mcv) {
65446590 .memory => |addr| .{
65456591 .base = .{ .reg = .ds },
6546 .disp = @as(i32, @intCast(@as(i64, @bitCast(addr)))),
6592 .disp = @intCast(@as(i64, @bitCast(addr))),
65476593 },
65486594 .indirect => |reg_off| .{
65496595 .base = .{ .reg = reg_off.reg },
......@@ -6569,7 +6615,7 @@ fn genBinOp(
65696615 }
65706616
65716617 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);
6572 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
6618 const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
65736619 else => unreachable,
65746620 .Float => switch (lhs_ty.floatBits(self.target.*)) {
65756621 16 => if (self.hasFeature(.f16c)) {
......@@ -7131,7 +7177,7 @@ fn genBinOp(
71317177 else => unreachable,
71327178 },
71337179 },
7134 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7180 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
71357181 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
71367182 });
71377183
......@@ -7194,7 +7240,7 @@ fn genBinOp(
71947240 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
71957241
71967242 try self.asmRegisterRegisterRegisterImmediate(
7197 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7243 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
71987244 .Float => switch (lhs_ty.floatBits(self.target.*)) {
71997245 32 => .{ .v_ss, .cmp },
72007246 64 => .{ .v_sd, .cmp },
......@@ -7219,7 +7265,7 @@ fn genBinOp(
72197265 else => unreachable,
72207266 },
72217267 else => unreachable,
7222 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7268 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
72237269 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
72247270 }),
72257271 mask_reg,
......@@ -7228,7 +7274,7 @@ fn genBinOp(
72287274 Immediate.u(3), // unord
72297275 );
72307276 try self.asmRegisterRegisterRegisterRegister(
7231 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7277 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
72327278 .Float => switch (lhs_ty.floatBits(self.target.*)) {
72337279 32 => .{ .v_ps, .blendv },
72347280 64 => .{ .v_pd, .blendv },
......@@ -7251,7 +7297,7 @@ fn genBinOp(
72517297 else => unreachable,
72527298 },
72537299 else => unreachable,
7254 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7300 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
72557301 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
72567302 }),
72577303 dst_reg,
......@@ -7262,7 +7308,7 @@ fn genBinOp(
72627308 } else {
72637309 const has_blend = self.hasFeature(.sse4_1);
72647310 try self.asmRegisterRegisterImmediate(
7265 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7311 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
72667312 .Float => switch (lhs_ty.floatBits(self.target.*)) {
72677313 32 => .{ ._ss, .cmp },
72687314 64 => .{ ._sd, .cmp },
......@@ -7287,7 +7333,7 @@ fn genBinOp(
72877333 else => unreachable,
72887334 },
72897335 else => unreachable,
7290 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7336 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
72917337 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
72927338 }),
72937339 mask_reg,
......@@ -7295,7 +7341,7 @@ fn genBinOp(
72957341 Immediate.u(if (has_blend) 3 else 7), // unord, ord
72967342 );
72977343 if (has_blend) try self.asmRegisterRegisterRegister(
7298 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7344 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
72997345 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73007346 32 => .{ ._ps, .blendv },
73017347 64 => .{ ._pd, .blendv },
......@@ -7318,7 +7364,7 @@ fn genBinOp(
73187364 else => unreachable,
73197365 },
73207366 else => unreachable,
7321 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7367 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
73227368 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
73237369 }),
73247370 dst_reg,
......@@ -7326,7 +7372,7 @@ fn genBinOp(
73267372 mask_reg,
73277373 ) else {
73287374 try self.asmRegisterRegister(
7329 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7375 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
73307376 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73317377 32 => .{ ._ps, .@"and" },
73327378 64 => .{ ._pd, .@"and" },
......@@ -7349,14 +7395,14 @@ fn genBinOp(
73497395 else => unreachable,
73507396 },
73517397 else => unreachable,
7352 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7398 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
73537399 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
73547400 }),
73557401 dst_reg,
73567402 mask_reg,
73577403 );
73587404 try self.asmRegisterRegister(
7359 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7405 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
73607406 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73617407 32 => .{ ._ps, .andn },
73627408 64 => .{ ._pd, .andn },
......@@ -7379,14 +7425,14 @@ fn genBinOp(
73797425 else => unreachable,
73807426 },
73817427 else => unreachable,
7382 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7428 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
73837429 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
73847430 }),
73857431 mask_reg,
73867432 lhs_copy_reg.?,
73877433 );
73887434 try self.asmRegisterRegister(
7389 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7435 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
73907436 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73917437 32 => .{ ._ps, .@"or" },
73927438 64 => .{ ._pd, .@"or" },
......@@ -7409,7 +7455,7 @@ fn genBinOp(
74097455 else => unreachable,
74107456 },
74117457 else => unreachable,
7412 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
7458 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
74137459 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
74147460 }),
74157461 dst_reg,
......@@ -7431,7 +7477,7 @@ fn genBinOpMir(
74317477 src_mcv: MCValue,
74327478) !void {
74337479 const mod = self.bin_file.options.module.?;
7434 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
7480 const abi_size: u32 = @intCast(ty.abiSize(mod));
74357481 switch (dst_mcv) {
74367482 .none,
74377483 .unreach,
......@@ -7679,10 +7725,10 @@ fn genBinOpMir(
76797725 else => unreachable,
76807726 },
76817727 .immediate => |src_imm| {
7682 const imm = switch (off) {
7728 const imm: u64 = switch (off) {
76837729 0 => src_imm,
76847730 else => switch (ty_signedness) {
7685 .signed => @as(u64, @bitCast(@as(i64, @bitCast(src_imm)) >> 63)),
7731 .signed => @bitCast(@as(i64, @bitCast(src_imm)) >> 63),
76867732 .unsigned => 0,
76877733 },
76887734 };
......@@ -7755,7 +7801,7 @@ fn genBinOpMir(
77557801 0 => src_mcv,
77567802 else => .{ .immediate = 0 },
77577803 },
7758 .memory => |addr| .{ .memory = @as(u64, @bitCast(@as(i64, @bitCast(addr)) + off)) },
7804 .memory => |addr| .{ .memory = @bitCast(@as(i64, @bitCast(addr)) + off) },
77597805 .indirect => |reg_off| .{ .indirect = .{
77607806 .reg = reg_off.reg,
77617807 .off = reg_off.off + off,
......@@ -7782,7 +7828,7 @@ fn genBinOpMir(
77827828/// Does not support byte-size operands.
77837829fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
77847830 const mod = self.bin_file.options.module.?;
7785 const abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));
7831 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));
77867832 switch (dst_mcv) {
77877833 .none,
77887834 .unreach,
......@@ -8016,7 +8062,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
80168062 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
80178063 const callee = pl_op.operand;
80188064 const extra = self.air.extraData(Air.Call, pl_op.payload);
8019 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
8065 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
80208066 const ty = self.typeOf(callee);
80218067
80228068 const fn_ty = switch (ty.zigTypeTag(mod)) {
......@@ -8109,7 +8155,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81098155 const got_addr = atom.getOffsetTableAddress(elf_file);
81108156 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
81118157 .base = .{ .reg = .ds },
8112 .disp = @as(i32, @intCast(got_addr)),
8158 .disp = @intCast(got_addr),
81138159 }));
81148160 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
81158161 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);
......@@ -8126,7 +8172,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81268172 const atom = p9.getAtom(atom_index);
81278173 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
81288174 .base = .{ .reg = .ds },
8129 .disp = @as(i32, @intCast(atom.getOffsetTableAddress(p9))),
8175 .disp = @intCast(atom.getOffsetTableAddress(p9)),
81308176 }));
81318177 } else unreachable;
81328178 } else if (func_value.getExternFunc(mod)) |extern_func| {
......@@ -8246,7 +8292,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
82468292 const result = MCValue{
82478293 .eflags = switch (ty.zigTypeTag(mod)) {
82488294 else => result: {
8249 const abi_size = @as(u16, @intCast(ty.abiSize(mod)));
8295 const abi_size: u16 = @intCast(ty.abiSize(mod));
82508296 const may_flip: enum {
82518297 may_flip,
82528298 must_flip,
......@@ -8443,7 +8489,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
84438489 self.eflags_inst = inst;
84448490
84458491 const op_ty = self.typeOf(un_op);
8446 const op_abi_size = @as(u32, @intCast(op_ty.abiSize(mod)));
8492 const op_abi_size: u32 = @intCast(op_ty.abiSize(mod));
84478493 const op_mcv = try self.resolveInst(un_op);
84488494 const dst_reg = switch (op_mcv) {
84498495 .register => |reg| reg,
......@@ -8652,7 +8698,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86528698 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
86538699 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
86548700 else
8655 .{ .off = @as(i32, @intCast(pl_ty.abiSize(mod))), .ty = Type.bool };
8701 .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool };
86568702
86578703 switch (opt_mcv) {
86588704 .none,
......@@ -8672,14 +8718,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86728718
86738719 .register => |opt_reg| {
86748720 if (some_info.off == 0) {
8675 const some_abi_size = @as(u32, @intCast(some_info.ty.abiSize(mod)));
8721 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));
86768722 const alias_reg = registerAlias(opt_reg, some_abi_size);
86778723 assert(some_abi_size * 8 == alias_reg.bitSize());
86788724 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);
86798725 return .{ .eflags = .z };
86808726 }
86818727 assert(some_info.ty.ip_index == .bool_type);
8682 const opt_abi_size = @as(u32, @intCast(opt_ty.abiSize(mod)));
8728 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(mod));
86838729 try self.asmRegisterImmediate(
86848730 .{ ._, .bt },
86858731 registerAlias(opt_reg, opt_abi_size),
......@@ -8698,7 +8744,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86988744 defer self.register_manager.unlockReg(addr_reg_lock);
86998745
87008746 try self.genSetReg(addr_reg, Type.usize, opt_mcv.address());
8701 const some_abi_size = @as(u32, @intCast(some_info.ty.abiSize(mod)));
8747 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));
87028748 try self.asmMemoryImmediate(
87038749 .{ ._, .cmp },
87048750 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{
......@@ -8711,7 +8757,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
87118757 },
87128758
87138759 .indirect, .load_frame => {
8714 const some_abi_size = @as(u32, @intCast(some_info.ty.abiSize(mod)));
8760 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));
87158761 try self.asmMemoryImmediate(
87168762 .{ ._, .cmp },
87178763 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), switch (opt_mcv) {
......@@ -8743,7 +8789,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87438789 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
87448790 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
87458791 else
8746 .{ .off = @as(i32, @intCast(pl_ty.abiSize(mod))), .ty = Type.bool };
8792 .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool };
87478793
87488794 const ptr_reg = switch (ptr_mcv) {
87498795 .register => |reg| reg,
......@@ -8752,7 +8798,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87528798 const ptr_lock = self.register_manager.lockReg(ptr_reg);
87538799 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
87548800
8755 const some_abi_size = @as(u32, @intCast(some_info.ty.abiSize(mod)));
8801 const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod));
87568802 try self.asmMemoryImmediate(
87578803 .{ ._, .cmp },
87588804 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{
......@@ -8785,12 +8831,11 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
87858831
87868832 const tmp_reg = try self.copyToTmpRegister(ty, operand);
87878833 if (err_off > 0) {
8788 const shift = @as(u6, @intCast(err_off * 8));
87898834 try self.genShiftBinOpMir(
87908835 .{ ._r, .sh },
87918836 ty,
87928837 .{ .register = tmp_reg },
8793 .{ .immediate = shift },
8838 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
87948839 );
87958840 } else {
87968841 try self.truncateRegister(Type.anyerror, tmp_reg);
......@@ -8945,7 +8990,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
89458990 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
89468991 const loop = self.air.extraData(Air.Block, ty_pl.payload);
89478992 const body = self.air.extra[loop.end..][0..loop.data.body_len];
8948 const jmp_target = @as(u32, @intCast(self.mir_instructions.len));
8993 const jmp_target: u32 = @intCast(self.mir_instructions.len);
89498994
89508995 self.scope_generation += 1;
89518996 const state = try self.saveState();
......@@ -9017,10 +9062,8 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
90179062
90189063 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
90199064 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
9020 const items = @as(
9021 []const Air.Inst.Ref,
9022 @ptrCast(self.air.extra[case.end..][0..case.data.items_len]),
9023 );
9065 const items: []const Air.Inst.Ref =
9066 @ptrCast(self.air.extra[case.end..][0..case.data.items_len]);
90249067 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
90259068 extra_index = case.end + items.len + case_body.len;
90269069
......@@ -9068,7 +9111,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
90689111}
90699112
90709113fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
9071 const next_inst = @as(u32, @intCast(self.mir_instructions.len));
9114 const next_inst: u32 = @intCast(self.mir_instructions.len);
90729115 switch (self.mir_instructions.items(.tag)[reloc]) {
90739116 .j, .jmp => {},
90749117 .pseudo => switch (self.mir_instructions.items(.ops)[reloc]) {
......@@ -9143,11 +9186,12 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
91439186fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
91449187 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
91459188 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
9146 const clobbers_len = @as(u31, @truncate(extra.data.flags));
9189 const clobbers_len: u31 = @truncate(extra.data.flags);
91479190 var extra_i: usize = extra.end;
9148 const outputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]));
9191 const outputs: []const Air.Inst.Ref =
9192 @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]);
91499193 extra_i += outputs.len;
9150 const inputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]));
9194 const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]);
91519195 extra_i += inputs.len;
91529196
91539197 var result: MCValue = .none;
......@@ -9282,16 +9326,14 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
92829326 } else if (mem.startsWith(u8, op_str, "$")) {
92839327 if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| {
92849328 if (mnem_size) |size| {
9285 const max = @as(u64, math.maxInt(u64)) >>
9286 @as(u6, @intCast(64 - (size.bitSize() - 1)));
9329 const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - (size.bitSize() - 1));
92879330 if ((if (s < 0) ~s else s) > max)
92889331 return self.fail("Invalid immediate size: '{s}'", .{op_str});
92899332 }
92909333 op.* = .{ .imm = Immediate.s(s) };
92919334 } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| {
92929335 if (mnem_size) |size| {
9293 const max = @as(u64, math.maxInt(u64)) >>
9294 @as(u6, @intCast(64 - size.bitSize()));
9336 const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - size.bitSize());
92959337 if (u > max)
92969338 return self.fail("Invalid immediate size: '{s}'", .{op_str});
92979339 }
......@@ -9643,7 +9685,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
96439685
96449686fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void {
96459687 const mod = self.bin_file.options.module.?;
9646 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
9688 const abi_size: u32 = @intCast(ty.abiSize(mod));
96479689 if (abi_size * 8 > dst_reg.bitSize())
96489690 return self.fail("genSetReg called with a value larger than dst_reg", .{});
96499691 switch (src_mcv) {
......@@ -9668,7 +9710,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
96689710 try self.asmRegisterImmediate(
96699711 .{ ._, .mov },
96709712 registerAlias(dst_reg, abi_size),
9671 Immediate.s(@as(i32, @intCast(@as(i64, @bitCast(imm))))),
9713 Immediate.s(@intCast(@as(i64, @bitCast(imm)))),
96729714 );
96739715 } else {
96749716 try self.asmRegisterImmediate(
......@@ -9726,7 +9768,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
97269768 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
97279769 ),
97289770 .sse => try self.asmRegisterRegister(
9729 if (@as(?Mir.Inst.FixedTag, switch (ty.scalarType(mod).zigTypeTag(mod)) {
9771 @as(?Mir.Inst.FixedTag, switch (ty.scalarType(mod).zigTypeTag(mod)) {
97309772 else => switch (abi_size) {
97319773 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
97329774 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },
......@@ -9750,7 +9792,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
97509792 80 => null,
97519793 else => unreachable,
97529794 },
9753 })) |tag| tag else return self.fail("TODO implement genSetReg for {}", .{
9795 }) orelse return self.fail("TODO implement genSetReg for {}", .{
97549796 ty.fmt(self.bin_file.options.module.?),
97559797 }),
97569798 registerAlias(dst_reg, abi_size),
......@@ -9930,9 +9972,9 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
99309972
99319973fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void {
99329974 const mod = self.bin_file.options.module.?;
9933 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
9975 const abi_size: u32 = @intCast(ty.abiSize(mod));
99349976 const dst_ptr_mcv: MCValue = switch (base) {
9935 .none => .{ .immediate = @as(u64, @bitCast(@as(i64, disp))) },
9977 .none => .{ .immediate = @bitCast(@as(i64, disp)) },
99369978 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },
99379979 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },
99389980 };
......@@ -9943,7 +9985,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
99439985 .immediate => |imm| switch (abi_size) {
99449986 1, 2, 4 => {
99459987 const immediate = if (ty.isSignedInt(mod))
9946 Immediate.s(@as(i32, @truncate(@as(i64, @bitCast(imm)))))
9988 Immediate.s(@truncate(@as(i64, @bitCast(imm))))
99479989 else
99489990 Immediate.u(@as(u32, @intCast(imm)));
99499991 try self.asmMemoryImmediate(
......@@ -9965,10 +10007,9 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
996510007 .{ ._, .mov },
996610008 Memory.sib(.dword, .{ .base = base, .disp = disp + offset }),
996710009 if (ty.isSignedInt(mod))
9968 Immediate.s(@as(
9969 i32,
10010 Immediate.s(
997010011 @truncate(@as(i64, @bitCast(imm)) >> (math.cast(u6, offset * 8) orelse 63)),
9971 ))
10012 )
997210013 else
997310014 Immediate.u(@as(
997410015 u32,
......@@ -10079,7 +10120,7 @@ fn genLazySymbolRef(
1007910120 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
1008010121 const got_addr = atom.getOffsetTableAddress(elf_file);
1008110122 const got_mem =
10082 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @as(i32, @intCast(got_addr)) });
10123 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(got_addr) });
1008310124 switch (tag) {
1008410125 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),
1008510126 .call => try self.asmMemory(.{ ._, .call }, got_mem),
......@@ -10101,7 +10142,7 @@ fn genLazySymbolRef(
1010110142 _ = atom.getOrCreateOffsetTableEntry(p9_file);
1010210143 const got_addr = atom.getOffsetTableAddress(p9_file);
1010310144 const got_mem =
10104 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @as(i32, @intCast(got_addr)) });
10145 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(got_addr) });
1010510146 switch (tag) {
1010610147 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),
1010710148 .call => try self.asmMemory(.{ ._, .call }, got_mem),
......@@ -10197,8 +10238,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1019710238 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
1019810239 if (dst_signedness == src_signedness) break :result dst_mcv;
1019910240
10200 const abi_size = @as(u16, @intCast(dst_ty.abiSize(mod)));
10201 const bit_size = @as(u16, @intCast(dst_ty.bitSize(mod)));
10241 const abi_size: u16 = @intCast(dst_ty.abiSize(mod));
10242 const bit_size: u16 = @intCast(dst_ty.bitSize(mod));
1020210243 if (abi_size * 8 <= bit_size) break :result dst_mcv;
1020310244
1020410245 const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable;
......@@ -10239,7 +10280,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
1023910280 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
1024010281 try self.genSetMem(
1024110282 .{ .frame = frame_index },
10242 @as(i32, @intCast(ptr_ty.abiSize(mod))),
10283 @intCast(ptr_ty.abiSize(mod)),
1024310284 Type.usize,
1024410285 .{ .immediate = array_len },
1024510286 );
......@@ -10253,7 +10294,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
1025310294 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1025410295
1025510296 const src_ty = self.typeOf(ty_op.operand);
10256 const src_bits = @as(u32, @intCast(src_ty.bitSize(mod)));
10297 const src_bits: u32 = @intCast(src_ty.bitSize(mod));
1025710298 const src_signedness =
1025810299 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
1025910300 const dst_ty = self.typeOfIndex(inst);
......@@ -10281,7 +10322,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
1028110322 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
1028210323 defer self.register_manager.unlockReg(dst_lock);
1028310324
10284 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(mod)) {
10325 const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(mod)) {
1028510326 .Float => switch (dst_ty.floatBits(self.target.*)) {
1028610327 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },
1028710328 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },
......@@ -10289,7 +10330,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
1028910330 else => unreachable,
1029010331 },
1029110332 else => null,
10292 })) |tag| tag else return self.fail("TODO implement airFloatFromInt from {} to {}", .{
10333 }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{
1029310334 src_ty.fmt(mod), dst_ty.fmt(mod),
1029410335 });
1029510336 const dst_alias = dst_reg.to128();
......@@ -10308,7 +10349,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
1030810349
1030910350 const src_ty = self.typeOf(ty_op.operand);
1031010351 const dst_ty = self.typeOfIndex(inst);
10311 const dst_bits = @as(u32, @intCast(dst_ty.bitSize(mod)));
10352 const dst_bits: u32 = @intCast(dst_ty.bitSize(mod));
1031210353 const dst_signedness =
1031310354 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;
1031410355
......@@ -10334,7 +10375,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
1033410375 defer self.register_manager.unlockReg(dst_lock);
1033510376
1033610377 try self.asmRegisterRegister(
10337 if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) {
10378 @as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) {
1033810379 .Float => switch (src_ty.floatBits(self.target.*)) {
1033910380 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },
1034010381 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },
......@@ -10342,7 +10383,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
1034210383 else => unreachable,
1034310384 },
1034410385 else => null,
10345 })) |tag| tag else return self.fail("TODO implement airIntFromFloat from {} to {}", .{
10386 }) orelse return self.fail("TODO implement airIntFromFloat from {} to {}", .{
1034610387 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
1034710388 }),
1034810389 registerAlias(dst_reg, dst_size),
......@@ -10361,7 +10402,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
1036110402
1036210403 const ptr_ty = self.typeOf(extra.ptr);
1036310404 const val_ty = self.typeOf(extra.expected_value);
10364 const val_abi_size = @as(u32, @intCast(val_ty.abiSize(mod)));
10405 const val_abi_size: u32 = @intCast(val_ty.abiSize(mod));
1036510406
1036610407 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
1036710408 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
......@@ -10463,7 +10504,7 @@ fn atomicOp(
1046310504 };
1046410505 defer if (val_lock) |lock| self.register_manager.unlockReg(lock);
1046510506
10466 const val_abi_size = @as(u32, @intCast(val_ty.abiSize(mod)));
10507 const val_abi_size: u32 = @intCast(val_ty.abiSize(mod));
1046710508 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);
1046810509 const ptr_mem = switch (ptr_mcv) {
1046910510 .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size),
......@@ -10541,7 +10582,7 @@ fn atomicOp(
1054110582 defer self.register_manager.unlockReg(tmp_lock);
1054210583
1054310584 try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(.rax, val_abi_size), ptr_mem);
10544 const loop = @as(u32, @intCast(self.mir_instructions.len));
10585 const loop: u32 = @intCast(self.mir_instructions.len);
1054510586 if (rmw_op != std.builtin.AtomicRmwOp.Xchg) {
1054610587 try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax });
1054710588 }
......@@ -10615,7 +10656,7 @@ fn atomicOp(
1061510656 .scale_index = ptr_mem.scaleIndex(),
1061610657 .disp = ptr_mem.sib.disp + 8,
1061710658 }));
10618 const loop = @as(u32, @intCast(self.mir_instructions.len));
10659 const loop: u32 = @intCast(self.mir_instructions.len);
1061910660 const val_mem_mcv: MCValue = switch (val_mcv) {
1062010661 .memory, .indirect, .load_frame => val_mcv,
1062110662 else => .{ .indirect = .{
......@@ -10771,7 +10812,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
1077110812 };
1077210813 defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock);
1077310814
10774 const elem_abi_size = @as(u31, @intCast(elem_ty.abiSize(mod)));
10815 const elem_abi_size: u31 = @intCast(elem_ty.abiSize(mod));
1077510816
1077610817 if (elem_abi_size == 1) {
1077710818 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) {
......@@ -11251,9 +11292,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
1125111292fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1125211293 const mod = self.bin_file.options.module.?;
1125311294 const result_ty = self.typeOfIndex(inst);
11254 const len = @as(usize, @intCast(result_ty.arrayLen(mod)));
11295 const len: usize = @intCast(result_ty.arrayLen(mod));
1125511296 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
11256 const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));
11297 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
1125711298 const result: MCValue = result: {
1125811299 switch (result_ty.zigTypeTag(mod)) {
1125911300 .Struct => {
......@@ -11270,17 +11311,17 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1127011311 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;
1127111312
1127211313 const elem_ty = result_ty.structFieldType(elem_i, mod);
11273 const elem_bit_size = @as(u32, @intCast(elem_ty.bitSize(mod)));
11314 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(mod));
1127411315 if (elem_bit_size > 64) {
1127511316 return self.fail(
1127611317 "TODO airAggregateInit implement packed structs with large fields",
1127711318 .{},
1127811319 );
1127911320 }
11280 const elem_abi_size = @as(u32, @intCast(elem_ty.abiSize(mod)));
11321 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod));
1128111322 const elem_abi_bits = elem_abi_size * 8;
1128211323 const elem_off = struct_obj.packedFieldBitOffset(mod, elem_i);
11283 const elem_byte_off = @as(i32, @intCast(elem_off / elem_abi_bits * elem_abi_size));
11324 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);
1128411325 const elem_bit_off = elem_off % elem_abi_bits;
1128511326 const elem_mcv = try self.resolveInst(elem);
1128611327 const mat_elem_mcv = switch (elem_mcv) {
......@@ -11342,7 +11383,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1134211383 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;
1134311384
1134411385 const elem_ty = result_ty.structFieldType(elem_i, mod);
11345 const elem_off = @as(i32, @intCast(result_ty.structFieldOffset(elem_i, mod)));
11386 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, mod));
1134611387 const elem_mcv = try self.resolveInst(elem);
1134711388 const mat_elem_mcv = switch (elem_mcv) {
1134811389 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
......@@ -11356,7 +11397,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1135611397 const frame_index =
1135711398 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));
1135811399 const elem_ty = result_ty.childType(mod);
11359 const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod)));
11400 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));
1136011401
1136111402 for (elements, 0..) |elem, elem_i| {
1136211403 const elem_mcv = try self.resolveInst(elem);
......@@ -11364,12 +11405,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1136411405 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
1136511406 else => elem_mcv,
1136611407 };
11367 const elem_off = @as(i32, @intCast(elem_size * elem_i));
11408 const elem_off: i32 = @intCast(elem_size * elem_i);
1136811409 try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv);
1136911410 }
1137011411 if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem(
1137111412 .{ .frame = frame_index },
11372 @as(i32, @intCast(elem_size * elements.len)),
11413 @intCast(elem_size * elements.len),
1137311414 elem_ty,
1137411415 try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }),
1137511416 );
......@@ -11417,16 +11458,16 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
1141711458 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
1141811459 const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);
1141911460 const tag_int = tag_int_val.toUnsignedInt(mod);
11420 const tag_off = if (layout.tag_align < layout.payload_align)
11421 @as(i32, @intCast(layout.payload_size))
11461 const tag_off: i32 = if (layout.tag_align < layout.payload_align)
11462 @intCast(layout.payload_size)
1142211463 else
1142311464 0;
1142411465 try self.genCopy(tag_ty, dst_mcv.address().offset(tag_off).deref(), .{ .immediate = tag_int });
1142511466
11426 const pl_off = if (layout.tag_align < layout.payload_align)
11467 const pl_off: i32 = if (layout.tag_align < layout.payload_align)
1142711468 0
1142811469 else
11429 @as(i32, @intCast(layout.tag_size));
11470 @intCast(layout.tag_size);
1143011471 try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv);
1143111472
1143211473 break :result dst_mcv;
......@@ -11456,7 +11497,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1145611497 var order = [1]u2{0} ** 3;
1145711498 var unused = std.StaticBitSet(3).initFull();
1145811499 for (ops, &mcvs, &locks, 0..) |op, *mcv, *lock, op_i| {
11459 const op_index = @as(u2, @intCast(op_i));
11500 const op_index: u2 = @intCast(op_i);
1146011501 mcv.* = try self.resolveInst(op);
1146111502 if (unused.isSet(0) and mcv.isRegister() and self.reuseOperand(inst, op, op_index, mcv.*)) {
1146211503 order[op_index] = 1;
......@@ -11480,99 +11521,97 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1148011521 lock.* = self.register_manager.lockRegAssumeUnused(reg);
1148111522 }
1148211523
11483 const mir_tag = if (@as(
11484 ?Mir.Inst.FixedTag,
11485 if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 }))
11486 switch (ty.zigTypeTag(mod)) {
11487 .Float => switch (ty.floatBits(self.target.*)) {
11488 32 => .{ .v_ss, .fmadd132 },
11489 64 => .{ .v_sd, .fmadd132 },
11490 16, 80, 128 => null,
11491 else => unreachable,
11492 },
11493 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11494 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11495 32 => switch (ty.vectorLen(mod)) {
11496 1 => .{ .v_ss, .fmadd132 },
11497 2...8 => .{ .v_ps, .fmadd132 },
11498 else => null,
11499 },
11500 64 => switch (ty.vectorLen(mod)) {
11501 1 => .{ .v_sd, .fmadd132 },
11502 2...4 => .{ .v_pd, .fmadd132 },
11503 else => null,
11504 },
11505 16, 80, 128 => null,
11506 else => unreachable,
11507 },
11508 else => unreachable,
11509 },
11524 const mir_tag = @as(?Mir.Inst.FixedTag, if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or
11525 mem.eql(u2, &order, &.{ 3, 1, 2 }))
11526 switch (ty.zigTypeTag(mod)) {
11527 .Float => switch (ty.floatBits(self.target.*)) {
11528 32 => .{ .v_ss, .fmadd132 },
11529 64 => .{ .v_sd, .fmadd132 },
11530 16, 80, 128 => null,
1151011531 else => unreachable,
11511 }
11512 else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 }))
11513 switch (ty.zigTypeTag(mod)) {
11514 .Float => switch (ty.floatBits(self.target.*)) {
11515 32 => .{ .v_ss, .fmadd213 },
11516 64 => .{ .v_sd, .fmadd213 },
11517 16, 80, 128 => null,
11518 else => unreachable,
11519 },
11520 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11521 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11522 32 => switch (ty.vectorLen(mod)) {
11523 1 => .{ .v_ss, .fmadd213 },
11524 2...8 => .{ .v_ps, .fmadd213 },
11525 else => null,
11526 },
11527 64 => switch (ty.vectorLen(mod)) {
11528 1 => .{ .v_sd, .fmadd213 },
11529 2...4 => .{ .v_pd, .fmadd213 },
11530 else => null,
11531 },
11532 16, 80, 128 => null,
11533 else => unreachable,
11532 },
11533 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11534 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11535 32 => switch (ty.vectorLen(mod)) {
11536 1 => .{ .v_ss, .fmadd132 },
11537 2...8 => .{ .v_ps, .fmadd132 },
11538 else => null,
11539 },
11540 64 => switch (ty.vectorLen(mod)) {
11541 1 => .{ .v_sd, .fmadd132 },
11542 2...4 => .{ .v_pd, .fmadd132 },
11543 else => null,
1153411544 },
11545 16, 80, 128 => null,
1153511546 else => unreachable,
1153611547 },
1153711548 else => unreachable,
11538 }
11539 else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 }))
11540 switch (ty.zigTypeTag(mod)) {
11541 .Float => switch (ty.floatBits(self.target.*)) {
11542 32 => .{ .v_ss, .fmadd231 },
11543 64 => .{ .v_sd, .fmadd231 },
11549 },
11550 else => unreachable,
11551 }
11552 else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 }))
11553 switch (ty.zigTypeTag(mod)) {
11554 .Float => switch (ty.floatBits(self.target.*)) {
11555 32 => .{ .v_ss, .fmadd213 },
11556 64 => .{ .v_sd, .fmadd213 },
11557 16, 80, 128 => null,
11558 else => unreachable,
11559 },
11560 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11561 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11562 32 => switch (ty.vectorLen(mod)) {
11563 1 => .{ .v_ss, .fmadd213 },
11564 2...8 => .{ .v_ps, .fmadd213 },
11565 else => null,
11566 },
11567 64 => switch (ty.vectorLen(mod)) {
11568 1 => .{ .v_sd, .fmadd213 },
11569 2...4 => .{ .v_pd, .fmadd213 },
11570 else => null,
11571 },
1154411572 16, 80, 128 => null,
1154511573 else => unreachable,
1154611574 },
11547 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11548 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11549 32 => switch (ty.vectorLen(mod)) {
11550 1 => .{ .v_ss, .fmadd231 },
11551 2...8 => .{ .v_ps, .fmadd231 },
11552 else => null,
11553 },
11554 64 => switch (ty.vectorLen(mod)) {
11555 1 => .{ .v_sd, .fmadd231 },
11556 2...4 => .{ .v_pd, .fmadd231 },
11557 else => null,
11558 },
11559 16, 80, 128 => null,
11560 else => unreachable,
11575 else => unreachable,
11576 },
11577 else => unreachable,
11578 }
11579 else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 }))
11580 switch (ty.zigTypeTag(mod)) {
11581 .Float => switch (ty.floatBits(self.target.*)) {
11582 32 => .{ .v_ss, .fmadd231 },
11583 64 => .{ .v_sd, .fmadd231 },
11584 16, 80, 128 => null,
11585 else => unreachable,
11586 },
11587 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11588 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11589 32 => switch (ty.vectorLen(mod)) {
11590 1 => .{ .v_ss, .fmadd231 },
11591 2...8 => .{ .v_ps, .fmadd231 },
11592 else => null,
1156111593 },
11594 64 => switch (ty.vectorLen(mod)) {
11595 1 => .{ .v_sd, .fmadd231 },
11596 2...4 => .{ .v_pd, .fmadd231 },
11597 else => null,
11598 },
11599 16, 80, 128 => null,
1156211600 else => unreachable,
1156311601 },
1156411602 else => unreachable,
11565 }
11566 else
11567 unreachable,
11568 )) |tag| tag else return self.fail("TODO implement airMulAdd for {}", .{
11603 },
11604 else => unreachable,
11605 }
11606 else
11607 unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{
1156911608 ty.fmt(self.bin_file.options.module.?),
1157011609 });
1157111610
1157211611 var mops: [3]MCValue = undefined;
1157311612 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;
1157411613
11575 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
11614 const abi_size: u32 = @intCast(ty.abiSize(mod));
1157611615 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
1157711616 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
1157811617 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
......@@ -11725,7 +11764,7 @@ fn resolveCallingConventionValues(
1172511764 switch (self.target.os.tag) {
1172611765 .windows => {
1172711766 // Align the stack to 16bytes before allocating shadow stack space (if any).
11728 result.stack_byte_count += @as(u31, @intCast(4 * Type.usize.abiSize(mod)));
11767 result.stack_byte_count += @intCast(4 * Type.usize.abiSize(mod));
1172911768 },
1173011769 else => {},
1173111770 }
......@@ -11748,7 +11787,7 @@ fn resolveCallingConventionValues(
1174811787 result.return_value = switch (classes[0]) {
1174911788 .integer => InstTracking.init(.{ .register = registerAlias(
1175011789 ret_reg,
11751 @as(u32, @intCast(ret_ty.abiSize(mod))),
11790 @intCast(ret_ty.abiSize(mod)),
1175211791 ) }),
1175311792 .float, .sse => InstTracking.init(.{ .register = .xmm0 }),
1175411793 .memory => ret: {
......@@ -11784,18 +11823,16 @@ fn resolveCallingConventionValues(
1178411823 },
1178511824 .float, .sse => switch (self.target.os.tag) {
1178611825 .windows => if (param_reg_i < 4) {
11787 arg.* = .{ .register = @as(
11788 Register,
11789 @enumFromInt(@intFromEnum(Register.xmm0) + param_reg_i),
11790 ) };
11826 arg.* = .{
11827 .register = @enumFromInt(@intFromEnum(Register.xmm0) + param_reg_i),
11828 };
1179111829 param_reg_i += 1;
1179211830 continue;
1179311831 },
1179411832 else => if (param_sse_reg_i < 8) {
11795 arg.* = .{ .register = @as(
11796 Register,
11797 @enumFromInt(@intFromEnum(Register.xmm0) + param_sse_reg_i),
11798 ) };
11833 arg.* = .{
11834 .register = @enumFromInt(@intFromEnum(Register.xmm0) + param_sse_reg_i),
11835 };
1179911836 param_sse_reg_i += 1;
1180011837 continue;
1180111838 },
......@@ -11806,8 +11843,8 @@ fn resolveCallingConventionValues(
1180611843 }),
1180711844 }
1180811845
11809 const param_size = @as(u31, @intCast(ty.abiSize(mod)));
11810 const param_align = @as(u31, @intCast(ty.abiAlignment(mod)));
11846 const param_size: u31 = @intCast(ty.abiSize(mod));
11847 const param_align: u31 = @intCast(ty.abiAlignment(mod));
1181111848 result.stack_byte_count =
1181211849 mem.alignForward(u31, result.stack_byte_count, param_align);
1181311850 arg.* = .{ .load_frame = .{
......@@ -11827,7 +11864,7 @@ fn resolveCallingConventionValues(
1182711864 result.return_value = InstTracking.init(.none);
1182811865 } else {
1182911866 const ret_reg = abi.getCAbiIntReturnRegs(self.target.*)[0];
11830 const ret_ty_size = @as(u31, @intCast(ret_ty.abiSize(mod)));
11867 const ret_ty_size: u31 = @intCast(ret_ty.abiSize(mod));
1183111868 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
1183211869 const aliased_reg = registerAlias(ret_reg, ret_ty_size);
1183311870 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };
......@@ -11846,8 +11883,8 @@ fn resolveCallingConventionValues(
1184611883 arg.* = .none;
1184711884 continue;
1184811885 }
11849 const param_size = @as(u31, @intCast(ty.abiSize(mod)));
11850 const param_align = @as(u31, @intCast(ty.abiAlignment(mod)));
11886 const param_size: u31 = @intCast(ty.abiSize(mod));
11887 const param_align: u31 = @intCast(ty.abiAlignment(mod));
1185111888 result.stack_byte_count =
1185211889 mem.alignForward(u31, result.stack_byte_count, param_align);
1185311890 arg.* = .{ .load_frame = .{
......@@ -11934,12 +11971,12 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
1193411971 const mod = self.bin_file.options.module.?;
1193511972 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
1193611973 .signedness = .unsigned,
11937 .bits = @as(u16, @intCast(ty.bitSize(mod))),
11974 .bits = @intCast(ty.bitSize(mod)),
1193811975 };
1193911976 const max_reg_bit_width = Register.rax.bitSize();
1194011977 switch (int_info.signedness) {
1194111978 .signed => {
11942 const shift = @as(u6, @intCast(max_reg_bit_width - int_info.bits));
11979 const shift: u6 = @intCast(max_reg_bit_width - int_info.bits);
1194311980 try self.genShiftBinOpMir(
1194411981 .{ ._l, .sa },
1194511982 Type.isize,
......@@ -11954,8 +11991,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
1195411991 );
1195511992 },
1195611993 .unsigned => {
11957 const shift = @as(u6, @intCast(max_reg_bit_width - int_info.bits));
11958 const mask = (~@as(u64, 0)) >> shift;
11994 const shift: u6 = @intCast(max_reg_bit_width - int_info.bits);
11995 const mask = ~@as(u64, 0) >> shift;
1195911996 if (int_info.bits <= 32) {
1196011997 try self.genBinOpMir(
1196111998 .{ ._, .@"and" },
src/arch/x86_64/bits.zig+1-1
......@@ -384,7 +384,7 @@ test "Register id - different classes" {
384384 try expect(Register.xmm0.id() != Register.mm0.id());
385385 try expect(Register.mm0.id() != Register.st0.id());
386386
387 try expect(Register.es.id() == 0b100000);
387 try expect(Register.es.id() == 0b110000);
388388}
389389
390390test "Register enc - different classes" {
src/arch/x86_64/encodings.zig+2-2
......@@ -369,11 +369,11 @@ pub const table = [_]Entry{
369369 .{ .mov, .rm, &.{ .sreg, .r32_m16 }, &.{ 0x8e }, 0, .none, .none },
370370 .{ .mov, .rm, &.{ .sreg, .r64_m16 }, &.{ 0x8e }, 0, .long, .none },
371371 .{ .mov, .fd, &.{ .al, .moffs }, &.{ 0xa0 }, 0, .none, .none },
372 .{ .mov, .fd, &.{ .ax, .moffs }, &.{ 0xa1 }, 0, .none, .none },
372 .{ .mov, .fd, &.{ .ax, .moffs }, &.{ 0xa1 }, 0, .short, .none },
373373 .{ .mov, .fd, &.{ .eax, .moffs }, &.{ 0xa1 }, 0, .none, .none },
374374 .{ .mov, .fd, &.{ .rax, .moffs }, &.{ 0xa1 }, 0, .long, .none },
375375 .{ .mov, .td, &.{ .moffs, .al }, &.{ 0xa2 }, 0, .none, .none },
376 .{ .mov, .td, &.{ .moffs, .ax }, &.{ 0xa3 }, 0, .none, .none },
376 .{ .mov, .td, &.{ .moffs, .ax }, &.{ 0xa3 }, 0, .short, .none },
377377 .{ .mov, .td, &.{ .moffs, .eax }, &.{ 0xa3 }, 0, .none, .none },
378378 .{ .mov, .td, &.{ .moffs, .rax }, &.{ 0xa3 }, 0, .long, .none },
379379 .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .none, .none },
src/codegen.zig+21-9
......@@ -558,7 +558,7 @@ pub fn generateSymbol(
558558 }
559559
560560 // Check if we should store the tag first.
561 if (layout.tag_align >= layout.payload_align) {
561 if (layout.tag_size > 0 and layout.tag_align >= layout.payload_align) {
562562 switch (try generateSymbol(bin_file, src_loc, .{
563563 .ty = typed_value.ty.unionTagType(mod).?,
564564 .val = un.tag.toValue(),
......@@ -589,7 +589,7 @@ pub fn generateSymbol(
589589 }
590590 }
591591
592 if (layout.tag_size > 0) {
592 if (layout.tag_size > 0 and layout.tag_align < layout.payload_align) {
593593 switch (try generateSymbol(bin_file, src_loc, .{
594594 .ty = union_ty.tag_ty,
595595 .val = un.tag.toValue(),
......@@ -597,10 +597,10 @@ pub fn generateSymbol(
597597 .ok => {},
598598 .fail => |em| return Result{ .fail = em },
599599 }
600 }
601600
602 if (layout.padding > 0) {
603 try code.writer().writeByteNTimes(0, layout.padding);
601 if (layout.padding > 0) {
602 try code.writer().writeByteNTimes(0, layout.padding);
603 }
604604 }
605605 },
606606 .memoized_call => unreachable,
......@@ -684,10 +684,22 @@ fn lowerParentPtr(
684684 .struct_type,
685685 .anon_struct_type,
686686 .union_type,
687 => @as(u32, @intCast(base_type.toType().structFieldOffset(
688 @as(u32, @intCast(field.index)),
689 mod,
690 ))),
687 => switch (base_type.toType().containerLayout(mod)) {
688 .Auto, .Extern => @intCast(base_type.toType().structFieldOffset(
689 @intCast(field.index),
690 mod,
691 )),
692 .Packed => if (mod.typeToStruct(base_type.toType())) |struct_obj|
693 math.divExact(u16, struct_obj.packedFieldBitOffset(
694 mod,
695 @intCast(field.index),
696 ), 8) catch |err| switch (err) {
697 error.UnexpectedRemainder => 0,
698 error.DivisionByZero => unreachable,
699 }
700 else
701 0,
702 },
691703 else => unreachable,
692704 }),
693705 );
test/behavior/bugs/13664.zig-1
......@@ -13,7 +13,6 @@ fn value() i64 {
1313 return 1341;
1414}
1515test {
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1716 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1817 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1918 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/bugs/1381.zig-1
......@@ -12,7 +12,6 @@ const A = union(enum) {
1212};
1313
1414test "union that needs padding bytes inside an array" {
15 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1615 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1716 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1817 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/packed-struct.zig-2
......@@ -376,7 +376,6 @@ test "load pointer from packed struct" {
376376}
377377
378378test "@intFromPtr on a packed struct field" {
379 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
380379 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
381380 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
382381 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -608,7 +607,6 @@ test "pointer to container level packed struct field" {
608607 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
609608 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
610609 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
611 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
612610 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
613611 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
614612
test/behavior/struct.zig-3
......@@ -427,7 +427,6 @@ test "packed struct 24bits" {
427427 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
428428 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
429429 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
430 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
431430 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO
432431 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO
433432 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -531,7 +530,6 @@ test "packed struct fields are ordered from LSB to MSB" {
531530test "implicit cast packed struct field to const ptr" {
532531 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
533532 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
534 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
535533 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
536534 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
537535
......@@ -1079,7 +1077,6 @@ test "packed struct with undefined initializers" {
10791077 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10801078 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
10811079 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1082 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10831080 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10841081 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10851082
test/behavior/threadlocal.zig+5
......@@ -12,6 +12,11 @@ test "thread local variable" {
1212 }; // TODO
1313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1414
15 if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .macos) {
16 // Fails due to register hazards.
17 return error.SkipZigTest;
18 }
19
1520 const S = struct {
1621 threadlocal var t: i32 = 1234;
1722 };