| ... | @@ -767,7 +767,7 @@ const FrameAlloc = struct { | ... | @@ -767,7 +767,7 @@ const FrameAlloc = struct { |
| 767 | .size = spill_size, | 767 | .size = spill_size, |
| 768 | .pad = @intCast(spill_size - abi_size), | 768 | .pad = @intCast(spill_size - abi_size), |
| 769 | .alignment = ty.abiAlignment(zcu).maxStrict( | 769 | .alignment = ty.abiAlignment(zcu).maxStrict( |
| 770 | InternPool.Alignment.fromNonzeroByteUnits(@min(spill_size, 8)), | 770 | .fromNonzeroByteUnits(@min(spill_size, 8)), |
| 771 | ), | 771 | ), |
| 772 | }); | 772 | }); |
| 773 | } | 773 | } |
| ... | @@ -806,7 +806,7 @@ pub fn generate( | ... | @@ -806,7 +806,7 @@ pub fn generate( |
| 806 | const gpa = zcu.gpa; | 806 | const gpa = zcu.gpa; |
| 807 | const ip = &zcu.intern_pool; | 807 | const ip = &zcu.intern_pool; |
| 808 | const func = zcu.funcInfo(func_index); | 808 | const func = zcu.funcInfo(func_index); |
| 809 | const fn_type = Type.fromInterned(func.ty); | 809 | const fn_type: Type = .fromInterned(func.ty); |
| 810 | const mod = zcu.navFileScope(func.owner_nav).mod; | 810 | const mod = zcu.navFileScope(func.owner_nav).mod; |
| 811 | | 811 | |
| 812 | var function: Self = .{ | 812 | var function: Self = .{ |
| ... | @@ -846,7 +846,7 @@ pub fn generate( | ... | @@ -846,7 +846,7 @@ pub fn generate( |
| 846 | try function.inst_tracking.ensureTotalCapacity(gpa, Temp.Index.max); | 846 | try function.inst_tracking.ensureTotalCapacity(gpa, Temp.Index.max); |
| 847 | for (0..Temp.Index.max) |temp_index| { | 847 | for (0..Temp.Index.max) |temp_index| { |
| 848 | const temp: Temp.Index = @enumFromInt(temp_index); | 848 | const temp: Temp.Index = @enumFromInt(temp_index); |
| 849 | function.inst_tracking.putAssumeCapacityNoClobber(temp.toIndex(), InstTracking.init(.none)); | 849 | function.inst_tracking.putAssumeCapacityNoClobber(temp.toIndex(), .init(.none)); |
| 850 | } | 850 | } |
| 851 | | 851 | |
| 852 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); | 852 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); |
| ... | @@ -854,11 +854,11 @@ pub fn generate( | ... | @@ -854,11 +854,11 @@ pub fn generate( |
| 854 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); | 854 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 855 | function.frame_allocs.set( | 855 | function.frame_allocs.set( |
| 856 | @intFromEnum(FrameIndex.stack_frame), | 856 | @intFromEnum(FrameIndex.stack_frame), |
| 857 | FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }), | 857 | .init(.{ .size = 0, .alignment = .@"1" }), |
| 858 | ); | 858 | ); |
| 859 | function.frame_allocs.set( | 859 | function.frame_allocs.set( |
| 860 | @intFromEnum(FrameIndex.call_frame), | 860 | @intFromEnum(FrameIndex.call_frame), |
| 861 | FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }), | 861 | .init(.{ .size = 0, .alignment = .@"1" }), |
| 862 | ); | 862 | ); |
| 863 | | 863 | |
| 864 | const fn_info = zcu.typeToFunc(fn_type).?; | 864 | const fn_info = zcu.typeToFunc(fn_type).?; |
| ... | @@ -871,20 +871,19 @@ pub fn generate( | ... | @@ -871,20 +871,19 @@ pub fn generate( |
| 871 | | 871 | |
| 872 | function.args = call_info.args; | 872 | function.args = call_info.args; |
| 873 | function.ret_mcv = call_info.return_value; | 873 | function.ret_mcv = call_info.return_value; |
| 874 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ | 874 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), .init(.{ |
| 875 | .size = Type.usize.abiSize(zcu), | 875 | .size = Type.usize.abiSize(zcu), |
| 876 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), | 876 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), |
| 877 | })); | 877 | })); |
| 878 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ | 878 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), .init(.{ |
| 879 | .size = Type.usize.abiSize(zcu), | 879 | .size = Type.usize.abiSize(zcu), |
| 880 | .alignment = InternPool.Alignment.min( | 880 | .alignment = call_info.stack_align.min( |
| 881 | call_info.stack_align, | 881 | .fromNonzeroByteUnits(function.target.stackAlignment()), |
| 882 | InternPool.Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), | | |
| 883 | ), | 882 | ), |
| 884 | })); | 883 | })); |
| 885 | function.frame_allocs.set( | 884 | function.frame_allocs.set( |
| 886 | @intFromEnum(FrameIndex.args_frame), | 885 | @intFromEnum(FrameIndex.args_frame), |
| 887 | FrameAlloc.init(.{ | 886 | .init(.{ |
| 888 | .size = call_info.stack_byte_count, | 887 | .size = call_info.stack_byte_count, |
| 889 | .alignment = call_info.stack_align, | 888 | .alignment = call_info.stack_align, |
| 890 | }), | 889 | }), |
| ... | @@ -1242,6 +1241,80 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -1242,6 +1241,80 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 1242 | return result; | 1241 | return result; |
| 1243 | } | 1242 | } |
| 1244 | | 1243 | |
| | 1244 | fn asmOps(self: *Self, tag: Mir.Inst.FixedTag, ops: [4]Operand) !void { |
| | 1245 | return switch (ops[0]) { |
| | 1246 | .none => self.asmOpOnly(tag), |
| | 1247 | .reg => |reg0| switch (ops[1]) { |
| | 1248 | .none => self.asmRegister(tag, reg0), |
| | 1249 | .reg => |reg1| switch (ops[2]) { |
| | 1250 | .none => self.asmRegisterRegister(tag, reg0, reg1), |
| | 1251 | .reg => |reg2| switch (ops[3]) { |
| | 1252 | .none => self.asmRegisterRegisterRegister(tag, reg0, reg1, reg2), |
| | 1253 | .reg => |reg3| self.asmRegisterRegisterRegisterRegister(tag, reg0, reg1, reg2, reg3), |
| | 1254 | .imm => |imm3| self.asmRegisterRegisterRegisterImmediate(tag, reg0, reg1, reg2, imm3), |
| | 1255 | else => error.InvalidInstruction, |
| | 1256 | }, |
| | 1257 | .mem => |mem2| switch (ops[3]) { |
| | 1258 | .none => self.asmRegisterRegisterMemory(tag, reg0, reg1, mem2), |
| | 1259 | .reg => |reg3| self.asmRegisterRegisterMemoryRegister(tag, reg0, reg1, mem2, reg3), |
| | 1260 | .imm => |imm3| self.asmRegisterRegisterMemoryImmediate(tag, reg0, reg1, mem2, imm3), |
| | 1261 | else => error.InvalidInstruction, |
| | 1262 | }, |
| | 1263 | .imm => |imm2| switch (ops[3]) { |
| | 1264 | .none => self.asmRegisterRegisterImmediate(tag, reg0, reg1, imm2), |
| | 1265 | else => error.InvalidInstruction, |
| | 1266 | }, |
| | 1267 | else => error.InvalidInstruction, |
| | 1268 | }, |
| | 1269 | .mem => |mem1| switch (ops[2]) { |
| | 1270 | .none => self.asmRegisterMemory(tag, reg0, mem1), |
| | 1271 | .reg => |reg2| switch (ops[3]) { |
| | 1272 | .none => self.asmRegisterMemoryRegister(tag, reg0, mem1, reg2), |
| | 1273 | else => error.InvalidInstruction, |
| | 1274 | }, |
| | 1275 | .imm => |imm2| switch (ops[3]) { |
| | 1276 | .none => self.asmRegisterMemoryImmediate(tag, reg0, mem1, imm2), |
| | 1277 | else => error.InvalidInstruction, |
| | 1278 | }, |
| | 1279 | else => error.InvalidInstruction, |
| | 1280 | }, |
| | 1281 | .imm => |imm1| switch (ops[2]) { |
| | 1282 | .none => self.asmRegisterImmediate(tag, reg0, imm1), |
| | 1283 | else => error.InvalidInstruction, |
| | 1284 | }, |
| | 1285 | else => error.InvalidInstruction, |
| | 1286 | }, |
| | 1287 | .mem => |mem0| switch (ops[1]) { |
| | 1288 | .none => self.asmMemory(tag, mem0), |
| | 1289 | .reg => |reg1| switch (ops[2]) { |
| | 1290 | .none => self.asmMemoryRegister(tag, mem0, reg1), |
| | 1291 | .reg => |reg2| switch (ops[3]) { |
| | 1292 | .none => self.asmMemoryRegisterRegister(tag, mem0, reg1, reg2), |
| | 1293 | else => error.InvalidInstruction, |
| | 1294 | }, |
| | 1295 | .imm => |imm2| switch (ops[3]) { |
| | 1296 | .none => self.asmMemoryRegisterImmediate(tag, mem0, reg1, imm2), |
| | 1297 | else => error.InvalidInstruction, |
| | 1298 | }, |
| | 1299 | else => error.InvalidInstruction, |
| | 1300 | }, |
| | 1301 | .imm => |imm1| switch (ops[2]) { |
| | 1302 | .none => self.asmMemoryImmediate(tag, mem0, imm1), |
| | 1303 | else => error.InvalidInstruction, |
| | 1304 | }, |
| | 1305 | else => error.InvalidInstruction, |
| | 1306 | }, |
| | 1307 | .imm => |imm0| switch (ops[1]) { |
| | 1308 | .none => self.asmImmediate(tag, imm0), |
| | 1309 | else => error.InvalidInstruction, |
| | 1310 | }, |
| | 1311 | .inst => |inst0| switch (ops[1]) { |
| | 1312 | .none => self.asmReloc(tag, inst0), |
| | 1313 | else => error.InvalidInstruction, |
| | 1314 | }, |
| | 1315 | }; |
| | 1316 | } |
| | 1317 | |
| 1245 | /// A `cc` of `.z_and_np` clobbers `reg2`! | 1318 | /// A `cc` of `.z_and_np` clobbers `reg2`! |
| 1246 | fn asmCmovccRegisterRegister(self: *Self, cc: Condition, reg1: Register, reg2: Register) !void { | 1319 | fn asmCmovccRegisterRegister(self: *Self, cc: Condition, reg1: Register, reg2: Register) !void { |
| 1247 | _ = try self.addInst(.{ | 1320 | _ = try self.addInst(.{ |
| ... | @@ -1256,7 +1329,7 @@ fn asmCmovccRegisterRegister(self: *Self, cc: Condition, reg1: Register, reg2: R | ... | @@ -1256,7 +1329,7 @@ fn asmCmovccRegisterRegister(self: *Self, cc: Condition, reg1: Register, reg2: R |
| 1256 | }, | 1329 | }, |
| 1257 | .data = .{ .rr = .{ | 1330 | .data = .{ .rr = .{ |
| 1258 | .fixes = switch (cc) { | 1331 | .fixes = switch (cc) { |
| 1259 | else => Mir.Inst.Fixes.fromCondition(cc), | 1332 | else => .fromCondition(cc), |
| 1260 | .z_and_np, .nz_or_p => ._, | 1333 | .z_and_np, .nz_or_p => ._, |
| 1261 | }, | 1334 | }, |
| 1262 | .r1 = reg1, | 1335 | .r1 = reg1, |
| ... | @@ -1280,7 +1353,7 @@ fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) | ... | @@ -1280,7 +1353,7 @@ fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) |
| 1280 | }, | 1353 | }, |
| 1281 | .data = .{ .rx = .{ | 1354 | .data = .{ .rx = .{ |
| 1282 | .fixes = switch (cc) { | 1355 | .fixes = switch (cc) { |
| 1283 | else => Mir.Inst.Fixes.fromCondition(cc), | 1356 | else => .fromCondition(cc), |
| 1284 | .z_and_np => unreachable, | 1357 | .z_and_np => unreachable, |
| 1285 | .nz_or_p => ._, | 1358 | .nz_or_p => ._, |
| 1286 | }, | 1359 | }, |
| ... | @@ -1303,7 +1376,7 @@ fn asmSetccRegister(self: *Self, cc: Condition, reg: Register) !void { | ... | @@ -1303,7 +1376,7 @@ fn asmSetccRegister(self: *Self, cc: Condition, reg: Register) !void { |
| 1303 | }, | 1376 | }, |
| 1304 | .data = switch (cc) { | 1377 | .data = switch (cc) { |
| 1305 | else => .{ .r = .{ | 1378 | else => .{ .r = .{ |
| 1306 | .fixes = Mir.Inst.Fixes.fromCondition(cc), | 1379 | .fixes = .fromCondition(cc), |
| 1307 | .r1 = reg, | 1380 | .r1 = reg, |
| 1308 | } }, | 1381 | } }, |
| 1309 | .z_and_np, .nz_or_p => .{ .rr = .{ | 1382 | .z_and_np, .nz_or_p => .{ .rr = .{ |
| ... | @@ -1328,7 +1401,7 @@ fn asmSetccMemory(self: *Self, cc: Condition, m: Memory) !void { | ... | @@ -1328,7 +1401,7 @@ fn asmSetccMemory(self: *Self, cc: Condition, m: Memory) !void { |
| 1328 | }, | 1401 | }, |
| 1329 | .data = switch (cc) { | 1402 | .data = switch (cc) { |
| 1330 | else => .{ .x = .{ | 1403 | else => .{ .x = .{ |
| 1331 | .fixes = Mir.Inst.Fixes.fromCondition(cc), | 1404 | .fixes = .fromCondition(cc), |
| 1332 | .payload = payload, | 1405 | .payload = payload, |
| 1333 | } }, | 1406 | } }, |
| 1334 | .z_and_np, .nz_or_p => .{ .rx = .{ | 1407 | .z_and_np, .nz_or_p => .{ .rx = .{ |
| ... | @@ -1362,7 +1435,7 @@ fn asmJccReloc(self: *Self, cc: Condition, target: Mir.Inst.Index) !Mir.Inst.Ind | ... | @@ -1362,7 +1435,7 @@ fn asmJccReloc(self: *Self, cc: Condition, target: Mir.Inst.Index) !Mir.Inst.Ind |
| 1362 | }, | 1435 | }, |
| 1363 | .data = .{ .inst = .{ | 1436 | .data = .{ .inst = .{ |
| 1364 | .fixes = switch (cc) { | 1437 | .fixes = switch (cc) { |
| 1365 | else => Mir.Inst.Fixes.fromCondition(cc), | 1438 | else => .fromCondition(cc), |
| 1366 | .z_and_np, .nz_or_p => ._, | 1439 | .z_and_np, .nz_or_p => ._, |
| 1367 | }, | 1440 | }, |
| 1368 | .inst = target, | 1441 | .inst = target, |
| ... | @@ -1969,7 +2042,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1969,7 +2042,7 @@ fn gen(self: *Self) InnerError!void { |
| 1969 | // The address where to store the return value for the caller is in a | 2042 | // The address where to store the return value for the caller is in a |
| 1970 | // register which the callee is free to clobber. Therefore, we purposely | 2043 | // register which the callee is free to clobber. Therefore, we purposely |
| 1971 | // spill it to stack immediately. | 2044 | // spill it to stack immediately. |
| 1972 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(Type.usize, zcu)); | 2045 | const frame_index = try self.allocFrameIndex(.initSpill(Type.usize, zcu)); |
| 1973 | try self.genSetMem( | 2046 | try self.genSetMem( |
| 1974 | .{ .frame = frame_index }, | 2047 | .{ .frame = frame_index }, |
| 1975 | 0, | 2048 | 0, |
| ... | @@ -1986,7 +2059,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1986,7 +2059,7 @@ fn gen(self: *Self) InnerError!void { |
| 1986 | if (fn_info.is_var_args) switch (cc) { | 2059 | if (fn_info.is_var_args) switch (cc) { |
| 1987 | .x86_64_sysv => { | 2060 | .x86_64_sysv => { |
| 1988 | const info = &self.va_info.sysv; | 2061 | const info = &self.va_info.sysv; |
| 1989 | const reg_save_area_fi = try self.allocFrameIndex(FrameAlloc.init(.{ | 2062 | const reg_save_area_fi = try self.allocFrameIndex(.init(.{ |
| 1990 | .size = abi.SysV.c_abi_int_param_regs.len * 8 + | 2063 | .size = abi.SysV.c_abi_int_param_regs.len * 8 + |
| 1991 | abi.SysV.c_abi_sse_param_regs.len * 16, | 2064 | abi.SysV.c_abi_sse_param_regs.len * 16, |
| 1992 | .alignment = .@"16", | 2065 | .alignment = .@"16", |
| ... | @@ -2192,7 +2265,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2192,7 +2265,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2192 | wip_mir_log.debug("{}", .{self.fmtAir(inst)}); | 2265 | wip_mir_log.debug("{}", .{self.fmtAir(inst)}); |
| 2193 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); | 2266 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); |
| 2194 | | 2267 | |
| 2195 | self.reused_operands = @TypeOf(self.reused_operands).initEmpty(); | 2268 | self.reused_operands = .initEmpty(); |
| 2196 | try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1); | 2269 | try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1); |
| 2197 | | 2270 | |
| 2198 | try self.airArg(inst); | 2271 | try self.airArg(inst); |
| ... | @@ -2210,7 +2283,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2210,7 +2283,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2210 | wip_mir_log.debug("{}", .{self.fmtAir(inst)}); | 2283 | wip_mir_log.debug("{}", .{self.fmtAir(inst)}); |
| 2211 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); | 2284 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); |
| 2212 | | 2285 | |
| 2213 | self.reused_operands = @TypeOf(self.reused_operands).initEmpty(); | 2286 | self.reused_operands = .initEmpty(); |
| 2214 | try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1); | 2287 | try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1); |
| 2215 | switch (air_tags[@intFromEnum(inst)]) { | 2288 | switch (air_tags[@intFromEnum(inst)]) { |
| 2216 | // zig fmt: off | 2289 | // zig fmt: off |
| ... | @@ -2223,9 +2296,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2223,9 +2296,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2223 | .sub_wrap, | 2296 | .sub_wrap, |
| 2224 | .bool_and, | 2297 | .bool_and, |
| 2225 | .bool_or, | 2298 | .bool_or, |
| 2226 | .bit_and, | | |
| 2227 | .bit_or, | | |
| 2228 | .xor, | | |
| 2229 | .min, | 2299 | .min, |
| 2230 | .max, | 2300 | .max, |
| 2231 | => |tag| try self.airBinOp(inst, tag), | 2301 | => |tag| try self.airBinOp(inst, tag), |
| ... | @@ -2391,6 +2461,55 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2391,6 +2461,55 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2391 | try slot.moveTo(inst, self); | 2461 | try slot.moveTo(inst, self); |
| 2392 | }, | 2462 | }, |
| 2393 | .assembly => try self.airAsm(inst), | 2463 | .assembly => try self.airAsm(inst), |
| | 2464 | inline .bit_and, .bit_or, .xor => |tag| if (use_old or self.typeOfIndex(inst).abiSize(zcu) > @as( |
| | 2465 | u64, |
| | 2466 | if (!self.typeOfIndex(inst).isVector(zcu)) |
| | 2467 | 8 |
| | 2468 | else if (!self.hasFeature(.avx2)) |
| | 2469 | 16 |
| | 2470 | else |
| | 2471 | 32, |
| | 2472 | )) try self.airBinOp(inst, tag) else { |
| | 2473 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| | 2474 | var ops = try self.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| | 2475 | try self.spillEflagsIfOccupied(); |
| | 2476 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| | 2477 | else => unreachable, |
| | 2478 | .bit_and => .@"and", |
| | 2479 | .bit_or => .@"or", |
| | 2480 | .xor => .xor, |
| | 2481 | }; |
| | 2482 | var res: [1]Temp = undefined; |
| | 2483 | try self.select(&res, &.{ &ops[0], &ops[1] }, &.{ |
| | 2484 | .{ .tag = .{ .vp_, mir_tag }, .ops = &.{ .ymm, .ymm, .mem }, .features = &.{.avx2} }, |
| | 2485 | .{ .tag = .{ .vp_, mir_tag }, .ops = &.{ .ymm, .mem, .ymm }, .commute = .{ 1, 2 }, .features = &.{.avx2} }, |
| | 2486 | .{ .tag = .{ .vp_, mir_tag }, .ops = &.{ .ymm, .ymm, .ymm }, .features = &.{.avx2} }, |
| | 2487 | .{ .tag = .{ .vp_, mir_tag }, .ops = &.{ .xmm, .xmm, .mem }, .features = &.{.avx} }, |
| | 2488 | .{ .tag = .{ .vp_, mir_tag }, .ops = &.{ .xmm, .mem, .xmm }, .commute = .{ 1, 2 }, .features = &.{.avx} }, |
| | 2489 | .{ .tag = .{ .vp_, mir_tag }, .ops = &.{ .xmm, .xmm, .xmm }, .features = &.{.avx} }, |
| | 2490 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .xmm, .{ .match = 0 }, .mem }, .features = &.{.sse2} }, |
| | 2491 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .xmm, .mem, .{ .match = 0 } }, .features = &.{.sse2} }, |
| | 2492 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .xmm, .{ .match = 0 }, .xmm }, .features = &.{.sse2} }, |
| | 2493 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .xmm, .xmm, .{ .match = 0 } }, .features = &.{.sse2} }, |
| | 2494 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .mm, .{ .match = 0 }, .mem }, .features = &.{.mmx} }, |
| | 2495 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .mm, .mem, .{ .match = 0 } }, .features = &.{.mmx} }, |
| | 2496 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .mm, .{ .match = 0 }, .mm }, .features = &.{.mmx} }, |
| | 2497 | .{ .tag = .{ .p_, mir_tag }, .ops = &.{ .mm, .mm, .{ .match = 0 } }, .features = &.{.mmx} }, |
| | 2498 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .mem, .{ .match = 0 }, .simm32 } }, |
| | 2499 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .mem, .simm32, .{ .match = 0 } } }, |
| | 2500 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .mem, .{ .match = 0 }, .gpr } }, |
| | 2501 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .mem, .gpr, .{ .match = 0 } } }, |
| | 2502 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .gpr, .{ .match = 0 }, .simm32 } }, |
| | 2503 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .gpr, .simm32, .{ .match = 0 } } }, |
| | 2504 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .gpr, .{ .match = 0 }, .mem } }, |
| | 2505 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .gpr, .mem, .{ .match = 0 } } }, |
| | 2506 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .gpr, .{ .match = 0 }, .gpr } }, |
| | 2507 | .{ .tag = .{ ._, mir_tag }, .ops = &.{ .gpr, .gpr, .{ .match = 0 } } }, |
| | 2508 | }); |
| | 2509 | if (ops[0].index != res[0].index) try ops[0].die(self); |
| | 2510 | if (ops[1].index != res[0].index) try ops[1].die(self); |
| | 2511 | try res[0].moveTo(inst, self); |
| | 2512 | }, |
| 2394 | .block => if (use_old) try self.airBlock(inst) else { | 2513 | .block => if (use_old) try self.airBlock(inst) else { |
| 2395 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 2514 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 2396 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 2515 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| ... | @@ -2506,7 +2625,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2506,7 +2625,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2506 | else if (opt_child_ty.isSlice(zcu)) | 2625 | else if (opt_child_ty.isSlice(zcu)) |
| 2507 | .qword | 2626 | .qword |
| 2508 | else | 2627 | else |
| 2509 | Memory.Size.fromSize(opt_child_abi_size)), | 2628 | .fromSize(opt_child_abi_size)), |
| 2510 | .u(0), | 2629 | .u(0), |
| 2511 | ); | 2630 | ); |
| 2512 | var is_null = try self.tempFromValue(self.typeOfIndex(inst), .{ .eflags = .e }); | 2631 | var is_null = try self.tempFromValue(self.typeOfIndex(inst), .{ .eflags = .e }); |
| ... | @@ -2529,7 +2648,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2529,7 +2648,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2529 | else if (opt_child_ty.isSlice(zcu)) | 2648 | else if (opt_child_ty.isSlice(zcu)) |
| 2530 | .qword | 2649 | .qword |
| 2531 | else | 2650 | else |
| 2532 | Memory.Size.fromSize(opt_child_abi_size)), | 2651 | .fromSize(opt_child_abi_size)), |
| 2533 | .u(0), | 2652 | .u(0), |
| 2534 | ); | 2653 | ); |
| 2535 | var is_non_null = try self.tempFromValue(self.typeOfIndex(inst), .{ .eflags = .ne }); | 2654 | var is_non_null = try self.tempFromValue(self.typeOfIndex(inst), .{ .eflags = .ne }); |
| ... | @@ -2646,31 +2765,51 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2646,31 +2765,51 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2646 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 2765 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 2647 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 2766 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 2648 | var ops = try self.tempsFromOperands(inst, .{extra.struct_operand}); | 2767 | var ops = try self.tempsFromOperands(inst, .{extra.struct_operand}); |
| 2649 | try ops[0].toOffset(self.fieldOffset(self.typeOf(extra.struct_operand), self.typeOfIndex(inst), extra.field_index), self); | 2768 | try ops[0].toOffset(self.fieldOffset( |
| | 2769 | self.typeOf(extra.struct_operand), |
| | 2770 | self.typeOfIndex(inst), |
| | 2771 | extra.field_index, |
| | 2772 | ), self); |
| 2650 | try ops[0].moveTo(inst, self); | 2773 | try ops[0].moveTo(inst, self); |
| 2651 | }, | 2774 | }, |
| 2652 | .struct_field_ptr_index_0 => if (use_old) try self.airStructFieldPtrIndex(inst, 0) else { | 2775 | .struct_field_ptr_index_0 => if (use_old) try self.airStructFieldPtrIndex(inst, 0) else { |
| 2653 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 2776 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 2654 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); | 2777 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); |
| 2655 | try ops[0].toOffset(self.fieldOffset(self.typeOf(ty_op.operand), self.typeOfIndex(inst), 0), self); | 2778 | try ops[0].toOffset(self.fieldOffset( |
| | 2779 | self.typeOf(ty_op.operand), |
| | 2780 | self.typeOfIndex(inst), |
| | 2781 | 0, |
| | 2782 | ), self); |
| 2656 | try ops[0].moveTo(inst, self); | 2783 | try ops[0].moveTo(inst, self); |
| 2657 | }, | 2784 | }, |
| 2658 | .struct_field_ptr_index_1 => if (use_old) try self.airStructFieldPtrIndex(inst, 1) else { | 2785 | .struct_field_ptr_index_1 => if (use_old) try self.airStructFieldPtrIndex(inst, 1) else { |
| 2659 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 2786 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 2660 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); | 2787 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); |
| 2661 | try ops[0].toOffset(self.fieldOffset(self.typeOf(ty_op.operand), self.typeOfIndex(inst), 1), self); | 2788 | try ops[0].toOffset(self.fieldOffset( |
| | 2789 | self.typeOf(ty_op.operand), |
| | 2790 | self.typeOfIndex(inst), |
| | 2791 | 1, |
| | 2792 | ), self); |
| 2662 | try ops[0].moveTo(inst, self); | 2793 | try ops[0].moveTo(inst, self); |
| 2663 | }, | 2794 | }, |
| 2664 | .struct_field_ptr_index_2 => if (use_old) try self.airStructFieldPtrIndex(inst, 2) else { | 2795 | .struct_field_ptr_index_2 => if (use_old) try self.airStructFieldPtrIndex(inst, 2) else { |
| 2665 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 2796 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 2666 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); | 2797 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); |
| 2667 | try ops[0].toOffset(self.fieldOffset(self.typeOf(ty_op.operand), self.typeOfIndex(inst), 2), self); | 2798 | try ops[0].toOffset(self.fieldOffset( |
| | 2799 | self.typeOf(ty_op.operand), |
| | 2800 | self.typeOfIndex(inst), |
| | 2801 | 2, |
| | 2802 | ), self); |
| 2668 | try ops[0].moveTo(inst, self); | 2803 | try ops[0].moveTo(inst, self); |
| 2669 | }, | 2804 | }, |
| 2670 | .struct_field_ptr_index_3 => if (use_old) try self.airStructFieldPtrIndex(inst, 3) else { | 2805 | .struct_field_ptr_index_3 => if (use_old) try self.airStructFieldPtrIndex(inst, 3) else { |
| 2671 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 2806 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 2672 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); | 2807 | var ops = try self.tempsFromOperands(inst, .{ty_op.operand}); |
| 2673 | try ops[0].toOffset(self.fieldOffset(self.typeOf(ty_op.operand), self.typeOfIndex(inst), 3), self); | 2808 | try ops[0].toOffset(self.fieldOffset( |
| | 2809 | self.typeOf(ty_op.operand), |
| | 2810 | self.typeOfIndex(inst), |
| | 2811 | 3, |
| | 2812 | ), self); |
| 2674 | try ops[0].moveTo(inst, self); | 2813 | try ops[0].moveTo(inst, self); |
| 2675 | }, | 2814 | }, |
| 2676 | .slice => if (use_old) try self.airSlice(inst) else { | 2815 | .slice => if (use_old) try self.airSlice(inst) else { |
| ... | @@ -2775,7 +2914,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2775,7 +2914,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2775 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 2914 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 2776 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 2915 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 2777 | var ops = try self.tempsFromOperands(inst, .{extra.field_ptr}); | 2916 | var ops = try self.tempsFromOperands(inst, .{extra.field_ptr}); |
| 2778 | try ops[0].toOffset(-self.fieldOffset(self.typeOfIndex(inst), self.typeOf(extra.field_ptr), extra.field_index), self); | 2917 | try ops[0].toOffset(-self.fieldOffset( |
| | 2918 | self.typeOfIndex(inst), |
| | 2919 | self.typeOf(extra.field_ptr), |
| | 2920 | extra.field_index, |
| | 2921 | ), self); |
| 2779 | try ops[0].moveTo(inst, self); | 2922 | try ops[0].moveTo(inst, self); |
| 2780 | }, | 2923 | }, |
| 2781 | | 2924 | |
| ... | @@ -2813,7 +2956,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2813,7 +2956,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2813 | const ip = &zcu.intern_pool; | 2956 | const ip = &zcu.intern_pool; |
| 2814 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) { | 2957 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) { |
| 2815 | .@"enum" => { | 2958 | .@"enum" => { |
| 2816 | const enum_ty = Type.fromInterned(lazy_sym.ty); | 2959 | const enum_ty: Type = .fromInterned(lazy_sym.ty); |
| 2817 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); | 2960 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); |
| 2818 | | 2961 | |
| 2819 | const resolved_cc = abi.resolveCallingConvention(.auto, self.target.*); | 2962 | const resolved_cc = abi.resolveCallingConvention(.auto, self.target.*); |
| ... | @@ -2919,7 +3062,7 @@ fn finishAirResult(self: *Self, inst: Air.Inst.Index, result: MCValue) void { | ... | @@ -2919,7 +3062,7 @@ fn finishAirResult(self: *Self, inst: Air.Inst.Index, result: MCValue) void { |
| 2919 | else => unreachable, // Why didn't the result die? | 3062 | else => unreachable, // Why didn't the result die? |
| 2920 | } else { | 3063 | } else { |
| 2921 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); | 3064 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); |
| 2922 | self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(result)); | 3065 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result)); |
| 2923 | // In some cases, an operand may be reused as the result. | 3066 | // In some cases, an operand may be reused as the result. |
| 2924 | // If that operand died and was a register, it was freed by | 3067 | // If that operand died and was a register, it was freed by |
| 2925 | // processDeath, so we have to "re-allocate" the register. | 3068 | // processDeath, so we have to "re-allocate" the register. |
| ... | @@ -3067,7 +3210,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { | ... | @@ -3067,7 +3210,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { |
| 3067 | const zcu = pt.zcu; | 3210 | const zcu = pt.zcu; |
| 3068 | const ptr_ty = self.typeOfIndex(inst); | 3211 | const ptr_ty = self.typeOfIndex(inst); |
| 3069 | const val_ty = ptr_ty.childType(zcu); | 3212 | const val_ty = ptr_ty.childType(zcu); |
| 3070 | return self.allocFrameIndex(FrameAlloc.init(.{ | 3213 | return self.allocFrameIndex(.init(.{ |
| 3071 | .size = std.math.cast(u32, val_ty.abiSize(zcu)) orelse { | 3214 | .size = std.math.cast(u32, val_ty.abiSize(zcu)) orelse { |
| 3072 | return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)}); | 3215 | return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)}); |
| 3073 | }, | 3216 | }, |
| ... | @@ -3107,35 +3250,49 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b | ... | @@ -3107,35 +3250,49 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b |
| 3107 | }, | 3250 | }, |
| 3108 | else => 8, | 3251 | else => 8, |
| 3109 | })) { | 3252 | })) { |
| 3110 | if (self.register_manager.tryAllocReg(inst, self.regClassForType(ty))) |reg| { | 3253 | if (self.register_manager.tryAllocReg(inst, self.regSetForType(ty))) |reg| { |
| 3111 | return MCValue{ .register = registerAlias(reg, abi_size) }; | 3254 | return MCValue{ .register = registerAlias(reg, abi_size) }; |
| 3112 | } | 3255 | } |
| 3113 | } | 3256 | } |
| 3114 | } | 3257 | } |
| 3115 | | 3258 | |
| 3116 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, zcu)); | 3259 | const frame_index = try self.allocFrameIndex(.initSpill(ty, zcu)); |
| 3117 | return .{ .load_frame = .{ .index = frame_index } }; | 3260 | return .{ .load_frame = .{ .index = frame_index } }; |
| 3118 | } | 3261 | } |
| 3119 | | 3262 | |
| 3120 | fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet { | 3263 | fn regClassForType(self: *Self, ty: Type) Register.Class { |
| 3121 | const pt = self.pt; | 3264 | const pt = self.pt; |
| 3122 | const zcu = pt.zcu; | 3265 | const zcu = pt.zcu; |
| 3123 | return switch (ty.zigTypeTag(zcu)) { | 3266 | return switch (ty.zigTypeTag(zcu)) { |
| 3124 | .float => switch (ty.floatBits(self.target.*)) { | 3267 | .float => switch (ty.floatBits(self.target.*)) { |
| 3125 | 80 => abi.RegisterClass.x87, | 3268 | 80 => .x87, |
| 3126 | else => abi.RegisterClass.sse, | 3269 | else => .sse, |
| 3127 | }, | 3270 | }, |
| 3128 | .vector => switch (ty.childType(zcu).toIntern()) { | 3271 | .vector => switch (ty.childType(zcu).toIntern()) { |
| 3129 | .bool_type, .u1_type => abi.RegisterClass.gp, | 3272 | .bool_type, .u1_type => .general_purpose, |
| 3130 | else => if (ty.isAbiInt(zcu) and ty.intInfo(zcu).bits == 1) | 3273 | else => if (ty.isAbiInt(zcu) and ty.intInfo(zcu).bits == 1) |
| 3131 | abi.RegisterClass.gp | 3274 | .general_purpose |
| 3132 | else | 3275 | else |
| 3133 | abi.RegisterClass.sse, | 3276 | .sse, |
| 3134 | }, | 3277 | }, |
| 3135 | else => abi.RegisterClass.gp, | 3278 | else => .general_purpose, |
| 3136 | }; | 3279 | }; |
| 3137 | } | 3280 | } |
| 3138 | | 3281 | |
| | 3282 | fn regSetForRegClass(rc: Register.Class) RegisterManager.RegisterBitSet { |
| | 3283 | return switch (rc) { |
| | 3284 | .general_purpose => abi.RegisterClass.gp, |
| | 3285 | .segment, .ip => unreachable, |
| | 3286 | .x87 => abi.RegisterClass.x87, |
| | 3287 | .mmx => @panic("TODO"), |
| | 3288 | .sse => abi.RegisterClass.sse, |
| | 3289 | }; |
| | 3290 | } |
| | 3291 | |
| | 3292 | fn regSetForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet { |
| | 3293 | return regSetForRegClass(self.regClassForType(ty)); |
| | 3294 | } |
| | 3295 | |
| 3139 | const State = struct { | 3296 | const State = struct { |
| 3140 | registers: RegisterManager.TrackedRegisters, | 3297 | registers: RegisterManager.TrackedRegisters, |
| 3141 | reg_tracking: [RegisterManager.RegisterBitSet.bit_length]InstTracking, | 3298 | reg_tracking: [RegisterManager.RegisterBitSet.bit_length]InstTracking, |
| ... | @@ -3292,7 +3449,7 @@ pub fn spillRegisters(self: *Self, comptime registers: []const Register) !void { | ... | @@ -3292,7 +3449,7 @@ pub fn spillRegisters(self: *Self, comptime registers: []const Register) !void { |
| 3292 | /// allocated. A second call to `copyToTmpRegister` may return the same register. | 3449 | /// allocated. A second call to `copyToTmpRegister` may return the same register. |
| 3293 | /// This can have a side effect of spilling instructions to the stack to free up a register. | 3450 | /// This can have a side effect of spilling instructions to the stack to free up a register. |
| 3294 | fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register { | 3451 | fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register { |
| 3295 | const reg = try self.register_manager.allocReg(null, self.regClassForType(ty)); | 3452 | const reg = try self.register_manager.allocReg(null, self.regSetForType(ty)); |
| 3296 | try self.genSetReg(reg, ty, mcv, .{}); | 3453 | try self.genSetReg(reg, ty, mcv, .{}); |
| 3297 | return reg; | 3454 | return reg; |
| 3298 | } | 3455 | } |
| ... | @@ -3307,7 +3464,7 @@ fn copyToRegisterWithInstTracking( | ... | @@ -3307,7 +3464,7 @@ fn copyToRegisterWithInstTracking( |
| 3307 | ty: Type, | 3464 | ty: Type, |
| 3308 | mcv: MCValue, | 3465 | mcv: MCValue, |
| 3309 | ) !MCValue { | 3466 | ) !MCValue { |
| 3310 | const reg: Register = try self.register_manager.allocReg(reg_owner, self.regClassForType(ty)); | 3467 | const reg: Register = try self.register_manager.allocReg(reg_owner, self.regSetForType(ty)); |
| 3311 | try self.genSetReg(reg, ty, mcv, .{}); | 3468 | try self.genSetReg(reg, ty, mcv, .{}); |
| 3312 | return MCValue{ .register = reg }; | 3469 | return MCValue{ .register = reg }; |
| 3313 | } | 3470 | } |
| ... | @@ -3910,7 +4067,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3910,7 +4067,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3910 | .storage = .{ .repeated_elem = mask_val.ip_index }, | 4067 | .storage = .{ .repeated_elem = mask_val.ip_index }, |
| 3911 | } }); | 4068 | } }); |
| 3912 | | 4069 | |
| 3913 | const splat_mcv = try self.genTypedValue(Value.fromInterned(splat_val)); | 4070 | const splat_mcv = try self.genTypedValue(.fromInterned(splat_val)); |
| 3914 | const splat_addr_mcv: MCValue = switch (splat_mcv) { | 4071 | const splat_addr_mcv: MCValue = switch (splat_mcv) { |
| 3915 | .memory, .indirect, .load_frame => splat_mcv.address(), | 4072 | .memory, .indirect, .load_frame => splat_mcv.address(), |
| 3916 | else => .{ .register = try self.copyToTmpRegister(Type.usize, splat_mcv.address()) }, | 4073 | else => .{ .register = try self.copyToTmpRegister(Type.usize, splat_mcv.address()) }, |
| ... | @@ -3923,7 +4080,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3923,7 +4080,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3923 | .{ .vp_, .@"and" }, | 4080 | .{ .vp_, .@"and" }, |
| 3924 | dst_alias, | 4081 | dst_alias, |
| 3925 | dst_alias, | 4082 | dst_alias, |
| 3926 | try splat_addr_mcv.deref().mem(self, Memory.Size.fromSize(splat_abi_size)), | 4083 | try splat_addr_mcv.deref().mem(self, .fromSize(splat_abi_size)), |
| 3927 | ); | 4084 | ); |
| 3928 | if (src_abi_size > 16) { | 4085 | if (src_abi_size > 16) { |
| 3929 | const temp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.sse); | 4086 | const temp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.sse); |
| ... | @@ -3947,7 +4104,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3947,7 +4104,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3947 | try self.asmRegisterMemory( | 4104 | try self.asmRegisterMemory( |
| 3948 | .{ .p_, .@"and" }, | 4105 | .{ .p_, .@"and" }, |
| 3949 | dst_alias, | 4106 | dst_alias, |
| 3950 | try splat_addr_mcv.deref().mem(self, Memory.Size.fromSize(splat_abi_size)), | 4107 | try splat_addr_mcv.deref().mem(self, .fromSize(splat_abi_size)), |
| 3951 | ); | 4108 | ); |
| 3952 | try self.asmRegisterRegister(mir_tag, dst_alias, dst_alias); | 4109 | try self.asmRegisterRegister(mir_tag, dst_alias, dst_alias); |
| 3953 | } | 4110 | } |
| ... | @@ -3992,7 +4149,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3992,7 +4149,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3992 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 4149 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3993 | | 4150 | |
| 3994 | const slice_ty = self.typeOfIndex(inst); | 4151 | const slice_ty = self.typeOfIndex(inst); |
| 3995 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | 4152 | const frame_index = try self.allocFrameIndex(.initSpill(slice_ty, zcu)); |
| 3996 | | 4153 | |
| 3997 | const ptr_ty = self.typeOf(bin_op.lhs); | 4154 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3998 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); | 4155 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); |
| ... | @@ -4129,7 +4286,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4129,7 +4286,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4129 | state: State, | 4286 | state: State, |
| 4130 | reloc: Mir.Inst.Index, | 4287 | reloc: Mir.Inst.Index, |
| 4131 | } = if (signed and tag == .div_floor) state: { | 4288 | } = if (signed and tag == .div_floor) state: { |
| 4132 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, zcu)); | 4289 | const frame_index = try self.allocFrameIndex(.initType(Type.usize, zcu)); |
| 4133 | try self.asmMemoryImmediate( | 4290 | try self.asmMemoryImmediate( |
| 4134 | .{ ._, .mov }, | 4291 | .{ ._, .mov }, |
| 4135 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, | 4292 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| ... | @@ -4259,7 +4416,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4259,7 +4416,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4259 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); | 4416 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 4260 | | 4417 | |
| 4261 | const tmp_regs = | 4418 | const tmp_regs = |
| 4262 | try self.register_manager.allocRegs(2, .{null} ** 2, abi.RegisterClass.gp); | 4419 | try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp); |
| 4263 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); | 4420 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); |
| 4264 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | 4421 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 4265 | | 4422 | |
| ... | @@ -4698,8 +4855,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4698,8 +4855,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4698 | else => {}, | 4855 | else => {}, |
| 4699 | } | 4856 | } |
| 4700 | | 4857 | |
| 4701 | const frame_index = | 4858 | const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu)); |
| 4702 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | | |
| 4703 | try self.genSetMem( | 4859 | try self.genSetMem( |
| 4704 | .{ .frame = frame_index }, | 4860 | .{ .frame = frame_index }, |
| 4705 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | 4861 | @intCast(tuple_ty.structFieldOffset(1, zcu)), |
| ... | @@ -4717,8 +4873,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4717,8 +4873,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4717 | break :result .{ .load_frame = .{ .index = frame_index } }; | 4873 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4718 | } | 4874 | } |
| 4719 | | 4875 | |
| 4720 | const frame_index = | 4876 | const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu)); |
| 4721 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | | |
| 4722 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); | 4877 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4723 | break :result .{ .load_frame = .{ .index = frame_index } }; | 4878 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4724 | }, | 4879 | }, |
| ... | @@ -4776,8 +4931,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4776,8 +4931,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4776 | else => {}, | 4931 | else => {}, |
| 4777 | } | 4932 | } |
| 4778 | | 4933 | |
| 4779 | const frame_index = | 4934 | const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu)); |
| 4780 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | | |
| 4781 | try self.genSetMem( | 4935 | try self.genSetMem( |
| 4782 | .{ .frame = frame_index }, | 4936 | .{ .frame = frame_index }, |
| 4783 | @intCast(tuple_ty.structFieldOffset(1, zcu)), | 4937 | @intCast(tuple_ty.structFieldOffset(1, zcu)), |
| ... | @@ -4796,7 +4950,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4796,7 +4950,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4796 | } | 4950 | } |
| 4797 | | 4951 | |
| 4798 | const frame_index = | 4952 | const frame_index = |
| 4799 | try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | 4953 | try self.allocFrameIndex(.initSpill(tuple_ty, zcu)); |
| 4800 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); | 4954 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 4801 | break :result .{ .load_frame = .{ .index = frame_index } }; | 4955 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 4802 | }, | 4956 | }, |
| ... | @@ -4833,7 +4987,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -4833,7 +4987,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 4833 | const rest_ty = try pt.intType(.unsigned, int_info.bits - hi_bits); | 4987 | const rest_ty = try pt.intType(.unsigned, int_info.bits - hi_bits); |
| 4834 | | 4988 | |
| 4835 | const temp_regs = | 4989 | const temp_regs = |
| 4836 | try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); | 4990 | try self.register_manager.allocRegs(3, @splat(null), abi.RegisterClass.gp); |
| 4837 | const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs); | 4991 | const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs); |
| 4838 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); | 4992 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 4839 | | 4993 | |
| ... | @@ -4916,7 +5070,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4916,7 +5070,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4916 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | 5070 | const rhs_mcv = try self.resolveInst(bin_op.rhs); |
| 4917 | | 5071 | |
| 4918 | const temp_regs = | 5072 | const temp_regs = |
| 4919 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); | 5073 | try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp); |
| 4920 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); | 5074 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); |
| 4921 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); | 5075 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 4922 | | 5076 | |
| ... | @@ -5080,7 +5234,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5080,7 +5234,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 5080 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); | 5234 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); |
| 5081 | | 5235 | |
| 5082 | const tmp_regs = | 5236 | const tmp_regs = |
| 5083 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); | 5237 | try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp); |
| 5084 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(4, tmp_regs); | 5238 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(4, tmp_regs); |
| 5085 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | 5239 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 5086 | | 5240 | |
| ... | @@ -5217,7 +5371,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5217,7 +5371,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 5217 | self.eflags_inst = inst; | 5371 | self.eflags_inst = inst; |
| 5218 | break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; | 5372 | break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; |
| 5219 | } else { | 5373 | } else { |
| 5220 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | 5374 | const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu)); |
| 5221 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); | 5375 | try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc); |
| 5222 | break :result .{ .load_frame = .{ .index = frame_index } }; | 5376 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 5223 | }, | 5377 | }, |
| ... | @@ -5228,7 +5382,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5228,7 +5382,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 5228 | src_ty.fmt(pt), dst_ty.fmt(pt), | 5382 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 5229 | }); | 5383 | }); |
| 5230 | | 5384 | |
| 5231 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(tuple_ty, zcu)); | 5385 | const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu)); |
| 5232 | if (dst_info.bits >= lhs_active_bits + rhs_active_bits) { | 5386 | if (dst_info.bits >= lhs_active_bits + rhs_active_bits) { |
| 5233 | try self.genSetMem( | 5387 | try self.genSetMem( |
| 5234 | .{ .frame = frame_index }, | 5388 | .{ .frame = frame_index }, |
| ... | @@ -5301,10 +5455,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue | ... | @@ -5301,10 +5455,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 5301 | }; | 5455 | }; |
| 5302 | switch (mat_rhs) { | 5456 | switch (mat_rhs) { |
| 5303 | .register => |reg| try self.asmRegister(tag, registerAlias(reg, abi_size)), | 5457 | .register => |reg| try self.asmRegister(tag, registerAlias(reg, abi_size)), |
| 5304 | .memory, .indirect, .load_frame => try self.asmMemory( | 5458 | .memory, .indirect, .load_frame => try self.asmMemory(tag, try mat_rhs.mem(self, .fromSize(abi_size))), |
| 5305 | tag, | | |
| 5306 | try mat_rhs.mem(self, Memory.Size.fromSize(abi_size)), | | |
| 5307 | ), | | |
| 5308 | else => unreachable, | 5459 | else => unreachable, |
| 5309 | } | 5460 | } |
| 5310 | if (tag[1] == .div and bit_size == 8) try self.asmRegisterRegister(.{ ._, .mov }, .dl, .ah); | 5461 | if (tag[1] == .div and bit_size == 8) try self.asmRegisterRegister(.{ ._, .mov }, .dl, .ah); |
| ... | @@ -5575,7 +5726,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5575,7 +5726,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 5575 | defer self.register_manager.unlockReg(shift_lock); | 5726 | defer self.register_manager.unlockReg(shift_lock); |
| 5576 | | 5727 | |
| 5577 | const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type }); | 5728 | const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type }); |
| 5578 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 5729 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 5579 | .ty = mask_ty.toIntern(), | 5730 | .ty = mask_ty.toIntern(), |
| 5580 | .storage = .{ .elems = &([1]InternPool.Index{ | 5731 | .storage = .{ .elems = &([1]InternPool.Index{ |
| 5581 | (try rhs_ty.childType(zcu).maxIntScalar(pt, Type.u8)).toIntern(), | 5732 | (try rhs_ty.childType(zcu).maxIntScalar(pt, Type.u8)).toIntern(), |
| ... | @@ -5811,7 +5962,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5811,7 +5962,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5811 | .{ | 5962 | .{ |
| 5812 | .base = .{ .reg = src_reg }, | 5963 | .base = .{ .reg = src_reg }, |
| 5813 | .mod = .{ .rm = .{ | 5964 | .mod = .{ .rm = .{ |
| 5814 | .size = Memory.Size.fromSize(err_abi_size), | 5965 | .size = .fromSize(err_abi_size), |
| 5815 | .disp = err_off, | 5966 | .disp = err_off, |
| 5816 | } }, | 5967 | } }, |
| 5817 | }, | 5968 | }, |
| ... | @@ -5853,7 +6004,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5853,7 +6004,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 5853 | .{ | 6004 | .{ |
| 5854 | .base = .{ .reg = src_reg }, | 6005 | .base = .{ .reg = src_reg }, |
| 5855 | .mod = .{ .rm = .{ | 6006 | .mod = .{ .rm = .{ |
| 5856 | .size = Memory.Size.fromSize(err_abi_size), | 6007 | .size = .fromSize(err_abi_size), |
| 5857 | .disp = err_off, | 6008 | .disp = err_off, |
| 5858 | } }, | 6009 | } }, |
| 5859 | }, | 6010 | }, |
| ... | @@ -5909,7 +6060,7 @@ fn genUnwrapErrUnionPayloadMir( | ... | @@ -5909,7 +6060,7 @@ fn genUnwrapErrUnionPayloadMir( |
| 5909 | const eu_lock = self.register_manager.lockReg(reg); | 6060 | const eu_lock = self.register_manager.lockReg(reg); |
| 5910 | defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); | 6061 | defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); |
| 5911 | | 6062 | |
| 5912 | const payload_in_gp = self.regClassForType(payload_ty).supersetOf(abi.RegisterClass.gp); | 6063 | const payload_in_gp = self.regSetForType(payload_ty).supersetOf(abi.RegisterClass.gp); |
| 5913 | const result_mcv: MCValue = if (payload_in_gp and maybe_inst != null) | 6064 | const result_mcv: MCValue = if (payload_in_gp and maybe_inst != null) |
| 5914 | try self.copyToRegisterWithInstTracking(maybe_inst.?, err_union_ty, err_union) | 6065 | try self.copyToRegisterWithInstTracking(maybe_inst.?, err_union_ty, err_union) |
| 5915 | else | 6066 | else |
| ... | @@ -6043,7 +6194,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6043,7 +6194,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 6043 | const result: MCValue = result: { | 6194 | const result: MCValue = result: { |
| 6044 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 }; | 6195 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 }; |
| 6045 | | 6196 | |
| 6046 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | 6197 | const frame_index = try self.allocFrameIndex(.initSpill(eu_ty, zcu)); |
| 6047 | const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu)); | 6198 | const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu)); |
| 6048 | const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu)); | 6199 | const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu)); |
| 6049 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); | 6200 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); |
| ... | @@ -6066,7 +6217,7 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6066,7 +6217,7 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 6066 | const result: MCValue = result: { | 6217 | const result: MCValue = result: { |
| 6067 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try self.resolveInst(ty_op.operand); | 6218 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try self.resolveInst(ty_op.operand); |
| 6068 | | 6219 | |
| 6069 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | 6220 | const frame_index = try self.allocFrameIndex(.initSpill(eu_ty, zcu)); |
| 6070 | const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu)); | 6221 | const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu)); |
| 6071 | const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu)); | 6222 | const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu)); |
| 6072 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); | 6223 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); |
| ... | @@ -6297,7 +6448,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6297,7 +6448,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6297 | index_reg.to64(), | 6448 | index_reg.to64(), |
| 6298 | ), | 6449 | ), |
| 6299 | .sse => { | 6450 | .sse => { |
| 6300 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | 6451 | const frame_index = try self.allocFrameIndex(.initType(array_ty, zcu)); |
| 6301 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); | 6452 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 6302 | try self.asmMemoryRegister( | 6453 | try self.asmMemoryRegister( |
| 6303 | .{ ._, .bt }, | 6454 | .{ ._, .bt }, |
| ... | @@ -6342,7 +6493,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6342,7 +6493,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6342 | | 6493 | |
| 6343 | switch (array_mcv) { | 6494 | switch (array_mcv) { |
| 6344 | .register => { | 6495 | .register => { |
| 6345 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | 6496 | const frame_index = try self.allocFrameIndex(.initType(array_ty, zcu)); |
| 6346 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); | 6497 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 6347 | try self.asmRegisterMemory( | 6498 | try self.asmRegisterMemory( |
| 6348 | .{ ._, .lea }, | 6499 | .{ ._, .lea }, |
| ... | @@ -7175,7 +7326,7 @@ fn genByteSwap( | ... | @@ -7175,7 +7326,7 @@ fn genByteSwap( |
| 7175 | const limbs_len = std.math.divCeil(u32, abi_size, 8) catch unreachable; | 7326 | const limbs_len = std.math.divCeil(u32, abi_size, 8) catch unreachable; |
| 7176 | | 7327 | |
| 7177 | const temp_regs = | 7328 | const temp_regs = |
| 7178 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); | 7329 | try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp); |
| 7179 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); | 7330 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); |
| 7180 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); | 7331 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 7181 | | 7332 | |
| ... | @@ -7472,11 +7623,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -7472,11 +7623,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 7472 | else => unreachable, | 7623 | else => unreachable, |
| 7473 | }); | 7624 | }); |
| 7474 | const sign_mem: Memory = if (sign_mcv.isMemory()) | 7625 | const sign_mem: Memory = if (sign_mcv.isMemory()) |
| 7475 | try sign_mcv.mem(self, Memory.Size.fromSize(abi_size)) | 7626 | try sign_mcv.mem(self, .fromSize(abi_size)) |
| 7476 | else | 7627 | else |
| 7477 | .{ | 7628 | .{ |
| 7478 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, sign_mcv.address()) }, | 7629 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, sign_mcv.address()) }, |
| 7479 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(abi_size) } }, | 7630 | .mod = .{ .rm = .{ .size = .fromSize(abi_size) } }, |
| 7480 | }; | 7631 | }; |
| 7481 | | 7632 | |
| 7482 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterMemory( | 7633 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterMemory( |
| ... | @@ -7657,7 +7808,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro | ... | @@ -7657,7 +7808,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 7657 | mir_tag, | 7808 | mir_tag, |
| 7658 | dst_alias, | 7809 | dst_alias, |
| 7659 | dst_alias, | 7810 | dst_alias, |
| 7660 | try src_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 7811 | try src_mcv.mem(self, .fromSize(abi_size)), |
| 7661 | .u(@as(u5, @bitCast(mode))), | 7812 | .u(@as(u5, @bitCast(mode))), |
| 7662 | ) else try self.asmRegisterRegisterRegisterImmediate( | 7813 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 7663 | mir_tag, | 7814 | mir_tag, |
| ... | @@ -7672,7 +7823,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro | ... | @@ -7672,7 +7823,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 7672 | else => if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 7823 | else => if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 7673 | mir_tag, | 7824 | mir_tag, |
| 7674 | dst_alias, | 7825 | dst_alias, |
| 7675 | try src_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 7826 | try src_mcv.mem(self, .fromSize(abi_size)), |
| 7676 | .u(@as(u5, @bitCast(mode))), | 7827 | .u(@as(u5, @bitCast(mode))), |
| 7677 | ) else try self.asmRegisterRegisterImmediate( | 7828 | ) else try self.asmRegisterRegisterImmediate( |
| 7678 | mir_tag, | 7829 | mir_tag, |
| ... | @@ -7714,7 +7865,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7714,7 +7865,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7714 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( | 7865 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( |
| 7715 | .l, | 7866 | .l, |
| 7716 | registerAlias(dst_mcv.register, cmov_abi_size), | 7867 | registerAlias(dst_mcv.register, cmov_abi_size), |
| 7717 | try src_mcv.mem(self, Memory.Size.fromSize(cmov_abi_size)), | 7868 | try src_mcv.mem(self, .fromSize(cmov_abi_size)), |
| 7718 | ), | 7869 | ), |
| 7719 | else => { | 7870 | else => { |
| 7720 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); | 7871 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); |
| ... | @@ -7767,7 +7918,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7767,7 +7918,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7767 | const limb_len = std.math.divCeil(u31, abi_size, 8) catch unreachable; | 7918 | const limb_len = std.math.divCeil(u31, abi_size, 8) catch unreachable; |
| 7768 | | 7919 | |
| 7769 | const tmp_regs = | 7920 | const tmp_regs = |
| 7770 | try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); | 7921 | try self.register_manager.allocRegs(3, @splat(null), abi.RegisterClass.gp); |
| 7771 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(3, tmp_regs); | 7922 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(3, tmp_regs); |
| 7772 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | 7923 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 7773 | | 7924 | |
| ... | @@ -7868,7 +8019,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7868,7 +8019,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 7868 | const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 8019 | const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 7869 | src_mcv.getReg().? | 8020 | src_mcv.getReg().? |
| 7870 | else | 8021 | else |
| 7871 | try self.register_manager.allocReg(inst, self.regClassForType(ty)); | 8022 | try self.register_manager.allocReg(inst, self.regSetForType(ty)); |
| 7872 | const dst_alias = registerAlias(dst_reg, abi_size); | 8023 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 7873 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 8024 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7874 | mir_tag, | 8025 | mir_tag, |
| ... | @@ -7980,7 +8131,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7980,7 +8131,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 7980 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 8131 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7981 | .{ .v_ps, .cvtph2 }, | 8132 | .{ .v_ps, .cvtph2 }, |
| 7982 | wide_reg, | 8133 | wide_reg, |
| 7983 | try src_mcv.mem(self, Memory.Size.fromSize( | 8134 | try src_mcv.mem(self, .fromSize( |
| 7984 | @intCast(@divExact(wide_reg.bitSize(), 16)), | 8135 | @intCast(@divExact(wide_reg.bitSize(), 16)), |
| 7985 | )), | 8136 | )), |
| 7986 | ) else try self.asmRegisterRegister( | 8137 | ) else try self.asmRegisterRegister( |
| ... | @@ -8026,7 +8177,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8026,7 +8177,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 8026 | mir_tag, | 8177 | mir_tag, |
| 8027 | dst_reg, | 8178 | dst_reg, |
| 8028 | dst_reg, | 8179 | dst_reg, |
| 8029 | try src_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 8180 | try src_mcv.mem(self, .fromSize(abi_size)), |
| 8030 | ) else try self.asmRegisterRegisterRegister( | 8181 | ) else try self.asmRegisterRegisterRegister( |
| 8031 | mir_tag, | 8182 | mir_tag, |
| 8032 | dst_reg, | 8183 | dst_reg, |
| ... | @@ -8039,7 +8190,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8039,7 +8190,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 8039 | else => if (src_mcv.isMemory()) try self.asmRegisterMemory( | 8190 | else => if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 8040 | mir_tag, | 8191 | mir_tag, |
| 8041 | dst_reg, | 8192 | dst_reg, |
| 8042 | try src_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 8193 | try src_mcv.mem(self, .fromSize(abi_size)), |
| 8043 | ) else try self.asmRegisterRegister( | 8194 | ) else try self.asmRegisterRegister( |
| 8044 | mir_tag, | 8195 | mir_tag, |
| 8045 | dst_reg, | 8196 | dst_reg, |
| ... | @@ -8136,7 +8287,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -8136,7 +8287,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 8136 | const zcu = pt.zcu; | 8287 | const zcu = pt.zcu; |
| 8137 | | 8288 | |
| 8138 | const ptr_info = ptr_ty.ptrInfo(zcu); | 8289 | const ptr_info = ptr_ty.ptrInfo(zcu); |
| 8139 | const val_ty = Type.fromInterned(ptr_info.child); | 8290 | const val_ty: Type = .fromInterned(ptr_info.child); |
| 8140 | if (!val_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; | 8291 | if (!val_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; |
| 8141 | const val_abi_size: u32 = @intCast(val_ty.abiSize(zcu)); | 8292 | const val_abi_size: u32 = @intCast(val_ty.abiSize(zcu)); |
| 8142 | | 8293 | |
| ... | @@ -8204,7 +8355,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -8204,7 +8355,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 8204 | try self.asmRegisterMemory(.{ ._, .mov }, load_reg, .{ | 8355 | try self.asmRegisterMemory(.{ ._, .mov }, load_reg, .{ |
| 8205 | .base = .{ .reg = ptr_reg }, | 8356 | .base = .{ .reg = ptr_reg }, |
| 8206 | .mod = .{ .rm = .{ | 8357 | .mod = .{ .rm = .{ |
| 8207 | .size = Memory.Size.fromSize(load_abi_size), | 8358 | .size = .fromSize(load_abi_size), |
| 8208 | .disp = val_byte_off, | 8359 | .disp = val_byte_off, |
| 8209 | } }, | 8360 | } }, |
| 8210 | }); | 8361 | }); |
| ... | @@ -8220,14 +8371,14 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -8220,14 +8371,14 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 8220 | try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{ | 8371 | try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{ |
| 8221 | .base = .{ .reg = ptr_reg }, | 8372 | .base = .{ .reg = ptr_reg }, |
| 8222 | .mod = .{ .rm = .{ | 8373 | .mod = .{ .rm = .{ |
| 8223 | .size = Memory.Size.fromSize(val_abi_size), | 8374 | .size = .fromSize(val_abi_size), |
| 8224 | .disp = val_byte_off, | 8375 | .disp = val_byte_off, |
| 8225 | } }, | 8376 | } }, |
| 8226 | }); | 8377 | }); |
| 8227 | try self.asmRegisterMemory(.{ ._, .mov }, tmp_reg, .{ | 8378 | try self.asmRegisterMemory(.{ ._, .mov }, tmp_reg, .{ |
| 8228 | .base = .{ .reg = ptr_reg }, | 8379 | .base = .{ .reg = ptr_reg }, |
| 8229 | .mod = .{ .rm = .{ | 8380 | .mod = .{ .rm = .{ |
| 8230 | .size = Memory.Size.fromSize(val_abi_size), | 8381 | .size = .fromSize(val_abi_size), |
| 8231 | .disp = val_byte_off + limb_abi_size, | 8382 | .disp = val_byte_off + limb_abi_size, |
| 8232 | } }, | 8383 | } }, |
| 8233 | }); | 8384 | }); |
| ... | @@ -8297,8 +8448,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8297,8 +8448,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 8297 | const ptr_ty = self.typeOf(ty_op.operand); | 8448 | const ptr_ty = self.typeOf(ty_op.operand); |
| 8298 | const elem_size = elem_ty.abiSize(zcu); | 8449 | const elem_size = elem_ty.abiSize(zcu); |
| 8299 | | 8450 | |
| 8300 | const elem_rc = self.regClassForType(elem_ty); | 8451 | const elem_rc = self.regSetForType(elem_ty); |
| 8301 | const ptr_rc = self.regClassForType(ptr_ty); | 8452 | const ptr_rc = self.regSetForType(ptr_ty); |
| 8302 | | 8453 | |
| 8303 | const ptr_mcv = try self.resolveInst(ty_op.operand); | 8454 | const ptr_mcv = try self.resolveInst(ty_op.operand); |
| 8304 | const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and | 8455 | const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and |
| ... | @@ -8345,7 +8496,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -8345,7 +8496,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 8345 | const pt = self.pt; | 8496 | const pt = self.pt; |
| 8346 | const zcu = pt.zcu; | 8497 | const zcu = pt.zcu; |
| 8347 | const ptr_info = ptr_ty.ptrInfo(zcu); | 8498 | const ptr_info = ptr_ty.ptrInfo(zcu); |
| 8348 | const src_ty = Type.fromInterned(ptr_info.child); | 8499 | const src_ty: Type = .fromInterned(ptr_info.child); |
| 8349 | if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; | 8500 | if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return; |
| 8350 | | 8501 | |
| 8351 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); | 8502 | const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); |
| ... | @@ -8373,7 +8524,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -8373,7 +8524,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 8373 | const limb_mem: Memory = .{ | 8524 | const limb_mem: Memory = .{ |
| 8374 | .base = .{ .reg = ptr_reg }, | 8525 | .base = .{ .reg = ptr_reg }, |
| 8375 | .mod = .{ .rm = .{ | 8526 | .mod = .{ .rm = .{ |
| 8376 | .size = Memory.Size.fromSize(limb_abi_size), | 8527 | .size = .fromSize(limb_abi_size), |
| 8377 | .disp = src_byte_off + limb_i * limb_abi_size, | 8528 | .disp = src_byte_off + limb_i * limb_abi_size, |
| 8378 | } }, | 8529 | } }, |
| 8379 | }; | 8530 | }; |
| ... | @@ -8563,10 +8714,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8563,10 +8714,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8563 | const index = extra.field_index; | 8714 | const index = extra.field_index; |
| 8564 | | 8715 | |
| 8565 | const container_ty = self.typeOf(operand); | 8716 | const container_ty = self.typeOf(operand); |
| 8566 | const container_rc = self.regClassForType(container_ty); | 8717 | const container_rc = self.regSetForType(container_ty); |
| 8567 | const field_ty = container_ty.fieldType(index, zcu); | 8718 | const field_ty = container_ty.fieldType(index, zcu); |
| 8568 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; | 8719 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; |
| 8569 | const field_rc = self.regClassForType(field_ty); | 8720 | const field_rc = self.regSetForType(field_ty); |
| 8570 | const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp); | 8721 | const field_is_gp = field_rc.supersetOf(abi.RegisterClass.gp); |
| 8571 | | 8722 | |
| 8572 | const src_mcv = try self.resolveInst(operand); | 8723 | const src_mcv = try self.resolveInst(operand); |
| ... | @@ -8624,7 +8775,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8624,7 +8775,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8624 | const dst_regs: [2]Register = if (field_rc.supersetOf(container_rc) and | 8775 | const dst_regs: [2]Register = if (field_rc.supersetOf(container_rc) and |
| 8625 | self.reuseOperand(inst, operand, 0, src_mcv)) src_regs else dst: { | 8776 | self.reuseOperand(inst, operand, 0, src_mcv)) src_regs else dst: { |
| 8626 | const dst_regs = | 8777 | const dst_regs = |
| 8627 | try self.register_manager.allocRegs(2, .{null} ** 2, field_rc); | 8778 | try self.register_manager.allocRegs(2, @splat(null), field_rc); |
| 8628 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); | 8779 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 8629 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); | 8780 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 8630 | | 8781 | |
| ... | @@ -8786,7 +8937,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8786,7 +8937,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8786 | try self.asmRegisterMemory(.{ ._, .mov }, load_reg, .{ | 8937 | try self.asmRegisterMemory(.{ ._, .mov }, load_reg, .{ |
| 8787 | .base = .{ .frame = frame_addr.index }, | 8938 | .base = .{ .frame = frame_addr.index }, |
| 8788 | .mod = .{ .rm = .{ | 8939 | .mod = .{ .rm = .{ |
| 8789 | .size = Memory.Size.fromSize(load_abi_size), | 8940 | .size = .fromSize(load_abi_size), |
| 8790 | .disp = frame_addr.off + field_byte_off, | 8941 | .disp = frame_addr.off + field_byte_off, |
| 8791 | } }, | 8942 | } }, |
| 8792 | }); | 8943 | }); |
| ... | @@ -8807,7 +8958,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8807,7 +8958,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8807 | .{ | 8958 | .{ |
| 8808 | .base = .{ .frame = frame_addr.index }, | 8959 | .base = .{ .frame = frame_addr.index }, |
| 8809 | .mod = .{ .rm = .{ | 8960 | .mod = .{ .rm = .{ |
| 8810 | .size = Memory.Size.fromSize(field_abi_size), | 8961 | .size = .fromSize(field_abi_size), |
| 8811 | .disp = frame_addr.off + field_byte_off, | 8962 | .disp = frame_addr.off + field_byte_off, |
| 8812 | } }, | 8963 | } }, |
| 8813 | }, | 8964 | }, |
| ... | @@ -8815,7 +8966,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8815,7 +8966,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 8815 | try self.asmRegisterMemory(.{ ._, .mov }, tmp_reg, .{ | 8966 | try self.asmRegisterMemory(.{ ._, .mov }, tmp_reg, .{ |
| 8816 | .base = .{ .frame = frame_addr.index }, | 8967 | .base = .{ .frame = frame_addr.index }, |
| 8817 | .mod = .{ .rm = .{ | 8968 | .mod = .{ .rm = .{ |
| 8818 | .size = Memory.Size.fromSize(field_abi_size), | 8969 | .size = .fromSize(field_abi_size), |
| 8819 | .disp = frame_addr.off + field_byte_off + limb_abi_size, | 8970 | .disp = frame_addr.off + field_byte_off + limb_abi_size, |
| 8820 | } }, | 8971 | } }, |
| 8821 | }); | 8972 | }); |
| ... | @@ -8977,12 +9128,12 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC | ... | @@ -8977,12 +9128,12 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC |
| 8977 | | 9128 | |
| 8978 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address(), .{}); | 9129 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address(), .{}); |
| 8979 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ | 9130 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ |
| 8980 | .size = Memory.Size.fromSize(abi_size), | 9131 | .size = .fromSize(abi_size), |
| 8981 | } } }); | 9132 | } } }); |
| 8982 | }, | 9133 | }, |
| 8983 | .indirect, .load_frame => try self.asmMemory( | 9134 | .indirect, .load_frame => try self.asmMemory( |
| 8984 | mir_tag, | 9135 | mir_tag, |
| 8985 | try dst_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 9136 | try dst_mcv.mem(self, .fromSize(abi_size)), |
| 8986 | ), | 9137 | ), |
| 8987 | } | 9138 | } |
| 8988 | } | 9139 | } |
| ... | @@ -9024,7 +9175,7 @@ fn genShiftBinOpMir( | ... | @@ -9024,7 +9175,7 @@ fn genShiftBinOpMir( |
| 9024 | }; | 9175 | }; |
| 9025 | defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); | 9176 | defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); |
| 9026 | | 9177 | |
| 9027 | const temp_regs = try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); | 9178 | const temp_regs = try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp); |
| 9028 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); | 9179 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); |
| 9029 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); | 9180 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 9030 | | 9181 | |
| ... | @@ -9576,7 +9727,7 @@ fn genShiftBinOpMir( | ... | @@ -9576,7 +9727,7 @@ fn genShiftBinOpMir( |
| 9576 | .memory => |addr| .{ | 9727 | .memory => |addr| .{ |
| 9577 | .base = .{ .reg = .ds }, | 9728 | .base = .{ .reg = .ds }, |
| 9578 | .mod = .{ .rm = .{ | 9729 | .mod = .{ .rm = .{ |
| 9579 | .size = Memory.Size.fromSize(abi_size), | 9730 | .size = .fromSize(abi_size), |
| 9580 | .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse | 9731 | .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| 9581 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 9732 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ |
| 9582 | @tagName(lhs_mcv), | 9733 | @tagName(lhs_mcv), |
| ... | @@ -9587,14 +9738,14 @@ fn genShiftBinOpMir( | ... | @@ -9587,14 +9738,14 @@ fn genShiftBinOpMir( |
| 9587 | .indirect => |reg_off| .{ | 9738 | .indirect => |reg_off| .{ |
| 9588 | .base = .{ .reg = reg_off.reg }, | 9739 | .base = .{ .reg = reg_off.reg }, |
| 9589 | .mod = .{ .rm = .{ | 9740 | .mod = .{ .rm = .{ |
| 9590 | .size = Memory.Size.fromSize(abi_size), | 9741 | .size = .fromSize(abi_size), |
| 9591 | .disp = reg_off.off, | 9742 | .disp = reg_off.off, |
| 9592 | } }, | 9743 | } }, |
| 9593 | }, | 9744 | }, |
| 9594 | .load_frame => |frame_addr| .{ | 9745 | .load_frame => |frame_addr| .{ |
| 9595 | .base = .{ .frame = frame_addr.index }, | 9746 | .base = .{ .frame = frame_addr.index }, |
| 9596 | .mod = .{ .rm = .{ | 9747 | .mod = .{ .rm = .{ |
| 9597 | .size = Memory.Size.fromSize(abi_size), | 9748 | .size = .fromSize(abi_size), |
| 9598 | .disp = frame_addr.off, | 9749 | .disp = frame_addr.off, |
| 9599 | } }, | 9750 | } }, |
| 9600 | }, | 9751 | }, |
| ... | @@ -9792,7 +9943,7 @@ fn genMulDivBinOp( | ... | @@ -9792,7 +9943,7 @@ fn genMulDivBinOp( |
| 9792 | ); | 9943 | ); |
| 9793 | | 9944 | |
| 9794 | const temp_regs = | 9945 | const temp_regs = |
| 9795 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); | 9946 | try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp); |
| 9796 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); | 9947 | const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); |
| 9797 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); | 9948 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 9798 | | 9949 | |
| ... | @@ -10208,7 +10359,7 @@ fn genBinOp( | ... | @@ -10208,7 +10359,7 @@ fn genBinOp( |
| 10208 | mir_tag, | 10359 | mir_tag, |
| 10209 | dst_reg, | 10360 | dst_reg, |
| 10210 | dst_reg, | 10361 | dst_reg, |
| 10211 | try src_mcv.mem(self, Memory.Size.fromBitSize(float_bits)), | 10362 | try src_mcv.mem(self, .fromBitSize(float_bits)), |
| 10212 | ) else try self.asmRegisterRegisterRegister( | 10363 | ) else try self.asmRegisterRegisterRegister( |
| 10213 | mir_tag, | 10364 | mir_tag, |
| 10214 | dst_reg, | 10365 | dst_reg, |
| ... | @@ -10227,7 +10378,7 @@ fn genBinOp( | ... | @@ -10227,7 +10378,7 @@ fn genBinOp( |
| 10227 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 10378 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 10228 | mir_tag, | 10379 | mir_tag, |
| 10229 | dst_reg, | 10380 | dst_reg, |
| 10230 | try src_mcv.mem(self, Memory.Size.fromBitSize(float_bits)), | 10381 | try src_mcv.mem(self, .fromBitSize(float_bits)), |
| 10231 | ) else try self.asmRegisterRegister( | 10382 | ) else try self.asmRegisterRegister( |
| 10232 | mir_tag, | 10383 | mir_tag, |
| 10233 | dst_reg, | 10384 | dst_reg, |
| ... | @@ -10358,14 +10509,14 @@ fn genBinOp( | ... | @@ -10358,14 +10509,14 @@ fn genBinOp( |
| 10358 | const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs); | 10509 | const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs); |
| 10359 | break :locks .{ locks[0], locks[1] }; | 10510 | break :locks .{ locks[0], locks[1] }; |
| 10360 | }, | 10511 | }, |
| 10361 | else => .{null} ** 2, | 10512 | else => @splat(null), |
| 10362 | }; | 10513 | }; |
| 10363 | defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock); | 10514 | defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 10364 | | 10515 | |
| 10365 | const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) { | 10516 | const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) { |
| 10366 | .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null }, | 10517 | .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null }, |
| 10367 | .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs), | 10518 | .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs), |
| 10368 | else => .{null} ** 2, | 10519 | else => @splat(null), |
| 10369 | }; | 10520 | }; |
| 10370 | defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); | 10521 | defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 10371 | | 10522 | |
| ... | @@ -10398,7 +10549,7 @@ fn genBinOp( | ... | @@ -10398,7 +10549,7 @@ fn genBinOp( |
| 10398 | const dst_locks: [2]?RegisterLock = switch (dst_mcv) { | 10549 | const dst_locks: [2]?RegisterLock = switch (dst_mcv) { |
| 10399 | .register => |dst_reg| .{ self.register_manager.lockReg(dst_reg), null }, | 10550 | .register => |dst_reg| .{ self.register_manager.lockReg(dst_reg), null }, |
| 10400 | .register_pair => |dst_regs| self.register_manager.lockRegs(2, dst_regs), | 10551 | .register_pair => |dst_regs| self.register_manager.lockRegs(2, dst_regs), |
| 10401 | else => .{null} ** 2, | 10552 | else => @splat(null), |
| 10402 | }; | 10553 | }; |
| 10403 | defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 10554 | defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 10404 | | 10555 | |
| ... | @@ -10414,7 +10565,7 @@ fn genBinOp( | ... | @@ -10414,7 +10565,7 @@ fn genBinOp( |
| 10414 | const src_locks: [2]?RegisterLock = switch (src_mcv) { | 10565 | const src_locks: [2]?RegisterLock = switch (src_mcv) { |
| 10415 | .register => |src_reg| .{ self.register_manager.lockReg(src_reg), null }, | 10566 | .register => |src_reg| .{ self.register_manager.lockReg(src_reg), null }, |
| 10416 | .register_pair => |src_regs| self.register_manager.lockRegs(2, src_regs), | 10567 | .register_pair => |src_regs| self.register_manager.lockRegs(2, src_regs), |
| 10417 | else => .{null} ** 2, | 10568 | else => @splat(null), |
| 10418 | }; | 10569 | }; |
| 10419 | defer for (src_locks) |src_lock| if (src_lock) |lock| self.register_manager.unlockReg(lock); | 10570 | defer for (src_locks) |src_lock| if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 10420 | | 10571 | |
| ... | @@ -10472,11 +10623,7 @@ fn genBinOp( | ... | @@ -10472,11 +10623,7 @@ fn genBinOp( |
| 10472 | const dst_regs = switch (dst_mcv) { | 10623 | const dst_regs = switch (dst_mcv) { |
| 10473 | .register_pair => |dst_regs| dst_regs, | 10624 | .register_pair => |dst_regs| dst_regs, |
| 10474 | else => dst: { | 10625 | else => dst: { |
| 10475 | const dst_regs = try self.register_manager.allocRegs( | 10626 | const dst_regs = try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp); |
| 10476 | 2, | | |
| 10477 | .{null} ** 2, | | |
| 10478 | abi.RegisterClass.gp, | | |
| 10479 | ); | | |
| 10480 | const dst_regs_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); | 10627 | const dst_regs_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 10481 | defer for (dst_regs_locks) |lock| self.register_manager.unlockReg(lock); | 10628 | defer for (dst_regs_locks) |lock| self.register_manager.unlockReg(lock); |
| 10482 | | 10629 | |
| ... | @@ -10624,21 +10771,21 @@ fn genBinOp( | ... | @@ -10624,21 +10771,21 @@ fn genBinOp( |
| 10624 | .memory => |addr| .{ | 10771 | .memory => |addr| .{ |
| 10625 | .base = .{ .reg = .ds }, | 10772 | .base = .{ .reg = .ds }, |
| 10626 | .mod = .{ .rm = .{ | 10773 | .mod = .{ .rm = .{ |
| 10627 | .size = Memory.Size.fromSize(cmov_abi_size), | 10774 | .size = .fromSize(cmov_abi_size), |
| 10628 | .disp = @intCast(@as(i64, @bitCast(addr))), | 10775 | .disp = @intCast(@as(i64, @bitCast(addr))), |
| 10629 | } }, | 10776 | } }, |
| 10630 | }, | 10777 | }, |
| 10631 | .indirect => |reg_off| .{ | 10778 | .indirect => |reg_off| .{ |
| 10632 | .base = .{ .reg = reg_off.reg }, | 10779 | .base = .{ .reg = reg_off.reg }, |
| 10633 | .mod = .{ .rm = .{ | 10780 | .mod = .{ .rm = .{ |
| 10634 | .size = Memory.Size.fromSize(cmov_abi_size), | 10781 | .size = .fromSize(cmov_abi_size), |
| 10635 | .disp = reg_off.off, | 10782 | .disp = reg_off.off, |
| 10636 | } }, | 10783 | } }, |
| 10637 | }, | 10784 | }, |
| 10638 | .load_frame => |frame_addr| .{ | 10785 | .load_frame => |frame_addr| .{ |
| 10639 | .base = .{ .frame = frame_addr.index }, | 10786 | .base = .{ .frame = frame_addr.index }, |
| 10640 | .mod = .{ .rm = .{ | 10787 | .mod = .{ .rm = .{ |
| 10641 | .size = Memory.Size.fromSize(cmov_abi_size), | 10788 | .size = .fromSize(cmov_abi_size), |
| 10642 | .disp = frame_addr.off, | 10789 | .disp = frame_addr.off, |
| 10643 | } }, | 10790 | } }, |
| 10644 | }, | 10791 | }, |
| ... | @@ -11433,8 +11580,8 @@ fn genBinOp( | ... | @@ -11433,8 +11580,8 @@ fn genBinOp( |
| 11433 | dst_reg, | 11580 | dst_reg, |
| 11434 | lhs_reg, | 11581 | lhs_reg, |
| 11435 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | 11582 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { |
| 11436 | else => Memory.Size.fromSize(abi_size), | 11583 | else => .fromSize(abi_size), |
| 11437 | .vector => Memory.Size.fromBitSize(dst_reg.bitSize()), | 11584 | .vector => .fromBitSize(dst_reg.bitSize()), |
| 11438 | }), | 11585 | }), |
| 11439 | ) else try self.asmRegisterRegisterRegister( | 11586 | ) else try self.asmRegisterRegisterRegister( |
| 11440 | mir_tag, | 11587 | mir_tag, |
| ... | @@ -11451,8 +11598,8 @@ fn genBinOp( | ... | @@ -11451,8 +11598,8 @@ fn genBinOp( |
| 11451 | mir_tag, | 11598 | mir_tag, |
| 11452 | dst_reg, | 11599 | dst_reg, |
| 11453 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | 11600 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { |
| 11454 | else => Memory.Size.fromSize(abi_size), | 11601 | else => .fromSize(abi_size), |
| 11455 | .vector => Memory.Size.fromBitSize(dst_reg.bitSize()), | 11602 | .vector => .fromBitSize(dst_reg.bitSize()), |
| 11456 | }), | 11603 | }), |
| 11457 | ) else try self.asmRegisterRegister( | 11604 | ) else try self.asmRegisterRegister( |
| 11458 | mir_tag, | 11605 | mir_tag, |
| ... | @@ -11479,8 +11626,8 @@ fn genBinOp( | ... | @@ -11479,8 +11626,8 @@ fn genBinOp( |
| 11479 | dst_reg, | 11626 | dst_reg, |
| 11480 | lhs_reg, | 11627 | lhs_reg, |
| 11481 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | 11628 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { |
| 11482 | else => Memory.Size.fromSize(abi_size), | 11629 | else => .fromSize(abi_size), |
| 11483 | .vector => Memory.Size.fromBitSize(dst_reg.bitSize()), | 11630 | .vector => .fromBitSize(dst_reg.bitSize()), |
| 11484 | }), | 11631 | }), |
| 11485 | imm, | 11632 | imm, |
| 11486 | ) else try self.asmRegisterRegisterRegisterImmediate( | 11633 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| ... | @@ -11499,8 +11646,8 @@ fn genBinOp( | ... | @@ -11499,8 +11646,8 @@ fn genBinOp( |
| 11499 | mir_tag, | 11646 | mir_tag, |
| 11500 | dst_reg, | 11647 | dst_reg, |
| 11501 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { | 11648 | try src_mcv.mem(self, switch (lhs_ty.zigTypeTag(zcu)) { |
| 11502 | else => Memory.Size.fromSize(abi_size), | 11649 | else => .fromSize(abi_size), |
| 11503 | .vector => Memory.Size.fromBitSize(dst_reg.bitSize()), | 11650 | .vector => .fromBitSize(dst_reg.bitSize()), |
| 11504 | }), | 11651 | }), |
| 11505 | imm, | 11652 | imm, |
| 11506 | ) else try self.asmRegisterRegisterImmediate( | 11653 | ) else try self.asmRegisterRegisterImmediate( |
| ... | @@ -11707,11 +11854,11 @@ fn genBinOp( | ... | @@ -11707,11 +11854,11 @@ fn genBinOp( |
| 11707 | const unsigned_ty = try lhs_ty.toUnsigned(pt); | 11854 | const unsigned_ty = try lhs_ty.toUnsigned(pt); |
| 11708 | const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(pt, unsigned_ty)); | 11855 | const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(pt, unsigned_ty)); |
| 11709 | const not_mem: Memory = if (not_mcv.isMemory()) | 11856 | const not_mem: Memory = if (not_mcv.isMemory()) |
| 11710 | try not_mcv.mem(self, Memory.Size.fromSize(abi_size)) | 11857 | try not_mcv.mem(self, .fromSize(abi_size)) |
| 11711 | else | 11858 | else |
| 11712 | .{ .base = .{ | 11859 | .{ .base = .{ |
| 11713 | .reg = try self.copyToTmpRegister(Type.usize, not_mcv.address()), | 11860 | .reg = try self.copyToTmpRegister(Type.usize, not_mcv.address()), |
| 11714 | }, .mod = .{ .rm = .{ .size = Memory.Size.fromSize(abi_size) } } }; | 11861 | }, .mod = .{ .rm = .{ .size = .fromSize(abi_size) } } }; |
| 11715 | switch (mir_tag[0]) { | 11862 | switch (mir_tag[0]) { |
| 11716 | .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory( | 11863 | .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory( |
| 11717 | .{ .vp_, .xor }, | 11864 | .{ .vp_, .xor }, |
| ... | @@ -11891,21 +12038,21 @@ fn genBinOpMir( | ... | @@ -11891,21 +12038,21 @@ fn genBinOpMir( |
| 11891 | .memory => |addr| .{ | 12038 | .memory => |addr| .{ |
| 11892 | .base = .{ .reg = .ds }, | 12039 | .base = .{ .reg = .ds }, |
| 11893 | .mod = .{ .rm = .{ | 12040 | .mod = .{ .rm = .{ |
| 11894 | .size = Memory.Size.fromSize(limb_abi_size), | 12041 | .size = .fromSize(limb_abi_size), |
| 11895 | .disp = std.math.cast(i32, addr + off) orelse break :direct, | 12042 | .disp = std.math.cast(i32, addr + off) orelse break :direct, |
| 11896 | } }, | 12043 | } }, |
| 11897 | }, | 12044 | }, |
| 11898 | .indirect => |reg_off| .{ | 12045 | .indirect => |reg_off| .{ |
| 11899 | .base = .{ .reg = reg_off.reg }, | 12046 | .base = .{ .reg = reg_off.reg }, |
| 11900 | .mod = .{ .rm = .{ | 12047 | .mod = .{ .rm = .{ |
| 11901 | .size = Memory.Size.fromSize(limb_abi_size), | 12048 | .size = .fromSize(limb_abi_size), |
| 11902 | .disp = reg_off.off + off, | 12049 | .disp = reg_off.off + off, |
| 11903 | } }, | 12050 | } }, |
| 11904 | }, | 12051 | }, |
| 11905 | .load_frame => |frame_addr| .{ | 12052 | .load_frame => |frame_addr| .{ |
| 11906 | .base = .{ .frame = frame_addr.index }, | 12053 | .base = .{ .frame = frame_addr.index }, |
| 11907 | .mod = .{ .rm = .{ | 12054 | .mod = .{ .rm = .{ |
| 11908 | .size = Memory.Size.fromSize(limb_abi_size), | 12055 | .size = .fromSize(limb_abi_size), |
| 11909 | .disp = frame_addr.off + off, | 12056 | .disp = frame_addr.off + off, |
| 11910 | } }, | 12057 | } }, |
| 11911 | }, | 12058 | }, |
| ... | @@ -12054,21 +12201,21 @@ fn genBinOpMir( | ... | @@ -12054,21 +12201,21 @@ fn genBinOpMir( |
| 12054 | => .{ | 12201 | => .{ |
| 12055 | .base = .{ .reg = dst_info.?.addr_reg }, | 12202 | .base = .{ .reg = dst_info.?.addr_reg }, |
| 12056 | .mod = .{ .rm = .{ | 12203 | .mod = .{ .rm = .{ |
| 12057 | .size = Memory.Size.fromSize(limb_abi_size), | 12204 | .size = .fromSize(limb_abi_size), |
| 12058 | .disp = off, | 12205 | .disp = off, |
| 12059 | } }, | 12206 | } }, |
| 12060 | }, | 12207 | }, |
| 12061 | .indirect => |reg_off| .{ | 12208 | .indirect => |reg_off| .{ |
| 12062 | .base = .{ .reg = reg_off.reg }, | 12209 | .base = .{ .reg = reg_off.reg }, |
| 12063 | .mod = .{ .rm = .{ | 12210 | .mod = .{ .rm = .{ |
| 12064 | .size = Memory.Size.fromSize(limb_abi_size), | 12211 | .size = .fromSize(limb_abi_size), |
| 12065 | .disp = reg_off.off + off, | 12212 | .disp = reg_off.off + off, |
| 12066 | } }, | 12213 | } }, |
| 12067 | }, | 12214 | }, |
| 12068 | .load_frame => |frame_addr| .{ | 12215 | .load_frame => |frame_addr| .{ |
| 12069 | .base = .{ .frame = frame_addr.index }, | 12216 | .base = .{ .frame = frame_addr.index }, |
| 12070 | .mod = .{ .rm = .{ | 12217 | .mod = .{ .rm = .{ |
| 12071 | .size = Memory.Size.fromSize(limb_abi_size), | 12218 | .size = .fromSize(limb_abi_size), |
| 12072 | .disp = frame_addr.off + off, | 12219 | .disp = frame_addr.off + off, |
| 12073 | } }, | 12220 | } }, |
| 12074 | }, | 12221 | }, |
| ... | @@ -12277,7 +12424,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -12277,7 +12424,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 12277 | .memory => |addr| .{ | 12424 | .memory => |addr| .{ |
| 12278 | .base = .{ .reg = .ds }, | 12425 | .base = .{ .reg = .ds }, |
| 12279 | .mod = .{ .rm = .{ | 12426 | .mod = .{ .rm = .{ |
| 12280 | .size = Memory.Size.fromSize(abi_size), | 12427 | .size = .fromSize(abi_size), |
| 12281 | .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse | 12428 | .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| 12282 | return self.asmRegisterRegister( | 12429 | return self.asmRegisterRegister( |
| 12283 | .{ .i_, .mul }, | 12430 | .{ .i_, .mul }, |
| ... | @@ -12292,14 +12439,14 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -12292,14 +12439,14 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 12292 | .indirect => |reg_off| .{ | 12439 | .indirect => |reg_off| .{ |
| 12293 | .base = .{ .reg = reg_off.reg }, | 12440 | .base = .{ .reg = reg_off.reg }, |
| 12294 | .mod = .{ .rm = .{ | 12441 | .mod = .{ .rm = .{ |
| 12295 | .size = Memory.Size.fromSize(abi_size), | 12442 | .size = .fromSize(abi_size), |
| 12296 | .disp = reg_off.off, | 12443 | .disp = reg_off.off, |
| 12297 | } }, | 12444 | } }, |
| 12298 | }, | 12445 | }, |
| 12299 | .load_frame => |frame_addr| .{ | 12446 | .load_frame => |frame_addr| .{ |
| 12300 | .base = .{ .frame = frame_addr.index }, | 12447 | .base = .{ .frame = frame_addr.index }, |
| 12301 | .mod = .{ .rm = .{ | 12448 | .mod = .{ .rm = .{ |
| 12302 | .size = Memory.Size.fromSize(abi_size), | 12449 | .size = .fromSize(abi_size), |
| 12303 | .disp = frame_addr.off, | 12450 | .disp = frame_addr.off, |
| 12304 | } }, | 12451 | } }, |
| 12305 | }, | 12452 | }, |
| ... | @@ -12475,7 +12622,7 @@ fn genLocalDebugInfo( | ... | @@ -12475,7 +12622,7 @@ fn genLocalDebugInfo( |
| 12475 | self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand, | 12622 | self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand, |
| 12476 | ), | 12623 | ), |
| 12477 | }; | 12624 | }; |
| 12478 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, self.pt.zcu)); | 12625 | const frame_index = try self.allocFrameIndex(.initSpill(ty, self.pt.zcu)); |
| 12479 | try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{}); | 12626 | try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{}); |
| 12480 | try self.asmAirMemory(.dbg_local, inst, .{ | 12627 | try self.asmAirMemory(.dbg_local, inst, .{ |
| 12481 | .base = .{ .frame = frame_index }, | 12628 | .base = .{ .frame = frame_index }, |
| ... | @@ -12602,7 +12749,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12602,7 +12749,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12602 | const frame_indices = try allocator.alloc(FrameIndex, args.len); | 12749 | const frame_indices = try allocator.alloc(FrameIndex, args.len); |
| 12603 | defer allocator.free(frame_indices); | 12750 | defer allocator.free(frame_indices); |
| 12604 | | 12751 | |
| 12605 | var reg_locks = std.ArrayList(?RegisterLock).init(allocator); | 12752 | var reg_locks: std.ArrayList(?RegisterLock) = .init(allocator); |
| 12606 | defer reg_locks.deinit(); | 12753 | defer reg_locks.deinit(); |
| 12607 | try reg_locks.ensureTotalCapacity(16); | 12754 | try reg_locks.ensureTotalCapacity(16); |
| 12608 | defer for (reg_locks.items) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); | 12755 | defer for (reg_locks.items) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -12612,7 +12759,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12612,7 +12759,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12612 | | 12759 | |
| 12613 | // We need a properly aligned and sized call frame to be able to call this function. | 12760 | // We need a properly aligned and sized call frame to be able to call this function. |
| 12614 | { | 12761 | { |
| 12615 | const needed_call_frame = FrameAlloc.init(.{ | 12762 | const needed_call_frame: FrameAlloc = .init(.{ |
| 12616 | .size = call_info.stack_byte_count, | 12763 | .size = call_info.stack_byte_count, |
| 12617 | .alignment = call_info.stack_align, | 12764 | .alignment = call_info.stack_align, |
| 12618 | }); | 12765 | }); |
| ... | @@ -12647,7 +12794,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12647,7 +12794,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12647 | try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs)); | 12794 | try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs)); |
| 12648 | }, | 12795 | }, |
| 12649 | .indirect => |reg_off| { | 12796 | .indirect => |reg_off| { |
| 12650 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, zcu)); | 12797 | frame_index.* = try self.allocFrameIndex(.initType(arg_ty, zcu)); |
| 12651 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); | 12798 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); |
| 12652 | try self.register_manager.getReg(reg_off.reg, null); | 12799 | try self.register_manager.getReg(reg_off.reg, null); |
| 12653 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); | 12800 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); |
| ... | @@ -12718,8 +12865,8 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12718,8 +12865,8 @@ fn genCall(self: *Self, info: union(enum) { |
| 12718 | switch (call_info.return_value.long) { | 12865 | switch (call_info.return_value.long) { |
| 12719 | .none, .unreach => {}, | 12866 | .none, .unreach => {}, |
| 12720 | .indirect => |reg_off| { | 12867 | .indirect => |reg_off| { |
| 12721 | const ret_ty = Type.fromInterned(fn_info.return_type); | 12868 | const ret_ty: Type = .fromInterned(fn_info.return_type); |
| 12722 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, zcu)); | 12869 | const frame_index = try self.allocFrameIndex(.initSpill(ret_ty, zcu)); |
| 12723 | try self.genSetReg(reg_off.reg, Type.usize, .{ | 12870 | try self.genSetReg(reg_off.reg, Type.usize, .{ |
| 12724 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 12871 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 12725 | }, .{}); | 12872 | }, .{}); |
| ... | @@ -12936,7 +13083,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void | ... | @@ -12936,7 +13083,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void |
| 12936 | self.register_manager.lockRegAssumeUnused(lhs_ro.reg), | 13083 | self.register_manager.lockRegAssumeUnused(lhs_ro.reg), |
| 12937 | null, | 13084 | null, |
| 12938 | }, | 13085 | }, |
| 12939 | else => .{null} ** 2, | 13086 | else => @splat(null), |
| 12940 | }; | 13087 | }; |
| 12941 | defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock); | 13088 | defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 12942 | | 13089 | |
| ... | @@ -12945,7 +13092,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void | ... | @@ -12945,7 +13092,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void |
| 12945 | .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null }, | 13092 | .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null }, |
| 12946 | .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs), | 13093 | .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs), |
| 12947 | .register_offset => |rhs_ro| .{ self.register_manager.lockReg(rhs_ro.reg), null }, | 13094 | .register_offset => |rhs_ro| .{ self.register_manager.lockReg(rhs_ro.reg), null }, |
| 12948 | else => .{null} ** 2, | 13095 | else => @splat(null), |
| 12949 | }; | 13096 | }; |
| 12950 | defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); | 13097 | defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 12951 | | 13098 | |
| ... | @@ -13080,7 +13227,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void | ... | @@ -13080,7 +13227,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void |
| 13080 | if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 13227 | if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 13081 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 13228 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 13082 | | 13229 | |
| 13083 | break :result Condition.fromCompareOperator( | 13230 | break :result .fromCompareOperator( |
| 13084 | if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned, | 13231 | if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned, |
| 13085 | result_op: { | 13232 | result_op: { |
| 13086 | const flipped_op = if (flipped) op.reverse() else op; | 13233 | const flipped_op = if (flipped) op.reverse() else op; |
| ... | @@ -13212,11 +13359,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void | ... | @@ -13212,11 +13359,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) !void |
| 13212 | defer if (src_info) |info| | 13359 | defer if (src_info) |info| |
| 13213 | self.register_manager.unlockReg(info.addr_lock); | 13360 | self.register_manager.unlockReg(info.addr_lock); |
| 13214 | | 13361 | |
| 13215 | const regs = try self.register_manager.allocRegs( | 13362 | const regs = try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp); |
| 13216 | 2, | | |
| 13217 | .{null} ** 2, | | |
| 13218 | abi.RegisterClass.gp, | | |
| 13219 | ); | | |
| 13220 | const acc_reg = regs[0].to64(); | 13363 | const acc_reg = regs[0].to64(); |
| 13221 | const locks = self.register_manager.lockRegsAssumeUnused(2, regs); | 13364 | const locks = self.register_manager.lockRegsAssumeUnused(2, regs); |
| 13222 | defer for (locks) |lock| self.register_manager.unlockReg(lock); | 13365 | defer for (locks) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -13367,7 +13510,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13367,7 +13510,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { |
| 13367 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; | 13510 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| 13368 | const dst_mcv = try self.genBinOp( | 13511 | const dst_mcv = try self.genBinOp( |
| 13369 | inst, | 13512 | inst, |
| 13370 | Air.Inst.Tag.fromCmpOp(extra.compareOperator(), false), | 13513 | .fromCmpOp(extra.compareOperator(), false), |
| 13371 | extra.lhs, | 13514 | extra.lhs, |
| 13372 | extra.rhs, | 13515 | extra.rhs, |
| 13373 | ); | 13516 | ); |
| ... | @@ -13399,7 +13542,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13399,7 +13542,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 13399 | registerAlias(dst_reg, op_abi_size), | 13542 | registerAlias(dst_reg, op_abi_size), |
| 13400 | .{ | 13543 | .{ |
| 13401 | .base = .{ .reg = addr_reg }, | 13544 | .base = .{ .reg = addr_reg }, |
| 13402 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(op_abi_size) } }, | 13545 | .mod = .{ .rm = .{ .size = .fromSize(op_abi_size) } }, |
| 13403 | }, | 13546 | }, |
| 13404 | ); | 13547 | ); |
| 13405 | | 13548 | |
| ... | @@ -13682,7 +13825,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13682,7 +13825,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13682 | .{ | 13825 | .{ |
| 13683 | .base = .{ .reg = addr_reg }, | 13826 | .base = .{ .reg = addr_reg }, |
| 13684 | .mod = .{ .rm = .{ | 13827 | .mod = .{ .rm = .{ |
| 13685 | .size = Memory.Size.fromSize(some_abi_size), | 13828 | .size = .fromSize(some_abi_size), |
| 13686 | .disp = some_info.off, | 13829 | .disp = some_info.off, |
| 13687 | } }, | 13830 | } }, |
| 13688 | }, | 13831 | }, |
| ... | @@ -13699,14 +13842,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -13699,14 +13842,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 13699 | .indirect => |reg_off| .{ | 13842 | .indirect => |reg_off| .{ |
| 13700 | .base = .{ .reg = reg_off.reg }, | 13843 | .base = .{ .reg = reg_off.reg }, |
| 13701 | .mod = .{ .rm = .{ | 13844 | .mod = .{ .rm = .{ |
| 13702 | .size = Memory.Size.fromSize(some_abi_size), | 13845 | .size = .fromSize(some_abi_size), |
| 13703 | .disp = reg_off.off + some_info.off, | 13846 | .disp = reg_off.off + some_info.off, |
| 13704 | } }, | 13847 | } }, |
| 13705 | }, | 13848 | }, |
| 13706 | .load_frame => |frame_addr| .{ | 13849 | .load_frame => |frame_addr| .{ |
| 13707 | .base = .{ .frame = frame_addr.index }, | 13850 | .base = .{ .frame = frame_addr.index }, |
| 13708 | .mod = .{ .rm = .{ | 13851 | .mod = .{ .rm = .{ |
| 13709 | .size = Memory.Size.fromSize(some_abi_size), | 13852 | .size = .fromSize(some_abi_size), |
| 13710 | .disp = frame_addr.off + some_info.off, | 13853 | .disp = frame_addr.off + some_info.off, |
| 13711 | } }, | 13854 | } }, |
| 13712 | }, | 13855 | }, |
| ... | @@ -13745,7 +13888,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -13745,7 +13888,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 13745 | .{ | 13888 | .{ |
| 13746 | .base = .{ .reg = ptr_reg }, | 13889 | .base = .{ .reg = ptr_reg }, |
| 13747 | .mod = .{ .rm = .{ | 13890 | .mod = .{ .rm = .{ |
| 13748 | .size = Memory.Size.fromSize(some_abi_size), | 13891 | .size = .fromSize(some_abi_size), |
| 13749 | .disp = some_info.off, | 13892 | .disp = some_info.off, |
| 13750 | } }, | 13893 | } }, |
| 13751 | }, | 13894 | }, |
| ... | @@ -13968,7 +14111,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13968,7 +14111,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 13968 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { | 14111 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { |
| 13969 | // A block is a setup to be able to jump to the end. | 14112 | // A block is a setup to be able to jump to the end. |
| 13970 | const inst_tracking_i = self.inst_tracking.count(); | 14113 | const inst_tracking_i = self.inst_tracking.count(); |
| 13971 | self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(.unreach)); | 14114 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(.unreach)); |
| 13972 | | 14115 | |
| 13973 | self.scope_generation += 1; | 14116 | self.scope_generation += 1; |
| 13974 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); | 14117 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); |
| ... | @@ -14140,7 +14283,7 @@ fn airLoopSwitchBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14140,7 +14283,7 @@ fn airLoopSwitchBr(self: *Self, inst: Air.Inst.Index) !void { |
| 14140 | try self.genCopy(self.typeOf(switch_br.operand), mat_cond, condition, .{}); | 14283 | try self.genCopy(self.typeOf(switch_br.operand), mat_cond, condition, .{}); |
| 14141 | break :mat_cond mat_cond; | 14284 | break :mat_cond mat_cond; |
| 14142 | }; | 14285 | }; |
| 14143 | self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(mat_cond)); | 14286 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(mat_cond)); |
| 14144 | | 14287 | |
| 14145 | // If the condition dies here in this switch instruction, process | 14288 | // If the condition dies here in this switch instruction, process |
| 14146 | // that death now instead of later as this has an effect on | 14289 | // that death now instead of later as this has an effect on |
| ... | @@ -14265,7 +14408,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14265,7 +14408,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 14265 | } | 14408 | } |
| 14266 | | 14409 | |
| 14267 | if (first_br) { | 14410 | if (first_br) { |
| 14268 | block_tracking.* = InstTracking.init(block_result); | 14411 | block_tracking.* = .init(block_result); |
| 14269 | try self.saveRetroactiveState(&block_data.state); | 14412 | try self.saveRetroactiveState(&block_data.state); |
| 14270 | } else try self.restoreState(block_data.state, &.{}, .{ | 14413 | } else try self.restoreState(block_data.state, &.{}, .{ |
| 14271 | .emit_instructions = true, | 14414 | .emit_instructions = true, |
| ... | @@ -14309,7 +14452,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14309,7 +14452,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 14309 | extra_i += inputs.len; | 14452 | extra_i += inputs.len; |
| 14310 | | 14453 | |
| 14311 | var result: MCValue = .none; | 14454 | var result: MCValue = .none; |
| 14312 | var args = std.ArrayList(MCValue).init(self.gpa); | 14455 | var args: std.ArrayList(MCValue) = .init(self.gpa); |
| 14313 | try args.ensureTotalCapacity(outputs.len + inputs.len); | 14456 | try args.ensureTotalCapacity(outputs.len + inputs.len); |
| 14314 | defer { | 14457 | defer { |
| 14315 | for (args.items) |arg| if (arg.getReg()) |reg| self.register_manager.unlockReg(.{ | 14458 | for (args.items) |arg| if (arg.getReg()) |reg| self.register_manager.unlockReg(.{ |
| ... | @@ -14317,7 +14460,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14317,7 +14460,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 14317 | }); | 14460 | }); |
| 14318 | args.deinit(); | 14461 | args.deinit(); |
| 14319 | } | 14462 | } |
| 14320 | var arg_map = std.StringHashMap(u8).init(self.gpa); | 14463 | var arg_map: std.StringHashMap(u8) = .init(self.gpa); |
| 14321 | try arg_map.ensureTotalCapacity(@intCast(outputs.len + inputs.len)); | 14464 | try arg_map.ensureTotalCapacity(@intCast(outputs.len + inputs.len)); |
| 14322 | defer arg_map.deinit(); | 14465 | defer arg_map.deinit(); |
| 14323 | | 14466 | |
| ... | @@ -14645,14 +14788,8 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14645,14 +14788,8 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 14645 | }); | 14788 | }); |
| 14646 | }; | 14789 | }; |
| 14647 | | 14790 | |
| 14648 | const Operand = union(enum) { | 14791 | var ops: [4]Operand = @splat(.none); |
| 14649 | none, | 14792 | var ops_len: usize = 0; |
| 14650 | reg: Register, | | |
| 14651 | mem: Memory, | | |
| 14652 | imm: Immediate, | | |
| 14653 | inst: Mir.Inst.Index, | | |
| 14654 | }; | | |
| 14655 | var ops: [4]Operand = .{.none} ** 4; | | |
| 14656 | | 14793 | |
| 14657 | var last_op = false; | 14794 | var last_op = false; |
| 14658 | var op_it = std.mem.splitScalar(u8, mnem_it.rest(), ','); | 14795 | var op_it = std.mem.splitScalar(u8, mnem_it.rest(), ','); |
| ... | @@ -14847,8 +14984,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14847,8 +14984,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 14847 | try pending_relocs.append(self.gpa, @intCast(self.mir_instructions.len)); | 14984 | try pending_relocs.append(self.gpa, @intCast(self.mir_instructions.len)); |
| 14848 | op.* = .{ .inst = label_gop.value_ptr.target }; | 14985 | op.* = .{ .inst = label_gop.value_ptr.target }; |
| 14849 | } else return self.fail("invalid operand: '{s}'", .{op_str}); | 14986 | } else return self.fail("invalid operand: '{s}'", .{op_str}); |
| | 14987 | ops_len += 1; |
| 14850 | } else if (op_it.next()) |op_str| return self.fail("extra operand: '{s}'", .{op_str}); | 14988 | } else if (op_it.next()) |op_str| return self.fail("extra operand: '{s}'", .{op_str}); |
| 14851 | | 14989 | |
| | 14990 | // convert from att syntax to intel syntax |
| | 14991 | std.mem.reverse(Operand, ops[0..ops_len]); |
| | 14992 | |
| 14852 | (if (prefix == .directive) switch (mnem_tag) { | 14993 | (if (prefix == .directive) switch (mnem_tag) { |
| 14853 | .@".cfi_def_cfa" => if (ops[0] == .reg and ops[1] == .imm and ops[2] == .none) | 14994 | .@".cfi_def_cfa" => if (ops[0] == .reg and ops[1] == .imm and ops[2] == .none) |
| 14854 | self.asmPseudoRegisterImmediate(.pseudo_cfi_def_cfa_ri_s, ops[0].reg, ops[1].imm) | 14995 | self.asmPseudoRegisterImmediate(.pseudo_cfi_def_cfa_ri_s, ops[0].reg, ops[1].imm) |
| ... | @@ -14904,68 +15045,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14904,68 +15045,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 14904 | error.InvalidInstruction, | 15045 | error.InvalidInstruction, |
| 14905 | .@".cfi_escape" => error.InvalidInstruction, | 15046 | .@".cfi_escape" => error.InvalidInstruction, |
| 14906 | else => unreachable, | 15047 | else => unreachable, |
| 14907 | } else switch (ops[0]) { | 15048 | } else self.asmOps(mnem_fixed_tag, ops)) catch |err| switch (err) { |
| 14908 | .none => self.asmOpOnly(mnem_fixed_tag), | | |
| 14909 | .reg => |reg0| switch (ops[1]) { | | |
| 14910 | .none => self.asmRegister(mnem_fixed_tag, reg0), | | |
| 14911 | .reg => |reg1| switch (ops[2]) { | | |
| 14912 | .none => self.asmRegisterRegister(mnem_fixed_tag, reg1, reg0), | | |
| 14913 | .reg => |reg2| switch (ops[3]) { | | |
| 14914 | .none => self.asmRegisterRegisterRegister(mnem_fixed_tag, reg2, reg1, reg0), | | |
| 14915 | else => error.InvalidInstruction, | | |
| 14916 | }, | | |
| 14917 | .mem => |mem2| switch (ops[3]) { | | |
| 14918 | .none => self.asmMemoryRegisterRegister(mnem_fixed_tag, mem2, reg1, reg0), | | |
| 14919 | else => error.InvalidInstruction, | | |
| 14920 | }, | | |
| 14921 | else => error.InvalidInstruction, | | |
| 14922 | }, | | |
| 14923 | .mem => |mem1| switch (ops[2]) { | | |
| 14924 | .none => self.asmMemoryRegister(mnem_fixed_tag, mem1, reg0), | | |
| 14925 | else => error.InvalidInstruction, | | |
| 14926 | }, | | |
| 14927 | else => error.InvalidInstruction, | | |
| 14928 | }, | | |
| 14929 | .mem => |mem0| switch (ops[1]) { | | |
| 14930 | .none => self.asmMemory(mnem_fixed_tag, mem0), | | |
| 14931 | .reg => |reg1| switch (ops[2]) { | | |
| 14932 | .none => self.asmRegisterMemory(mnem_fixed_tag, reg1, mem0), | | |
| 14933 | else => error.InvalidInstruction, | | |
| 14934 | }, | | |
| 14935 | else => error.InvalidInstruction, | | |
| 14936 | }, | | |
| 14937 | .imm => |imm0| switch (ops[1]) { | | |
| 14938 | .none => self.asmImmediate(mnem_fixed_tag, imm0), | | |
| 14939 | .reg => |reg1| switch (ops[2]) { | | |
| 14940 | .none => self.asmRegisterImmediate(mnem_fixed_tag, reg1, imm0), | | |
| 14941 | .reg => |reg2| switch (ops[3]) { | | |
| 14942 | .none => self.asmRegisterRegisterImmediate(mnem_fixed_tag, reg2, reg1, imm0), | | |
| 14943 | .reg => |reg3| self.asmRegisterRegisterRegisterImmediate( | | |
| 14944 | mnem_fixed_tag, | | |
| 14945 | reg3, | | |
| 14946 | reg2, | | |
| 14947 | reg1, | | |
| 14948 | imm0, | | |
| 14949 | ), | | |
| 14950 | else => error.InvalidInstruction, | | |
| 14951 | }, | | |
| 14952 | .mem => |mem2| switch (ops[3]) { | | |
| 14953 | .none => self.asmMemoryRegisterImmediate(mnem_fixed_tag, mem2, reg1, imm0), | | |
| 14954 | else => error.InvalidInstruction, | | |
| 14955 | }, | | |
| 14956 | else => error.InvalidInstruction, | | |
| 14957 | }, | | |
| 14958 | .mem => |mem1| switch (ops[2]) { | | |
| 14959 | .none => self.asmMemoryImmediate(mnem_fixed_tag, mem1, imm0), | | |
| 14960 | else => error.InvalidInstruction, | | |
| 14961 | }, | | |
| 14962 | else => error.InvalidInstruction, | | |
| 14963 | }, | | |
| 14964 | .inst => |inst0| switch (ops[1]) { | | |
| 14965 | .none => self.asmReloc(mnem_fixed_tag, inst0), | | |
| 14966 | else => error.InvalidInstruction, | | |
| 14967 | }, | | |
| 14968 | }) catch |err| switch (err) { | | |
| 14969 | error.InvalidInstruction => return self.fail( | 15049 | error.InvalidInstruction => return self.fail( |
| 14970 | "invalid instruction: '{s} {s} {s} {s} {s}'", | 15050 | "invalid instruction: '{s} {s} {s} {s} {s}'", |
| 14971 | .{ | 15051 | .{ |
| ... | @@ -15000,7 +15080,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15000,7 +15080,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 15000 | } | 15080 | } |
| 15001 | | 15081 | |
| 15002 | simple: { | 15082 | simple: { |
| 15003 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); | 15083 | var buf: [Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); |
| 15004 | var buf_index: usize = 0; | 15084 | var buf_index: usize = 0; |
| 15005 | for (outputs) |output| { | 15085 | for (outputs) |output| { |
| 15006 | if (output == .none) continue; | 15086 | if (output == .none) continue; |
| ... | @@ -15583,7 +15663,7 @@ fn genSetReg( | ... | @@ -15583,7 +15663,7 @@ fn genSetReg( |
| 15583 | .load_frame => |frame_addr| try self.moveStrategy( | 15663 | .load_frame => |frame_addr| try self.moveStrategy( |
| 15584 | ty, | 15664 | ty, |
| 15585 | dst_reg.class(), | 15665 | dst_reg.class(), |
| 15586 | self.getFrameAddrAlignment(frame_addr).compare(.gte, InternPool.Alignment.fromLog2Units( | 15666 | self.getFrameAddrAlignment(frame_addr).compare(.gte, .fromLog2Units( |
| 15587 | std.math.log2_int_ceil(u10, @divExact(dst_reg.bitSize(), 8)), | 15667 | std.math.log2_int_ceil(u10, @divExact(dst_reg.bitSize(), 8)), |
| 15588 | )), | 15668 | )), |
| 15589 | ), | 15669 | ), |
| ... | @@ -15742,7 +15822,7 @@ fn genSetMem( | ... | @@ -15742,7 +15822,7 @@ fn genSetMem( |
| 15742 | try self.asmMemoryImmediate( | 15822 | try self.asmMemoryImmediate( |
| 15743 | .{ ._, .mov }, | 15823 | .{ ._, .mov }, |
| 15744 | .{ .base = base, .mod = .{ .rm = .{ | 15824 | .{ .base = base, .mod = .{ .rm = .{ |
| 15745 | .size = Memory.Size.fromSize(abi_size), | 15825 | .size = .fromSize(abi_size), |
| 15746 | .disp = disp, | 15826 | .disp = disp, |
| 15747 | } } }, | 15827 | } } }, |
| 15748 | immediate, | 15828 | immediate, |
| ... | @@ -15753,7 +15833,7 @@ fn genSetMem( | ... | @@ -15753,7 +15833,7 @@ fn genSetMem( |
| 15753 | try self.asmMemoryImmediate( | 15833 | try self.asmMemoryImmediate( |
| 15754 | .{ ._, .mov }, | 15834 | .{ ._, .mov }, |
| 15755 | .{ .base = base, .mod = .{ .rm = .{ | 15835 | .{ .base = base, .mod = .{ .rm = .{ |
| 15756 | .size = Memory.Size.fromSize(abi_size), | 15836 | .size = .fromSize(abi_size), |
| 15757 | .disp = disp, | 15837 | .disp = disp, |
| 15758 | } } }, | 15838 | } } }, |
| 15759 | .s(small), | 15839 | .s(small), |
| ... | @@ -15796,11 +15876,11 @@ fn genSetMem( | ... | @@ -15796,11 +15876,11 @@ fn genSetMem( |
| 15796 | .general_purpose, .segment, .x87, .ip => @divExact(src_alias.bitSize(), 8), | 15876 | .general_purpose, .segment, .x87, .ip => @divExact(src_alias.bitSize(), 8), |
| 15797 | .mmx, .sse => abi_size, | 15877 | .mmx, .sse => abi_size, |
| 15798 | }); | 15878 | }); |
| 15799 | const src_align = InternPool.Alignment.fromNonzeroByteUnits( | 15879 | const src_align: InternPool.Alignment = .fromNonzeroByteUnits( |
| 15800 | std.math.ceilPowerOfTwoAssert(u32, src_size), | 15880 | std.math.ceilPowerOfTwoAssert(u32, src_size), |
| 15801 | ); | 15881 | ); |
| 15802 | if (src_size > mem_size) { | 15882 | if (src_size > mem_size) { |
| 15803 | const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{ | 15883 | const frame_index = try self.allocFrameIndex(.init(.{ |
| 15804 | .size = src_size, | 15884 | .size = src_size, |
| 15805 | .alignment = src_align, | 15885 | .alignment = src_align, |
| 15806 | })); | 15886 | })); |
| ... | @@ -15808,7 +15888,7 @@ fn genSetMem( | ... | @@ -15808,7 +15888,7 @@ fn genSetMem( |
| 15808 | try (try self.moveStrategy(ty, src_alias.class(), true)).write( | 15888 | try (try self.moveStrategy(ty, src_alias.class(), true)).write( |
| 15809 | self, | 15889 | self, |
| 15810 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ | 15890 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ |
| 15811 | .size = Memory.Size.fromSize(src_size), | 15891 | .size = .fromSize(src_size), |
| 15812 | } } }, | 15892 | } } }, |
| 15813 | src_alias, | 15893 | src_alias, |
| 15814 | ); | 15894 | ); |
| ... | @@ -15828,7 +15908,7 @@ fn genSetMem( | ... | @@ -15828,7 +15908,7 @@ fn genSetMem( |
| 15828 | })).write( | 15908 | })).write( |
| 15829 | self, | 15909 | self, |
| 15830 | .{ .base = base, .mod = .{ .rm = .{ | 15910 | .{ .base = base, .mod = .{ .rm = .{ |
| 15831 | .size = Memory.Size.fromBitSize(@min(self.memSize(ty).bitSize(), src_alias.bitSize())), | 15911 | .size = .fromBitSize(@min(self.memSize(ty).bitSize(), src_alias.bitSize())), |
| 15832 | .disp = disp, | 15912 | .disp = disp, |
| 15833 | } } }, | 15913 | } } }, |
| 15834 | src_alias, | 15914 | src_alias, |
| ... | @@ -16037,7 +16117,7 @@ fn genLazySymbolRef( | ... | @@ -16037,7 +16117,7 @@ fn genLazySymbolRef( |
| 16037 | .mov => try self.asmRegisterMemory( | 16117 | .mov => try self.asmRegisterMemory( |
| 16038 | .{ ._, tag }, | 16118 | .{ ._, tag }, |
| 16039 | reg.to64(), | 16119 | reg.to64(), |
| 16040 | Memory.initSib(.qword, .{ .base = .{ .reg = reg.to64() } }), | 16120 | .initSib(.qword, .{ .base = .{ .reg = reg.to64() } }), |
| 16041 | ), | 16121 | ), |
| 16042 | else => unreachable, | 16122 | else => unreachable, |
| 16043 | } | 16123 | } |
| ... | @@ -16108,8 +16188,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16108,8 +16188,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 16108 | else => if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv, | 16188 | else => if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv, |
| 16109 | }; | 16189 | }; |
| 16110 | | 16190 | |
| 16111 | const dst_rc = self.regClassForType(dst_ty); | 16191 | const dst_rc = self.regSetForType(dst_ty); |
| 16112 | const src_rc = self.regClassForType(src_ty); | 16192 | const src_rc = self.regSetForType(src_ty); |
| 16113 | | 16193 | |
| 16114 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 16194 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 16115 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 16195 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -16170,7 +16250,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16170,7 +16250,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 16170 | const array_ty = ptr_ty.childType(zcu); | 16250 | const array_ty = ptr_ty.childType(zcu); |
| 16171 | const array_len = array_ty.arrayLen(zcu); | 16251 | const array_len = array_ty.arrayLen(zcu); |
| 16172 | | 16252 | |
| 16173 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, zcu)); | 16253 | const frame_index = try self.allocFrameIndex(.initSpill(slice_ty, zcu)); |
| 16174 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); | 16254 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); |
| 16175 | try self.genSetMem( | 16255 | try self.genSetMem( |
| 16176 | .{ .frame = frame_index }, | 16256 | .{ .frame = frame_index }, |
| ... | @@ -16236,7 +16316,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16236,7 +16316,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 16236 | | 16316 | |
| 16237 | if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg); | 16317 | if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg); |
| 16238 | | 16318 | |
| 16239 | const dst_reg = try self.register_manager.allocReg(inst, self.regClassForType(dst_ty)); | 16319 | const dst_reg = try self.register_manager.allocReg(inst, self.regSetForType(dst_ty)); |
| 16240 | const dst_mcv = MCValue{ .register = dst_reg }; | 16320 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 16241 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 16321 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 16242 | defer self.register_manager.unlockReg(dst_lock); | 16322 | defer self.register_manager.unlockReg(dst_lock); |
| ... | @@ -16314,7 +16394,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16314,7 +16394,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 16314 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | 16394 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| 16315 | defer self.register_manager.unlockReg(src_lock); | 16395 | defer self.register_manager.unlockReg(src_lock); |
| 16316 | | 16396 | |
| 16317 | const dst_reg = try self.register_manager.allocReg(inst, self.regClassForType(dst_ty)); | 16397 | const dst_reg = try self.register_manager.allocReg(inst, self.regSetForType(dst_ty)); |
| 16318 | const dst_mcv = MCValue{ .register = dst_reg }; | 16398 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 16319 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 16399 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 16320 | defer self.register_manager.unlockReg(dst_lock); | 16400 | defer self.register_manager.unlockReg(dst_lock); |
| ... | @@ -16381,7 +16461,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16381,7 +16461,7 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 16381 | defer if (new_lock) |lock| self.register_manager.unlockReg(lock); | 16461 | defer if (new_lock) |lock| self.register_manager.unlockReg(lock); |
| 16382 | | 16462 | |
| 16383 | const ptr_mcv = try self.resolveInst(extra.ptr); | 16463 | const ptr_mcv = try self.resolveInst(extra.ptr); |
| 16384 | const mem_size = Memory.Size.fromSize(val_abi_size); | 16464 | const mem_size: Memory.Size = .fromSize(val_abi_size); |
| 16385 | const ptr_mem: Memory = switch (ptr_mcv) { | 16465 | const ptr_mem: Memory = switch (ptr_mcv) { |
| 16386 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), | 16466 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), |
| 16387 | else => .{ | 16467 | else => .{ |
| ... | @@ -16448,7 +16528,7 @@ fn atomicOp( | ... | @@ -16448,7 +16528,7 @@ fn atomicOp( |
| 16448 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); | 16528 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); |
| 16449 | | 16529 | |
| 16450 | const val_abi_size: u32 = @intCast(val_ty.abiSize(zcu)); | 16530 | const val_abi_size: u32 = @intCast(val_ty.abiSize(zcu)); |
| 16451 | const mem_size = Memory.Size.fromSize(val_abi_size); | 16531 | const mem_size: Memory.Size = .fromSize(val_abi_size); |
| 16452 | const ptr_mem: Memory = switch (ptr_mcv) { | 16532 | const ptr_mem: Memory = switch (ptr_mcv) { |
| 16453 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), | 16533 | .immediate, .register, .register_offset, .lea_frame => try ptr_mcv.deref().mem(self, mem_size), |
| 16454 | else => .{ | 16534 | else => .{ |
| ... | @@ -16637,7 +16717,7 @@ fn atomicOp( | ... | @@ -16637,7 +16717,7 @@ fn atomicOp( |
| 16637 | try self.asmCmovccRegisterMemory( | 16717 | try self.asmCmovccRegisterMemory( |
| 16638 | cc, | 16718 | cc, |
| 16639 | registerAlias(tmp_reg, cmov_abi_size), | 16719 | registerAlias(tmp_reg, cmov_abi_size), |
| 16640 | try val_mcv.mem(self, Memory.Size.fromSize(cmov_abi_size)), | 16720 | try val_mcv.mem(self, .fromSize(cmov_abi_size)), |
| 16641 | ); | 16721 | ); |
| 16642 | }, | 16722 | }, |
| 16643 | else => { | 16723 | else => { |
| ... | @@ -17069,7 +17149,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17069,7 +17149,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 17069 | | 17149 | |
| 17070 | // We need a properly aligned and sized call frame to be able to call this function. | 17150 | // We need a properly aligned and sized call frame to be able to call this function. |
| 17071 | { | 17151 | { |
| 17072 | const needed_call_frame = FrameAlloc.init(.{ | 17152 | const needed_call_frame: FrameAlloc = .init(.{ |
| 17073 | .size = inst_ty.abiSize(zcu), | 17153 | .size = inst_ty.abiSize(zcu), |
| 17074 | .alignment = inst_ty.abiAlignment(zcu), | 17154 | .alignment = inst_ty.abiAlignment(zcu), |
| 17075 | }); | 17155 | }); |
| ... | @@ -17207,7 +17287,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17207,7 +17287,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 17207 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 17287 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 17208 | const vector_ty = self.typeOfIndex(inst); | 17288 | const vector_ty = self.typeOfIndex(inst); |
| 17209 | const vector_len = vector_ty.vectorLen(zcu); | 17289 | const vector_len = vector_ty.vectorLen(zcu); |
| 17210 | const dst_rc = self.regClassForType(vector_ty); | 17290 | const dst_rc = self.regSetForType(vector_ty); |
| 17211 | const scalar_ty = self.typeOf(ty_op.operand); | 17291 | const scalar_ty = self.typeOf(ty_op.operand); |
| 17212 | | 17292 | |
| 17213 | const result: MCValue = result: { | 17293 | const result: MCValue = result: { |
| ... | @@ -17675,7 +17755,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17675,7 +17755,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17675 | .ty = mask_elem_ty.toIntern(), | 17755 | .ty = mask_elem_ty.toIntern(), |
| 17676 | .storage = .{ .u64 = bit / elem_bits }, | 17756 | .storage = .{ .u64 = bit / elem_bits }, |
| 17677 | } }); | 17757 | } }); |
| 17678 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 17758 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 17679 | .ty = mask_ty.toIntern(), | 17759 | .ty = mask_ty.toIntern(), |
| 17680 | .storage = .{ .elems = mask_elems[0..vec_len] }, | 17760 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 17681 | } }))); | 17761 | } }))); |
| ... | @@ -17700,7 +17780,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17700,7 +17780,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17700 | .ty = mask_elem_ty.toIntern(), | 17780 | .ty = mask_elem_ty.toIntern(), |
| 17701 | .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) }, | 17781 | .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) }, |
| 17702 | } }); | 17782 | } }); |
| 17703 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 17783 | const mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 17704 | .ty = mask_ty.toIntern(), | 17784 | .ty = mask_ty.toIntern(), |
| 17705 | .storage = .{ .elems = mask_elems[0..vec_len] }, | 17785 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 17706 | } }))); | 17786 | } }))); |
| ... | @@ -17853,7 +17933,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17853,7 +17933,7 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 17853 | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( | 17933 | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 17854 | .{ mir_fixes, .andn }, | 17934 | .{ mir_fixes, .andn }, |
| 17855 | mask_alias, | 17935 | mask_alias, |
| 17856 | try rhs_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 17936 | try rhs_mcv.mem(self, .fromSize(abi_size)), |
| 17857 | ) else try self.asmRegisterRegister( | 17937 | ) else try self.asmRegisterRegister( |
| 17858 | .{ mir_fixes, .andn }, | 17938 | .{ mir_fixes, .andn }, |
| 17859 | mask_alias, | 17939 | mask_alias, |
| ... | @@ -17934,7 +18014,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17934,7 +18014,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17934 | else | 18014 | else |
| 17935 | self.hasFeature(.avx2)) 32 else 16)) break :unpck; | 18015 | self.hasFeature(.avx2)) 32 else 16)) break :unpck; |
| 17936 | | 18016 | |
| 17937 | var sources = [1]?u1{null} ** 2; | 18017 | var sources: [2]?u1 = @splat(null); |
| 17938 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { | 18018 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { |
| 17939 | const mask_elem = maybe_mask_elem orelse continue; | 18019 | const mask_elem = maybe_mask_elem orelse continue; |
| 17940 | const mask_elem_index = | 18020 | const mask_elem_index = |
| ... | @@ -17994,7 +18074,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17994,7 +18074,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17994 | mir_tag, | 18074 | mir_tag, |
| 17995 | dst_alias, | 18075 | dst_alias, |
| 17996 | registerAlias(lhs_mcv.getReg() orelse dst_reg, max_abi_size), | 18076 | registerAlias(lhs_mcv.getReg() orelse dst_reg, max_abi_size), |
| 17997 | try rhs_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18077 | try rhs_mcv.mem(self, .fromSize(max_abi_size)), |
| 17998 | ) else try self.asmRegisterRegisterRegister( | 18078 | ) else try self.asmRegisterRegisterRegister( |
| 17999 | mir_tag, | 18079 | mir_tag, |
| 18000 | dst_alias, | 18080 | dst_alias, |
| ... | @@ -18006,7 +18086,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18006,7 +18086,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18006 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemory( | 18086 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 18007 | mir_tag, | 18087 | mir_tag, |
| 18008 | dst_alias, | 18088 | dst_alias, |
| 18009 | try rhs_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18089 | try rhs_mcv.mem(self, .fromSize(max_abi_size)), |
| 18010 | ) else try self.asmRegisterRegister( | 18090 | ) else try self.asmRegisterRegister( |
| 18011 | mir_tag, | 18091 | mir_tag, |
| 18012 | dst_alias, | 18092 | dst_alias, |
| ... | @@ -18023,7 +18103,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18023,7 +18103,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18023 | if (max_abi_size > @as(u32, if (has_avx) 32 else 16)) break :pshufd; | 18103 | if (max_abi_size > @as(u32, if (has_avx) 32 else 16)) break :pshufd; |
| 18024 | | 18104 | |
| 18025 | var control: u8 = 0b00_00_00_00; | 18105 | var control: u8 = 0b00_00_00_00; |
| 18026 | var sources = [1]?u1{null} ** 1; | 18106 | var sources: [1]?u1 = @splat(null); |
| 18027 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { | 18107 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { |
| 18028 | const mask_elem = maybe_mask_elem orelse continue; | 18108 | const mask_elem = maybe_mask_elem orelse continue; |
| 18029 | const mask_elem_index: u3 = @intCast(if (mask_elem < 0) ~mask_elem else mask_elem); | 18109 | const mask_elem_index: u3 = @intCast(if (mask_elem < 0) ~mask_elem else mask_elem); |
| ... | @@ -18055,7 +18135,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18055,7 +18135,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18055 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 18135 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 18056 | .{ if (has_avx) .vp_d else .p_d, .shuf }, | 18136 | .{ if (has_avx) .vp_d else .p_d, .shuf }, |
| 18057 | dst_alias, | 18137 | dst_alias, |
| 18058 | try src_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18138 | try src_mcv.mem(self, .fromSize(max_abi_size)), |
| 18059 | .u(control), | 18139 | .u(control), |
| 18060 | ) else try self.asmRegisterRegisterImmediate( | 18140 | ) else try self.asmRegisterRegisterImmediate( |
| 18061 | .{ if (has_avx) .vp_d else .p_d, .shuf }, | 18141 | .{ if (has_avx) .vp_d else .p_d, .shuf }, |
| ... | @@ -18074,7 +18154,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18074,7 +18154,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18074 | if (max_abi_size > @as(u32, if (has_avx) 32 else 16)) break :shufps; | 18154 | if (max_abi_size > @as(u32, if (has_avx) 32 else 16)) break :shufps; |
| 18075 | | 18155 | |
| 18076 | var control: u8 = 0b00_00_00_00; | 18156 | var control: u8 = 0b00_00_00_00; |
| 18077 | var sources = [1]?u1{null} ** 2; | 18157 | var sources: [2]?u1 = @splat(null); |
| 18078 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { | 18158 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { |
| 18079 | const mask_elem = maybe_mask_elem orelse continue; | 18159 | const mask_elem = maybe_mask_elem orelse continue; |
| 18080 | const mask_elem_index: u3 = @intCast(if (mask_elem < 0) ~mask_elem else mask_elem); | 18160 | const mask_elem_index: u3 = @intCast(if (mask_elem < 0) ~mask_elem else mask_elem); |
| ... | @@ -18112,7 +18192,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18112,7 +18192,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18112 | .{ .v_ps, .shuf }, | 18192 | .{ .v_ps, .shuf }, |
| 18113 | dst_alias, | 18193 | dst_alias, |
| 18114 | registerAlias(lhs_mcv.getReg() orelse dst_reg, max_abi_size), | 18194 | registerAlias(lhs_mcv.getReg() orelse dst_reg, max_abi_size), |
| 18115 | try rhs_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18195 | try rhs_mcv.mem(self, .fromSize(max_abi_size)), |
| 18116 | .u(control), | 18196 | .u(control), |
| 18117 | ) else try self.asmRegisterRegisterRegisterImmediate( | 18197 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 18118 | .{ .v_ps, .shuf }, | 18198 | .{ .v_ps, .shuf }, |
| ... | @@ -18126,7 +18206,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18126,7 +18206,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18126 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 18206 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 18127 | .{ ._ps, .shuf }, | 18207 | .{ ._ps, .shuf }, |
| 18128 | dst_alias, | 18208 | dst_alias, |
| 18129 | try rhs_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18209 | try rhs_mcv.mem(self, .fromSize(max_abi_size)), |
| 18130 | .u(control), | 18210 | .u(control), |
| 18131 | ) else try self.asmRegisterRegisterImmediate( | 18211 | ) else try self.asmRegisterRegisterImmediate( |
| 18132 | .{ ._ps, .shuf }, | 18212 | .{ ._ps, .shuf }, |
| ... | @@ -18145,7 +18225,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18145,7 +18225,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18145 | if (max_abi_size > @as(u32, if (has_avx) 32 else 16)) break :shufpd; | 18225 | if (max_abi_size > @as(u32, if (has_avx) 32 else 16)) break :shufpd; |
| 18146 | | 18226 | |
| 18147 | var control: u4 = 0b0_0_0_0; | 18227 | var control: u4 = 0b0_0_0_0; |
| 18148 | var sources = [1]?u1{null} ** 2; | 18228 | var sources: [2]?u1 = @splat(null); |
| 18149 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { | 18229 | for (mask_elems, 0..) |maybe_mask_elem, elem_index| { |
| 18150 | const mask_elem = maybe_mask_elem orelse continue; | 18230 | const mask_elem = maybe_mask_elem orelse continue; |
| 18151 | const mask_elem_index: u2 = @intCast(if (mask_elem < 0) ~mask_elem else mask_elem); | 18231 | const mask_elem_index: u2 = @intCast(if (mask_elem < 0) ~mask_elem else mask_elem); |
| ... | @@ -18179,7 +18259,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18179,7 +18259,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18179 | .{ .v_pd, .shuf }, | 18259 | .{ .v_pd, .shuf }, |
| 18180 | dst_alias, | 18260 | dst_alias, |
| 18181 | registerAlias(lhs_mcv.getReg() orelse dst_reg, max_abi_size), | 18261 | registerAlias(lhs_mcv.getReg() orelse dst_reg, max_abi_size), |
| 18182 | try rhs_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18262 | try rhs_mcv.mem(self, .fromSize(max_abi_size)), |
| 18183 | .u(control), | 18263 | .u(control), |
| 18184 | ) else try self.asmRegisterRegisterRegisterImmediate( | 18264 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 18185 | .{ .v_pd, .shuf }, | 18265 | .{ .v_pd, .shuf }, |
| ... | @@ -18193,7 +18273,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18193,7 +18273,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18193 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 18273 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 18194 | .{ ._pd, .shuf }, | 18274 | .{ ._pd, .shuf }, |
| 18195 | dst_alias, | 18275 | dst_alias, |
| 18196 | try rhs_mcv.mem(self, Memory.Size.fromSize(max_abi_size)), | 18276 | try rhs_mcv.mem(self, .fromSize(max_abi_size)), |
| 18197 | .u(control), | 18277 | .u(control), |
| 18198 | ) else try self.asmRegisterRegisterImmediate( | 18278 | ) else try self.asmRegisterRegisterImmediate( |
| 18199 | .{ ._pd, .shuf }, | 18279 | .{ ._pd, .shuf }, |
| ... | @@ -18249,7 +18329,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18249,7 +18329,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18249 | .{ .vp_d, .blend }, | 18329 | .{ .vp_d, .blend }, |
| 18250 | registerAlias(dst_reg, dst_abi_size), | 18330 | registerAlias(dst_reg, dst_abi_size), |
| 18251 | registerAlias(lhs_reg, dst_abi_size), | 18331 | registerAlias(lhs_reg, dst_abi_size), |
| 18252 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18332 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18253 | .u(expanded_control), | 18333 | .u(expanded_control), |
| 18254 | ) else try self.asmRegisterRegisterRegisterImmediate( | 18334 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 18255 | .{ .vp_d, .blend }, | 18335 | .{ .vp_d, .blend }, |
| ... | @@ -18304,7 +18384,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18304,7 +18384,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18304 | lhs_mcv.getReg().? | 18384 | lhs_mcv.getReg().? |
| 18305 | else | 18385 | else |
| 18306 | dst_reg, dst_abi_size), | 18386 | dst_reg, dst_abi_size), |
| 18307 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18387 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18308 | .u(expanded_control), | 18388 | .u(expanded_control), |
| 18309 | ) else try self.asmRegisterRegisterRegisterImmediate( | 18389 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 18310 | .{ .vp_w, .blend }, | 18390 | .{ .vp_w, .blend }, |
| ... | @@ -18321,7 +18401,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18321,7 +18401,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18321 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 18401 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 18322 | .{ .p_w, .blend }, | 18402 | .{ .p_w, .blend }, |
| 18323 | registerAlias(dst_reg, dst_abi_size), | 18403 | registerAlias(dst_reg, dst_abi_size), |
| 18324 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18404 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18325 | .u(expanded_control), | 18405 | .u(expanded_control), |
| 18326 | ) else try self.asmRegisterRegisterImmediate( | 18406 | ) else try self.asmRegisterRegisterImmediate( |
| 18327 | .{ .p_w, .blend }, | 18407 | .{ .p_w, .blend }, |
| ... | @@ -18365,7 +18445,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18365,7 +18445,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18365 | lhs_mcv.getReg().? | 18445 | lhs_mcv.getReg().? |
| 18366 | else | 18446 | else |
| 18367 | dst_reg, dst_abi_size), | 18447 | dst_reg, dst_abi_size), |
| 18368 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18448 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18369 | .u(expanded_control), | 18449 | .u(expanded_control), |
| 18370 | ) else try self.asmRegisterRegisterRegisterImmediate( | 18450 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 18371 | switch (elem_abi_size) { | 18451 | switch (elem_abi_size) { |
| ... | @@ -18390,7 +18470,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18390,7 +18470,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18390 | else => unreachable, | 18470 | else => unreachable, |
| 18391 | }, | 18471 | }, |
| 18392 | registerAlias(dst_reg, dst_abi_size), | 18472 | registerAlias(dst_reg, dst_abi_size), |
| 18393 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18473 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18394 | .u(expanded_control), | 18474 | .u(expanded_control), |
| 18395 | ) else try self.asmRegisterRegisterImmediate( | 18475 | ) else try self.asmRegisterRegisterImmediate( |
| 18396 | switch (elem_abi_size) { | 18476 | switch (elem_abi_size) { |
| ... | @@ -18435,7 +18515,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18435,7 +18515,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18435 | else | 18515 | else |
| 18436 | try select_mask_elem_ty.minIntScalar(pt, select_mask_elem_ty)).toIntern(); | 18516 | try select_mask_elem_ty.minIntScalar(pt, select_mask_elem_ty)).toIntern(); |
| 18437 | } | 18517 | } |
| 18438 | const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 18518 | const select_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 18439 | .ty = select_mask_ty.toIntern(), | 18519 | .ty = select_mask_ty.toIntern(), |
| 18440 | .storage = .{ .elems = select_mask_elems[0..mask_elems.len] }, | 18520 | .storage = .{ .elems = select_mask_elems[0..mask_elems.len] }, |
| 18441 | } }))); | 18521 | } }))); |
| ... | @@ -18480,7 +18560,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18480,7 +18560,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18480 | registerAlias(lhs_mcv.getReg().?, dst_abi_size) | 18560 | registerAlias(lhs_mcv.getReg().?, dst_abi_size) |
| 18481 | else | 18561 | else |
| 18482 | dst_alias, | 18562 | dst_alias, |
| 18483 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18563 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18484 | select_mask_alias, | 18564 | select_mask_alias, |
| 18485 | ) else try self.asmRegisterRegisterRegisterRegister( | 18565 | ) else try self.asmRegisterRegisterRegisterRegister( |
| 18486 | mir_tag, | 18566 | mir_tag, |
| ... | @@ -18497,7 +18577,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18497,7 +18577,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18497 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryRegister( | 18577 | ) else if (rhs_mcv.isMemory()) try self.asmRegisterMemoryRegister( |
| 18498 | mir_tag, | 18578 | mir_tag, |
| 18499 | dst_alias, | 18579 | dst_alias, |
| 18500 | try rhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18580 | try rhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18501 | select_mask_alias, | 18581 | select_mask_alias, |
| 18502 | ) else try self.asmRegisterRegisterRegister( | 18582 | ) else try self.asmRegisterRegisterRegister( |
| 18503 | mir_tag, | 18583 | mir_tag, |
| ... | @@ -18540,7 +18620,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18540,7 +18620,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18540 | if (lhs_mcv.isMemory()) try self.asmRegisterMemory( | 18620 | if (lhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 18541 | .{ mir_fixes, .andn }, | 18621 | .{ mir_fixes, .andn }, |
| 18542 | mask_alias, | 18622 | mask_alias, |
| 18543 | try lhs_mcv.mem(self, Memory.Size.fromSize(dst_abi_size)), | 18623 | try lhs_mcv.mem(self, .fromSize(dst_abi_size)), |
| 18544 | ) else try self.asmRegisterRegister( | 18624 | ) else try self.asmRegisterRegister( |
| 18545 | .{ mir_fixes, .andn }, | 18625 | .{ mir_fixes, .andn }, |
| 18546 | mask_alias, | 18626 | mask_alias, |
| ... | @@ -18583,13 +18663,13 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18583,13 +18663,13 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18583 | } }); | 18663 | } }); |
| 18584 | } | 18664 | } |
| 18585 | const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 18665 | const lhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 18586 | const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 18666 | const lhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 18587 | .ty = lhs_mask_ty.toIntern(), | 18667 | .ty = lhs_mask_ty.toIntern(), |
| 18588 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, | 18668 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, |
| 18589 | } }))); | 18669 | } }))); |
| 18590 | const lhs_mask_mem: Memory = .{ | 18670 | const lhs_mask_mem: Memory = .{ |
| 18591 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, lhs_mask_mcv.address()) }, | 18671 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, lhs_mask_mcv.address()) }, |
| 18592 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } }, | 18672 | .mod = .{ .rm = .{ .size = .fromSize(@max(max_abi_size, 16)) } }, |
| 18593 | }; | 18673 | }; |
| 18594 | if (has_avx) try self.asmRegisterRegisterMemory( | 18674 | if (has_avx) try self.asmRegisterRegisterMemory( |
| 18595 | .{ .vp_b, .shuf }, | 18675 | .{ .vp_b, .shuf }, |
| ... | @@ -18617,13 +18697,13 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18617,13 +18697,13 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 18617 | } }); | 18697 | } }); |
| 18618 | } | 18698 | } |
| 18619 | const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 18699 | const rhs_mask_ty = try pt.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 18620 | const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try pt.intern(.{ .aggregate = .{ | 18700 | const rhs_mask_mcv = try self.genTypedValue(.fromInterned(try pt.intern(.{ .aggregate = .{ |
| 18621 | .ty = rhs_mask_ty.toIntern(), | 18701 | .ty = rhs_mask_ty.toIntern(), |
| 18622 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, | 18702 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, |
| 18623 | } }))); | 18703 | } }))); |
| 18624 | const rhs_mask_mem: Memory = .{ | 18704 | const rhs_mask_mem: Memory = .{ |
| 18625 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, rhs_mask_mcv.address()) }, | 18705 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, rhs_mask_mcv.address()) }, |
| 18626 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } }, | 18706 | .mod = .{ .rm = .{ .size = .fromSize(@max(max_abi_size, 16)) } }, |
| 18627 | }; | 18707 | }; |
| 18628 | if (has_avx) try self.asmRegisterRegisterMemory( | 18708 | if (has_avx) try self.asmRegisterRegisterMemory( |
| 18629 | .{ .vp_b, .shuf }, | 18709 | .{ .vp_b, .shuf }, |
| ... | @@ -18696,7 +18776,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18696,7 +18776,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 18696 | .Or => { | 18776 | .Or => { |
| 18697 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( | 18777 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( |
| 18698 | .{ ._, .@"test" }, | 18778 | .{ ._, .@"test" }, |
| 18699 | try operand_mcv.mem(self, Memory.Size.fromSize(abi_size)), | 18779 | try operand_mcv.mem(self, .fromSize(abi_size)), |
| 18700 | .u(mask), | 18780 | .u(mask), |
| 18701 | ) else { | 18781 | ) else { |
| 18702 | const operand_reg = registerAlias(if (operand_mcv.isRegister()) | 18782 | const operand_reg = registerAlias(if (operand_mcv.isRegister()) |
| ... | @@ -18745,7 +18825,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18745,7 +18825,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18745 | const result: MCValue = result: { | 18825 | const result: MCValue = result: { |
| 18746 | switch (result_ty.zigTypeTag(zcu)) { | 18826 | switch (result_ty.zigTypeTag(zcu)) { |
| 18747 | .@"struct" => { | 18827 | .@"struct" => { |
| 18748 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | 18828 | const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu)); |
| 18749 | if (result_ty.containerLayout(zcu) == .@"packed") { | 18829 | if (result_ty.containerLayout(zcu) == .@"packed") { |
| 18750 | const struct_obj = zcu.typeToStruct(result_ty).?; | 18830 | const struct_obj = zcu.typeToStruct(result_ty).?; |
| 18751 | try self.genInlineMemset( | 18831 | try self.genInlineMemset( |
| ... | @@ -18885,7 +18965,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18885,7 +18965,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18885 | } | 18965 | } |
| 18886 | break :result .{ .register = dst_reg }; | 18966 | break :result .{ .register = dst_reg }; |
| 18887 | } else { | 18967 | } else { |
| 18888 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | 18968 | const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu)); |
| 18889 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); | 18969 | const elem_size: u32 = @intCast(elem_ty.abiSize(zcu)); |
| 18890 | | 18970 | |
| 18891 | for (elements, 0..) |elem, elem_i| { | 18971 | for (elements, 0..) |elem, elem_i| { |
| ... | @@ -18918,7 +18998,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18918,7 +18998,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18918 | }; | 18998 | }; |
| 18919 | | 18999 | |
| 18920 | if (elements.len <= Liveness.bpi - 1) { | 19000 | if (elements.len <= Liveness.bpi - 1) { |
| 18921 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); | 19001 | var buf: [Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); |
| 18922 | @memcpy(buf[0..elements.len], elements); | 19002 | @memcpy(buf[0..elements.len], elements); |
| 18923 | return self.finishAir(inst, result, buf); | 19003 | return self.finishAir(inst, result, buf); |
| 18924 | } | 19004 | } |
| ... | @@ -18952,7 +19032,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18952,7 +19032,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18952 | | 19032 | |
| 18953 | const union_obj = zcu.typeToUnion(union_ty).?; | 19033 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 18954 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; | 19034 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 18955 | const tag_ty = Type.fromInterned(union_obj.enum_tag_ty); | 19035 | const tag_ty: Type = .fromInterned(union_obj.enum_tag_ty); |
| 18956 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; | 19036 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; |
| 18957 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); | 19037 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 18958 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); | 19038 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); |
| ... | @@ -19010,10 +19090,10 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -19010,10 +19090,10 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 19010 | } | 19090 | } |
| 19011 | | 19091 | |
| 19012 | var mcvs: [3]MCValue = undefined; | 19092 | var mcvs: [3]MCValue = undefined; |
| 19013 | var locks = [1]?RegisterManager.RegisterLock{null} ** 3; | 19093 | var locks: [3]?RegisterManager.RegisterLock = @splat(null); |
| 19014 | defer for (locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); | 19094 | defer for (locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); |
| 19015 | var order = [1]u2{0} ** 3; | 19095 | var order: [3]u2 = @splat(0); |
| 19016 | var unused = std.StaticBitSet(3).initFull(); | 19096 | var unused: std.StaticBitSet(3) = .initFull(); |
| 19017 | for (ops, &mcvs, &locks, 0..) |op, *mcv, *lock, op_i| { | 19097 | for (ops, &mcvs, &locks, 0..) |op, *mcv, *lock, op_i| { |
| 19018 | const op_index: u2 = @intCast(op_i); | 19098 | const op_index: u2 = @intCast(op_i); |
| 19019 | mcv.* = try self.resolveInst(op); | 19099 | mcv.* = try self.resolveInst(op); |
| ... | @@ -19139,7 +19219,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -19139,7 +19219,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 19139 | mir_tag, | 19219 | mir_tag, |
| 19140 | mop1_reg, | 19220 | mop1_reg, |
| 19141 | mop2_reg, | 19221 | mop2_reg, |
| 19142 | try mops[2].mem(self, Memory.Size.fromSize(abi_size)), | 19222 | try mops[2].mem(self, .fromSize(abi_size)), |
| 19143 | ); | 19223 | ); |
| 19144 | break :result mops[0]; | 19224 | break :result mops[0]; |
| 19145 | }; | 19225 | }; |
| ... | @@ -19158,7 +19238,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -19158,7 +19238,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 19158 | )) { | 19238 | )) { |
| 19159 | .x86_64_sysv => result: { | 19239 | .x86_64_sysv => result: { |
| 19160 | const info = self.va_info.sysv; | 19240 | const info = self.va_info.sysv; |
| 19161 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, zcu)); | 19241 | const dst_fi = try self.allocFrameIndex(.initSpill(va_list_ty, zcu)); |
| 19162 | var field_off: u31 = 0; | 19242 | var field_off: u31 = 0; |
| 19163 | // gp_offset: c_uint, | 19243 | // gp_offset: c_uint, |
| 19164 | try self.genSetMem( | 19244 | try self.genSetMem( |
| ... | @@ -19221,7 +19301,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -19221,7 +19301,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 19221 | try self.spillEflagsIfOccupied(); | 19301 | try self.spillEflagsIfOccupied(); |
| 19222 | | 19302 | |
| 19223 | const tmp_regs = | 19303 | const tmp_regs = |
| 19224 | try self.register_manager.allocRegs(2, .{null} ** 2, abi.RegisterClass.gp); | 19304 | try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp); |
| 19225 | const offset_reg = tmp_regs[0].to32(); | 19305 | const offset_reg = tmp_regs[0].to32(); |
| 19226 | const addr_reg = tmp_regs[1].to64(); | 19306 | const addr_reg = tmp_regs[1].to64(); |
| 19227 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); | 19307 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); |
| ... | @@ -19426,8 +19506,8 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -19426,8 +19506,8 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 19426 | } else mcv: { | 19506 | } else mcv: { |
| 19427 | const ip_index = ref.toInterned().?; | 19507 | const ip_index = ref.toInterned().?; |
| 19428 | const gop = try self.const_tracking.getOrPut(self.gpa, ip_index); | 19508 | const gop = try self.const_tracking.getOrPut(self.gpa, ip_index); |
| 19429 | if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: { | 19509 | if (!gop.found_existing) gop.value_ptr.* = .init(init: { |
| 19430 | const const_mcv = try self.genTypedValue(Value.fromInterned(ip_index)); | 19510 | const const_mcv = try self.genTypedValue(.fromInterned(ip_index)); |
| 19431 | switch (const_mcv) { | 19511 | switch (const_mcv) { |
| 19432 | .lea_tlv => |tlv_sym| switch (self.bin_file.tag) { | 19512 | .lea_tlv => |tlv_sym| switch (self.bin_file.tag) { |
| 19433 | .elf, .macho => { | 19513 | .elf, .macho => { |
| ... | @@ -19436,7 +19516,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -19436,7 +19516,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 19436 | } else { | 19516 | } else { |
| 19437 | try self.spillRegisters(&.{.rax}); | 19517 | try self.spillRegisters(&.{.rax}); |
| 19438 | } | 19518 | } |
| 19439 | const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{ | 19519 | const frame_index = try self.allocFrameIndex(.init(.{ |
| 19440 | .size = 8, | 19520 | .size = 8, |
| 19441 | .alignment = .@"8", | 19521 | .alignment = .@"8", |
| 19442 | })); | 19522 | })); |
| ... | @@ -19539,9 +19619,8 @@ fn resolveCallingConventionValues( | ... | @@ -19539,9 +19619,8 @@ fn resolveCallingConventionValues( |
| 19539 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); | 19619 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); |
| 19540 | defer self.gpa.free(param_types); | 19620 | defer self.gpa.free(param_types); |
| 19541 | | 19621 | |
| 19542 | for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src| { | 19622 | for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src| |
| 19543 | dest.* = Type.fromInterned(src); | 19623 | dest.* = .fromInterned(src); |
| 19544 | } | | |
| 19545 | for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty| | 19624 | for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty| |
| 19546 | param_ty.* = self.promoteVarArg(arg_ty); | 19625 | param_ty.* = self.promoteVarArg(arg_ty); |
| 19547 | | 19626 | |
| ... | @@ -19556,13 +19635,13 @@ fn resolveCallingConventionValues( | ... | @@ -19556,13 +19635,13 @@ fn resolveCallingConventionValues( |
| 19556 | }; | 19635 | }; |
| 19557 | errdefer self.gpa.free(result.args); | 19636 | errdefer self.gpa.free(result.args); |
| 19558 | | 19637 | |
| 19559 | const ret_ty = Type.fromInterned(fn_info.return_type); | 19638 | const ret_ty: Type = .fromInterned(fn_info.return_type); |
| 19560 | | 19639 | |
| 19561 | const resolved_cc = abi.resolveCallingConvention(cc, self.target.*); | 19640 | const resolved_cc = abi.resolveCallingConvention(cc, self.target.*); |
| 19562 | switch (cc) { | 19641 | switch (cc) { |
| 19563 | .naked => { | 19642 | .naked => { |
| 19564 | assert(result.args.len == 0); | 19643 | assert(result.args.len == 0); |
| 19565 | result.return_value = InstTracking.init(.unreach); | 19644 | result.return_value = .init(.unreach); |
| 19566 | result.stack_align = .@"8"; | 19645 | result.stack_align = .@"8"; |
| 19567 | }, | 19646 | }, |
| 19568 | .x86_64_sysv, .x86_64_win => |cc_opts| { | 19647 | .x86_64_sysv, .x86_64_win => |cc_opts| { |
| ... | @@ -19583,10 +19662,10 @@ fn resolveCallingConventionValues( | ... | @@ -19583,10 +19662,10 @@ fn resolveCallingConventionValues( |
| 19583 | | 19662 | |
| 19584 | // Return values | 19663 | // Return values |
| 19585 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { | 19664 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { |
| 19586 | result.return_value = InstTracking.init(.unreach); | 19665 | result.return_value = .init(.unreach); |
| 19587 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 19666 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 19588 | // TODO: is this even possible for C calling convention? | 19667 | // TODO: is this even possible for C calling convention? |
| 19589 | result.return_value = InstTracking.init(.none); | 19668 | result.return_value = .init(.none); |
| 19590 | } else { | 19669 | } else { |
| 19591 | var ret_tracking: [2]InstTracking = undefined; | 19670 | var ret_tracking: [2]InstTracking = undefined; |
| 19592 | var ret_tracking_i: usize = 0; | 19671 | var ret_tracking_i: usize = 0; |
| ... | @@ -19604,7 +19683,7 @@ fn resolveCallingConventionValues( | ... | @@ -19604,7 +19683,7 @@ fn resolveCallingConventionValues( |
| 19604 | ); | 19683 | ); |
| 19605 | ret_int_reg_i += 1; | 19684 | ret_int_reg_i += 1; |
| 19606 | | 19685 | |
| 19607 | ret_tracking[ret_tracking_i] = InstTracking.init(.{ .register = ret_int_reg }); | 19686 | ret_tracking[ret_tracking_i] = .init(.{ .register = ret_int_reg }); |
| 19608 | ret_tracking_i += 1; | 19687 | ret_tracking_i += 1; |
| 19609 | }, | 19688 | }, |
| 19610 | .sse, .float, .float_combine, .win_i128 => { | 19689 | .sse, .float, .float_combine, .win_i128 => { |
| ... | @@ -19614,18 +19693,17 @@ fn resolveCallingConventionValues( | ... | @@ -19614,18 +19693,17 @@ fn resolveCallingConventionValues( |
| 19614 | ); | 19693 | ); |
| 19615 | ret_sse_reg_i += 1; | 19694 | ret_sse_reg_i += 1; |
| 19616 | | 19695 | |
| 19617 | ret_tracking[ret_tracking_i] = InstTracking.init(.{ .register = ret_sse_reg }); | 19696 | ret_tracking[ret_tracking_i] = .init(.{ .register = ret_sse_reg }); |
| 19618 | ret_tracking_i += 1; | 19697 | ret_tracking_i += 1; |
| 19619 | }, | 19698 | }, |
| 19620 | .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .sse), | 19699 | .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .sse), |
| 19621 | .x87 => { | 19700 | .x87 => { |
| 19622 | ret_tracking[ret_tracking_i] = InstTracking.init(.{ .register = .st0 }); | 19701 | ret_tracking[ret_tracking_i] = .init(.{ .register = .st0 }); |
| 19623 | ret_tracking_i += 1; | 19702 | ret_tracking_i += 1; |
| 19624 | }, | 19703 | }, |
| 19625 | .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .x87), | 19704 | .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .x87), |
| 19626 | .complex_x87 => { | 19705 | .complex_x87 => { |
| 19627 | ret_tracking[ret_tracking_i] = | 19706 | ret_tracking[ret_tracking_i] = .init(.{ .register_pair = .{ .st0, .st1 } }); |
| 19628 | InstTracking.init(.{ .register_pair = .{ .st0, .st1 } }); | | |
| 19629 | ret_tracking_i += 1; | 19707 | ret_tracking_i += 1; |
| 19630 | }, | 19708 | }, |
| 19631 | .memory => { | 19709 | .memory => { |
| ... | @@ -19645,8 +19723,9 @@ fn resolveCallingConventionValues( | ... | @@ -19645,8 +19723,9 @@ fn resolveCallingConventionValues( |
| 19645 | result.return_value = switch (ret_tracking_i) { | 19723 | result.return_value = switch (ret_tracking_i) { |
| 19646 | else => unreachable, | 19724 | else => unreachable, |
| 19647 | 1 => ret_tracking[0], | 19725 | 1 => ret_tracking[0], |
| 19648 | 2 => InstTracking.init(.{ .register_pair = .{ | 19726 | 2 => .init(.{ .register_pair = .{ |
| 19649 | ret_tracking[0].short.register, ret_tracking[1].short.register, | 19727 | ret_tracking[0].short.register, |
| | 19728 | ret_tracking[1].short.register, |
| 19650 | } }), | 19729 | } }), |
| 19651 | }; | 19730 | }; |
| 19652 | } | 19731 | } |
| ... | @@ -19769,9 +19848,9 @@ fn resolveCallingConventionValues( | ... | @@ -19769,9 +19848,9 @@ fn resolveCallingConventionValues( |
| 19769 | | 19848 | |
| 19770 | // Return values | 19849 | // Return values |
| 19771 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { | 19850 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { |
| 19772 | result.return_value = InstTracking.init(.unreach); | 19851 | result.return_value = .init(.unreach); |
| 19773 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 19852 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 19774 | result.return_value = InstTracking.init(.none); | 19853 | result.return_value = .init(.none); |
| 19775 | } else { | 19854 | } else { |
| 19776 | const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0]; | 19855 | const ret_reg = abi.getCAbiIntReturnRegs(resolved_cc)[0]; |
| 19777 | const ret_ty_size: u31 = @intCast(ret_ty.abiSize(zcu)); | 19856 | const ret_ty_size: u31 = @intCast(ret_ty.abiSize(zcu)); |
| ... | @@ -19884,8 +19963,8 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { | ... | @@ -19884,8 +19963,8 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 19884 | fn memSize(self: *Self, ty: Type) Memory.Size { | 19963 | fn memSize(self: *Self, ty: Type) Memory.Size { |
| 19885 | const zcu = self.pt.zcu; | 19964 | const zcu = self.pt.zcu; |
| 19886 | return switch (ty.zigTypeTag(zcu)) { | 19965 | return switch (ty.zigTypeTag(zcu)) { |
| 19887 | .float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)), | 19966 | .float => .fromBitSize(ty.floatBits(self.target.*)), |
| 19888 | else => Memory.Size.fromSize(@intCast(ty.abiSize(zcu))), | 19967 | else => .fromSize(@intCast(ty.abiSize(zcu))), |
| 19889 | }; | 19968 | }; |
| 19890 | } | 19969 | } |
| 19891 | | 19970 | |
| ... | @@ -20140,7 +20219,7 @@ const Temp = struct { | ... | @@ -20140,7 +20219,7 @@ const Temp = struct { |
| 20140 | .register => |reg| { | 20219 | .register => |reg| { |
| 20141 | const new_reg = | 20220 | const new_reg = |
| 20142 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20221 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20143 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20222 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20144 | try self.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ | 20223 | try self.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ |
| 20145 | .base = .{ .reg = reg.to64() }, | 20224 | .base = .{ .reg = reg.to64() }, |
| 20146 | .mod = .{ .rm = .{ | 20225 | .mod = .{ .rm = .{ |
| ... | @@ -20152,7 +20231,7 @@ const Temp = struct { | ... | @@ -20152,7 +20231,7 @@ const Temp = struct { |
| 20152 | .register_offset => |reg_off| { | 20231 | .register_offset => |reg_off| { |
| 20153 | const new_reg = | 20232 | const new_reg = |
| 20154 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20233 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20155 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20234 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20156 | try self.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ | 20235 | try self.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ |
| 20157 | .base = .{ .reg = reg_off.reg.to64() }, | 20236 | .base = .{ .reg = reg_off.reg.to64() }, |
| 20158 | .mod = .{ .rm = .{ | 20237 | .mod = .{ .rm = .{ |
| ... | @@ -20161,14 +20240,14 @@ const Temp = struct { | ... | @@ -20161,14 +20240,14 @@ const Temp = struct { |
| 20161 | } }, | 20240 | } }, |
| 20162 | }); | 20241 | }); |
| 20163 | }, | 20242 | }, |
| 20164 | .lea_symbol => |sym_off| new_temp_index.tracking(self).* = InstTracking.init(.{ .lea_symbol = .{ | 20243 | .lea_symbol => |sym_off| new_temp_index.tracking(self).* = .init(.{ .lea_symbol = .{ |
| 20165 | .sym_index = sym_off.sym_index, | 20244 | .sym_index = sym_off.sym_index, |
| 20166 | .off = sym_off.off + off, | 20245 | .off = sym_off.off + off, |
| 20167 | } }), | 20246 | } }), |
| 20168 | .load_frame => |frame_addr| { | 20247 | .load_frame => |frame_addr| { |
| 20169 | const new_reg = | 20248 | const new_reg = |
| 20170 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20249 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20171 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register_offset = .{ | 20250 | new_temp_index.tracking(self).* = .init(.{ .register_offset = .{ |
| 20172 | .reg = new_reg, | 20251 | .reg = new_reg, |
| 20173 | .off = off, | 20252 | .off = off, |
| 20174 | } }); | 20253 | } }); |
| ... | @@ -20180,7 +20259,7 @@ const Temp = struct { | ... | @@ -20180,7 +20259,7 @@ const Temp = struct { |
| 20180 | } }, | 20259 | } }, |
| 20181 | }); | 20260 | }); |
| 20182 | }, | 20261 | }, |
| 20183 | .lea_frame => |frame_addr| new_temp_index.tracking(self).* = InstTracking.init(.{ .lea_frame = .{ | 20262 | .lea_frame => |frame_addr| new_temp_index.tracking(self).* = .init(.{ .lea_frame = .{ |
| 20184 | .index = frame_addr.index, | 20263 | .index = frame_addr.index, |
| 20185 | .off = frame_addr.off + off, | 20264 | .off = frame_addr.off + off, |
| 20186 | } }), | 20265 | } }), |
| ... | @@ -20198,7 +20277,7 @@ const Temp = struct { | ... | @@ -20198,7 +20277,7 @@ const Temp = struct { |
| 20198 | else => {}, | 20277 | else => {}, |
| 20199 | .register => |reg| { | 20278 | .register => |reg| { |
| 20200 | try self.freeValue(temp_tracking.long); | 20279 | try self.freeValue(temp_tracking.long); |
| 20201 | temp_tracking.* = InstTracking.init(.{ .register_offset = .{ | 20280 | temp_tracking.* = .init(.{ .register_offset = .{ |
| 20202 | .reg = reg, | 20281 | .reg = reg, |
| 20203 | .off = off, | 20282 | .off = off, |
| 20204 | } }); | 20283 | } }); |
| ... | @@ -20206,7 +20285,7 @@ const Temp = struct { | ... | @@ -20206,7 +20285,7 @@ const Temp = struct { |
| 20206 | }, | 20285 | }, |
| 20207 | .register_offset => |reg_off| { | 20286 | .register_offset => |reg_off| { |
| 20208 | try self.freeValue(temp_tracking.long); | 20287 | try self.freeValue(temp_tracking.long); |
| 20209 | temp_tracking.* = InstTracking.init(.{ .register_offset = .{ | 20288 | temp_tracking.* = .init(.{ .register_offset = .{ |
| 20210 | .reg = reg_off.reg, | 20289 | .reg = reg_off.reg, |
| 20211 | .off = reg_off.off + off, | 20290 | .off = reg_off.off + off, |
| 20212 | } }); | 20291 | } }); |
| ... | @@ -20214,7 +20293,7 @@ const Temp = struct { | ... | @@ -20214,7 +20293,7 @@ const Temp = struct { |
| 20214 | }, | 20293 | }, |
| 20215 | .lea_symbol => |sym_off| { | 20294 | .lea_symbol => |sym_off| { |
| 20216 | assert(std.meta.eql(temp_tracking.long.lea_symbol, sym_off)); | 20295 | assert(std.meta.eql(temp_tracking.long.lea_symbol, sym_off)); |
| 20217 | temp_tracking.* = InstTracking.init(.{ .lea_symbol = .{ | 20296 | temp_tracking.* = .init(.{ .lea_symbol = .{ |
| 20218 | .sym_index = sym_off.sym_index, | 20297 | .sym_index = sym_off.sym_index, |
| 20219 | .off = sym_off.off + off, | 20298 | .off = sym_off.off + off, |
| 20220 | } }); | 20299 | } }); |
| ... | @@ -20222,7 +20301,7 @@ const Temp = struct { | ... | @@ -20222,7 +20301,7 @@ const Temp = struct { |
| 20222 | }, | 20301 | }, |
| 20223 | .lea_frame => |frame_addr| { | 20302 | .lea_frame => |frame_addr| { |
| 20224 | assert(std.meta.eql(temp_tracking.long.lea_frame, frame_addr)); | 20303 | assert(std.meta.eql(temp_tracking.long.lea_frame, frame_addr)); |
| 20225 | temp_tracking.* = InstTracking.init(.{ .lea_frame = .{ | 20304 | temp_tracking.* = .init(.{ .lea_frame = .{ |
| 20226 | .index = frame_addr.index, | 20305 | .index = frame_addr.index, |
| 20227 | .off = frame_addr.off + off, | 20306 | .off = frame_addr.off + off, |
| 20228 | } }); | 20307 | } }); |
| ... | @@ -20243,26 +20322,26 @@ const Temp = struct { | ... | @@ -20243,26 +20322,26 @@ const Temp = struct { |
| 20243 | else => |tag| std.debug.panic("{s}: {any}\n", .{ @src().fn_name, tag }), | 20322 | else => |tag| std.debug.panic("{s}: {any}\n", .{ @src().fn_name, tag }), |
| 20244 | .immediate => |imm| { | 20323 | .immediate => |imm| { |
| 20245 | assert(limb_index == 0); | 20324 | assert(limb_index == 0); |
| 20246 | new_temp_index.tracking(self).* = InstTracking.init(.{ .immediate = imm }); | 20325 | new_temp_index.tracking(self).* = .init(.{ .immediate = imm }); |
| 20247 | }, | 20326 | }, |
| 20248 | .register => |reg| { | 20327 | .register => |reg| { |
| 20249 | assert(limb_index == 0); | 20328 | assert(limb_index == 0); |
| 20250 | const new_reg = | 20329 | const new_reg = |
| 20251 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20330 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20252 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20331 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20253 | try self.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), reg.to64()); | 20332 | try self.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), reg.to64()); |
| 20254 | }, | 20333 | }, |
| 20255 | .register_pair => |regs| { | 20334 | .register_pair => |regs| { |
| 20256 | const new_reg = | 20335 | const new_reg = |
| 20257 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20336 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20258 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20337 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20259 | try self.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), regs[limb_index].to64()); | 20338 | try self.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), regs[limb_index].to64()); |
| 20260 | }, | 20339 | }, |
| 20261 | .register_offset => |reg_off| { | 20340 | .register_offset => |reg_off| { |
| 20262 | assert(limb_index == 0); | 20341 | assert(limb_index == 0); |
| 20263 | const new_reg = | 20342 | const new_reg = |
| 20264 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20343 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20265 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20344 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20266 | try self.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ | 20345 | try self.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ |
| 20267 | .base = .{ .reg = reg_off.reg.to64() }, | 20346 | .base = .{ .reg = reg_off.reg.to64() }, |
| 20268 | .mod = .{ .rm = .{ | 20347 | .mod = .{ .rm = .{ |
| ... | @@ -20274,7 +20353,7 @@ const Temp = struct { | ... | @@ -20274,7 +20353,7 @@ const Temp = struct { |
| 20274 | .load_symbol => |sym_off| { | 20353 | .load_symbol => |sym_off| { |
| 20275 | const new_reg = | 20354 | const new_reg = |
| 20276 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20355 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20277 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20356 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20278 | try self.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ | 20357 | try self.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| 20279 | .base = .{ .reloc = sym_off.sym_index }, | 20358 | .base = .{ .reloc = sym_off.sym_index }, |
| 20280 | .mod = .{ .rm = .{ | 20359 | .mod = .{ .rm = .{ |
| ... | @@ -20285,12 +20364,12 @@ const Temp = struct { | ... | @@ -20285,12 +20364,12 @@ const Temp = struct { |
| 20285 | }, | 20364 | }, |
| 20286 | .lea_symbol => |sym_off| { | 20365 | .lea_symbol => |sym_off| { |
| 20287 | assert(limb_index == 0); | 20366 | assert(limb_index == 0); |
| 20288 | new_temp_index.tracking(self).* = InstTracking.init(.{ .lea_symbol = sym_off }); | 20367 | new_temp_index.tracking(self).* = .init(.{ .lea_symbol = sym_off }); |
| 20289 | }, | 20368 | }, |
| 20290 | .load_frame => |frame_addr| { | 20369 | .load_frame => |frame_addr| { |
| 20291 | const new_reg = | 20370 | const new_reg = |
| 20292 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 20371 | try self.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 20293 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20372 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20294 | try self.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ | 20373 | try self.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| 20295 | .base = .{ .frame = frame_addr.index }, | 20374 | .base = .{ .frame = frame_addr.index }, |
| 20296 | .mod = .{ .rm = .{ | 20375 | .mod = .{ .rm = .{ |
| ... | @@ -20301,7 +20380,7 @@ const Temp = struct { | ... | @@ -20301,7 +20380,7 @@ const Temp = struct { |
| 20301 | }, | 20380 | }, |
| 20302 | .lea_frame => |frame_addr| { | 20381 | .lea_frame => |frame_addr| { |
| 20303 | assert(limb_index == 0); | 20382 | assert(limb_index == 0); |
| 20304 | new_temp_index.tracking(self).* = InstTracking.init(.{ .lea_frame = frame_addr }); | 20383 | new_temp_index.tracking(self).* = .init(.{ .lea_frame = frame_addr }); |
| 20305 | }, | 20384 | }, |
| 20306 | } | 20385 | } |
| 20307 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 20386 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| ... | @@ -20328,13 +20407,13 @@ const Temp = struct { | ... | @@ -20328,13 +20407,13 @@ const Temp = struct { |
| 20328 | } | 20407 | } |
| 20329 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) | 20408 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) |
| 20330 | self.register_manager.freeReg(reg); | 20409 | self.register_manager.freeReg(reg); |
| 20331 | temp_tracking.* = InstTracking.init(.{ .register = regs[limb_index] }); | 20410 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); |
| 20332 | self.temp_type[@intFromEnum(temp_index)] = Type.usize; | 20411 | self.temp_type[@intFromEnum(temp_index)] = Type.usize; |
| 20333 | return; | 20412 | return; |
| 20334 | }, | 20413 | }, |
| 20335 | .load_symbol => |sym_off| { | 20414 | .load_symbol => |sym_off| { |
| 20336 | assert(std.meta.eql(temp_tracking.long.load_symbol, sym_off)); | 20415 | assert(std.meta.eql(temp_tracking.long.load_symbol, sym_off)); |
| 20337 | temp_tracking.* = InstTracking.init(.{ .load_symbol = .{ | 20416 | temp_tracking.* = .init(.{ .load_symbol = .{ |
| 20338 | .sym_index = sym_off.sym_index, | 20417 | .sym_index = sym_off.sym_index, |
| 20339 | .off = sym_off.off + @as(u31, limb_index) * 8, | 20418 | .off = sym_off.off + @as(u31, limb_index) * 8, |
| 20340 | } }); | 20419 | } }); |
| ... | @@ -20343,7 +20422,7 @@ const Temp = struct { | ... | @@ -20343,7 +20422,7 @@ const Temp = struct { |
| 20343 | }, | 20422 | }, |
| 20344 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { | 20423 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { |
| 20345 | assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr)); | 20424 | assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr)); |
| 20346 | temp_tracking.* = InstTracking.init(.{ .load_frame = .{ | 20425 | temp_tracking.* = .init(.{ .load_frame = .{ |
| 20347 | .index = frame_addr.index, | 20426 | .index = frame_addr.index, |
| 20348 | .off = frame_addr.off + @as(u31, limb_index) * 8, | 20427 | .off = frame_addr.off + @as(u31, limb_index) * 8, |
| 20349 | } }); | 20428 | } }); |
| ... | @@ -20371,7 +20450,7 @@ const Temp = struct { | ... | @@ -20371,7 +20450,7 @@ const Temp = struct { |
| 20371 | const new_temp_index = self.next_temp_index; | 20450 | const new_temp_index = self.next_temp_index; |
| 20372 | self.temp_type[@intFromEnum(new_temp_index)] = ty; | 20451 | self.temp_type[@intFromEnum(new_temp_index)] = ty; |
| 20373 | try self.genSetReg(new_reg, ty, val, .{}); | 20452 | try self.genSetReg(new_reg, ty, val, .{}); |
| 20374 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20453 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20375 | try temp.die(self); | 20454 | try temp.die(self); |
| 20376 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 20455 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| 20377 | temp.* = .{ .index = new_temp_index.toIndex() }; | 20456 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| ... | @@ -20390,9 +20469,32 @@ const Temp = struct { | ... | @@ -20390,9 +20469,32 @@ const Temp = struct { |
| 20390 | const new_temp_index = self.next_temp_index; | 20469 | const new_temp_index = self.next_temp_index; |
| 20391 | self.temp_type[@intFromEnum(new_temp_index)] = ty; | 20470 | self.temp_type[@intFromEnum(new_temp_index)] = ty; |
| 20392 | const new_reg = | 20471 | const new_reg = |
| 20393 | try self.register_manager.allocReg(new_temp_index.toIndex(), self.regClassForType(ty)); | 20472 | try self.register_manager.allocReg(new_temp_index.toIndex(), self.regSetForType(ty)); |
| 20394 | try self.genSetReg(new_reg, ty, val, .{}); | 20473 | try self.genSetReg(new_reg, ty, val, .{}); |
| 20395 | new_temp_index.tracking(self).* = InstTracking.init(.{ .register = new_reg }); | 20474 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| | 20475 | try temp.die(self); |
| | 20476 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| | 20477 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| | 20478 | return true; |
| | 20479 | } |
| | 20480 | |
| | 20481 | fn toRegClass(temp: *Temp, rc: Register.Class, self: *Self) !bool { |
| | 20482 | const val, const ty = switch (temp.unwrap(self)) { |
| | 20483 | .ref => |ref| .{ temp.tracking(self).short, self.typeOf(ref) }, |
| | 20484 | .temp => |temp_index| val: { |
| | 20485 | const temp_tracking = temp_index.tracking(self); |
| | 20486 | switch (temp_tracking.short) { |
| | 20487 | else => {}, |
| | 20488 | .register => |reg| if (reg.class() == rc) return false, |
| | 20489 | } |
| | 20490 | break :val .{ temp_tracking.short, temp_index.typeOf(self) }; |
| | 20491 | }, |
| | 20492 | }; |
| | 20493 | const new_temp_index = self.next_temp_index; |
| | 20494 | self.temp_type[@intFromEnum(new_temp_index)] = ty; |
| | 20495 | const new_reg = try self.register_manager.allocReg(new_temp_index.toIndex(), regSetForRegClass(rc)); |
| | 20496 | try self.genSetReg(new_reg, ty, val, .{}); |
| | 20497 | new_temp_index.tracking(self).* = .init(.{ .register = new_reg }); |
| 20396 | try temp.die(self); | 20498 | try temp.die(self); |
| 20397 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 20499 | self.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| 20398 | temp.* = .{ .index = new_temp_index.toIndex() }; | 20500 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| ... | @@ -20414,7 +20516,7 @@ const Temp = struct { | ... | @@ -20414,7 +20516,7 @@ const Temp = struct { |
| 20414 | assert(self.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking)); | 20516 | assert(self.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking)); |
| 20415 | assert(self.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking)); | 20517 | assert(self.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking)); |
| 20416 | self.temp_type[@intFromEnum(result_temp_index)] = Type.slice_const_u8; | 20518 | self.temp_type[@intFromEnum(result_temp_index)] = Type.slice_const_u8; |
| 20417 | result_temp_index.tracking(self).* = InstTracking.init(result); | 20519 | result_temp_index.tracking(self).* = .init(result); |
| 20418 | first_temp.* = result_temp; | 20520 | first_temp.* = result_temp; |
| 20419 | } | 20521 | } |
| 20420 | | 20522 | |
| ... | @@ -20520,13 +20622,43 @@ const Temp = struct { | ... | @@ -20520,13 +20622,43 @@ const Temp = struct { |
| 20520 | try self.asmOpOnly(.{ .@"rep _sb", .mov }); | 20622 | try self.asmOpOnly(.{ .@"rep _sb", .mov }); |
| 20521 | } | 20623 | } |
| 20522 | | 20624 | |
| | 20625 | // i, m, r |
| | 20626 | fn add(lhs: *Temp, rhs: *Temp, self: *Self) !Temp { |
| | 20627 | const res_index = self.next_temp_index; |
| | 20628 | var res: Temp = .{ .index = res_index.toIndex() }; |
| | 20629 | try self.select(&.{ &res, lhs, rhs }, .{ ._, .add }, &.{ |
| | 20630 | .{ .ops = &.{ .{ .match = 1 }, .r, .i } }, |
| | 20631 | .{ .ops = &.{ .{ .match = 1 }, .m, .i } }, |
| | 20632 | .{ .ops = &.{ .{ .match = 1 }, .r, .m } }, |
| | 20633 | .{ .ops = &.{ .{ .match = 1 }, .m, .r } }, |
| | 20634 | .{ .ops = &.{ .{ .match = 1 }, .r, .r } }, |
| | 20635 | }); |
| | 20636 | self.next_temp_index = @enumFromInt(@intFromEnum(res_index) + 1); |
| | 20637 | self.temp_type[@intFromEnum(res_index)] = lhs.typeOf(self); |
| | 20638 | return res; |
| | 20639 | } |
| | 20640 | |
| | 20641 | fn mul(lhs: *Temp, rhs: *Temp, self: *Self) !Temp { |
| | 20642 | const res_index = self.next_temp_index; |
| | 20643 | var res: Temp = .{ .index = self.next_temp_index.toIndex() }; |
| | 20644 | try self.select(&.{ &res, lhs, rhs }, .{ .i_, .mul }, &.{ |
| | 20645 | .{ .ops = &.{ .r, .m, .i } }, |
| | 20646 | .{ .ops = &.{ .r, .r, .i } }, |
| | 20647 | .{ .ops = &.{ .{ .match = 1 }, .r, .m } }, |
| | 20648 | .{ .ops = &.{ .{ .match = 1 }, .r, .r } }, |
| | 20649 | }); |
| | 20650 | self.next_temp_index = @enumFromInt(@intFromEnum(res_index) + 1); |
| | 20651 | self.temp_type[@intFromEnum(res_index)] = lhs.typeOf(self); |
| | 20652 | return res; |
| | 20653 | } |
| | 20654 | |
| 20523 | fn moveTo(temp: Temp, inst: Air.Inst.Index, self: *Self) !void { | 20655 | fn moveTo(temp: Temp, inst: Air.Inst.Index, self: *Self) !void { |
| 20524 | if (self.liveness.isUnused(inst)) try temp.die(self) else switch (temp.unwrap(self)) { | 20656 | if (self.liveness.isUnused(inst)) try temp.die(self) else switch (temp.unwrap(self)) { |
| 20525 | .ref => { | 20657 | .ref => { |
| 20526 | const result = try self.allocRegOrMem(inst, true); | 20658 | const result = try self.allocRegOrMem(inst, true); |
| 20527 | try self.genCopy(self.typeOfIndex(inst), result, temp.tracking(self).short, .{}); | 20659 | try self.genCopy(self.typeOfIndex(inst), result, temp.tracking(self).short, .{}); |
| 20528 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); | 20660 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); |
| 20529 | self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(result)); | 20661 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result)); |
| 20530 | }, | 20662 | }, |
| 20531 | .temp => |temp_index| { | 20663 | .temp => |temp_index| { |
| 20532 | const temp_tracking = temp_index.tracking(self); | 20664 | const temp_tracking = temp_index.tracking(self); |
| ... | @@ -20548,7 +20680,7 @@ const Temp = struct { | ... | @@ -20548,7 +20680,7 @@ const Temp = struct { |
| 20548 | _, | 20680 | _, |
| 20549 | | 20681 | |
| 20550 | fn toIndex(index: Index) Air.Inst.Index { | 20682 | fn toIndex(index: Index) Air.Inst.Index { |
| 20551 | return Air.Inst.Index.fromTargetIndex(@intFromEnum(index)); | 20683 | return .fromTargetIndex(@intFromEnum(index)); |
| 20552 | } | 20684 | } |
| 20553 | | 20685 | |
| 20554 | fn fromIndex(index: Air.Inst.Index) Index { | 20686 | fn fromIndex(index: Air.Inst.Index) Index { |
| ... | @@ -20629,7 +20761,19 @@ fn reuseTemp( | ... | @@ -20629,7 +20761,19 @@ fn reuseTemp( |
| 20629 | | 20761 | |
| 20630 | fn tempAlloc(self: *Self, ty: Type) !Temp { | 20762 | fn tempAlloc(self: *Self, ty: Type) !Temp { |
| 20631 | const temp_index = self.next_temp_index; | 20763 | const temp_index = self.next_temp_index; |
| 20632 | temp_index.tracking(self).* = InstTracking.init(try self.allocRegOrMemAdvanced(ty, temp_index.toIndex(), true)); | 20764 | temp_index.tracking(self).* = .init( |
| | 20765 | try self.allocRegOrMemAdvanced(ty, temp_index.toIndex(), true), |
| | 20766 | ); |
| | 20767 | self.temp_type[@intFromEnum(temp_index)] = ty; |
| | 20768 | self.next_temp_index = @enumFromInt(@intFromEnum(temp_index) + 1); |
| | 20769 | return .{ .index = temp_index.toIndex() }; |
| | 20770 | } |
| | 20771 | |
| | 20772 | fn tempAllocReg(self: *Self, ty: Type, rc: RegisterManager.RegisterBitSet) !Temp { |
| | 20773 | const temp_index = self.next_temp_index; |
| | 20774 | temp_index.tracking(self).* = .init( |
| | 20775 | .{ .register = try self.register_manager.allocReg(temp_index.toIndex(), rc) }, |
| | 20776 | ); |
| 20633 | self.temp_type[@intFromEnum(temp_index)] = ty; | 20777 | self.temp_type[@intFromEnum(temp_index)] = ty; |
| 20634 | self.next_temp_index = @enumFromInt(@intFromEnum(temp_index) + 1); | 20778 | self.next_temp_index = @enumFromInt(@intFromEnum(temp_index) + 1); |
| 20635 | return .{ .index = temp_index.toIndex() }; | 20779 | return .{ .index = temp_index.toIndex() }; |
| ... | @@ -20637,7 +20781,7 @@ fn tempAlloc(self: *Self, ty: Type) !Temp { | ... | @@ -20637,7 +20781,7 @@ fn tempAlloc(self: *Self, ty: Type) !Temp { |
| 20637 | | 20781 | |
| 20638 | fn tempFromValue(self: *Self, ty: Type, value: MCValue) !Temp { | 20782 | fn tempFromValue(self: *Self, ty: Type, value: MCValue) !Temp { |
| 20639 | const temp_index = self.next_temp_index; | 20783 | const temp_index = self.next_temp_index; |
| 20640 | temp_index.tracking(self).* = InstTracking.init(value); | 20784 | temp_index.tracking(self).* = .init(value); |
| 20641 | self.temp_type[@intFromEnum(temp_index)] = ty; | 20785 | self.temp_type[@intFromEnum(temp_index)] = ty; |
| 20642 | try self.getValue(value, temp_index.toIndex()); | 20786 | try self.getValue(value, temp_index.toIndex()); |
| 20643 | self.next_temp_index = @enumFromInt(@intFromEnum(temp_index) + 1); | 20787 | self.next_temp_index = @enumFromInt(@intFromEnum(temp_index) + 1); |
| ... | @@ -20657,8 +20801,8 @@ fn tempFromOperand( | ... | @@ -20657,8 +20801,8 @@ fn tempFromOperand( |
| 20657 | if (op_ref.toIndex()) |op_inst| return .{ .index = op_inst }; | 20801 | if (op_ref.toIndex()) |op_inst| return .{ .index = op_inst }; |
| 20658 | const val = op_ref.toInterned().?; | 20802 | const val = op_ref.toInterned().?; |
| 20659 | const gop = try self.const_tracking.getOrPut(self.gpa, val); | 20803 | const gop = try self.const_tracking.getOrPut(self.gpa, val); |
| 20660 | if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: { | 20804 | if (!gop.found_existing) gop.value_ptr.* = .init(init: { |
| 20661 | const const_mcv = try self.genTypedValue(Value.fromInterned(val)); | 20805 | const const_mcv = try self.genTypedValue(.fromInterned(val)); |
| 20662 | switch (const_mcv) { | 20806 | switch (const_mcv) { |
| 20663 | .lea_tlv => |tlv_sym| switch (self.bin_file.tag) { | 20807 | .lea_tlv => |tlv_sym| switch (self.bin_file.tag) { |
| 20664 | .elf, .macho => { | 20808 | .elf, .macho => { |
| ... | @@ -20667,7 +20811,7 @@ fn tempFromOperand( | ... | @@ -20667,7 +20811,7 @@ fn tempFromOperand( |
| 20667 | } else { | 20811 | } else { |
| 20668 | try self.spillRegisters(&.{.rax}); | 20812 | try self.spillRegisters(&.{.rax}); |
| 20669 | } | 20813 | } |
| 20670 | const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{ | 20814 | const frame_index = try self.allocFrameIndex(.init(.{ |
| 20671 | .size = 8, | 20815 | .size = 8, |
| 20672 | .alignment = .@"8", | 20816 | .alignment = .@"8", |
| 20673 | })); | 20817 | })); |
| ... | @@ -20685,7 +20829,7 @@ fn tempFromOperand( | ... | @@ -20685,7 +20829,7 @@ fn tempFromOperand( |
| 20685 | else => break :init const_mcv, | 20829 | else => break :init const_mcv, |
| 20686 | } | 20830 | } |
| 20687 | }); | 20831 | }); |
| 20688 | return self.tempFromValue(Type.fromInterned(ip.typeOf(val)), gop.value_ptr.short); | 20832 | return self.tempFromValue(.fromInterned(ip.typeOf(val)), gop.value_ptr.short); |
| 20689 | } | 20833 | } |
| 20690 | | 20834 | |
| 20691 | const temp_index = self.next_temp_index; | 20835 | const temp_index = self.next_temp_index; |
| ... | @@ -20706,3 +20850,193 @@ inline fn tempsFromOperands(self: *Self, inst: Air.Inst.Index, op_refs: anytype) | ... | @@ -20706,3 +20850,193 @@ inline fn tempsFromOperands(self: *Self, inst: Air.Inst.Index, op_refs: anytype) |
| 20706 | } | 20850 | } |
| 20707 | return temps; | 20851 | return temps; |
| 20708 | } | 20852 | } |
| | 20853 | |
| | 20854 | const Operand = union(enum) { |
| | 20855 | none, |
| | 20856 | reg: Register, |
| | 20857 | mem: Memory, |
| | 20858 | imm: Immediate, |
| | 20859 | inst: Mir.Inst.Index, |
| | 20860 | }; |
| | 20861 | |
| | 20862 | const Pattern = struct { |
| | 20863 | tag: Mir.Inst.FixedTag, |
| | 20864 | ops: []const Op, |
| | 20865 | commute: struct { u8, u8 } = .{ 0, 0 }, |
| | 20866 | features: []const std.Target.x86.Feature = &.{}, |
| | 20867 | |
| | 20868 | const Op = union(enum) { |
| | 20869 | /// match another operand |
| | 20870 | match: u8, |
| | 20871 | /// any general purpose register |
| | 20872 | gpr, |
| | 20873 | /// any 64-bit mmx register |
| | 20874 | mm, |
| | 20875 | /// any 128-bit sse register |
| | 20876 | xmm, |
| | 20877 | /// any 256-bit sse register |
| | 20878 | ymm, |
| | 20879 | /// any memory |
| | 20880 | mem, |
| | 20881 | /// specific immediate |
| | 20882 | imm: i8, |
| | 20883 | /// any immediate signed extended from 32 bits |
| | 20884 | simm32, |
| | 20885 | |
| | 20886 | fn matches(op: Op, is_mut: bool, temp: Temp, self: *Self) bool { |
| | 20887 | return switch (op) { |
| | 20888 | .match => unreachable, |
| | 20889 | .gpr => switch (temp.tracking(self).short) { |
| | 20890 | .register => |reg| reg.class() == .general_purpose, |
| | 20891 | .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and |
| | 20892 | reg_off.off == 0, |
| | 20893 | else => self.regClassForType(temp.typeOf(self)) == .general_purpose, |
| | 20894 | }, |
| | 20895 | .mm => switch (temp.tracking(self).short) { |
| | 20896 | .register => |reg| reg.class() == .mmx, |
| | 20897 | .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0, |
| | 20898 | else => self.regClassForType(temp.typeOf(self)) == .mmx, |
| | 20899 | }, |
| | 20900 | .xmm => switch (temp.tracking(self).short) { |
| | 20901 | .register => |reg| reg.class() == .sse, |
| | 20902 | .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, |
| | 20903 | else => self.regClassForType(temp.typeOf(self)) == .sse, |
| | 20904 | }, |
| | 20905 | .ymm => switch (temp.tracking(self).short) { |
| | 20906 | .register => |reg| reg.class() == .sse, |
| | 20907 | .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, |
| | 20908 | else => self.regClassForType(temp.typeOf(self)) == .sse, |
| | 20909 | } and temp.typeOf(self).abiSize(self.pt.zcu) > 16, |
| | 20910 | .mem => (!is_mut or temp.isMut(self)) and temp.tracking(self).short.isMemory(), |
| | 20911 | .imm => |specific_imm| if (is_mut) unreachable else switch (temp.tracking(self).short) { |
| | 20912 | .immediate => |imm| @as(i64, @bitCast(imm)) == specific_imm, |
| | 20913 | else => false, |
| | 20914 | }, |
| | 20915 | .simm32 => if (is_mut) unreachable else switch (temp.tracking(self).short) { |
| | 20916 | .immediate => |imm| temp.typeOf(self).abiSize(self.pt.zcu) <= 4 or |
| | 20917 | std.math.cast(i32, @as(i64, @bitCast(imm))) != null, |
| | 20918 | else => false, |
| | 20919 | }, |
| | 20920 | }; |
| | 20921 | } |
| | 20922 | }; |
| | 20923 | }; |
| | 20924 | fn select(self: *Self, dst_temps: []Temp, src_temps: []const *Temp, patterns: []const Pattern) !void { |
| | 20925 | patterns: for (patterns) |pattern| { |
| | 20926 | for (pattern.features) |feature| if (!self.hasFeature(feature)) continue :patterns; |
| | 20927 | for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| if (!switch (src_op) { |
| | 20928 | .match => |match_index| pattern.ops[match_index], |
| | 20929 | else => src_op, |
| | 20930 | }.matches(src_op == .match, src_temp.*, self)) continue :patterns; |
| | 20931 | while (true) for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| { |
| | 20932 | if (switch (switch (src_op) { |
| | 20933 | .match => |match_index| pattern.ops[match_index], |
| | 20934 | else => src_op, |
| | 20935 | }) { |
| | 20936 | .match => unreachable, |
| | 20937 | .gpr => try src_temp.toRegClass(.general_purpose, self), |
| | 20938 | .mm => try src_temp.toRegClass(.mmx, self), |
| | 20939 | .xmm, .ymm => try src_temp.toRegClass(.sse, self), |
| | 20940 | .mem, .imm, .simm32 => false, |
| | 20941 | }) break; |
| | 20942 | } else break; |
| | 20943 | var mir_ops: [4]Operand = @splat(.none); |
| | 20944 | var mir_ops_len = dst_temps.len; |
| | 20945 | for (src_temps, pattern.ops[dst_temps.len..]) |src_temp, src_op| { |
| | 20946 | const mir_op, const matched_src_op = op: switch (src_op) { |
| | 20947 | .match => |match_index| { |
| | 20948 | dst_temps[match_index] = src_temp.*; |
| | 20949 | break :op .{ &mir_ops[match_index], pattern.ops[match_index] }; |
| | 20950 | }, |
| | 20951 | else => { |
| | 20952 | defer mir_ops_len += 1; |
| | 20953 | break :op .{ &mir_ops[mir_ops_len], src_op }; |
| | 20954 | }, |
| | 20955 | }; |
| | 20956 | const src_mcv = src_temp.tracking(self).short; |
| | 20957 | mir_op.* = switch (matched_src_op) { |
| | 20958 | .match => unreachable, |
| | 20959 | .gpr => .{ .reg = registerAlias( |
| | 20960 | src_mcv.register, |
| | 20961 | @intCast(src_temp.typeOf(self).abiSize(self.pt.zcu)), |
| | 20962 | ) }, |
| | 20963 | .mm => .{ .reg = src_mcv.register }, |
| | 20964 | .xmm => .{ .reg = src_mcv.register.to128() }, |
| | 20965 | .ymm => .{ .reg = src_mcv.register.to256() }, |
| | 20966 | .mem => .{ .mem = try src_mcv.mem(self, self.memSize(src_temp.typeOf(self))) }, |
| | 20967 | .imm => |imm| .{ .imm = .s(imm) }, |
| | 20968 | .simm32 => switch (src_temp.typeOf(self).abiSize(self.pt.zcu)) { |
| | 20969 | else => unreachable, |
| | 20970 | 1 => .{ .imm = if (std.math.cast(i8, @as(i64, @bitCast(src_mcv.immediate)))) |small| |
| | 20971 | .s(small) |
| | 20972 | else |
| | 20973 | .u(@as(u8, @intCast(src_mcv.immediate))) }, |
| | 20974 | 2 => .{ .imm = if (std.math.cast(i16, @as(i64, @bitCast(src_mcv.immediate)))) |small| |
| | 20975 | .s(small) |
| | 20976 | else |
| | 20977 | .u(@as(u16, @intCast(src_mcv.immediate))) }, |
| | 20978 | 3...8 => .{ .imm = if (std.math.cast(i32, @as(i64, @bitCast(src_mcv.immediate)))) |small| |
| | 20979 | .s(small) |
| | 20980 | else |
| | 20981 | .u(@as(u32, @intCast(src_mcv.immediate))) }, |
| | 20982 | }, |
| | 20983 | }; |
| | 20984 | } |
| | 20985 | for ( |
| | 20986 | pattern.ops[0..dst_temps.len], |
| | 20987 | dst_temps, |
| | 20988 | mir_ops[0..dst_temps.len], |
| | 20989 | ) |dst_op, *dst_temp, *mir_op| { |
| | 20990 | if (mir_op.* != .none) continue; |
| | 20991 | const ty = src_temps[0].typeOf(self); |
| | 20992 | switch (dst_op) { |
| | 20993 | .match => |match_index| { |
| | 20994 | dst_temp.* = dst_temps[match_index]; |
| | 20995 | mir_op.* = mir_ops[match_index]; |
| | 20996 | }, |
| | 20997 | .gpr => { |
| | 20998 | dst_temp.* = try self.tempAllocReg(ty, abi.RegisterClass.gp); |
| | 20999 | mir_op.* = .{ .reg = registerAlias( |
| | 21000 | dst_temp.tracking(self).short.register, |
| | 21001 | @intCast(ty.abiSize(self.pt.zcu)), |
| | 21002 | ) }; |
| | 21003 | }, |
| | 21004 | .mm => @panic("TODO"), |
| | 21005 | .xmm => { |
| | 21006 | dst_temp.* = try self.tempAllocReg(ty, abi.RegisterClass.sse); |
| | 21007 | mir_op.* = .{ .reg = dst_temp.tracking(self).short.register.to128() }; |
| | 21008 | }, |
| | 21009 | .ymm => { |
| | 21010 | dst_temp.* = try self.tempAllocReg(ty, abi.RegisterClass.sse); |
| | 21011 | mir_op.* = .{ .reg = dst_temp.tracking(self).short.register.to256() }; |
| | 21012 | }, |
| | 21013 | .mem => @panic("TODO"), |
| | 21014 | .imm, .simm32 => unreachable, // unmodifiable destination |
| | 21015 | } |
| | 21016 | } |
| | 21017 | std.mem.swap(Operand, &mir_ops[pattern.commute[0]], &mir_ops[pattern.commute[1]]); |
| | 21018 | self.asmOps(pattern.tag, mir_ops) catch |err| switch (err) { |
| | 21019 | error.InvalidInstruction => { |
| | 21020 | const fixes = @tagName(pattern.tag[0]); |
| | 21021 | const fixes_replace = std.mem.indexOfScalar(u8, fixes, '_').?; |
| | 21022 | return self.fail( |
| | 21023 | "invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'", |
| | 21024 | .{ |
| | 21025 | fixes[0..fixes_replace], |
| | 21026 | @tagName(pattern.tag[1]), |
| | 21027 | fixes[fixes_replace + 1 ..], |
| | 21028 | @tagName(mir_ops[0]), |
| | 21029 | @tagName(mir_ops[1]), |
| | 21030 | @tagName(mir_ops[2]), |
| | 21031 | @tagName(mir_ops[3]), |
| | 21032 | }, |
| | 21033 | ); |
| | 21034 | }, |
| | 21035 | else => |e| return e, |
| | 21036 | }; |
| | 21037 | return; |
| | 21038 | } |
| | 21039 | log.err("failed to select:", .{}); |
| | 21040 | for (src_temps) |src_temp| log.err("{}", .{src_temp.tracking(self)}); |
| | 21041 | return self.fail("failed to select", .{}); |
| | 21042 | } |