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...@@ -1832,7 +1832,6 @@ pub fn writeIntSlice(comptime T: type, buffer: []u8, value: T, endian: Endian) v
1832pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value: anytype, endian: std.builtin.Endian) void {1832pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value: anytype, endian: std.builtin.Endian) void {
1833 const T = @TypeOf(value);1833 const T = @TypeOf(value);
1834 const uN = std.meta.Int(.unsigned, @bitSizeOf(T));1834 const uN = std.meta.Int(.unsigned, @bitSizeOf(T));
1835 const Log2N = std.math.Log2Int(T);
18361835
1837 const bit_shift = @as(u3, @intCast(bit_offset % 8));1836 const bit_shift = @as(u3, @intCast(bit_offset % 8));
1838 const write_size = (bit_count + bit_shift + 7) / 8;1837 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...@@ -1861,9 +1860,9 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
18611860
1862 // Write first byte, using a mask to protects bits preceding bit_offset1861 // Write first byte, using a mask to protects bits preceding bit_offset
1863 const head_mask = @as(u8, 0xff) >> bit_shift;1862 const head_mask = @as(u8, 0xff) >> bit_shift;
1864 write_bytes[@as(usize, @intCast(i))] &= ~(head_mask << bit_shift);1863 write_bytes[@intCast(i)] &= ~(head_mask << bit_shift);
1865 write_bytes[@as(usize, @intCast(i))] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & head_mask)) << bit_shift;1864 write_bytes[@intCast(i)] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & head_mask)) << bit_shift;
1866 remaining >>= @as(Log2N, @intCast(@as(u4, 8) - bit_shift));1865 remaining = math.shr(T, remaining, @as(u4, 8) - bit_shift);
1867 i += delta;1866 i += delta;
18681867
1869 // Write bytes[1..bytes.len - 1]1868 // Write bytes[1..bytes.len - 1]
src/arch/x86_64/CodeGen.zig+366-329
...@@ -329,7 +329,7 @@ pub const MCValue = union(enum) {...@@ -329,7 +329,7 @@ pub const MCValue = union(enum) {
329 .load_frame,329 .load_frame,
330 .reserved_frame,330 .reserved_frame,
331 => unreachable, // not offsettable331 => 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) },
333 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },333 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },
334 .register_offset => |reg_off| .{334 .register_offset => |reg_off| .{
335 .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off },335 .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off },
...@@ -606,7 +606,7 @@ const FrameAlloc = struct {...@@ -606,7 +606,7 @@ const FrameAlloc = struct {
606 fn init(alloc_abi: struct { size: u64, alignment: u32 }) FrameAlloc {606 fn init(alloc_abi: struct { size: u64, alignment: u32 }) FrameAlloc {
607 assert(math.isPowerOfTwo(alloc_abi.alignment));607 assert(math.isPowerOfTwo(alloc_abi.alignment));
608 return .{608 return .{
609 .abi_size = @as(u31, @intCast(alloc_abi.size)),609 .abi_size = @intCast(alloc_abi.size),
610 .abi_align = math.log2_int(u32, alloc_abi.alignment),610 .abi_align = math.log2_int(u32, alloc_abi.alignment),
611 .ref_count = 0,611 .ref_count = 0,
612 };612 };
...@@ -694,7 +694,7 @@ pub fn generate(...@@ -694,7 +694,7 @@ pub fn generate(
694 FrameAlloc.init(.{694 FrameAlloc.init(.{
695 .size = 0,695 .size = 0,
696 .alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|696 .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().?)
698 else698 else
699 1,699 1,
700 }),700 }),
...@@ -979,7 +979,7 @@ fn fmtTracking(self: *Self) std.fmt.Formatter(formatTracking) {...@@ -979,7 +979,7 @@ fn fmtTracking(self: *Self) std.fmt.Formatter(formatTracking) {
979fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {979fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
980 const gpa = self.gpa;980 const gpa = self.gpa;
981 try self.mir_instructions.ensureUnusedCapacity(gpa, 1);981 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);
983 self.mir_instructions.appendAssumeCapacity(inst);983 self.mir_instructions.appendAssumeCapacity(inst);
984 if (inst.tag != .pseudo or switch (inst.ops) {984 if (inst.tag != .pseudo or switch (inst.ops) {
985 else => true,985 else => true,
...@@ -1000,11 +1000,11 @@ fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 {...@@ -1000,11 +1000,11 @@ fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 {
10001000
1001fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {1001fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
1002 const fields = std.meta.fields(@TypeOf(extra));1002 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);
1004 inline for (fields) |field| {1004 inline for (fields) |field| {
1005 self.mir_extra.appendAssumeCapacity(switch (field.type) {1005 self.mir_extra.appendAssumeCapacity(switch (field.type) {
1006 u32 => @field(extra, field.name),1006 u32 => @field(extra, field.name),
1007 i32 => @as(u32, @bitCast(@field(extra, field.name))),1007 i32 => @bitCast(@field(extra, field.name)),
1008 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),1008 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
1009 });1009 });
1010 }1010 }
...@@ -1214,8 +1214,8 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void {...@@ -1214,8 +1214,8 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void {
1214 .data = .{ .i = .{1214 .data = .{ .i = .{
1215 .fixes = tag[0],1215 .fixes = tag[0],
1216 .i = switch (imm) {1216 .i = switch (imm) {
1217 .signed => |s| @as(u32, @bitCast(s)),1217 .signed => |s| @bitCast(s),
1218 .unsigned => |u| @as(u32, @intCast(u)),1218 .unsigned => |u| @intCast(u),
1219 },1219 },
1220 } },1220 } },
1221 });1221 });
...@@ -1246,8 +1246,8 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:...@@ -1246,8 +1246,8 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:
1246 .fixes = tag[0],1246 .fixes = tag[0],
1247 .r1 = reg,1247 .r1 = reg,
1248 .i = switch (imm) {1248 .i = switch (imm) {
1249 .signed => |s| @as(u32, @bitCast(s)),1249 .signed => |s| @bitCast(s),
1250 .unsigned => |u| @as(u32, @intCast(u)),1250 .unsigned => |u| @intCast(u),
1251 },1251 },
1252 } },1252 } },
1253 .ri64 => .{ .rx = .{1253 .ri64 => .{ .rx = .{
...@@ -1339,8 +1339,8 @@ fn asmRegisterRegisterImmediate(...@@ -1339,8 +1339,8 @@ fn asmRegisterRegisterImmediate(
1339 .r1 = reg1,1339 .r1 = reg1,
1340 .r2 = reg2,1340 .r2 = reg2,
1341 .i = switch (imm) {1341 .i = switch (imm) {
1342 .signed => |s| @as(u32, @bitCast(s)),1342 .signed => |s| @bitCast(s),
1343 .unsigned => |u| @as(u32, @intCast(u)),1343 .unsigned => |u| @intCast(u),
1344 },1344 },
1345 } },1345 } },
1346 });1346 });
...@@ -1458,7 +1458,7 @@ fn asmRegisterRegisterMemoryImmediate(...@@ -1458,7 +1458,7 @@ fn asmRegisterRegisterMemoryImmediate(
1458 .fixes = tag[0],1458 .fixes = tag[0],
1459 .r1 = reg1,1459 .r1 = reg1,
1460 .r2 = reg2,1460 .r2 = reg2,
1461 .i = @as(u8, @intCast(imm.unsigned)),1461 .i = @intCast(imm.unsigned),
1462 .payload = switch (m) {1462 .payload = switch (m) {
1463 .sib => try self.addExtra(Mir.MemorySib.encode(m)),1463 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
1464 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),1464 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),
...@@ -1490,8 +1490,8 @@ fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Regist...@@ -1490,8 +1490,8 @@ fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Regist
14901490
1491fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immediate) !void {1491fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immediate) !void {
1492 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {1492 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
1493 .signed => |s| @as(u32, @bitCast(s)),1493 .signed => |s| @bitCast(s),
1494 .unsigned => |u| @as(u32, @intCast(u)),1494 .unsigned => |u| @intCast(u),
1495 } });1495 } });
1496 assert(payload + 1 == switch (m) {1496 assert(payload + 1 == switch (m) {
1497 .sib => try self.addExtra(Mir.MemorySib.encode(m)),1497 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
...@@ -1562,7 +1562,7 @@ fn asmMemoryRegisterImmediate(...@@ -1562,7 +1562,7 @@ fn asmMemoryRegisterImmediate(
1562 .data = .{ .rix = .{1562 .data = .{ .rix = .{
1563 .fixes = tag[0],1563 .fixes = tag[0],
1564 .r1 = reg,1564 .r1 = reg,
1565 .i = @as(u8, @intCast(imm.unsigned)),1565 .i = @intCast(imm.unsigned),
1566 .payload = switch (m) {1566 .payload = switch (m) {
1567 .sib => try self.addExtra(Mir.MemorySib.encode(m)),1567 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
1568 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),1568 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),
...@@ -1617,7 +1617,7 @@ fn gen(self: *Self) InnerError!void {...@@ -1617,7 +1617,7 @@ fn gen(self: *Self) InnerError!void {
1617 // Eliding the reloc will cause a miscompilation in this case.1617 // Eliding the reloc will cause a miscompilation in this case.
1618 for (self.exitlude_jump_relocs.items) |jmp_reloc| {1618 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
1619 self.mir_instructions.items(.data)[jmp_reloc].inst.inst =1619 self.mir_instructions.items(.data)[jmp_reloc].inst.inst =
1620 @as(u32, @intCast(self.mir_instructions.len));1620 @intCast(self.mir_instructions.len);
1621 }1621 }
16221622
1623 try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);1623 try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
...@@ -1739,7 +1739,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1739,7 +1739,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
17391739
1740 for (body) |inst| {1740 for (body) |inst| {
1741 if (builtin.mode == .Debug) {1741 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);
1743 try self.mir_to_air_map.put(self.gpa, mir_inst, inst);1743 try self.mir_to_air_map.put(self.gpa, mir_inst, inst);
1744 }1744 }
17451745
...@@ -2034,7 +2034,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -2034,7 +2034,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
20342034
2035 var data_off: i32 = 0;2035 var data_off: i32 = 0;
2036 for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, index_usize| {2036 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);
2038 const tag_name = mod.intern_pool.stringToSlice(enum_ty.enumFields(mod)[index_usize]);2038 const tag_name = mod.intern_pool.stringToSlice(enum_ty.enumFields(mod)[index_usize]);
2039 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);2039 const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
2040 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });2040 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 {...@@ -2052,7 +2052,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2052 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);2052 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
2053 try self.performReloc(skip_reloc);2053 try self.performReloc(skip_reloc);
20542054
2055 data_off += @as(i32, @intCast(tag_name.len + 1));2055 data_off += @intCast(tag_name.len + 1);
2056 }2056 }
20572057
2058 try self.airTrap();2058 try self.airTrap();
...@@ -2169,7 +2169,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {...@@ -2169,7 +2169,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
2169 const frame_offset = self.frame_locs.items(.disp);2169 const frame_offset = self.frame_locs.items(.disp);
21702170
2171 for (stack_frame_order, FrameIndex.named_count..) |*frame_order, frame_index|2171 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);
2173 {2173 {
2174 const SortContext = struct {2174 const SortContext = struct {
2175 frame_align: @TypeOf(frame_align),2175 frame_align: @TypeOf(frame_align),
...@@ -2197,7 +2197,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {...@@ -2197,7 +2197,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
2197 }2197 }
2198 }2198 }
21992199
2200 var rbp_offset = @as(i32, @intCast(save_reg_list.count() * 8));2200 var rbp_offset: i32 = @intCast(save_reg_list.count() * 8);
2201 self.setFrameLoc(.base_ptr, .rbp, &rbp_offset, false);2201 self.setFrameLoc(.base_ptr, .rbp, &rbp_offset, false);
2202 self.setFrameLoc(.ret_addr, .rbp, &rbp_offset, false);2202 self.setFrameLoc(.ret_addr, .rbp, &rbp_offset, false);
2203 self.setFrameLoc(.args_frame, .rbp, &rbp_offset, false);2203 self.setFrameLoc(.args_frame, .rbp, &rbp_offset, false);
...@@ -2212,11 +2212,11 @@ fn computeFrameLayout(self: *Self) !FrameLayout {...@@ -2212,11 +2212,11 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
2212 rsp_offset = mem.alignForward(i32, rsp_offset, @as(i32, 1) << needed_align);2212 rsp_offset = mem.alignForward(i32, rsp_offset, @as(i32, 1) << needed_align);
2213 rsp_offset -= stack_frame_align_offset;2213 rsp_offset -= stack_frame_align_offset;
2214 frame_size[@intFromEnum(FrameIndex.call_frame)] =2214 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
2217 return .{2217 return .{
2218 .stack_mask = @as(u32, math.maxInt(u32)) << (if (need_align_stack) needed_align else 0),2218 .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)]),
2220 .save_reg_list = save_reg_list,2220 .save_reg_list = save_reg_list,
2221 };2221 };
2222}2222}
...@@ -2247,7 +2247,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {...@@ -2247,7 +2247,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
2247 _ = self.free_frame_indices.swapRemoveAt(free_i);2247 _ = self.free_frame_indices.swapRemoveAt(free_i);
2248 return frame_index;2248 return frame_index;
2249 }2249 }
2250 const frame_index = @as(FrameIndex, @enumFromInt(self.frame_allocs.len));2250 const frame_index: FrameIndex = @enumFromInt(self.frame_allocs.len);
2251 try self.frame_allocs.append(self.gpa, alloc);2251 try self.frame_allocs.append(self.gpa, alloc);
2252 return frame_index;2252 return frame_index;
2253}2253}
...@@ -2323,7 +2323,7 @@ const State = struct {...@@ -2323,7 +2323,7 @@ const State = struct {
23232323
2324fn initRetroactiveState(self: *Self) State {2324fn initRetroactiveState(self: *Self) State {
2325 var state: State = undefined;2325 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());
2327 state.scope_generation = self.scope_generation;2327 state.scope_generation = self.scope_generation;
2328 return state;2328 return state;
2329}2329}
...@@ -2394,9 +2394,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt...@@ -2394,9 +2394,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt
2394 self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst);2394 self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst);
2395 }2395 }
2396 {2396 {
2397 const reg = RegisterManager.regAtTrackedIndex(2397 const reg = RegisterManager.regAtTrackedIndex(@intCast(index));
2398 @as(RegisterManager.RegisterBitSet.ShiftInt, @intCast(index)),
2399 );
2400 self.register_manager.freeReg(reg);2398 self.register_manager.freeReg(reg);
2401 self.register_manager.getRegAssumeFree(reg, target_maybe_inst);2399 self.register_manager.getRegAssumeFree(reg, target_maybe_inst);
2402 }2400 }
...@@ -2630,7 +2628,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -2630,7 +2628,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
26302628
2631 const dst_ty = self.typeOfIndex(inst);2629 const dst_ty = self.typeOfIndex(inst);
2632 const dst_int_info = dst_ty.intInfo(mod);2630 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
2635 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;2633 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;
2636 const extend = switch (src_int_info.signedness) {2634 const extend = switch (src_int_info.signedness) {
...@@ -2708,9 +2706,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2708,9 +2706,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2708 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2706 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27092707
2710 const dst_ty = self.typeOfIndex(inst);2708 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));
2712 const src_ty = self.typeOf(ty_op.operand);2710 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
2715 const result = result: {2713 const result = result: {
2716 const src_mcv = try self.resolveInst(ty_op.operand);2714 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -2727,7 +2725,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2727,7 +2725,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2727 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod));2725 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod));
2728 const dst_info = dst_ty.childType(mod).intInfo(mod);2726 const dst_info = dst_ty.childType(mod).intInfo(mod);
2729 const src_info = src_ty.childType(mod).intInfo(mod);2727 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) {
2731 8 => switch (src_info.bits) {2729 8 => switch (src_info.bits) {
2732 16 => switch (dst_ty.vectorLen(mod)) {2730 16 => switch (dst_ty.vectorLen(mod)) {
2733 1...8 => if (self.hasFeature(.avx)) .{ .vp_b, .ackusw } else .{ .p_b, .ackusw },2731 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 {...@@ -2750,18 +2748,18 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2750 else => null,2748 else => null,
2751 },2749 },
2752 else => null,2750 else => null,
2753 })) |tag| tag else return self.fail("TODO implement airTrunc for {}", .{2751 }) orelse return self.fail("TODO implement airTrunc for {}", .{
2754 dst_ty.fmt(self.bin_file.options.module.?),2752 dst_ty.fmt(self.bin_file.options.module.?),
2755 });2753 });
27562754
2757 const elem_ty = src_ty.childType(mod);2755 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
2760 const splat_ty = try mod.vectorType(.{2758 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)),
2762 .child = elem_ty.ip_index,2760 .child = elem_ty.ip_index,
2763 });2761 });
2764 const splat_abi_size = @as(u32, @intCast(splat_ty.abiSize(mod)));2762 const splat_abi_size: u32 = @intCast(splat_ty.abiSize(mod));
27652763
2766 const splat_val = try mod.intern(.{ .aggregate = .{2764 const splat_val = try mod.intern(.{ .aggregate = .{
2767 .ty = splat_ty.ip_index,2765 .ty = splat_ty.ip_index,
...@@ -2836,7 +2834,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -2836,7 +2834,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2836 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);2834 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
2837 try self.genSetMem(2835 try self.genSetMem(
2838 .{ .frame = frame_index },2836 .{ .frame = frame_index },
2839 @as(i32, @intCast(ptr_ty.abiSize(mod))),2837 @intCast(ptr_ty.abiSize(mod)),
2840 len_ty,2838 len_ty,
2841 len,2839 len,
2842 );2840 );
...@@ -2935,6 +2933,10 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2935,6 +2933,10 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2935 const mod = self.bin_file.options.module.?;2933 const mod = self.bin_file.options.module.?;
2936 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2934 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2937 const ty = self.typeOf(bin_op.lhs);2935 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
2939 const lhs_mcv = try self.resolveInst(bin_op.lhs);2941 const lhs_mcv = try self.resolveInst(bin_op.lhs);
2940 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))2942 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 {...@@ -2966,7 +2968,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2966 try self.genSetReg(limit_reg, ty, dst_mcv);2968 try self.genSetReg(limit_reg, ty, dst_mcv);
2967 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });2969 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
2968 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{2970 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,
2970 });2972 });
2971 if (reg_extra_bits > 0) {2973 if (reg_extra_bits > 0) {
2972 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);2974 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);
...@@ -2985,7 +2987,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2985,7 +2987,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2985 break :cc .o;2987 break :cc .o;
2986 } else cc: {2988 } else cc: {
2987 try self.genSetReg(limit_reg, ty, .{2989 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)),
2989 });2991 });
29902992
2991 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);2993 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
...@@ -3014,6 +3016,10 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3014,6 +3016,10 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3014 const mod = self.bin_file.options.module.?;3016 const mod = self.bin_file.options.module.?;
3015 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3017 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3016 const ty = self.typeOf(bin_op.lhs);3018 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
3018 const lhs_mcv = try self.resolveInst(bin_op.lhs);3024 const lhs_mcv = try self.resolveInst(bin_op.lhs);
3019 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))3025 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 {...@@ -3045,7 +3051,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3045 try self.genSetReg(limit_reg, ty, dst_mcv);3051 try self.genSetReg(limit_reg, ty, dst_mcv);
3046 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });3052 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
3047 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{3053 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,
3049 });3055 });
3050 if (reg_extra_bits > 0) {3056 if (reg_extra_bits > 0) {
3051 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);3057 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);
...@@ -3086,6 +3092,10 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3086,6 +3092,10 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3086 const mod = self.bin_file.options.module.?;3092 const mod = self.bin_file.options.module.?;
3087 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3093 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3088 const ty = self.typeOf(bin_op.lhs);3094 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
3090 try self.spillRegisters(&.{ .rax, .rdx });3100 try self.spillRegisters(&.{ .rax, .rdx });
3091 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });3101 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });
...@@ -3116,12 +3126,12 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3116,12 +3126,12 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3116 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);3126 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);
3117 try self.genShiftBinOpMir(.{ ._, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });3127 try self.genShiftBinOpMir(.{ ._, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
3118 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{3128 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,
3120 });3130 });
3121 break :cc .o;3131 break :cc .o;
3122 } else cc: {3132 } else cc: {
3123 try self.genSetReg(limit_reg, ty, .{3133 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),
3125 });3135 });
3126 break :cc .c;3136 break :cc .c;
3127 };3137 };
...@@ -3174,13 +3184,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3174,13 +3184,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3174 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));3184 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3175 try self.genSetMem(3185 try self.genSetMem(
3176 .{ .frame = frame_index },3186 .{ .frame = frame_index },
3177 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),3187 @intCast(tuple_ty.structFieldOffset(1, mod)),
3178 Type.u1,3188 Type.u1,
3179 .{ .eflags = cc },3189 .{ .eflags = cc },
3180 );3190 );
3181 try self.genSetMem(3191 try self.genSetMem(
3182 .{ .frame = frame_index },3192 .{ .frame = frame_index },
3183 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),3193 @intCast(tuple_ty.structFieldOffset(0, mod)),
3184 ty,3194 ty,
3185 partial_mcv,3195 partial_mcv,
3186 );3196 );
...@@ -3247,13 +3257,13 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3247,13 +3257,13 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3247 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));3257 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
3248 try self.genSetMem(3258 try self.genSetMem(
3249 .{ .frame = frame_index },3259 .{ .frame = frame_index },
3250 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),3260 @intCast(tuple_ty.structFieldOffset(1, mod)),
3251 tuple_ty.structFieldType(1, mod),3261 tuple_ty.structFieldType(1, mod),
3252 .{ .eflags = cc },3262 .{ .eflags = cc },
3253 );3263 );
3254 try self.genSetMem(3264 try self.genSetMem(
3255 .{ .frame = frame_index },3265 .{ .frame = frame_index },
3256 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),3266 @intCast(tuple_ty.structFieldOffset(0, mod)),
3257 tuple_ty.structFieldType(0, mod),3267 tuple_ty.structFieldType(0, mod),
3258 partial_mcv,3268 partial_mcv,
3259 );3269 );
...@@ -3321,7 +3331,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -3321,7 +3331,7 @@ fn genSetFrameTruncatedOverflowCompare(
3321 );3331 );
3322 }3332 }
33233333
3324 const payload_off = @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod)));3334 const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod));
3325 if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv);3335 if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv);
3326 try self.genSetMem(3336 try self.genSetMem(
3327 .{ .frame = frame_index },3337 .{ .frame = frame_index },
...@@ -3331,7 +3341,7 @@ fn genSetFrameTruncatedOverflowCompare(...@@ -3331,7 +3341,7 @@ fn genSetFrameTruncatedOverflowCompare(
3331 );3341 );
3332 try self.genSetMem(3342 try self.genSetMem(
3333 .{ .frame = frame_index },3343 .{ .frame = frame_index },
3334 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),3344 @intCast(tuple_ty.structFieldOffset(1, mod)),
3335 tuple_ty.structFieldType(1, mod),3345 tuple_ty.structFieldType(1, mod),
3336 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },3346 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
3337 );3347 );
...@@ -3388,13 +3398,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3388,13 +3398,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3388 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {3398 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {
3389 try self.genSetMem(3399 try self.genSetMem(
3390 .{ .frame = frame_index },3400 .{ .frame = frame_index },
3391 @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))),3401 @intCast(tuple_ty.structFieldOffset(0, mod)),
3392 tuple_ty.structFieldType(0, mod),3402 tuple_ty.structFieldType(0, mod),
3393 partial_mcv,3403 partial_mcv,
3394 );3404 );
3395 try self.genSetMem(3405 try self.genSetMem(
3396 .{ .frame = frame_index },3406 .{ .frame = frame_index },
3397 @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))),3407 @intCast(tuple_ty.structFieldOffset(1, mod)),
3398 tuple_ty.structFieldType(1, mod),3408 tuple_ty.structFieldType(1, mod),
3399 .{ .immediate = 0 }, // cc being set is impossible3409 .{ .immediate = 0 }, // cc being set is impossible
3400 );3410 );
...@@ -3418,7 +3428,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3418,7 +3428,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3418/// Quotient is saved in .rax and remainder in .rdx.3428/// Quotient is saved in .rax and remainder in .rdx.
3419fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {3429fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {
3420 const mod = self.bin_file.options.module.?;3430 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));
3422 if (abi_size > 8) {3432 if (abi_size > 8) {
3423 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});3433 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});
3424 }3434 }
...@@ -3458,7 +3468,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue...@@ -3458,7 +3468,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue
3458/// Clobbers .rax and .rdx registers.3468/// Clobbers .rax and .rdx registers.
3459fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {3469fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
3460 const mod = self.bin_file.options.module.?;3470 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));
3462 const int_info = ty.intInfo(mod);3472 const int_info = ty.intInfo(mod);
3463 const dividend: Register = switch (lhs) {3473 const dividend: Register = switch (lhs) {
3464 .register => |reg| reg,3474 .register => |reg| reg,
...@@ -3597,7 +3607,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3597,7 +3607,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3597 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);3607 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
35983608
3599 const pl_ty = dst_ty.childType(mod);3609 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));
3601 try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });3611 try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });
3602 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;3612 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
3603 };3613 };
...@@ -3629,17 +3639,12 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3629,17 +3639,12 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3629 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);3639 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
36303640
3631 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);3641 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);
3632 if (err_off > 0) {3642 if (err_off > 0) try self.genShiftBinOpMir(
3633 const shift = @as(u6, @intCast(err_off * 8));3643 .{ ._r, .sh },
3634 try self.genShiftBinOpMir(3644 err_union_ty,
3635 .{ ._r, .sh },3645 result,
3636 err_union_ty,3646 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
3637 result,3647 ) else try self.truncateRegister(Type.anyerror, result.register);
3638 .{ .immediate = shift },
3639 );
3640 } else {
3641 try self.truncateRegister(Type.anyerror, result.register);
3642 }
3643 break :result result;3648 break :result result;
3644 },3649 },
3645 .load_frame => |frame_addr| break :result .{ .load_frame = .{3650 .load_frame => |frame_addr| break :result .{ .load_frame = .{
...@@ -3687,17 +3692,12 @@ fn genUnwrapErrorUnionPayloadMir(...@@ -3687,17 +3692,12 @@ fn genUnwrapErrorUnionPayloadMir(
3687 try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union)3692 try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union)
3688 else3693 else
3689 .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) };3694 .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) };
3690 if (payload_off > 0) {3695 if (payload_off > 0) try self.genShiftBinOpMir(
3691 const shift = @as(u6, @intCast(payload_off * 8));3696 .{ ._r, .sh },
3692 try self.genShiftBinOpMir(3697 err_union_ty,
3693 .{ ._r, .sh },3698 result_mcv,
3694 err_union_ty,3699 .{ .immediate = @as(u6, @intCast(payload_off * 8)) },
3695 result_mcv,3700 ) else try self.truncateRegister(payload_ty, result_mcv.register);
3696 .{ .immediate = shift },
3697 );
3698 } else {
3699 try self.truncateRegister(payload_ty, result_mcv.register);
3700 }
3701 break :result result_mcv;3701 break :result result_mcv;
3702 },3702 },
3703 else => return self.fail("TODO implement genUnwrapErrorUnionPayloadMir for {}", .{err_union}),3703 else => return self.fail("TODO implement genUnwrapErrorUnionPayloadMir for {}", .{err_union}),
...@@ -3729,8 +3729,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3729,8 +3729,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3729 const eu_ty = src_ty.childType(mod);3729 const eu_ty = src_ty.childType(mod);
3730 const pl_ty = eu_ty.errorUnionPayload(mod);3730 const pl_ty = eu_ty.errorUnionPayload(mod);
3731 const err_ty = eu_ty.errorUnionSet(mod);3731 const err_ty = eu_ty.errorUnionSet(mod);
3732 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));3732 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
3733 const err_abi_size = @as(u32, @intCast(err_ty.abiSize(mod)));3733 const err_abi_size: u32 = @intCast(err_ty.abiSize(mod));
3734 try self.asmRegisterMemory(3734 try self.asmRegisterMemory(
3735 .{ ._, .mov },3735 .{ ._, .mov },
3736 registerAlias(dst_reg, err_abi_size),3736 registerAlias(dst_reg, err_abi_size),
...@@ -3768,8 +3768,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3768,8 +3768,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
37683768
3769 const eu_ty = src_ty.childType(mod);3769 const eu_ty = src_ty.childType(mod);
3770 const pl_ty = eu_ty.errorUnionPayload(mod);3770 const pl_ty = eu_ty.errorUnionPayload(mod);
3771 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));3771 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3772 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));3772 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
3773 try self.asmRegisterMemory(3773 try self.asmRegisterMemory(
3774 .{ ._, .lea },3774 .{ ._, .lea },
3775 registerAlias(dst_reg, dst_abi_size),3775 registerAlias(dst_reg, dst_abi_size),
...@@ -3795,8 +3795,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3795,8 +3795,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3795 const eu_ty = src_ty.childType(mod);3795 const eu_ty = src_ty.childType(mod);
3796 const pl_ty = eu_ty.errorUnionPayload(mod);3796 const pl_ty = eu_ty.errorUnionPayload(mod);
3797 const err_ty = eu_ty.errorUnionSet(mod);3797 const err_ty = eu_ty.errorUnionSet(mod);
3798 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));3798 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
3799 const err_abi_size = @as(u32, @intCast(err_ty.abiSize(mod)));3799 const err_abi_size: u32 = @intCast(err_ty.abiSize(mod));
3800 try self.asmMemoryImmediate(3800 try self.asmMemoryImmediate(
3801 .{ ._, .mov },3801 .{ ._, .mov },
3802 Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{3802 Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{
...@@ -3816,8 +3816,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3816,8 +3816,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3816 const dst_lock = self.register_manager.lockReg(dst_reg);3816 const dst_lock = self.register_manager.lockReg(dst_reg);
3817 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);3817 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
38183818
3819 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));3819 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3820 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));3820 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
3821 try self.asmRegisterMemory(3821 try self.asmRegisterMemory(
3822 .{ ._, .lea },3822 .{ ._, .lea },
3823 registerAlias(dst_reg, dst_abi_size),3823 registerAlias(dst_reg, dst_abi_size),
...@@ -3866,7 +3866,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3866,7 +3866,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3866 try self.genCopy(pl_ty, opt_mcv, pl_mcv);3866 try self.genCopy(pl_ty, opt_mcv, pl_mcv);
38673867
3868 if (!same_repr) {3868 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));
3870 switch (opt_mcv) {3870 switch (opt_mcv) {
3871 else => unreachable,3871 else => unreachable,
38723872
...@@ -3905,8 +3905,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3905,8 +3905,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3905 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .{ .immediate = 0 };3905 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .{ .immediate = 0 };
39063906
3907 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));3907 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3908 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));3908 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3909 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));3909 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
3910 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);3910 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);
3911 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });3911 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });
3912 break :result .{ .load_frame = .{ .index = frame_index } };3912 break :result .{ .load_frame = .{ .index = frame_index } };
...@@ -3927,8 +3927,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3927,8 +3927,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3927 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);3927 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);
39283928
3929 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));3929 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3930 const pl_off = @as(i32, @intCast(errUnionPayloadOffset(pl_ty, mod)));3930 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod));
3931 const err_off = @as(i32, @intCast(errUnionErrorOffset(pl_ty, mod)));3931 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod));
3932 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);3932 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);
3933 const operand = try self.resolveInst(ty_op.operand);3933 const operand = try self.resolveInst(ty_op.operand);
3934 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);3934 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);
...@@ -3990,7 +3990,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3990,7 +3990,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
3990 const dst_lock = self.register_manager.lockReg(dst_reg);3990 const dst_lock = self.register_manager.lockReg(dst_reg);
3991 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);3991 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));
3994 try self.asmRegisterMemory(3994 try self.asmRegisterMemory(
3995 .{ ._, .lea },3995 .{ ._, .lea },
3996 registerAlias(dst_reg, dst_abi_size),3996 registerAlias(dst_reg, dst_abi_size),
...@@ -4167,7 +4167,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4167,7 +4167,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
4167 // additional `mov` is needed at the end to get the actual value4167 // additional `mov` is needed at the end to get the actual value
41684168
4169 const elem_ty = ptr_ty.elemType2(mod);4169 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));
4171 const index_ty = self.typeOf(bin_op.rhs);4171 const index_ty = self.typeOf(bin_op.rhs);
4172 const index_mcv = try self.resolveInst(bin_op.rhs);4172 const index_mcv = try self.resolveInst(bin_op.rhs);
4173 const index_lock = switch (index_mcv) {4173 const index_lock = switch (index_mcv) {
...@@ -4307,7 +4307,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -4307,7 +4307,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4307 .load_frame => |frame_addr| {4307 .load_frame => |frame_addr| {
4308 if (tag_abi_size <= 8) {4308 if (tag_abi_size <= 8) {
4309 const off: i32 = if (layout.tag_align < layout.payload_align)4309 const off: i32 = if (layout.tag_align < layout.payload_align)
4310 @as(i32, @intCast(layout.payload_size))4310 @intCast(layout.payload_size)
4311 else4311 else
4312 0;4312 0;
4313 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{4313 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{
...@@ -4319,13 +4319,13 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -4319,13 +4319,13 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4319 },4319 },
4320 .register => {4320 .register => {
4321 const shift: u6 = if (layout.tag_align < layout.payload_align)4321 const shift: u6 = if (layout.tag_align < layout.payload_align)
4322 @as(u6, @intCast(layout.payload_size * 8))4322 @intCast(layout.payload_size * 8)
4323 else4323 else
4324 0;4324 0;
4325 const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand);4325 const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand);
4326 try self.genShiftBinOpMir(.{ ._r, .sh }, Type.usize, result, .{ .immediate = shift });4326 try self.genShiftBinOpMir(.{ ._r, .sh }, Type.usize, result, .{ .immediate = shift });
4327 break :blk MCValue{4327 break :blk MCValue{
4328 .register = registerAlias(result.register, @as(u32, @intCast(layout.tag_size))),4328 .register = registerAlias(result.register, @intCast(layout.tag_size)),
4329 };4329 };
4330 },4330 },
4331 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),4331 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),
...@@ -4341,6 +4341,9 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4341,6 +4341,9 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4341 const result = result: {4341 const result = result: {
4342 const dst_ty = self.typeOfIndex(inst);4342 const dst_ty = self.typeOfIndex(inst);
4343 const src_ty = self.typeOf(ty_op.operand);4343 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
4345 const src_mcv = try self.resolveInst(ty_op.operand);4348 const src_mcv = try self.resolveInst(ty_op.operand);
4346 const mat_src_mcv = switch (src_mcv) {4349 const mat_src_mcv = switch (src_mcv) {
...@@ -4432,7 +4435,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4432,7 +4435,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4432 try self.genBinOpMir(.{ ._, .xor }, dst_ty, dst_mcv, .{ .immediate = src_bits - 1 });4435 try self.genBinOpMir(.{ ._, .xor }, dst_ty, dst_mcv, .{ .immediate = src_bits - 1 });
4433 } else {4436 } else {
4434 const imm_reg = try self.copyToTmpRegister(dst_ty, .{4437 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)),
4436 });4439 });
4437 const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg);4440 const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg);
4438 defer self.register_manager.unlockReg(imm_lock);4441 defer self.register_manager.unlockReg(imm_lock);
...@@ -4503,8 +4506,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4503,8 +4506,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4503 .{ ._, .@"or" },4506 .{ ._, .@"or" },
4504 wide_ty,4507 wide_ty,
4505 tmp_mcv,4508 tmp_mcv,
4506 .{ .immediate = (@as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - extra_bits))) <<4509 .{ .immediate = (@as(u64, math.maxInt(u64)) >> @intCast(64 - extra_bits)) <<
4507 @as(u6, @intCast(src_bits)) },4510 @intCast(src_bits) },
4508 );4511 );
4509 break :masked tmp_mcv;4512 break :masked tmp_mcv;
4510 } else mat_src_mcv;4513 } else mat_src_mcv;
...@@ -4521,7 +4524,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4521,7 +4524,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4521 .{ ._, .@"or" },4524 .{ ._, .@"or" },
4522 Type.u64,4525 Type.u64,
4523 dst_mcv,4526 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) },
4525 );4528 );
4526 break :masked dst_mcv;4529 break :masked dst_mcv;
4527 } else mat_src_mcv.address().offset(8).deref();4530 } else mat_src_mcv.address().offset(8).deref();
...@@ -4565,7 +4568,9 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {...@@ -4565,7 +4568,9 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
4565 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4568 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4566 const result: MCValue = result: {4569 const result: MCValue = result: {
4567 const src_ty = self.typeOf(ty_op.operand);4570 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)});
4569 const src_mcv = try self.resolveInst(ty_op.operand);4574 const src_mcv = try self.resolveInst(ty_op.operand);
45704575
4571 if (self.hasFeature(.popcnt)) {4576 if (self.hasFeature(.popcnt)) {
...@@ -4590,7 +4595,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {...@@ -4590,7 +4595,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
4590 break :result dst_mcv;4595 break :result dst_mcv;
4591 }4596 }
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);
4594 const imm_0_1 = Immediate.u(mask / 0b1_1);4599 const imm_0_1 = Immediate.u(mask / 0b1_1);
4595 const imm_00_11 = Immediate.u(mask / 0b01_01);4600 const imm_00_11 = Immediate.u(mask / 0b01_01);
4596 const imm_0000_1111 = Immediate.u(mask / 0b0001_0001);4601 const imm_0000_1111 = Immediate.u(mask / 0b0001_0001);
...@@ -4674,8 +4679,13 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {...@@ -4674,8 +4679,13 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
4674}4679}
46754680
4676fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, mem_ok: bool) !MCValue {4681fn 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.?;
4677 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4683 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 );
4679 const src_bits = self.regBitSize(src_ty);4689 const src_bits = self.regBitSize(src_ty);
4680 const src_lock = switch (src_mcv) {4690 const src_lock = switch (src_mcv) {
4681 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4691 .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...@@ -4684,7 +4694,9 @@ fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, m
4684 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);4694 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
46854695
4686 switch (src_bits) {4696 switch (src_bits) {
4687 else => unreachable,4697 else => return self.fail("TODO implement byteSwap for {}", .{
4698 src_ty.fmt(mod),
4699 }),
4688 8 => return if ((mem_ok or src_mcv.isRegister()) and4700 8 => return if ((mem_ok or src_mcv.isRegister()) and
4689 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))4701 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
4690 src_mcv4702 src_mcv
...@@ -4756,7 +4768,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {...@@ -4756,7 +4768,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4756 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4768 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47574769
4758 const src_ty = self.typeOf(ty_op.operand);4770 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));
4760 const src_mcv = try self.resolveInst(ty_op.operand);4772 const src_mcv = try self.resolveInst(ty_op.operand);
47614773
4762 const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, false);4774 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 {...@@ -4776,7 +4788,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4776 else4788 else
4777 undefined;4789 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);
4780 const imm_0000_1111 = Immediate.u(mask / 0b0001_0001);4792 const imm_0000_1111 = Immediate.u(mask / 0b0001_0001);
4781 const imm_00_11 = Immediate.u(mask / 0b01_01);4793 const imm_00_11 = Immediate.u(mask / 0b01_01);
4782 const imm_0_1 = Immediate.u(mask / 0b1_1);4794 const imm_0_1 = Immediate.u(mask / 0b1_1);
...@@ -4874,6 +4886,9 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -4874,6 +4886,9 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4874 }),4886 }),
4875 };4887 };
4876 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);4888 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
4878 const src_mcv = try self.resolveInst(un_op);4893 const src_mcv = try self.resolveInst(un_op);
4879 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;4894 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...@@ -4989,7 +5004,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
4989 if (!self.hasFeature(.sse4_1))5004 if (!self.hasFeature(.sse4_1))
4990 return self.fail("TODO implement genRound without sse4_1 feature", .{});5005 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)) {
4993 .Float => switch (ty.floatBits(self.target.*)) {5008 .Float => switch (ty.floatBits(self.target.*)) {
4994 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },5009 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
4995 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },5010 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...@@ -5016,10 +5031,10 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
5016 else => null,5031 else => null,
5017 },5032 },
5018 else => unreachable,5033 else => unreachable,
5019 })) |tag| tag else return self.fail("TODO implement genRound for {}", .{5034 }) orelse return self.fail("TODO implement genRound for {}", .{
5020 ty.fmt(self.bin_file.options.module.?),5035 ty.fmt(self.bin_file.options.module.?),
5021 });5036 });
5022 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));5037 const abi_size: u32 = @intCast(ty.abiSize(mod));
5023 const dst_alias = registerAlias(dst_reg, abi_size);5038 const dst_alias = registerAlias(dst_reg, abi_size);
5024 switch (mir_tag[0]) {5039 switch (mir_tag[0]) {
5025 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(5040 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
...@@ -5059,7 +5074,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -5059,7 +5074,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5059 const mod = self.bin_file.options.module.?;5074 const mod = self.bin_file.options.module.?;
5060 const un_op = self.air.instructions.items(.data)[inst].un_op;5075 const un_op = self.air.instructions.items(.data)[inst].un_op;
5061 const ty = self.typeOf(un_op);5076 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
5064 const src_mcv = try self.resolveInst(un_op);5079 const src_mcv = try self.resolveInst(un_op);
5065 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))5080 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 {...@@ -5071,7 +5086,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5071 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);5086 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
50725087
5073 const result: MCValue = result: {5088 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)) {
5075 .Float => switch (ty.floatBits(self.target.*)) {5090 .Float => switch (ty.floatBits(self.target.*)) {
5076 16 => if (self.hasFeature(.f16c)) {5091 16 => if (self.hasFeature(.f16c)) {
5077 const mat_src_reg = if (src_mcv.isRegister())5092 const mat_src_reg = if (src_mcv.isRegister())
...@@ -5125,7 +5140,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -5125,7 +5140,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5125 .{ .v_ps, .cvtph2 },5140 .{ .v_ps, .cvtph2 },
5126 wide_reg,5141 wide_reg,
5127 src_mcv.mem(Memory.PtrSize.fromSize(5142 src_mcv.mem(Memory.PtrSize.fromSize(
5128 @as(u32, @intCast(@divExact(wide_reg.bitSize(), 16))),5143 @intCast(@divExact(wide_reg.bitSize(), 16)),
5129 )),5144 )),
5130 ) else try self.asmRegisterRegister(5145 ) else try self.asmRegisterRegister(
5131 .{ .v_ps, .cvtph2 },5146 .{ .v_ps, .cvtph2 },
...@@ -5164,7 +5179,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -5164,7 +5179,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5164 else => unreachable,5179 else => unreachable,
5165 },5180 },
5166 else => unreachable,5181 else => unreachable,
5167 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{5182 }) orelse return self.fail("TODO implement airSqrt for {}", .{
5168 ty.fmt(mod),5183 ty.fmt(mod),
5169 });5184 });
5170 switch (mir_tag[0]) {5185 switch (mir_tag[0]) {
...@@ -5257,10 +5272,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn...@@ -5257,10 +5272,10 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
5257 const ptr_info = ptr_ty.ptrInfo(mod);5272 const ptr_info = ptr_ty.ptrInfo(mod);
52585273
5259 const val_ty = ptr_info.child.toType();5274 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));
5261 const limb_abi_size: u32 = @min(val_abi_size, 8);5276 const limb_abi_size: u32 = @min(val_abi_size, 8);
5262 const limb_abi_bits = limb_abi_size * 8;5277 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);
5264 const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;5279 const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
5265 const val_extra_bits = self.regExtraBits(val_ty);5280 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...@@ -5404,9 +5419,10 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
54045419
5405 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);5420 const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8);
5406 const limb_abi_bits = limb_abi_size * 8;5421 const limb_abi_bits = limb_abi_size * 8;
5422 const limb_ty = try mod.intType(.unsigned, limb_abi_bits);
54075423
5408 const src_bit_size = src_ty.bitSize(mod);5424 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);
5410 const src_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;5426 const src_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits;
54115427
5412 const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);5428 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...@@ -5423,10 +5439,9 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
5423 .disp = src_byte_off + limb_i * limb_abi_bits,5439 .disp = src_byte_off + limb_i * limb_abi_bits,
5424 });5440 });
54255441
5426 const part_mask = (@as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - part_bit_size))) <<5442 const part_mask = (@as(u64, math.maxInt(u64)) >> @intCast(64 - part_bit_size)) <<
5427 @as(u6, @intCast(part_bit_off));5443 @intCast(part_bit_off);
5428 const part_mask_not = part_mask ^5444 const part_mask_not = part_mask ^ (@as(u64, math.maxInt(u64)) >> @intCast(64 - limb_abi_bits));
5429 (@as(u64, math.maxInt(u64)) >> @as(u6, @intCast(64 - limb_abi_bits)));
5430 if (limb_abi_size <= 4) {5445 if (limb_abi_size <= 4) {
5431 try self.asmMemoryImmediate(.{ ._, .@"and" }, limb_mem, Immediate.u(part_mask_not));5446 try self.asmMemoryImmediate(.{ ._, .@"and" }, limb_mem, Immediate.u(part_mask_not));
5432 } else if (math.cast(i32, @as(i64, @bitCast(part_mask_not)))) |small| {5447 } 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...@@ -5443,23 +5458,23 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
5443 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);5458 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
5444 defer self.register_manager.unlockReg(tmp_lock);5459 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);
5447 switch (limb_i) {5462 switch (limb_i) {
5448 0 => try self.genShiftBinOpMir(5463 0 => try self.genShiftBinOpMir(
5449 .{ ._l, .sh },5464 .{ ._l, .sh },
5450 src_ty,5465 limb_ty,
5451 tmp_mcv,5466 tmp_mcv,
5452 .{ .immediate = src_bit_off },5467 .{ .immediate = src_bit_off },
5453 ),5468 ),
5454 1 => try self.genShiftBinOpMir(5469 1 => try self.genShiftBinOpMir(
5455 .{ ._r, .sh },5470 .{ ._r, .sh },
5456 src_ty,5471 limb_ty,
5457 tmp_mcv,5472 tmp_mcv,
5458 .{ .immediate = limb_abi_bits - src_bit_off },5473 .{ .immediate = limb_abi_bits - src_bit_off },
5459 ),5474 ),
5460 else => unreachable,5475 else => unreachable,
5461 }5476 }
5462 try self.genBinOpMir(.{ ._, .@"and" }, src_ty, tmp_mcv, .{ .immediate = part_mask });5477 try self.genBinOpMir(.{ ._, .@"and" }, limb_ty, tmp_mcv, .{ .immediate = part_mask });
5463 try self.asmMemoryRegister(5478 try self.asmMemoryRegister(
5464 .{ ._, .@"or" },5479 .{ ._, .@"or" },
5465 limb_mem,5480 limb_mem,
...@@ -5544,14 +5559,14 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32...@@ -5544,14 +5559,14 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
5544 const ptr_field_ty = self.typeOfIndex(inst);5559 const ptr_field_ty = self.typeOfIndex(inst);
5545 const ptr_container_ty = self.typeOf(operand);5560 const ptr_container_ty = self.typeOf(operand);
5546 const container_ty = ptr_container_ty.childType(mod);5561 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)) {
5548 .Auto, .Extern => container_ty.structFieldOffset(index, mod),5563 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
5549 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and5564 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and
5550 ptr_field_ty.ptrInfo(mod).packed_offset.host_size == 0)5565 ptr_field_ty.ptrInfo(mod).packed_offset.host_size == 0)
5551 container_ty.packedStructFieldByteOffset(index, mod)5566 container_ty.packedStructFieldByteOffset(index, mod)
5552 else5567 else
5553 0,5568 0,
5554 }));5569 });
55555570
5556 const src_mcv = try self.resolveInst(operand);5571 const src_mcv = try self.resolveInst(operand);
5557 const dst_mcv = if (switch (src_mcv) {5572 const dst_mcv = if (switch (src_mcv) {
...@@ -5578,8 +5593,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5578,8 +5593,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5578 const field_is_gp = field_rc.supersetOf(gp);5593 const field_is_gp = field_rc.supersetOf(gp);
55795594
5580 const src_mcv = try self.resolveInst(operand);5595 const src_mcv = try self.resolveInst(operand);
5581 const field_off = switch (container_ty.containerLayout(mod)) {5596 const field_off: u32 = switch (container_ty.containerLayout(mod)) {
5582 .Auto, .Extern => @as(u32, @intCast(container_ty.structFieldOffset(index, mod) * 8)),5597 .Auto, .Extern => @intCast(container_ty.structFieldOffset(index, mod) * 8),
5583 .Packed => if (mod.typeToStruct(container_ty)) |struct_obj|5598 .Packed => if (mod.typeToStruct(container_ty)) |struct_obj|
5584 struct_obj.packedFieldBitOffset(mod, index)5599 struct_obj.packedFieldBitOffset(mod, index)
5585 else5600 else
...@@ -5588,9 +5603,31 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5588,9 +5603,31 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
55885603
5589 switch (src_mcv) {5604 switch (src_mcv) {
5590 .load_frame => |frame_addr| {5605 .load_frame => |frame_addr| {
5606 const field_abi_size: u32 = @intCast(field_ty.abiSize(mod));
5591 if (field_off % 8 == 0) {5607 if (field_off % 8 == 0) {
5592 const off_mcv =5608 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
5594 if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result off_mcv;5631 if (self.reuseOperand(inst, operand, 0, src_mcv)) break :result off_mcv;
55955632
5596 const dst_mcv = try self.allocRegOrMem(inst, true);5633 const dst_mcv = try self.allocRegOrMem(inst, true);
...@@ -5598,10 +5635,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5598,10 +5635,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5598 break :result dst_mcv;5635 break :result dst_mcv;
5599 }5636 }
56005637
5601 const field_abi_size = @as(u32, @intCast(field_ty.abiSize(mod)));
5602 const limb_abi_size: u32 = @min(field_abi_size, 8);5638 const limb_abi_size: u32 = @min(field_abi_size, 8);
5603 const limb_abi_bits = limb_abi_size * 8;5639 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);
5605 const field_bit_off = field_off % limb_abi_bits;5641 const field_bit_off = field_off % limb_abi_bits;
56065642
5607 if (field_abi_size > 8) {5643 if (field_abi_size > 8) {
...@@ -5726,7 +5762,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5726,7 +5762,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
57265762
5727 const inst_ty = self.typeOfIndex(inst);5763 const inst_ty = self.typeOfIndex(inst);
5728 const parent_ty = inst_ty.childType(mod);5764 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
5731 const src_mcv = try self.resolveInst(extra.field_ptr);5767 const src_mcv = try self.resolveInst(extra.field_ptr);
5732 const dst_mcv = if (src_mcv.isRegisterOffset() and5768 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:...@@ -5775,14 +5811,14 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
57755811
5776 switch (tag) {5812 switch (tag) {
5777 .not => {5813 .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));
5779 const int_info = if (src_ty.ip_index == .bool_type)5815 const int_info = if (src_ty.ip_index == .bool_type)
5780 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }5816 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }
5781 else5817 else
5782 src_ty.intInfo(mod);5818 src_ty.intInfo(mod);
5783 var byte_off: i32 = 0;5819 var byte_off: i32 = 0;
5784 while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) {5820 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));
5786 const limb_ty = try mod.intType(int_info.signedness, limb_bits);5822 const limb_ty = try mod.intType(int_info.signedness, limb_bits);
5787 const limb_mcv = switch (byte_off) {5823 const limb_mcv = switch (byte_off) {
5788 0 => dst_mcv,5824 0 => dst_mcv,
...@@ -5790,7 +5826,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -5790,7 +5826,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
5790 };5826 };
57915827
5792 if (int_info.signedness == .unsigned and self.regExtraBits(limb_ty) > 0) {5828 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);
5794 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });5830 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });
5795 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);5831 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);
5796 }5832 }
...@@ -5803,7 +5839,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -5803,7 +5839,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
58035839
5804fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {5840fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
5805 const mod = self.bin_file.options.module.?;5841 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));
5807 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{5843 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{
5808 mir_tag,5844 mir_tag,
5809 dst_ty.fmt(self.bin_file.options.module.?),5845 dst_ty.fmt(self.bin_file.options.module.?),
...@@ -5865,7 +5901,7 @@ fn genShiftBinOpMir(...@@ -5865,7 +5901,7 @@ fn genShiftBinOpMir(
5865 break :rhs .{ .register = .rcx };5901 break :rhs .{ .register = .rcx };
5866 };5902 };
58675903
5868 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));5904 const abi_size: u32 = @intCast(ty.abiSize(mod));
5869 if (abi_size <= 8) {5905 if (abi_size <= 8) {
5870 switch (lhs_mcv) {5906 switch (lhs_mcv) {
5871 .register => |lhs_reg| switch (rhs_mcv) {5907 .register => |lhs_reg| switch (rhs_mcv) {
...@@ -6085,16 +6121,16 @@ fn genShiftBinOp(...@@ -6085,16 +6121,16 @@ fn genShiftBinOp(
6085 rhs_ty: Type,6121 rhs_ty: Type,
6086) !MCValue {6122) !MCValue {
6087 const mod = self.bin_file.options.module.?;6123 const mod = self.bin_file.options.module.?;
6088 if (lhs_ty.zigTypeTag(mod) == .Vector) {6124 if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{
6089 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});6125 lhs_ty.fmt(mod),
6090 }6126 });
60916127
6092 assert(rhs_ty.abiSize(mod) == 1);6128 assert(rhs_ty.abiSize(mod) == 1);
60936129
6094 const lhs_abi_size = lhs_ty.abiSize(mod);6130 const lhs_abi_size = lhs_ty.abiSize(mod);
6095 if (lhs_abi_size > 16) {6131 if (lhs_abi_size > 16) return self.fail("TODO implement genShiftBinOp for {}", .{
6096 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});6132 lhs_ty.fmt(mod),
6097 }6133 });
60986134
6099 try self.register_manager.getReg(.rcx, null);6135 try self.register_manager.getReg(.rcx, null);
6100 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);6136 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);
...@@ -6150,11 +6186,12 @@ fn genMulDivBinOp(...@@ -6150,11 +6186,12 @@ fn genMulDivBinOp(
6150 rhs: MCValue,6186 rhs: MCValue,
6151) !MCValue {6187) !MCValue {
6152 const mod = self.bin_file.options.module.?;6188 const mod = self.bin_file.options.module.?;
6153 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) {6189 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail(
6154 return self.fail("TODO implement genMulDivBinOp for {}", .{dst_ty.fmtDebug()});6190 "TODO implement genMulDivBinOp for {}",
6155 }6191 .{dst_ty.fmt(mod)},
6156 const dst_abi_size = @as(u32, @intCast(dst_ty.abiSize(mod)));6192 );
6157 const src_abi_size = @as(u32, @intCast(src_ty.abiSize(mod)));6193 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod));
6194 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));
6158 if (switch (tag) {6195 if (switch (tag) {
6159 else => unreachable,6196 else => unreachable,
6160 .mul, .mul_wrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,6197 .mul, .mul_wrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,
...@@ -6328,7 +6365,13 @@ fn genBinOp(...@@ -6328,7 +6365,13 @@ fn genBinOp(
6328 const mod = self.bin_file.options.module.?;6365 const mod = self.bin_file.options.module.?;
6329 const lhs_ty = self.typeOf(lhs_air);6366 const lhs_ty = self.typeOf(lhs_air);
6330 const rhs_ty = self.typeOf(rhs_air);6367 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
6333 const maybe_mask_reg = switch (air_tag) {6376 const maybe_mask_reg = switch (air_tag) {
6334 else => null,6377 else => null,
...@@ -6339,6 +6382,9 @@ fn genBinOp(...@@ -6339,6 +6382,9 @@ fn genBinOp(
6339 } else try self.register_manager.allocReg(null, sse),6382 } else try self.register_manager.allocReg(null, sse),
6340 abi_size,6383 abi_size,
6341 ) else null,6384 ) 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 }),
6342 };6388 };
6343 const mask_lock =6389 const mask_lock =
6344 if (maybe_mask_reg) |mask_reg| self.register_manager.lockRegAssumeUnused(mask_reg) else null;6390 if (maybe_mask_reg) |mask_reg| self.register_manager.lockRegAssumeUnused(mask_reg) else null;
...@@ -6543,7 +6589,7 @@ fn genBinOp(...@@ -6543,7 +6589,7 @@ fn genBinOp(
6543 Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), switch (mat_src_mcv) {6589 Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), switch (mat_src_mcv) {
6544 .memory => |addr| .{6590 .memory => |addr| .{
6545 .base = .{ .reg = .ds },6591 .base = .{ .reg = .ds },
6546 .disp = @as(i32, @intCast(@as(i64, @bitCast(addr)))),6592 .disp = @intCast(@as(i64, @bitCast(addr))),
6547 },6593 },
6548 .indirect => |reg_off| .{6594 .indirect => |reg_off| .{
6549 .base = .{ .reg = reg_off.reg },6595 .base = .{ .reg = reg_off.reg },
...@@ -6569,7 +6615,7 @@ fn genBinOp(...@@ -6569,7 +6615,7 @@ fn genBinOp(
6569 }6615 }
65706616
6571 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);6617 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)) {
6573 else => unreachable,6619 else => unreachable,
6574 .Float => switch (lhs_ty.floatBits(self.target.*)) {6620 .Float => switch (lhs_ty.floatBits(self.target.*)) {
6575 16 => if (self.hasFeature(.f16c)) {6621 16 => if (self.hasFeature(.f16c)) {
...@@ -7131,7 +7177,7 @@ fn genBinOp(...@@ -7131,7 +7177,7 @@ fn genBinOp(
7131 else => unreachable,7177 else => unreachable,
7132 },7178 },
7133 },7179 },
7134 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7180 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7135 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7181 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7136 });7182 });
71377183
...@@ -7194,7 +7240,7 @@ fn genBinOp(...@@ -7194,7 +7240,7 @@ fn genBinOp(
7194 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);7240 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
71957241
7196 try self.asmRegisterRegisterRegisterImmediate(7242 try self.asmRegisterRegisterRegisterImmediate(
7197 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {7243 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7198 .Float => switch (lhs_ty.floatBits(self.target.*)) {7244 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7199 32 => .{ .v_ss, .cmp },7245 32 => .{ .v_ss, .cmp },
7200 64 => .{ .v_sd, .cmp },7246 64 => .{ .v_sd, .cmp },
...@@ -7219,7 +7265,7 @@ fn genBinOp(...@@ -7219,7 +7265,7 @@ fn genBinOp(
7219 else => unreachable,7265 else => unreachable,
7220 },7266 },
7221 else => unreachable,7267 else => unreachable,
7222 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7268 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7223 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7269 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7224 }),7270 }),
7225 mask_reg,7271 mask_reg,
...@@ -7228,7 +7274,7 @@ fn genBinOp(...@@ -7228,7 +7274,7 @@ fn genBinOp(
7228 Immediate.u(3), // unord7274 Immediate.u(3), // unord
7229 );7275 );
7230 try self.asmRegisterRegisterRegisterRegister(7276 try self.asmRegisterRegisterRegisterRegister(
7231 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {7277 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7232 .Float => switch (lhs_ty.floatBits(self.target.*)) {7278 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7233 32 => .{ .v_ps, .blendv },7279 32 => .{ .v_ps, .blendv },
7234 64 => .{ .v_pd, .blendv },7280 64 => .{ .v_pd, .blendv },
...@@ -7251,7 +7297,7 @@ fn genBinOp(...@@ -7251,7 +7297,7 @@ fn genBinOp(
7251 else => unreachable,7297 else => unreachable,
7252 },7298 },
7253 else => unreachable,7299 else => unreachable,
7254 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7300 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7255 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7301 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7256 }),7302 }),
7257 dst_reg,7303 dst_reg,
...@@ -7262,7 +7308,7 @@ fn genBinOp(...@@ -7262,7 +7308,7 @@ fn genBinOp(
7262 } else {7308 } else {
7263 const has_blend = self.hasFeature(.sse4_1);7309 const has_blend = self.hasFeature(.sse4_1);
7264 try self.asmRegisterRegisterImmediate(7310 try self.asmRegisterRegisterImmediate(
7265 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {7311 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7266 .Float => switch (lhs_ty.floatBits(self.target.*)) {7312 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7267 32 => .{ ._ss, .cmp },7313 32 => .{ ._ss, .cmp },
7268 64 => .{ ._sd, .cmp },7314 64 => .{ ._sd, .cmp },
...@@ -7287,7 +7333,7 @@ fn genBinOp(...@@ -7287,7 +7333,7 @@ fn genBinOp(
7287 else => unreachable,7333 else => unreachable,
7288 },7334 },
7289 else => unreachable,7335 else => unreachable,
7290 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7336 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7291 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7337 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7292 }),7338 }),
7293 mask_reg,7339 mask_reg,
...@@ -7295,7 +7341,7 @@ fn genBinOp(...@@ -7295,7 +7341,7 @@ fn genBinOp(
7295 Immediate.u(if (has_blend) 3 else 7), // unord, ord7341 Immediate.u(if (has_blend) 3 else 7), // unord, ord
7296 );7342 );
7297 if (has_blend) try self.asmRegisterRegisterRegister(7343 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)) {
7299 .Float => switch (lhs_ty.floatBits(self.target.*)) {7345 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7300 32 => .{ ._ps, .blendv },7346 32 => .{ ._ps, .blendv },
7301 64 => .{ ._pd, .blendv },7347 64 => .{ ._pd, .blendv },
...@@ -7318,7 +7364,7 @@ fn genBinOp(...@@ -7318,7 +7364,7 @@ fn genBinOp(
7318 else => unreachable,7364 else => unreachable,
7319 },7365 },
7320 else => unreachable,7366 else => unreachable,
7321 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7367 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7322 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7368 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7323 }),7369 }),
7324 dst_reg,7370 dst_reg,
...@@ -7326,7 +7372,7 @@ fn genBinOp(...@@ -7326,7 +7372,7 @@ fn genBinOp(
7326 mask_reg,7372 mask_reg,
7327 ) else {7373 ) else {
7328 try self.asmRegisterRegister(7374 try self.asmRegisterRegister(
7329 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {7375 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7330 .Float => switch (lhs_ty.floatBits(self.target.*)) {7376 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7331 32 => .{ ._ps, .@"and" },7377 32 => .{ ._ps, .@"and" },
7332 64 => .{ ._pd, .@"and" },7378 64 => .{ ._pd, .@"and" },
...@@ -7349,14 +7395,14 @@ fn genBinOp(...@@ -7349,14 +7395,14 @@ fn genBinOp(
7349 else => unreachable,7395 else => unreachable,
7350 },7396 },
7351 else => unreachable,7397 else => unreachable,
7352 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7398 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7353 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7399 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7354 }),7400 }),
7355 dst_reg,7401 dst_reg,
7356 mask_reg,7402 mask_reg,
7357 );7403 );
7358 try self.asmRegisterRegister(7404 try self.asmRegisterRegister(
7359 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {7405 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7360 .Float => switch (lhs_ty.floatBits(self.target.*)) {7406 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7361 32 => .{ ._ps, .andn },7407 32 => .{ ._ps, .andn },
7362 64 => .{ ._pd, .andn },7408 64 => .{ ._pd, .andn },
...@@ -7379,14 +7425,14 @@ fn genBinOp(...@@ -7379,14 +7425,14 @@ fn genBinOp(
7379 else => unreachable,7425 else => unreachable,
7380 },7426 },
7381 else => unreachable,7427 else => unreachable,
7382 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7428 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7383 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7429 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7384 }),7430 }),
7385 mask_reg,7431 mask_reg,
7386 lhs_copy_reg.?,7432 lhs_copy_reg.?,
7387 );7433 );
7388 try self.asmRegisterRegister(7434 try self.asmRegisterRegister(
7389 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {7435 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
7390 .Float => switch (lhs_ty.floatBits(self.target.*)) {7436 .Float => switch (lhs_ty.floatBits(self.target.*)) {
7391 32 => .{ ._ps, .@"or" },7437 32 => .{ ._ps, .@"or" },
7392 64 => .{ ._pd, .@"or" },7438 64 => .{ ._pd, .@"or" },
...@@ -7409,7 +7455,7 @@ fn genBinOp(...@@ -7409,7 +7455,7 @@ fn genBinOp(
7409 else => unreachable,7455 else => unreachable,
7410 },7456 },
7411 else => unreachable,7457 else => unreachable,
7412 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{7458 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
7413 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),7459 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7414 }),7460 }),
7415 dst_reg,7461 dst_reg,
...@@ -7431,7 +7477,7 @@ fn genBinOpMir(...@@ -7431,7 +7477,7 @@ fn genBinOpMir(
7431 src_mcv: MCValue,7477 src_mcv: MCValue,
7432) !void {7478) !void {
7433 const mod = self.bin_file.options.module.?;7479 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));
7435 switch (dst_mcv) {7481 switch (dst_mcv) {
7436 .none,7482 .none,
7437 .unreach,7483 .unreach,
...@@ -7679,10 +7725,10 @@ fn genBinOpMir(...@@ -7679,10 +7725,10 @@ fn genBinOpMir(
7679 else => unreachable,7725 else => unreachable,
7680 },7726 },
7681 .immediate => |src_imm| {7727 .immediate => |src_imm| {
7682 const imm = switch (off) {7728 const imm: u64 = switch (off) {
7683 0 => src_imm,7729 0 => src_imm,
7684 else => switch (ty_signedness) {7730 else => switch (ty_signedness) {
7685 .signed => @as(u64, @bitCast(@as(i64, @bitCast(src_imm)) >> 63)),7731 .signed => @bitCast(@as(i64, @bitCast(src_imm)) >> 63),
7686 .unsigned => 0,7732 .unsigned => 0,
7687 },7733 },
7688 };7734 };
...@@ -7755,7 +7801,7 @@ fn genBinOpMir(...@@ -7755,7 +7801,7 @@ fn genBinOpMir(
7755 0 => src_mcv,7801 0 => src_mcv,
7756 else => .{ .immediate = 0 },7802 else => .{ .immediate = 0 },
7757 },7803 },
7758 .memory => |addr| .{ .memory = @as(u64, @bitCast(@as(i64, @bitCast(addr)) + off)) },7804 .memory => |addr| .{ .memory = @bitCast(@as(i64, @bitCast(addr)) + off) },
7759 .indirect => |reg_off| .{ .indirect = .{7805 .indirect => |reg_off| .{ .indirect = .{
7760 .reg = reg_off.reg,7806 .reg = reg_off.reg,
7761 .off = reg_off.off + off,7807 .off = reg_off.off + off,
...@@ -7782,7 +7828,7 @@ fn genBinOpMir(...@@ -7782,7 +7828,7 @@ fn genBinOpMir(
7782/// Does not support byte-size operands.7828/// Does not support byte-size operands.
7783fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {7829fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
7784 const mod = self.bin_file.options.module.?;7830 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));
7786 switch (dst_mcv) {7832 switch (dst_mcv) {
7787 .none,7833 .none,
7788 .unreach,7834 .unreach,
...@@ -8016,7 +8062,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8016,7 +8062,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8016 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8062 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8017 const callee = pl_op.operand;8063 const callee = pl_op.operand;
8018 const extra = self.air.extraData(Air.Call, pl_op.payload);8064 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]);
8020 const ty = self.typeOf(callee);8066 const ty = self.typeOf(callee);
80218067
8022 const fn_ty = switch (ty.zigTypeTag(mod)) {8068 const fn_ty = switch (ty.zigTypeTag(mod)) {
...@@ -8109,7 +8155,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8109,7 +8155,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8109 const got_addr = atom.getOffsetTableAddress(elf_file);8155 const got_addr = atom.getOffsetTableAddress(elf_file);
8110 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{8156 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
8111 .base = .{ .reg = .ds },8157 .base = .{ .reg = .ds },
8112 .disp = @as(i32, @intCast(got_addr)),8158 .disp = @intCast(got_addr),
8113 }));8159 }));
8114 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {8160 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8115 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);8161 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);
...@@ -8126,7 +8172,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8126,7 +8172,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8126 const atom = p9.getAtom(atom_index);8172 const atom = p9.getAtom(atom_index);
8127 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{8173 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
8128 .base = .{ .reg = .ds },8174 .base = .{ .reg = .ds },
8129 .disp = @as(i32, @intCast(atom.getOffsetTableAddress(p9))),8175 .disp = @intCast(atom.getOffsetTableAddress(p9)),
8130 }));8176 }));
8131 } else unreachable;8177 } else unreachable;
8132 } else if (func_value.getExternFunc(mod)) |extern_func| {8178 } else if (func_value.getExternFunc(mod)) |extern_func| {
...@@ -8246,7 +8292,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -8246,7 +8292,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8246 const result = MCValue{8292 const result = MCValue{
8247 .eflags = switch (ty.zigTypeTag(mod)) {8293 .eflags = switch (ty.zigTypeTag(mod)) {
8248 else => result: {8294 else => result: {
8249 const abi_size = @as(u16, @intCast(ty.abiSize(mod)));8295 const abi_size: u16 = @intCast(ty.abiSize(mod));
8250 const may_flip: enum {8296 const may_flip: enum {
8251 may_flip,8297 may_flip,
8252 must_flip,8298 must_flip,
...@@ -8443,7 +8489,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -8443,7 +8489,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
8443 self.eflags_inst = inst;8489 self.eflags_inst = inst;
84448490
8445 const op_ty = self.typeOf(un_op);8491 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));
8447 const op_mcv = try self.resolveInst(un_op);8493 const op_mcv = try self.resolveInst(un_op);
8448 const dst_reg = switch (op_mcv) {8494 const dst_reg = switch (op_mcv) {
8449 .register => |reg| reg,8495 .register => |reg| reg,
...@@ -8652,7 +8698,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -8652,7 +8698,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8652 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))8698 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
8653 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }8699 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
8654 else8700 else
8655 .{ .off = @as(i32, @intCast(pl_ty.abiSize(mod))), .ty = Type.bool };8701 .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool };
86568702
8657 switch (opt_mcv) {8703 switch (opt_mcv) {
8658 .none,8704 .none,
...@@ -8672,14 +8718,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -8672,14 +8718,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86728718
8673 .register => |opt_reg| {8719 .register => |opt_reg| {
8674 if (some_info.off == 0) {8720 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));
8676 const alias_reg = registerAlias(opt_reg, some_abi_size);8722 const alias_reg = registerAlias(opt_reg, some_abi_size);
8677 assert(some_abi_size * 8 == alias_reg.bitSize());8723 assert(some_abi_size * 8 == alias_reg.bitSize());
8678 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);8724 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);
8679 return .{ .eflags = .z };8725 return .{ .eflags = .z };
8680 }8726 }
8681 assert(some_info.ty.ip_index == .bool_type);8727 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));
8683 try self.asmRegisterImmediate(8729 try self.asmRegisterImmediate(
8684 .{ ._, .bt },8730 .{ ._, .bt },
8685 registerAlias(opt_reg, opt_abi_size),8731 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...@@ -8698,7 +8744,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8698 defer self.register_manager.unlockReg(addr_reg_lock);8744 defer self.register_manager.unlockReg(addr_reg_lock);
86998745
8700 try self.genSetReg(addr_reg, Type.usize, opt_mcv.address());8746 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));
8702 try self.asmMemoryImmediate(8748 try self.asmMemoryImmediate(
8703 .{ ._, .cmp },8749 .{ ._, .cmp },
8704 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{8750 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...@@ -8711,7 +8757,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
8711 },8757 },
87128758
8713 .indirect, .load_frame => {8759 .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));
8715 try self.asmMemoryImmediate(8761 try self.asmMemoryImmediate(
8716 .{ ._, .cmp },8762 .{ ._, .cmp },
8717 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), switch (opt_mcv) {8763 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)...@@ -8743,7 +8789,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
8743 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))8789 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
8744 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }8790 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty }
8745 else8791 else
8746 .{ .off = @as(i32, @intCast(pl_ty.abiSize(mod))), .ty = Type.bool };8792 .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool };
87478793
8748 const ptr_reg = switch (ptr_mcv) {8794 const ptr_reg = switch (ptr_mcv) {
8749 .register => |reg| reg,8795 .register => |reg| reg,
...@@ -8752,7 +8798,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -8752,7 +8798,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
8752 const ptr_lock = self.register_manager.lockReg(ptr_reg);8798 const ptr_lock = self.register_manager.lockReg(ptr_reg);
8753 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);8799 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));
8756 try self.asmMemoryImmediate(8802 try self.asmMemoryImmediate(
8757 .{ ._, .cmp },8803 .{ ._, .cmp },
8758 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{8804 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) !...@@ -8785,12 +8831,11 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
87858831
8786 const tmp_reg = try self.copyToTmpRegister(ty, operand);8832 const tmp_reg = try self.copyToTmpRegister(ty, operand);
8787 if (err_off > 0) {8833 if (err_off > 0) {
8788 const shift = @as(u6, @intCast(err_off * 8));
8789 try self.genShiftBinOpMir(8834 try self.genShiftBinOpMir(
8790 .{ ._r, .sh },8835 .{ ._r, .sh },
8791 ty,8836 ty,
8792 .{ .register = tmp_reg },8837 .{ .register = tmp_reg },
8793 .{ .immediate = shift },8838 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
8794 );8839 );
8795 } else {8840 } else {
8796 try self.truncateRegister(Type.anyerror, tmp_reg);8841 try self.truncateRegister(Type.anyerror, tmp_reg);
...@@ -8945,7 +8990,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {...@@ -8945,7 +8990,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
8945 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8990 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8946 const loop = self.air.extraData(Air.Block, ty_pl.payload);8991 const loop = self.air.extraData(Air.Block, ty_pl.payload);
8947 const body = self.air.extra[loop.end..][0..loop.data.body_len];8992 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
8950 self.scope_generation += 1;8995 self.scope_generation += 1;
8951 const state = try self.saveState();8996 const state = try self.saveState();
...@@ -9017,10 +9062,8 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -9017,10 +9062,8 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
90179062
9018 while (case_i < switch_br.data.cases_len) : (case_i += 1) {9063 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
9019 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);9064 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
9020 const items = @as(9065 const items: []const Air.Inst.Ref =
9021 []const Air.Inst.Ref,9066 @ptrCast(self.air.extra[case.end..][0..case.data.items_len]);
9022 @ptrCast(self.air.extra[case.end..][0..case.data.items_len]),
9023 );
9024 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];9067 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
9025 extra_index = case.end + items.len + case_body.len;9068 extra_index = case.end + items.len + case_body.len;
90269069
...@@ -9068,7 +9111,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -9068,7 +9111,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
9068}9111}
90699112
9070fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {9113fn 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);
9072 switch (self.mir_instructions.items(.tag)[reloc]) {9115 switch (self.mir_instructions.items(.tag)[reloc]) {
9073 .j, .jmp => {},9116 .j, .jmp => {},
9074 .pseudo => switch (self.mir_instructions.items(.ops)[reloc]) {9117 .pseudo => switch (self.mir_instructions.items(.ops)[reloc]) {
...@@ -9143,11 +9186,12 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -9143,11 +9186,12 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
9143fn airAsm(self: *Self, inst: Air.Inst.Index) !void {9186fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
9144 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9187 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9145 const extra = self.air.extraData(Air.Asm, ty_pl.payload);9188 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);
9147 var extra_i: usize = extra.end;9190 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]);
9149 extra_i += outputs.len;9193 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]);
9151 extra_i += inputs.len;9195 extra_i += inputs.len;
91529196
9153 var result: MCValue = .none;9197 var result: MCValue = .none;
...@@ -9282,16 +9326,14 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -9282,16 +9326,14 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
9282 } else if (mem.startsWith(u8, op_str, "$")) {9326 } else if (mem.startsWith(u8, op_str, "$")) {
9283 if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| {9327 if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| {
9284 if (mnem_size) |size| {9328 if (mnem_size) |size| {
9285 const max = @as(u64, math.maxInt(u64)) >>9329 const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - (size.bitSize() - 1));
9286 @as(u6, @intCast(64 - (size.bitSize() - 1)));
9287 if ((if (s < 0) ~s else s) > max)9330 if ((if (s < 0) ~s else s) > max)
9288 return self.fail("Invalid immediate size: '{s}'", .{op_str});9331 return self.fail("Invalid immediate size: '{s}'", .{op_str});
9289 }9332 }
9290 op.* = .{ .imm = Immediate.s(s) };9333 op.* = .{ .imm = Immediate.s(s) };
9291 } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| {9334 } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| {
9292 if (mnem_size) |size| {9335 if (mnem_size) |size| {
9293 const max = @as(u64, math.maxInt(u64)) >>9336 const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - size.bitSize());
9294 @as(u6, @intCast(64 - size.bitSize()));
9295 if (u > max)9337 if (u > max)
9296 return self.fail("Invalid immediate size: '{s}'", .{op_str});9338 return self.fail("Invalid immediate size: '{s}'", .{op_str});
9297 }9339 }
...@@ -9643,7 +9685,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -9643,7 +9685,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
96439685
9644fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void {9686fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void {
9645 const mod = self.bin_file.options.module.?;9687 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));
9647 if (abi_size * 8 > dst_reg.bitSize())9689 if (abi_size * 8 > dst_reg.bitSize())
9648 return self.fail("genSetReg called with a value larger than dst_reg", .{});9690 return self.fail("genSetReg called with a value larger than dst_reg", .{});
9649 switch (src_mcv) {9691 switch (src_mcv) {
...@@ -9668,7 +9710,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9668,7 +9710,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9668 try self.asmRegisterImmediate(9710 try self.asmRegisterImmediate(
9669 .{ ._, .mov },9711 .{ ._, .mov },
9670 registerAlias(dst_reg, abi_size),9712 registerAlias(dst_reg, abi_size),
9671 Immediate.s(@as(i32, @intCast(@as(i64, @bitCast(imm))))),9713 Immediate.s(@intCast(@as(i64, @bitCast(imm)))),
9672 );9714 );
9673 } else {9715 } else {
9674 try self.asmRegisterImmediate(9716 try self.asmRegisterImmediate(
...@@ -9726,7 +9768,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9726,7 +9768,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9726 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },9768 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
9727 ),9769 ),
9728 .sse => try self.asmRegisterRegister(9770 .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)) {
9730 else => switch (abi_size) {9772 else => switch (abi_size) {
9731 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },9773 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
9732 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },9774 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...@@ -9750,7 +9792,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
9750 80 => null,9792 80 => null,
9751 else => unreachable,9793 else => unreachable,
9752 },9794 },
9753 })) |tag| tag else return self.fail("TODO implement genSetReg for {}", .{9795 }) orelse return self.fail("TODO implement genSetReg for {}", .{
9754 ty.fmt(self.bin_file.options.module.?),9796 ty.fmt(self.bin_file.options.module.?),
9755 }),9797 }),
9756 registerAlias(dst_reg, abi_size),9798 registerAlias(dst_reg, abi_size),
...@@ -9930,9 +9972,9 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -9930,9 +9972,9 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
99309972
9931fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void {9973fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void {
9932 const mod = self.bin_file.options.module.?;9974 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));
9934 const dst_ptr_mcv: MCValue = switch (base) {9976 const dst_ptr_mcv: MCValue = switch (base) {
9935 .none => .{ .immediate = @as(u64, @bitCast(@as(i64, disp))) },9977 .none => .{ .immediate = @bitCast(@as(i64, disp)) },
9936 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },9978 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },
9937 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },9979 .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } },
9938 };9980 };
...@@ -9943,7 +9985,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -9943,7 +9985,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
9943 .immediate => |imm| switch (abi_size) {9985 .immediate => |imm| switch (abi_size) {
9944 1, 2, 4 => {9986 1, 2, 4 => {
9945 const immediate = if (ty.isSignedInt(mod))9987 const immediate = if (ty.isSignedInt(mod))
9946 Immediate.s(@as(i32, @truncate(@as(i64, @bitCast(imm)))))9988 Immediate.s(@truncate(@as(i64, @bitCast(imm))))
9947 else9989 else
9948 Immediate.u(@as(u32, @intCast(imm)));9990 Immediate.u(@as(u32, @intCast(imm)));
9949 try self.asmMemoryImmediate(9991 try self.asmMemoryImmediate(
...@@ -9965,10 +10007,9 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -9965,10 +10007,9 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
9965 .{ ._, .mov },10007 .{ ._, .mov },
9966 Memory.sib(.dword, .{ .base = base, .disp = disp + offset }),10008 Memory.sib(.dword, .{ .base = base, .disp = disp + offset }),
9967 if (ty.isSignedInt(mod))10009 if (ty.isSignedInt(mod))
9968 Immediate.s(@as(10010 Immediate.s(
9969 i32,
9970 @truncate(@as(i64, @bitCast(imm)) >> (math.cast(u6, offset * 8) orelse 63)),10011 @truncate(@as(i64, @bitCast(imm)) >> (math.cast(u6, offset * 8) orelse 63)),
9971 ))10012 )
9972 else10013 else
9973 Immediate.u(@as(10014 Immediate.u(@as(
9974 u32,10015 u32,
...@@ -10079,7 +10120,7 @@ fn genLazySymbolRef(...@@ -10079,7 +10120,7 @@ fn genLazySymbolRef(
10079 _ = try atom.getOrCreateOffsetTableEntry(elf_file);10120 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
10080 const got_addr = atom.getOffsetTableAddress(elf_file);10121 const got_addr = atom.getOffsetTableAddress(elf_file);
10081 const got_mem =10122 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) });
10083 switch (tag) {10124 switch (tag) {
10084 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),10125 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),
10085 .call => try self.asmMemory(.{ ._, .call }, got_mem),10126 .call => try self.asmMemory(.{ ._, .call }, got_mem),
...@@ -10101,7 +10142,7 @@ fn genLazySymbolRef(...@@ -10101,7 +10142,7 @@ fn genLazySymbolRef(
10101 _ = atom.getOrCreateOffsetTableEntry(p9_file);10142 _ = atom.getOrCreateOffsetTableEntry(p9_file);
10102 const got_addr = atom.getOffsetTableAddress(p9_file);10143 const got_addr = atom.getOffsetTableAddress(p9_file);
10103 const got_mem =10144 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) });
10105 switch (tag) {10146 switch (tag) {
10106 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),10147 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),
10107 .call => try self.asmMemory(.{ ._, .call }, got_mem),10148 .call => try self.asmMemory(.{ ._, .call }, got_mem),
...@@ -10197,8 +10238,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -10197,8 +10238,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10197 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;10238 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
10198 if (dst_signedness == src_signedness) break :result dst_mcv;10239 if (dst_signedness == src_signedness) break :result dst_mcv;
1019910240
10200 const abi_size = @as(u16, @intCast(dst_ty.abiSize(mod)));10241 const abi_size: u16 = @intCast(dst_ty.abiSize(mod));
10201 const bit_size = @as(u16, @intCast(dst_ty.bitSize(mod)));10242 const bit_size: u16 = @intCast(dst_ty.bitSize(mod));
10202 if (abi_size * 8 <= bit_size) break :result dst_mcv;10243 if (abi_size * 8 <= bit_size) break :result dst_mcv;
1020310244
10204 const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable;10245 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 {...@@ -10239,7 +10280,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
10239 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);10280 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
10240 try self.genSetMem(10281 try self.genSetMem(
10241 .{ .frame = frame_index },10282 .{ .frame = frame_index },
10242 @as(i32, @intCast(ptr_ty.abiSize(mod))),10283 @intCast(ptr_ty.abiSize(mod)),
10243 Type.usize,10284 Type.usize,
10244 .{ .immediate = array_len },10285 .{ .immediate = array_len },
10245 );10286 );
...@@ -10253,7 +10294,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10253,7 +10294,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
10253 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10294 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1025410295
10255 const src_ty = self.typeOf(ty_op.operand);10296 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));
10257 const src_signedness =10298 const src_signedness =
10258 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;10299 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
10259 const dst_ty = self.typeOfIndex(inst);10300 const dst_ty = self.typeOfIndex(inst);
...@@ -10281,7 +10322,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10281,7 +10322,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
10281 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);10322 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
10282 defer self.register_manager.unlockReg(dst_lock);10323 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)) {
10285 .Float => switch (dst_ty.floatBits(self.target.*)) {10326 .Float => switch (dst_ty.floatBits(self.target.*)) {
10286 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },10327 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },
10287 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },10328 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },
...@@ -10289,7 +10330,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10289,7 +10330,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
10289 else => unreachable,10330 else => unreachable,
10290 },10331 },
10291 else => null,10332 else => null,
10292 })) |tag| tag else return self.fail("TODO implement airFloatFromInt from {} to {}", .{10333 }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{
10293 src_ty.fmt(mod), dst_ty.fmt(mod),10334 src_ty.fmt(mod), dst_ty.fmt(mod),
10294 });10335 });
10295 const dst_alias = dst_reg.to128();10336 const dst_alias = dst_reg.to128();
...@@ -10308,7 +10349,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10308,7 +10349,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
1030810349
10309 const src_ty = self.typeOf(ty_op.operand);10350 const src_ty = self.typeOf(ty_op.operand);
10310 const dst_ty = self.typeOfIndex(inst);10351 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));
10312 const dst_signedness =10353 const dst_signedness =
10313 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;10354 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 {...@@ -10334,7 +10375,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
10334 defer self.register_manager.unlockReg(dst_lock);10375 defer self.register_manager.unlockReg(dst_lock);
1033510376
10336 try self.asmRegisterRegister(10377 try self.asmRegisterRegister(
10337 if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) {10378 @as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) {
10338 .Float => switch (src_ty.floatBits(self.target.*)) {10379 .Float => switch (src_ty.floatBits(self.target.*)) {
10339 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },10380 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },
10340 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },10381 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },
...@@ -10342,7 +10383,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10342,7 +10383,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
10342 else => unreachable,10383 else => unreachable,
10343 },10384 },
10344 else => null,10385 else => null,
10345 })) |tag| tag else return self.fail("TODO implement airIntFromFloat from {} to {}", .{10386 }) orelse return self.fail("TODO implement airIntFromFloat from {} to {}", .{
10346 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),10387 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
10347 }),10388 }),
10348 registerAlias(dst_reg, dst_size),10389 registerAlias(dst_reg, dst_size),
...@@ -10361,7 +10402,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {...@@ -10361,7 +10402,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
1036110402
10362 const ptr_ty = self.typeOf(extra.ptr);10403 const ptr_ty = self.typeOf(extra.ptr);
10363 const val_ty = self.typeOf(extra.expected_value);10404 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
10366 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });10407 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
10367 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });10408 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
...@@ -10463,7 +10504,7 @@ fn atomicOp(...@@ -10463,7 +10504,7 @@ fn atomicOp(
10463 };10504 };
10464 defer if (val_lock) |lock| self.register_manager.unlockReg(lock);10505 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));
10467 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);10508 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);
10468 const ptr_mem = switch (ptr_mcv) {10509 const ptr_mem = switch (ptr_mcv) {
10469 .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size),10510 .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size),
...@@ -10541,7 +10582,7 @@ fn atomicOp(...@@ -10541,7 +10582,7 @@ fn atomicOp(
10541 defer self.register_manager.unlockReg(tmp_lock);10582 defer self.register_manager.unlockReg(tmp_lock);
1054210583
10543 try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(.rax, val_abi_size), ptr_mem);10584 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);
10545 if (rmw_op != std.builtin.AtomicRmwOp.Xchg) {10586 if (rmw_op != std.builtin.AtomicRmwOp.Xchg) {
10546 try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax });10587 try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax });
10547 }10588 }
...@@ -10615,7 +10656,7 @@ fn atomicOp(...@@ -10615,7 +10656,7 @@ fn atomicOp(
10615 .scale_index = ptr_mem.scaleIndex(),10656 .scale_index = ptr_mem.scaleIndex(),
10616 .disp = ptr_mem.sib.disp + 8,10657 .disp = ptr_mem.sib.disp + 8,
10617 }));10658 }));
10618 const loop = @as(u32, @intCast(self.mir_instructions.len));10659 const loop: u32 = @intCast(self.mir_instructions.len);
10619 const val_mem_mcv: MCValue = switch (val_mcv) {10660 const val_mem_mcv: MCValue = switch (val_mcv) {
10620 .memory, .indirect, .load_frame => val_mcv,10661 .memory, .indirect, .load_frame => val_mcv,
10621 else => .{ .indirect = .{10662 else => .{ .indirect = .{
...@@ -10771,7 +10812,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -10771,7 +10812,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10771 };10812 };
10772 defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock);10813 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
10776 if (elem_abi_size == 1) {10817 if (elem_abi_size == 1) {
10777 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) {10818 const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) {
...@@ -11251,9 +11292,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -11251,9 +11292,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
11251fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {11292fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11252 const mod = self.bin_file.options.module.?;11293 const mod = self.bin_file.options.module.?;
11253 const result_ty = self.typeOfIndex(inst);11294 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));
11255 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;11296 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]);
11257 const result: MCValue = result: {11298 const result: MCValue = result: {
11258 switch (result_ty.zigTypeTag(mod)) {11299 switch (result_ty.zigTypeTag(mod)) {
11259 .Struct => {11300 .Struct => {
...@@ -11270,17 +11311,17 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11270,17 +11311,17 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11270 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;11311 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;
1127111312
11272 const elem_ty = result_ty.structFieldType(elem_i, mod);11313 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));
11274 if (elem_bit_size > 64) {11315 if (elem_bit_size > 64) {
11275 return self.fail(11316 return self.fail(
11276 "TODO airAggregateInit implement packed structs with large fields",11317 "TODO airAggregateInit implement packed structs with large fields",
11277 .{},11318 .{},
11278 );11319 );
11279 }11320 }
11280 const elem_abi_size = @as(u32, @intCast(elem_ty.abiSize(mod)));11321 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod));
11281 const elem_abi_bits = elem_abi_size * 8;11322 const elem_abi_bits = elem_abi_size * 8;
11282 const elem_off = struct_obj.packedFieldBitOffset(mod, elem_i);11323 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);
11284 const elem_bit_off = elem_off % elem_abi_bits;11325 const elem_bit_off = elem_off % elem_abi_bits;
11285 const elem_mcv = try self.resolveInst(elem);11326 const elem_mcv = try self.resolveInst(elem);
11286 const mat_elem_mcv = switch (elem_mcv) {11327 const mat_elem_mcv = switch (elem_mcv) {
...@@ -11342,7 +11383,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11342,7 +11383,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11342 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;11383 if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue;
1134311384
11344 const elem_ty = result_ty.structFieldType(elem_i, mod);11385 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));
11346 const elem_mcv = try self.resolveInst(elem);11387 const elem_mcv = try self.resolveInst(elem);
11347 const mat_elem_mcv = switch (elem_mcv) {11388 const mat_elem_mcv = switch (elem_mcv) {
11348 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },11389 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
...@@ -11356,7 +11397,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11356,7 +11397,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11356 const frame_index =11397 const frame_index =
11357 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));11398 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));
11358 const elem_ty = result_ty.childType(mod);11399 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
11361 for (elements, 0..) |elem, elem_i| {11402 for (elements, 0..) |elem, elem_i| {
11362 const elem_mcv = try self.resolveInst(elem);11403 const elem_mcv = try self.resolveInst(elem);
...@@ -11364,12 +11405,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11364,12 +11405,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11364 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },11405 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
11365 else => elem_mcv,11406 else => elem_mcv,
11366 };11407 };
11367 const elem_off = @as(i32, @intCast(elem_size * elem_i));11408 const elem_off: i32 = @intCast(elem_size * elem_i);
11368 try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv);11409 try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv);
11369 }11410 }
11370 if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem(11411 if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem(
11371 .{ .frame = frame_index },11412 .{ .frame = frame_index },
11372 @as(i32, @intCast(elem_size * elements.len)),11413 @intCast(elem_size * elements.len),
11373 elem_ty,11414 elem_ty,
11374 try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }),11415 try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }),
11375 );11416 );
...@@ -11417,16 +11458,16 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11417,16 +11458,16 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11417 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);11458 const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
11418 const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);11459 const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);
11419 const tag_int = tag_int_val.toUnsignedInt(mod);11460 const tag_int = tag_int_val.toUnsignedInt(mod);
11420 const tag_off = if (layout.tag_align < layout.payload_align)11461 const tag_off: i32 = if (layout.tag_align < layout.payload_align)
11421 @as(i32, @intCast(layout.payload_size))11462 @intCast(layout.payload_size)
11422 else11463 else
11423 0;11464 0;
11424 try self.genCopy(tag_ty, dst_mcv.address().offset(tag_off).deref(), .{ .immediate = tag_int });11465 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)
11427 011468 0
11428 else11469 else
11429 @as(i32, @intCast(layout.tag_size));11470 @intCast(layout.tag_size);
11430 try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv);11471 try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv);
1143111472
11432 break :result dst_mcv;11473 break :result dst_mcv;
...@@ -11456,7 +11497,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11456,7 +11497,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11456 var order = [1]u2{0} ** 3;11497 var order = [1]u2{0} ** 3;
11457 var unused = std.StaticBitSet(3).initFull();11498 var unused = std.StaticBitSet(3).initFull();
11458 for (ops, &mcvs, &locks, 0..) |op, *mcv, *lock, op_i| {11499 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);
11460 mcv.* = try self.resolveInst(op);11501 mcv.* = try self.resolveInst(op);
11461 if (unused.isSet(0) and mcv.isRegister() and self.reuseOperand(inst, op, op_index, mcv.*)) {11502 if (unused.isSet(0) and mcv.isRegister() and self.reuseOperand(inst, op, op_index, mcv.*)) {
11462 order[op_index] = 1;11503 order[op_index] = 1;
...@@ -11480,99 +11521,97 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11480,99 +11521,97 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11480 lock.* = self.register_manager.lockRegAssumeUnused(reg);11521 lock.* = self.register_manager.lockRegAssumeUnused(reg);
11481 }11522 }
1148211523
11483 const mir_tag = if (@as(11524 const mir_tag = @as(?Mir.Inst.FixedTag, if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or
11484 ?Mir.Inst.FixedTag,11525 mem.eql(u2, &order, &.{ 3, 1, 2 }))
11485 if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 }))11526 switch (ty.zigTypeTag(mod)) {
11486 switch (ty.zigTypeTag(mod)) {11527 .Float => switch (ty.floatBits(self.target.*)) {
11487 .Float => switch (ty.floatBits(self.target.*)) {11528 32 => .{ .v_ss, .fmadd132 },
11488 32 => .{ .v_ss, .fmadd132 },11529 64 => .{ .v_sd, .fmadd132 },
11489 64 => .{ .v_sd, .fmadd132 },11530 16, 80, 128 => null,
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 },
11510 else => unreachable,11531 else => unreachable,
11511 }11532 },
11512 else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 }))11533 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11513 switch (ty.zigTypeTag(mod)) {11534 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11514 .Float => switch (ty.floatBits(self.target.*)) {11535 32 => switch (ty.vectorLen(mod)) {
11515 32 => .{ .v_ss, .fmadd213 },11536 1 => .{ .v_ss, .fmadd132 },
11516 64 => .{ .v_sd, .fmadd213 },11537 2...8 => .{ .v_ps, .fmadd132 },
11517 16, 80, 128 => null,11538 else => null,
11518 else => unreachable,11539 },
11519 },11540 64 => switch (ty.vectorLen(mod)) {
11520 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {11541 1 => .{ .v_sd, .fmadd132 },
11521 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {11542 2...4 => .{ .v_pd, .fmadd132 },
11522 32 => switch (ty.vectorLen(mod)) {11543 else => null,
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,
11534 },11544 },
11545 16, 80, 128 => null,
11535 else => unreachable,11546 else => unreachable,
11536 },11547 },
11537 else => unreachable,11548 else => unreachable,
11538 }11549 },
11539 else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 }))11550 else => unreachable,
11540 switch (ty.zigTypeTag(mod)) {11551 }
11541 .Float => switch (ty.floatBits(self.target.*)) {11552 else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 }))
11542 32 => .{ .v_ss, .fmadd231 },11553 switch (ty.zigTypeTag(mod)) {
11543 64 => .{ .v_sd, .fmadd231 },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 },
11544 16, 80, 128 => null,11572 16, 80, 128 => null,
11545 else => unreachable,11573 else => unreachable,
11546 },11574 },
11547 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {11575 else => unreachable,
11548 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {11576 },
11549 32 => switch (ty.vectorLen(mod)) {11577 else => unreachable,
11550 1 => .{ .v_ss, .fmadd231 },11578 }
11551 2...8 => .{ .v_ps, .fmadd231 },11579 else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 }))
11552 else => null,11580 switch (ty.zigTypeTag(mod)) {
11553 },11581 .Float => switch (ty.floatBits(self.target.*)) {
11554 64 => switch (ty.vectorLen(mod)) {11582 32 => .{ .v_ss, .fmadd231 },
11555 1 => .{ .v_sd, .fmadd231 },11583 64 => .{ .v_sd, .fmadd231 },
11556 2...4 => .{ .v_pd, .fmadd231 },11584 16, 80, 128 => null,
11557 else => null,11585 else => unreachable,
11558 },11586 },
11559 16, 80, 128 => null,11587 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
11560 else => unreachable,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,
11561 },11593 },
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,
11562 else => unreachable,11600 else => unreachable,
11563 },11601 },
11564 else => unreachable,11602 else => unreachable,
11565 }11603 },
11566 else11604 else => unreachable,
11567 unreachable,11605 }
11568 )) |tag| tag else return self.fail("TODO implement airMulAdd for {}", .{11606 else
11607 unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{
11569 ty.fmt(self.bin_file.options.module.?),11608 ty.fmt(self.bin_file.options.module.?),
11570 });11609 });
1157111610
11572 var mops: [3]MCValue = undefined;11611 var mops: [3]MCValue = undefined;
11573 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;11612 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));
11576 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);11615 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
11577 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);11616 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
11578 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(11617 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
...@@ -11725,7 +11764,7 @@ fn resolveCallingConventionValues(...@@ -11725,7 +11764,7 @@ fn resolveCallingConventionValues(
11725 switch (self.target.os.tag) {11764 switch (self.target.os.tag) {
11726 .windows => {11765 .windows => {
11727 // Align the stack to 16bytes before allocating shadow stack space (if any).11766 // 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));
11729 },11768 },
11730 else => {},11769 else => {},
11731 }11770 }
...@@ -11748,7 +11787,7 @@ fn resolveCallingConventionValues(...@@ -11748,7 +11787,7 @@ fn resolveCallingConventionValues(
11748 result.return_value = switch (classes[0]) {11787 result.return_value = switch (classes[0]) {
11749 .integer => InstTracking.init(.{ .register = registerAlias(11788 .integer => InstTracking.init(.{ .register = registerAlias(
11750 ret_reg,11789 ret_reg,
11751 @as(u32, @intCast(ret_ty.abiSize(mod))),11790 @intCast(ret_ty.abiSize(mod)),
11752 ) }),11791 ) }),
11753 .float, .sse => InstTracking.init(.{ .register = .xmm0 }),11792 .float, .sse => InstTracking.init(.{ .register = .xmm0 }),
11754 .memory => ret: {11793 .memory => ret: {
...@@ -11784,18 +11823,16 @@ fn resolveCallingConventionValues(...@@ -11784,18 +11823,16 @@ fn resolveCallingConventionValues(
11784 },11823 },
11785 .float, .sse => switch (self.target.os.tag) {11824 .float, .sse => switch (self.target.os.tag) {
11786 .windows => if (param_reg_i < 4) {11825 .windows => if (param_reg_i < 4) {
11787 arg.* = .{ .register = @as(11826 arg.* = .{
11788 Register,11827 .register = @enumFromInt(@intFromEnum(Register.xmm0) + param_reg_i),
11789 @enumFromInt(@intFromEnum(Register.xmm0) + param_reg_i),11828 };
11790 ) };
11791 param_reg_i += 1;11829 param_reg_i += 1;
11792 continue;11830 continue;
11793 },11831 },
11794 else => if (param_sse_reg_i < 8) {11832 else => if (param_sse_reg_i < 8) {
11795 arg.* = .{ .register = @as(11833 arg.* = .{
11796 Register,11834 .register = @enumFromInt(@intFromEnum(Register.xmm0) + param_sse_reg_i),
11797 @enumFromInt(@intFromEnum(Register.xmm0) + param_sse_reg_i),11835 };
11798 ) };
11799 param_sse_reg_i += 1;11836 param_sse_reg_i += 1;
11800 continue;11837 continue;
11801 },11838 },
...@@ -11806,8 +11843,8 @@ fn resolveCallingConventionValues(...@@ -11806,8 +11843,8 @@ fn resolveCallingConventionValues(
11806 }),11843 }),
11807 }11844 }
1180811845
11809 const param_size = @as(u31, @intCast(ty.abiSize(mod)));11846 const param_size: u31 = @intCast(ty.abiSize(mod));
11810 const param_align = @as(u31, @intCast(ty.abiAlignment(mod)));11847 const param_align: u31 = @intCast(ty.abiAlignment(mod));
11811 result.stack_byte_count =11848 result.stack_byte_count =
11812 mem.alignForward(u31, result.stack_byte_count, param_align);11849 mem.alignForward(u31, result.stack_byte_count, param_align);
11813 arg.* = .{ .load_frame = .{11850 arg.* = .{ .load_frame = .{
...@@ -11827,7 +11864,7 @@ fn resolveCallingConventionValues(...@@ -11827,7 +11864,7 @@ fn resolveCallingConventionValues(
11827 result.return_value = InstTracking.init(.none);11864 result.return_value = InstTracking.init(.none);
11828 } else {11865 } else {
11829 const ret_reg = abi.getCAbiIntReturnRegs(self.target.*)[0];11866 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));
11831 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {11868 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
11832 const aliased_reg = registerAlias(ret_reg, ret_ty_size);11869 const aliased_reg = registerAlias(ret_reg, ret_ty_size);
11833 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };11870 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };
...@@ -11846,8 +11883,8 @@ fn resolveCallingConventionValues(...@@ -11846,8 +11883,8 @@ fn resolveCallingConventionValues(
11846 arg.* = .none;11883 arg.* = .none;
11847 continue;11884 continue;
11848 }11885 }
11849 const param_size = @as(u31, @intCast(ty.abiSize(mod)));11886 const param_size: u31 = @intCast(ty.abiSize(mod));
11850 const param_align = @as(u31, @intCast(ty.abiAlignment(mod)));11887 const param_align: u31 = @intCast(ty.abiAlignment(mod));
11851 result.stack_byte_count =11888 result.stack_byte_count =
11852 mem.alignForward(u31, result.stack_byte_count, param_align);11889 mem.alignForward(u31, result.stack_byte_count, param_align);
11853 arg.* = .{ .load_frame = .{11890 arg.* = .{ .load_frame = .{
...@@ -11934,12 +11971,12 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {...@@ -11934,12 +11971,12 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
11934 const mod = self.bin_file.options.module.?;11971 const mod = self.bin_file.options.module.?;
11935 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{11972 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
11936 .signedness = .unsigned,11973 .signedness = .unsigned,
11937 .bits = @as(u16, @intCast(ty.bitSize(mod))),11974 .bits = @intCast(ty.bitSize(mod)),
11938 };11975 };
11939 const max_reg_bit_width = Register.rax.bitSize();11976 const max_reg_bit_width = Register.rax.bitSize();
11940 switch (int_info.signedness) {11977 switch (int_info.signedness) {
11941 .signed => {11978 .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);
11943 try self.genShiftBinOpMir(11980 try self.genShiftBinOpMir(
11944 .{ ._l, .sa },11981 .{ ._l, .sa },
11945 Type.isize,11982 Type.isize,
...@@ -11954,8 +11991,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {...@@ -11954,8 +11991,8 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
11954 );11991 );
11955 },11992 },
11956 .unsigned => {11993 .unsigned => {
11957 const shift = @as(u6, @intCast(max_reg_bit_width - int_info.bits));11994 const shift: u6 = @intCast(max_reg_bit_width - int_info.bits);
11958 const mask = (~@as(u64, 0)) >> shift;11995 const mask = ~@as(u64, 0) >> shift;
11959 if (int_info.bits <= 32) {11996 if (int_info.bits <= 32) {
11960 try self.genBinOpMir(11997 try self.genBinOpMir(
11961 .{ ._, .@"and" },11998 .{ ._, .@"and" },
src/arch/x86_64/bits.zig+1-1
...@@ -384,7 +384,7 @@ test "Register id - different classes" {...@@ -384,7 +384,7 @@ test "Register id - different classes" {
384 try expect(Register.xmm0.id() != Register.mm0.id());384 try expect(Register.xmm0.id() != Register.mm0.id());
385 try expect(Register.mm0.id() != Register.st0.id());385 try expect(Register.mm0.id() != Register.st0.id());
386386
387 try expect(Register.es.id() == 0b100000);387 try expect(Register.es.id() == 0b110000);
388}388}
389389
390test "Register enc - different classes" {390test "Register enc - different classes" {
src/arch/x86_64/encodings.zig+2-2
...@@ -369,11 +369,11 @@ pub const table = [_]Entry{...@@ -369,11 +369,11 @@ pub const table = [_]Entry{
369 .{ .mov, .rm, &.{ .sreg, .r32_m16 }, &.{ 0x8e }, 0, .none, .none },369 .{ .mov, .rm, &.{ .sreg, .r32_m16 }, &.{ 0x8e }, 0, .none, .none },
370 .{ .mov, .rm, &.{ .sreg, .r64_m16 }, &.{ 0x8e }, 0, .long, .none },370 .{ .mov, .rm, &.{ .sreg, .r64_m16 }, &.{ 0x8e }, 0, .long, .none },
371 .{ .mov, .fd, &.{ .al, .moffs }, &.{ 0xa0 }, 0, .none, .none },371 .{ .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 },
373 .{ .mov, .fd, &.{ .eax, .moffs }, &.{ 0xa1 }, 0, .none, .none },373 .{ .mov, .fd, &.{ .eax, .moffs }, &.{ 0xa1 }, 0, .none, .none },
374 .{ .mov, .fd, &.{ .rax, .moffs }, &.{ 0xa1 }, 0, .long, .none },374 .{ .mov, .fd, &.{ .rax, .moffs }, &.{ 0xa1 }, 0, .long, .none },
375 .{ .mov, .td, &.{ .moffs, .al }, &.{ 0xa2 }, 0, .none, .none },375 .{ .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 },
377 .{ .mov, .td, &.{ .moffs, .eax }, &.{ 0xa3 }, 0, .none, .none },377 .{ .mov, .td, &.{ .moffs, .eax }, &.{ 0xa3 }, 0, .none, .none },
378 .{ .mov, .td, &.{ .moffs, .rax }, &.{ 0xa3 }, 0, .long, .none },378 .{ .mov, .td, &.{ .moffs, .rax }, &.{ 0xa3 }, 0, .long, .none },
379 .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .none, .none },379 .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .none, .none },
src/codegen.zig+21-9
...@@ -558,7 +558,7 @@ pub fn generateSymbol(...@@ -558,7 +558,7 @@ pub fn generateSymbol(
558 }558 }
559559
560 // Check if we should store the tag first.560 // 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) {
562 switch (try generateSymbol(bin_file, src_loc, .{562 switch (try generateSymbol(bin_file, src_loc, .{
563 .ty = typed_value.ty.unionTagType(mod).?,563 .ty = typed_value.ty.unionTagType(mod).?,
564 .val = un.tag.toValue(),564 .val = un.tag.toValue(),
...@@ -589,7 +589,7 @@ pub fn generateSymbol(...@@ -589,7 +589,7 @@ pub fn generateSymbol(
589 }589 }
590 }590 }
591591
592 if (layout.tag_size > 0) {592 if (layout.tag_size > 0 and layout.tag_align < layout.payload_align) {
593 switch (try generateSymbol(bin_file, src_loc, .{593 switch (try generateSymbol(bin_file, src_loc, .{
594 .ty = union_ty.tag_ty,594 .ty = union_ty.tag_ty,
595 .val = un.tag.toValue(),595 .val = un.tag.toValue(),
...@@ -597,10 +597,10 @@ pub fn generateSymbol(...@@ -597,10 +597,10 @@ pub fn generateSymbol(
597 .ok => {},597 .ok => {},
598 .fail => |em| return Result{ .fail = em },598 .fail => |em| return Result{ .fail = em },
599 }599 }
600 }
601600
602 if (layout.padding > 0) {601 if (layout.padding > 0) {
603 try code.writer().writeByteNTimes(0, layout.padding);602 try code.writer().writeByteNTimes(0, layout.padding);
603 }
604 }604 }
605 },605 },
606 .memoized_call => unreachable,606 .memoized_call => unreachable,
...@@ -684,10 +684,22 @@ fn lowerParentPtr(...@@ -684,10 +684,22 @@ fn lowerParentPtr(
684 .struct_type,684 .struct_type,
685 .anon_struct_type,685 .anon_struct_type,
686 .union_type,686 .union_type,
687 => @as(u32, @intCast(base_type.toType().structFieldOffset(687 => switch (base_type.toType().containerLayout(mod)) {
688 @as(u32, @intCast(field.index)),688 .Auto, .Extern => @intCast(base_type.toType().structFieldOffset(
689 mod,689 @intCast(field.index),
690 ))),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 },
691 else => unreachable,703 else => unreachable,
692 }),704 }),
693 );705 );
test/behavior/bugs/13664.zig-1
...@@ -13,7 +13,6 @@ fn value() i64 {...@@ -13,7 +13,6 @@ fn value() i64 {
13 return 1341;13 return 1341;
14}14}
15test {15test {
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO18 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/bugs/1381.zig-1
...@@ -12,7 +12,6 @@ const A = union(enum) {...@@ -12,7 +12,6 @@ const A = union(enum) {
12};12};
1313
14test "union that needs padding bytes inside an array" {14test "union that needs padding bytes inside an array" {
15 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO17 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" {...@@ -376,7 +376,6 @@ test "load pointer from packed struct" {
376}376}
377377
378test "@intFromPtr on a packed struct field" {378test "@intFromPtr on a packed struct field" {
379 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
380 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;379 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
381 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;380 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
382 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO381 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -608,7 +607,6 @@ test "pointer to container level packed struct field" {...@@ -608,7 +607,6 @@ test "pointer to container level packed struct field" {
608 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;607 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
609 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;608 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
610 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;609 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
611 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
612 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO610 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
613 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;611 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
614612
test/behavior/struct.zig-3
...@@ -427,7 +427,6 @@ test "packed struct 24bits" {...@@ -427,7 +427,6 @@ test "packed struct 24bits" {
427 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;427 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
428 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO428 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
429 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO429 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
430 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
431 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO430 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO
432 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO431 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO
433 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO432 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -531,7 +530,6 @@ test "packed struct fields are ordered from LSB to MSB" {...@@ -531,7 +530,6 @@ test "packed struct fields are ordered from LSB to MSB" {
531test "implicit cast packed struct field to const ptr" {530test "implicit cast packed struct field to const ptr" {
532 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;531 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
533 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO532 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
534 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
535 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO533 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
536 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;534 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
537535
...@@ -1079,7 +1077,6 @@ test "packed struct with undefined initializers" {...@@ -1079,7 +1077,6 @@ test "packed struct with undefined initializers" {
1079 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1077 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1080 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1078 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1081 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1079 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1082 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1083 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1080 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1084 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1081 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10851082
test/behavior/threadlocal.zig+5
...@@ -12,6 +12,11 @@ test "thread local variable" {...@@ -12,6 +12,11 @@ test "thread local variable" {
12 }; // TODO12 }; // TODO
13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO13 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
15 const S = struct {20 const S = struct {
16 threadlocal var t: i32 = 1234;21 threadlocal var t: i32 = 1234;
17 };22 };