| ... | @@ -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 offsettable | 331 | => 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 | else | 698 | 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) { |
| 979 | fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { | 979 | fn 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 { |
| 1000 | | 1000 | |
| 1001 | fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | 1001 | fn 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 |
| 1490 | | 1490 | |
| 1491 | fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immediate) !void { | 1491 | fn 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 | } |
| 1622 | | 1622 | |
| 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 { |
| 1739 | | 1739 | |
| 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 | } |
| 1745 | | 1745 | |
| ... | @@ -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 { |
| 2034 | | 2034 | |
| 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); |
| 2054 | | 2054 | |
| 2055 | data_off += @as(i32, @intCast(tag_name.len + 1)); | 2055 | data_off += @intCast(tag_name.len + 1); |
| 2056 | } | 2056 | } |
| 2057 | | 2057 | |
| 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); |
| 2170 | | 2170 | |
| 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 | } |
| 2199 | | 2199 | |
| 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)]); |
| 2216 | | 2216 | |
| 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 { |
| 2323 | | 2323 | |
| 2324 | fn initRetroactiveState(self: *Self) State { | 2324 | fn 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 { |
| 2630 | | 2628 | |
| 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)); |
| 2634 | | 2632 | |
| 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; |
| 2709 | | 2707 | |
| 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)); |
| 2714 | | 2712 | |
| 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 | }); |
| 2756 | | 2754 | |
| 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)); |
| 2759 | | 2757 | |
| 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)); |
| 2765 | | 2763 | |
| 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 | ); |
| 2938 | | 2940 | |
| 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 | }); |
| 2990 | | 2992 | |
| 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 | ); |
| 3017 | | 3023 | |
| 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 | ); |
| 3089 | | 3099 | |
| 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 | } |
| 3323 | | 3333 | |
| 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 impossible | 3409 | .{ .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. |
| 3419 | fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void { | 3429 | fn 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. |
| 3459 | fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue { | 3469 | fn 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); |
| 3598 | | 3608 | |
| 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); |
| 3630 | | 3640 | |
| 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 | else | 3693 | 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 { |
| 3768 | | 3768 | |
| 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); |
| 3818 | | 3818 | |
| 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); |
| 3867 | | 3867 | |
| 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, |
| 3872 | | 3872 | |
| ... | @@ -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 }; |
| 3906 | | 3906 | |
| 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); |
| 3928 | | 3928 | |
| 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); |
| 3992 | | 3992 | |
| 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 value | 4167 | // additional `mov` is needed at the end to get the actual value |
| 4168 | | 4168 | |
| 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 | else | 4311 | 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 | else | 4323 | 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 | }); |
| 4344 | | 4347 | |
| 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); |
| 4570 | | 4575 | |
| 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 | } |
| 4592 | | 4597 | |
| 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 | } |
| 4675 | | 4680 | |
| 4676 | fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, mem_ok: bool) !MCValue { | 4681 | fn 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; |
| 4678 | | 4684 | |
| | 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); |
| 4685 | | 4695 | |
| 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()) and | 4700 | 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_mcv | 4702 | 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; |
| 4757 | | 4769 | |
| 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); |
| 4761 | | 4773 | |
| 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 | else | 4788 | else |
| 4777 | undefined; | 4789 | undefined; |
| 4778 | | 4790 | |
| 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 | }); |
| 4877 | | 4892 | |
| 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", .{}); |
| 4991 | | 5006 | |
| 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)); |
| 5063 | | 5078 | |
| 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); |
| 5072 | | 5087 | |
| 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); |
| 5258 | | 5273 | |
| 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); |
| 5266 | | 5281 | |
| ... | @@ -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 |
| 5404 | | 5419 | |
| 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); |
| 5407 | | 5423 | |
| 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; |
| 5411 | | 5427 | |
| 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 | }); |
| 5425 | | 5441 | |
| 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); |
| 5445 | | 5460 | |
| 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 and | 5564 | .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 | else | 5567 | else |
| 5553 | 0, | 5568 | 0, |
| 5554 | })); | 5569 | }); |
| 5555 | | 5570 | |
| 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); |
| 5579 | | 5594 | |
| 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 | else | 5600 | 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 { |
| 5588 | | 5603 | |
| 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; |
| 5595 | | 5632 | |
| 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 | } |
| 5600 | | 5637 | |
| 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; |
| 5606 | | 5642 | |
| 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 { |
| 5726 | | 5762 | |
| 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)); |
| 5730 | | 5766 | |
| 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() and | 5768 | 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: |
| 5775 | | 5811 | |
| 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 | else | 5817 | 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 | }; |
| 5791 | | 5827 | |
| 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: |
| 5803 | | 5839 | |
| 5804 | fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void { | 5840 | fn 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 | }; |
| 5867 | | 5903 | |
| 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 | }); |
| 6091 | | 6127 | |
| 6092 | assert(rhs_ty.abiSize(mod) == 1); | 6128 | assert(rhs_ty.abiSize(mod) == 1); |
| 6093 | | 6129 | |
| 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 | }); |
| 6098 | | 6134 | |
| 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 | }); |
| 6332 | | 6375 | |
| 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 | } |
| 6570 | | 6616 | |
| 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 | }); |
| 7137 | | 7183 | |
| ... | @@ -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); |
| 7195 | | 7241 | |
| 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), // unord | 7274 | 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, ord | 7341 | 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. |
| 7783 | fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 7829 | fn 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); |
| 8021 | | 8067 | |
| 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; |
| 8444 | | 8490 | |
| 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 | else | 8700 | else |
| 8655 | .{ .off = @as(i32, @intCast(pl_ty.abiSize(mod))), .ty = Type.bool }; | 8701 | .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool }; |
| 8656 | | 8702 | |
| 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 |
| 8672 | | 8718 | |
| 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); |
| 8699 | | 8745 | |
| 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 | }, |
| 8712 | | 8758 | |
| 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 | else | 8791 | else |
| 8746 | .{ .off = @as(i32, @intCast(pl_ty.abiSize(mod))), .ty = Type.bool }; | 8792 | .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool }; |
| 8747 | | 8793 | |
| 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); |
| 8754 | | 8800 | |
| 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) ! |
| 8785 | | 8831 | |
| 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); |
| 8949 | | 8994 | |
| 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 { |
| 9017 | | 9062 | |
| 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; |
| 9026 | | 9069 | |
| ... | @@ -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 | } |
| 9069 | | 9112 | |
| 9070 | fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void { | 9113 | fn 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 { |
| 9143 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | 9186 | fn 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; |
| 9152 | | 9196 | |
| 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 |
| 9643 | | 9685 | |
| 9644 | fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void { | 9686 | fn 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 |
| 9930 | | 9972 | |
| 9931 | fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void { | 9973 | fn 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 | else | 9989 | 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 | else | 10013 | 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; |
| 10199 | | 10240 | |
| 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; |
| 10203 | | 10244 | |
| 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; |
| 10254 | | 10295 | |
| 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); |
| 10283 | | 10324 | |
| 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 { |
| 10308 | | 10349 | |
| 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; |
| 10314 | | 10355 | |
| ... | @@ -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); |
| 10335 | | 10376 | |
| 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 { |
| 10361 | | 10402 | |
| 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)); |
| 10365 | | 10406 | |
| 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); |
| 10465 | | 10506 | |
| 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); |
| 10542 | | 10583 | |
| 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); |
| 10773 | | 10814 | |
| 10774 | const elem_abi_size = @as(u31, @intCast(elem_ty.abiSize(mod))); | 10815 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(mod)); |
| 10775 | | 10816 | |
| 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 { |
| 11251 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | 11292 | fn 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; |
| 11271 | | 11312 | |
| 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; |
| 11343 | | 11384 | |
| 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)); |
| 11360 | | 11401 | |
| 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 | else | 11463 | 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 }); |
| 11425 | | 11466 | |
| 11426 | const pl_off = if (layout.tag_align < layout.payload_align) | 11467 | const pl_off: i32 = if (layout.tag_align < layout.payload_align) |
| 11427 | 0 | 11468 | 0 |
| 11428 | else | 11469 | 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); |
| 11431 | | 11472 | |
| 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 | } |
| 11482 | | 11523 | |
| 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 | else | 11604 | 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 | }); |
| 11571 | | 11610 | |
| 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; |
| 11574 | | 11613 | |
| 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 | } |
| 11808 | | 11845 | |
| 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" }, |