| ... | @@ -48,6 +48,7 @@ const RegisterLock = RegisterManager.RegisterLock; | ... | @@ -48,6 +48,7 @@ const RegisterLock = RegisterManager.RegisterLock; |
| 48 | const FrameIndex = bits.FrameIndex; | 48 | const FrameIndex = bits.FrameIndex; |
| 49 | | 49 | |
| 50 | const gp = abi.RegisterClass.gp; | 50 | const gp = abi.RegisterClass.gp; |
| | 51 | const x87 = abi.RegisterClass.x87; |
| 51 | const sse = abi.RegisterClass.sse; | 52 | const sse = abi.RegisterClass.sse; |
| 52 | | 53 | |
| 53 | const InnerError = CodeGenError || error{OutOfRegisters}; | 54 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| ... | @@ -532,8 +533,8 @@ const InstTracking = struct { | ... | @@ -532,8 +533,8 @@ const InstTracking = struct { |
| 532 | }; | 533 | }; |
| 533 | } | 534 | } |
| 534 | | 535 | |
| 535 | fn trackSpill(self: *InstTracking, function: *Self, inst: Air.Inst.Index) void { | 536 | fn trackSpill(self: *InstTracking, function: *Self, inst: Air.Inst.Index) !void { |
| 536 | function.freeValue(self.short); | 537 | try function.freeValue(self.short); |
| 537 | self.reuseFrame(); | 538 | self.reuseFrame(); |
| 538 | tracking_log.debug("%{d} => {} (spilled)", .{ inst, self.* }); | 539 | tracking_log.debug("%{d} => {} (spilled)", .{ inst, self.* }); |
| 539 | } | 540 | } |
| ... | @@ -618,8 +619,8 @@ const InstTracking = struct { | ... | @@ -618,8 +619,8 @@ const InstTracking = struct { |
| 618 | } | 619 | } |
| 619 | } | 620 | } |
| 620 | | 621 | |
| 621 | fn die(self: *InstTracking, function: *Self, inst: Air.Inst.Index) void { | 622 | fn die(self: *InstTracking, function: *Self, inst: Air.Inst.Index) !void { |
| 622 | function.freeValue(self.short); | 623 | try function.freeValue(self.short); |
| 623 | self.short = .{ .dead = function.scope_generation }; | 624 | self.short = .{ .dead = function.scope_generation }; |
| 624 | tracking_log.debug("%{d} => {} (death)", .{ inst, self.* }); | 625 | tracking_log.debug("%{d} => {} (death)", .{ inst, self.* }); |
| 625 | } | 626 | } |
| ... | @@ -980,7 +981,6 @@ fn formatWipMir( | ... | @@ -980,7 +981,6 @@ fn formatWipMir( |
| 980 | _: std.fmt.FormatOptions, | 981 | _: std.fmt.FormatOptions, |
| 981 | writer: anytype, | 982 | writer: anytype, |
| 982 | ) @TypeOf(writer).Error!void { | 983 | ) @TypeOf(writer).Error!void { |
| 983 | const mod = data.self.bin_file.options.module.?; | | |
| 984 | var lower = Lower{ | 984 | var lower = Lower{ |
| 985 | .allocator = data.self.gpa, | 985 | .allocator = data.self.gpa, |
| 986 | .mir = .{ | 986 | .mir = .{ |
| ... | @@ -988,7 +988,7 @@ fn formatWipMir( | ... | @@ -988,7 +988,7 @@ fn formatWipMir( |
| 988 | .extra = data.self.mir_extra.items, | 988 | .extra = data.self.mir_extra.items, |
| 989 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), | 989 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), |
| 990 | }, | 990 | }, |
| 991 | .cc = mod.typeToFunc(data.self.fn_type).?.cc, | 991 | .cc = .Unspecified, |
| 992 | .src_loc = data.self.src_loc, | 992 | .src_loc = data.self.src_loc, |
| 993 | }; | 993 | }; |
| 994 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { | 994 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { |
| ... | @@ -2132,9 +2132,12 @@ fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { | ... | @@ -2132,9 +2132,12 @@ fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { |
| 2132 | self.register_manager.getRegAssumeFree(reg, inst); | 2132 | self.register_manager.getRegAssumeFree(reg, inst); |
| 2133 | } | 2133 | } |
| 2134 | | 2134 | |
| 2135 | fn freeValue(self: *Self, value: MCValue) void { | 2135 | fn freeValue(self: *Self, value: MCValue) !void { |
| 2136 | switch (value) { | 2136 | switch (value) { |
| 2137 | .register => |reg| self.register_manager.freeReg(reg), | 2137 | .register => |reg| { |
| | 2138 | if (reg.class() == .x87) try self.asmRegister(.{ .f_, .free }, reg); |
| | 2139 | self.register_manager.freeReg(reg); |
| | 2140 | }, |
| 2138 | .register_pair => |regs| for (regs) |reg| self.register_manager.freeReg(reg), | 2141 | .register_pair => |regs| for (regs) |reg| self.register_manager.freeReg(reg), |
| 2139 | .register_offset => |reg_off| self.register_manager.freeReg(reg_off.reg), | 2142 | .register_offset => |reg_off| self.register_manager.freeReg(reg_off.reg), |
| 2140 | .register_overflow => |reg_ov| { | 2143 | .register_overflow => |reg_ov| { |
| ... | @@ -2146,13 +2149,13 @@ fn freeValue(self: *Self, value: MCValue) void { | ... | @@ -2146,13 +2149,13 @@ fn freeValue(self: *Self, value: MCValue) void { |
| 2146 | } | 2149 | } |
| 2147 | } | 2150 | } |
| 2148 | | 2151 | |
| 2149 | fn feed(self: *Self, bt: *Liveness.BigTomb, operand: Air.Inst.Ref) void { | 2152 | fn feed(self: *Self, bt: *Liveness.BigTomb, operand: Air.Inst.Ref) !void { |
| 2150 | if (bt.feed()) if (Air.refToIndex(operand)) |inst| self.processDeath(inst); | 2153 | if (bt.feed()) if (Air.refToIndex(operand)) |inst| try self.processDeath(inst); |
| 2151 | } | 2154 | } |
| 2152 | | 2155 | |
| 2153 | /// Asserts there is already capacity to insert into top branch inst_table. | 2156 | /// Asserts there is already capacity to insert into top branch inst_table. |
| 2154 | fn processDeath(self: *Self, inst: Air.Inst.Index) void { | 2157 | fn processDeath(self: *Self, inst: Air.Inst.Index) !void { |
| 2155 | self.inst_tracking.getPtr(inst).?.die(self, inst); | 2158 | try self.inst_tracking.getPtr(inst).?.die(self, inst); |
| 2156 | } | 2159 | } |
| 2157 | | 2160 | |
| 2158 | /// Called when there are no operands, and the instruction is always unreferenced. | 2161 | /// Called when there are no operands, and the instruction is always unreferenced. |
| ... | @@ -2177,13 +2180,18 @@ fn finishAirResult(self: *Self, inst: Air.Inst.Index, result: MCValue) void { | ... | @@ -2177,13 +2180,18 @@ fn finishAirResult(self: *Self, inst: Air.Inst.Index, result: MCValue) void { |
| 2177 | self.finishAirBookkeeping(); | 2180 | self.finishAirBookkeeping(); |
| 2178 | } | 2181 | } |
| 2179 | | 2182 | |
| 2180 | fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Liveness.bpi - 1]Air.Inst.Ref) void { | 2183 | fn finishAir( |
| | 2184 | self: *Self, |
| | 2185 | inst: Air.Inst.Index, |
| | 2186 | result: MCValue, |
| | 2187 | operands: [Liveness.bpi - 1]Air.Inst.Ref, |
| | 2188 | ) !void { |
| 2181 | var tomb_bits = self.liveness.getTombBits(inst); | 2189 | var tomb_bits = self.liveness.getTombBits(inst); |
| 2182 | for (operands) |op| { | 2190 | for (operands) |op| { |
| 2183 | const dies = @as(u1, @truncate(tomb_bits)) != 0; | 2191 | const dies = @as(u1, @truncate(tomb_bits)) != 0; |
| 2184 | tomb_bits >>= 1; | 2192 | tomb_bits >>= 1; |
| 2185 | if (!dies) continue; | 2193 | if (!dies) continue; |
| 2186 | self.processDeath(Air.refToIndexAllowNone(op) orelse continue); | 2194 | try self.processDeath(Air.refToIndexAllowNone(op) orelse continue); |
| 2187 | } | 2195 | } |
| 2188 | self.finishAirResult(inst, result); | 2196 | self.finishAirResult(inst, result); |
| 2189 | } | 2197 | } |
| ... | @@ -2409,7 +2417,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt | ... | @@ -2409,7 +2417,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt |
| 2409 | for ( | 2417 | for ( |
| 2410 | self.inst_tracking.keys()[state.inst_tracking_len..], | 2418 | self.inst_tracking.keys()[state.inst_tracking_len..], |
| 2411 | self.inst_tracking.values()[state.inst_tracking_len..], | 2419 | self.inst_tracking.values()[state.inst_tracking_len..], |
| 2412 | ) |inst, *tracking| tracking.die(self, inst); | 2420 | ) |inst, *tracking| try tracking.die(self, inst); |
| 2413 | self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len); | 2421 | self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len); |
| 2414 | } | 2422 | } |
| 2415 | | 2423 | |
| ... | @@ -2417,7 +2425,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt | ... | @@ -2417,7 +2425,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt |
| 2417 | self.inst_tracking.keys()[0..state.inst_tracking_len], | 2425 | self.inst_tracking.keys()[0..state.inst_tracking_len], |
| 2418 | self.inst_tracking.values()[0..state.inst_tracking_len], | 2426 | self.inst_tracking.values()[0..state.inst_tracking_len], |
| 2419 | ) |inst, *tracking| tracking.resurrect(inst, state.scope_generation); | 2427 | ) |inst, *tracking| tracking.resurrect(inst, state.scope_generation); |
| 2420 | for (deaths) |death| self.processDeath(death); | 2428 | for (deaths) |death| try self.processDeath(death); |
| 2421 | | 2429 | |
| 2422 | for (0..state.registers.len) |index| { | 2430 | for (0..state.registers.len) |index| { |
| 2423 | const current_maybe_inst = if (self.register_manager.free_registers.isSet(index)) | 2431 | const current_maybe_inst = if (self.register_manager.free_registers.isSet(index)) |
| ... | @@ -2444,7 +2452,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt | ... | @@ -2444,7 +2452,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt |
| 2444 | } | 2452 | } |
| 2445 | if (opts.update_tracking) { | 2453 | if (opts.update_tracking) { |
| 2446 | if (current_maybe_inst) |current_inst| { | 2454 | if (current_maybe_inst) |current_inst| { |
| 2447 | self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst); | 2455 | try self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst); |
| 2448 | } | 2456 | } |
| 2449 | { | 2457 | { |
| 2450 | const reg = RegisterManager.regAtTrackedIndex(@intCast(index)); | 2458 | const reg = RegisterManager.regAtTrackedIndex(@intCast(index)); |
| ... | @@ -2463,7 +2471,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt | ... | @@ -2463,7 +2471,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt |
| 2463 | try self.inst_tracking.getPtr(inst).?.spill(self, inst); | 2471 | try self.inst_tracking.getPtr(inst).?.spill(self, inst); |
| 2464 | if (opts.update_tracking) if (self.eflags_inst) |inst| { | 2472 | if (opts.update_tracking) if (self.eflags_inst) |inst| { |
| 2465 | self.eflags_inst = null; | 2473 | self.eflags_inst = null; |
| 2466 | self.inst_tracking.getPtr(inst).?.trackSpill(self, inst); | 2474 | try self.inst_tracking.getPtr(inst).?.trackSpill(self, inst); |
| 2467 | }; | 2475 | }; |
| 2468 | | 2476 | |
| 2469 | if (opts.update_tracking and std.debug.runtime_safety) { | 2477 | if (opts.update_tracking and std.debug.runtime_safety) { |
| ... | @@ -2481,7 +2489,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void | ... | @@ -2481,7 +2489,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void |
| 2481 | if (tracked_reg.id() == reg.id()) break; | 2489 | if (tracked_reg.id() == reg.id()) break; |
| 2482 | } else unreachable; // spilled reg not tracked with spilled instruciton | 2490 | } else unreachable; // spilled reg not tracked with spilled instruciton |
| 2483 | try tracking.spill(self, inst); | 2491 | try tracking.spill(self, inst); |
| 2484 | tracking.trackSpill(self, inst); | 2492 | try tracking.trackSpill(self, inst); |
| 2485 | } | 2493 | } |
| 2486 | | 2494 | |
| 2487 | pub fn spillEflagsIfOccupied(self: *Self) !void { | 2495 | pub fn spillEflagsIfOccupied(self: *Self) !void { |
| ... | @@ -2490,7 +2498,7 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { | ... | @@ -2490,7 +2498,7 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { |
| 2490 | const tracking = self.inst_tracking.getPtr(inst).?; | 2498 | const tracking = self.inst_tracking.getPtr(inst).?; |
| 2491 | assert(tracking.getCondition() != null); | 2499 | assert(tracking.getCondition() != null); |
| 2492 | try tracking.spill(self, inst); | 2500 | try tracking.spill(self, inst); |
| 2493 | tracking.trackSpill(self, inst); | 2501 | try tracking.trackSpill(self, inst); |
| 2494 | } | 2502 | } |
| 2495 | } | 2503 | } |
| 2496 | | 2504 | |
| ... | @@ -8428,8 +8436,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -8428,8 +8436,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 8428 | const ret = try self.genCall(.{ .air = pl_op.operand }, arg_tys, arg_vals); | 8436 | const ret = try self.genCall(.{ .air = pl_op.operand }, arg_tys, arg_vals); |
| 8429 | | 8437 | |
| 8430 | var bt = self.liveness.iterateBigTomb(inst); | 8438 | var bt = self.liveness.iterateBigTomb(inst); |
| 8431 | self.feed(&bt, pl_op.operand); | 8439 | try self.feed(&bt, pl_op.operand); |
| 8432 | for (arg_refs) |arg_ref| self.feed(&bt, arg_ref); | 8440 | for (arg_refs) |arg_ref| try self.feed(&bt, arg_ref); |
| 8433 | | 8441 | |
| 8434 | const result = if (self.liveness.isUnused(inst)) .unreach else ret; | 8442 | const result = if (self.liveness.isUnused(inst)) .unreach else ret; |
| 8435 | return self.finishAirResult(inst, result); | 8443 | return self.finishAirResult(inst, result); |
| ... | @@ -9086,13 +9094,13 @@ fn genTry( | ... | @@ -9086,13 +9094,13 @@ fn genTry( |
| 9086 | const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv); | 9094 | const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv); |
| 9087 | | 9095 | |
| 9088 | if (self.liveness.operandDies(inst, 0)) { | 9096 | if (self.liveness.operandDies(inst, 0)) { |
| 9089 | if (Air.refToIndex(err_union)) |err_union_inst| self.processDeath(err_union_inst); | 9097 | if (Air.refToIndex(err_union)) |err_union_inst| try self.processDeath(err_union_inst); |
| 9090 | } | 9098 | } |
| 9091 | | 9099 | |
| 9092 | self.scope_generation += 1; | 9100 | self.scope_generation += 1; |
| 9093 | const state = try self.saveState(); | 9101 | const state = try self.saveState(); |
| 9094 | | 9102 | |
| 9095 | for (liveness_cond_br.else_deaths) |operand| self.processDeath(operand); | 9103 | for (liveness_cond_br.else_deaths) |operand| try self.processDeath(operand); |
| 9096 | try self.genBody(body); | 9104 | try self.genBody(body); |
| 9097 | try self.restoreState(state, &.{}, .{ | 9105 | try self.restoreState(state, &.{}, .{ |
| 9098 | .emit_instructions = false, | 9106 | .emit_instructions = false, |
| ... | @@ -9103,7 +9111,7 @@ fn genTry( | ... | @@ -9103,7 +9111,7 @@ fn genTry( |
| 9103 | | 9111 | |
| 9104 | try self.performReloc(reloc); | 9112 | try self.performReloc(reloc); |
| 9105 | | 9113 | |
| 9106 | for (liveness_cond_br.then_deaths) |operand| self.processDeath(operand); | 9114 | for (liveness_cond_br.then_deaths) |operand| try self.processDeath(operand); |
| 9107 | | 9115 | |
| 9108 | const result = if (self.liveness.isUnused(inst)) | 9116 | const result = if (self.liveness.isUnused(inst)) |
| 9109 | .unreach | 9117 | .unreach |
| ... | @@ -9196,13 +9204,13 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9196,13 +9204,13 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9196 | // that death now instead of later as this has an effect on | 9204 | // that death now instead of later as this has an effect on |
| 9197 | // whether it needs to be spilled in the branches | 9205 | // whether it needs to be spilled in the branches |
| 9198 | if (self.liveness.operandDies(inst, 0)) { | 9206 | if (self.liveness.operandDies(inst, 0)) { |
| 9199 | if (Air.refToIndex(pl_op.operand)) |op_inst| self.processDeath(op_inst); | 9207 | if (Air.refToIndex(pl_op.operand)) |op_inst| try self.processDeath(op_inst); |
| 9200 | } | 9208 | } |
| 9201 | | 9209 | |
| 9202 | self.scope_generation += 1; | 9210 | self.scope_generation += 1; |
| 9203 | const state = try self.saveState(); | 9211 | const state = try self.saveState(); |
| 9204 | | 9212 | |
| 9205 | for (liveness_cond_br.then_deaths) |operand| self.processDeath(operand); | 9213 | for (liveness_cond_br.then_deaths) |operand| try self.processDeath(operand); |
| 9206 | try self.genBody(then_body); | 9214 | try self.genBody(then_body); |
| 9207 | try self.restoreState(state, &.{}, .{ | 9215 | try self.restoreState(state, &.{}, .{ |
| 9208 | .emit_instructions = false, | 9216 | .emit_instructions = false, |
| ... | @@ -9213,7 +9221,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9213,7 +9221,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9213 | | 9221 | |
| 9214 | try self.performReloc(reloc); | 9222 | try self.performReloc(reloc); |
| 9215 | | 9223 | |
| 9216 | for (liveness_cond_br.else_deaths) |operand| self.processDeath(operand); | 9224 | for (liveness_cond_br.else_deaths) |operand| try self.processDeath(operand); |
| 9217 | try self.genBody(else_body); | 9225 | try self.genBody(else_body); |
| 9218 | try self.restoreState(state, &.{}, .{ | 9226 | try self.restoreState(state, &.{}, .{ |
| 9219 | .emit_instructions = false, | 9227 | .emit_instructions = false, |
| ... | @@ -9580,7 +9588,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9580,7 +9588,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 9580 | | 9588 | |
| 9581 | if (std.debug.runtime_safety) assert(self.inst_tracking.getIndex(inst).? == inst_tracking_i); | 9589 | if (std.debug.runtime_safety) assert(self.inst_tracking.getIndex(inst).? == inst_tracking_i); |
| 9582 | const tracking = &self.inst_tracking.values()[inst_tracking_i]; | 9590 | const tracking = &self.inst_tracking.values()[inst_tracking_i]; |
| 9583 | if (self.liveness.isUnused(inst)) tracking.die(self, inst); | 9591 | if (self.liveness.isUnused(inst)) try tracking.die(self, inst); |
| 9584 | self.getValue(tracking.short, inst); | 9592 | self.getValue(tracking.short, inst); |
| 9585 | self.finishAirBookkeeping(); | 9593 | self.finishAirBookkeeping(); |
| 9586 | } | 9594 | } |
| ... | @@ -9599,7 +9607,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9599,7 +9607,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9599 | // that death now instead of later as this has an effect on | 9607 | // that death now instead of later as this has an effect on |
| 9600 | // whether it needs to be spilled in the branches | 9608 | // whether it needs to be spilled in the branches |
| 9601 | if (self.liveness.operandDies(inst, 0)) { | 9609 | if (self.liveness.operandDies(inst, 0)) { |
| 9602 | if (Air.refToIndex(pl_op.operand)) |op_inst| self.processDeath(op_inst); | 9610 | if (Air.refToIndex(pl_op.operand)) |op_inst| try self.processDeath(op_inst); |
| 9603 | } | 9611 | } |
| 9604 | | 9612 | |
| 9605 | self.scope_generation += 1; | 9613 | self.scope_generation += 1; |
| ... | @@ -9622,7 +9630,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9622,7 +9630,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9622 | reloc.* = try self.asmJccReloc(undefined, if (i < relocs.len - 1) .e else .ne); | 9630 | reloc.* = try self.asmJccReloc(undefined, if (i < relocs.len - 1) .e else .ne); |
| 9623 | } | 9631 | } |
| 9624 | | 9632 | |
| 9625 | for (liveness.deaths[case_i]) |operand| self.processDeath(operand); | 9633 | for (liveness.deaths[case_i]) |operand| try self.processDeath(operand); |
| 9626 | | 9634 | |
| 9627 | for (relocs[0 .. relocs.len - 1]) |reloc| try self.performReloc(reloc); | 9635 | for (relocs[0 .. relocs.len - 1]) |reloc| try self.performReloc(reloc); |
| 9628 | try self.genBody(case_body); | 9636 | try self.genBody(case_body); |
| ... | @@ -9640,7 +9648,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9640,7 +9648,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9640 | const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len]; | 9648 | const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len]; |
| 9641 | | 9649 | |
| 9642 | const else_deaths = liveness.deaths.len - 1; | 9650 | const else_deaths = liveness.deaths.len - 1; |
| 9643 | for (liveness.deaths[else_deaths]) |operand| self.processDeath(operand); | 9651 | for (liveness.deaths[else_deaths]) |operand| try self.processDeath(operand); |
| 9644 | | 9652 | |
| 9645 | try self.genBody(else_body); | 9653 | try self.genBody(else_body); |
| 9646 | try self.restoreState(state, &.{}, .{ | 9654 | try self.restoreState(state, &.{}, .{ |
| ... | @@ -9704,7 +9712,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9704,7 +9712,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9704 | | 9712 | |
| 9705 | // Process operand death so that it is properly accounted for in the State below. | 9713 | // Process operand death so that it is properly accounted for in the State below. |
| 9706 | if (self.liveness.operandDies(inst, 0)) { | 9714 | if (self.liveness.operandDies(inst, 0)) { |
| 9707 | if (Air.refToIndex(br.operand)) |op_inst| self.processDeath(op_inst); | 9715 | if (Air.refToIndex(br.operand)) |op_inst| try self.processDeath(op_inst); |
| 9708 | } | 9716 | } |
| 9709 | | 9717 | |
| 9710 | if (first_br) { | 9718 | if (first_br) { |
| ... | @@ -9718,7 +9726,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9718,7 +9726,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9718 | }); | 9726 | }); |
| 9719 | | 9727 | |
| 9720 | // Stop tracking block result without forgetting tracking info | 9728 | // Stop tracking block result without forgetting tracking info |
| 9721 | self.freeValue(block_tracking.short); | 9729 | try self.freeValue(block_tracking.short); |
| 9722 | | 9730 | |
| 9723 | // Emit a jump with a relocation. It will be patched up after the block ends. | 9731 | // Emit a jump with a relocation. It will be patched up after the block ends. |
| 9724 | // Leave the jump offset undefined | 9732 | // Leave the jump offset undefined |
| ... | @@ -10077,13 +10085,14 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10077,13 +10085,14 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 10077 | return self.finishAir(inst, result, buf); | 10085 | return self.finishAir(inst, result, buf); |
| 10078 | } | 10086 | } |
| 10079 | var bt = self.liveness.iterateBigTomb(inst); | 10087 | var bt = self.liveness.iterateBigTomb(inst); |
| 10080 | for (outputs) |output| if (output != .none) self.feed(&bt, output); | 10088 | for (outputs) |output| if (output != .none) try self.feed(&bt, output); |
| 10081 | for (inputs) |input| self.feed(&bt, input); | 10089 | for (inputs) |input| try self.feed(&bt, input); |
| 10082 | return self.finishAirResult(inst, result); | 10090 | return self.finishAirResult(inst, result); |
| 10083 | } | 10091 | } |
| 10084 | | 10092 | |
| 10085 | const MoveStrategy = union(enum) { | 10093 | const MoveStrategy = union(enum) { |
| 10086 | move: Mir.Inst.FixedTag, | 10094 | move: Mir.Inst.FixedTag, |
| | 10095 | x87_load_store, |
| 10087 | insert_extract: InsertExtract, | 10096 | insert_extract: InsertExtract, |
| 10088 | vex_insert_extract: InsertExtract, | 10097 | vex_insert_extract: InsertExtract, |
| 10089 | | 10098 | |
| ... | @@ -10091,6 +10100,44 @@ const MoveStrategy = union(enum) { | ... | @@ -10091,6 +10100,44 @@ const MoveStrategy = union(enum) { |
| 10091 | insert: Mir.Inst.FixedTag, | 10100 | insert: Mir.Inst.FixedTag, |
| 10092 | extract: Mir.Inst.FixedTag, | 10101 | extract: Mir.Inst.FixedTag, |
| 10093 | }; | 10102 | }; |
| | 10103 | |
| | 10104 | pub fn read(strat: MoveStrategy, self: *Self, dst_reg: Register, src_mem: Memory) !void { |
| | 10105 | switch (strat) { |
| | 10106 | .move => |tag| try self.asmRegisterMemory(tag, dst_reg, src_mem), |
| | 10107 | .x87_load_store => { |
| | 10108 | try self.asmMemory(.{ .f_, .ld }, src_mem); |
| | 10109 | try self.asmRegister(.{ .f_p, .st }, @enumFromInt(@intFromEnum(dst_reg) + 1)); |
| | 10110 | }, |
| | 10111 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( |
| | 10112 | ie.insert, |
| | 10113 | dst_reg, |
| | 10114 | src_mem, |
| | 10115 | Immediate.u(0), |
| | 10116 | ), |
| | 10117 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| | 10118 | ie.insert, |
| | 10119 | dst_reg, |
| | 10120 | dst_reg, |
| | 10121 | src_mem, |
| | 10122 | Immediate.u(0), |
| | 10123 | ), |
| | 10124 | } |
| | 10125 | } |
| | 10126 | pub fn write(strat: MoveStrategy, self: *Self, dst_mem: Memory, src_reg: Register) !void { |
| | 10127 | switch (strat) { |
| | 10128 | .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_reg), |
| | 10129 | .x87_load_store => { |
| | 10130 | try self.asmRegister(.{ .f_, .ld }, src_reg); |
| | 10131 | try self.asmMemory(.{ .f_p, .st }, dst_mem); |
| | 10132 | }, |
| | 10133 | .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate( |
| | 10134 | ie.extract, |
| | 10135 | dst_mem, |
| | 10136 | src_reg, |
| | 10137 | Immediate.u(0), |
| | 10138 | ), |
| | 10139 | } |
| | 10140 | } |
| 10094 | }; | 10141 | }; |
| 10095 | fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { | 10142 | fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { |
| 10096 | const mod = self.bin_file.options.module.?; | 10143 | const mod = self.bin_file.options.module.?; |
| ... | @@ -10106,6 +10153,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { | ... | @@ -10106,6 +10153,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { |
| 10106 | } }, | 10153 | } }, |
| 10107 | 32 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov } }, | 10154 | 32 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov } }, |
| 10108 | 64 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov } }, | 10155 | 64 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov } }, |
| | 10156 | 80 => return .x87_load_store, |
| 10109 | 128 => return .{ .move = if (self.hasFeature(.avx)) | 10157 | 128 => return .{ .move = if (self.hasFeature(.avx)) |
| 10110 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | 10158 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } |
| 10111 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | 10159 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, |
| ... | @@ -10370,7 +10418,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -10370,7 +10418,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 10370 | fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void { | 10418 | fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void { |
| 10371 | const mod = self.bin_file.options.module.?; | 10419 | const mod = self.bin_file.options.module.?; |
| 10372 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 10420 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 10373 | if (abi_size * 8 > dst_reg.bitSize()) | 10421 | if (ty.bitSize(mod) > dst_reg.bitSize()) |
| 10374 | return self.fail("genSetReg called with a value larger than dst_reg", .{}); | 10422 | return self.fail("genSetReg called with a value larger than dst_reg", .{}); |
| 10375 | switch (src_mcv) { | 10423 | switch (src_mcv) { |
| 10376 | .none, | 10424 | .none, |
| ... | @@ -10486,9 +10534,21 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -10486,9 +10534,21 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 10486 | .indirect, | 10534 | .indirect, |
| 10487 | .load_frame, | 10535 | .load_frame, |
| 10488 | .lea_frame, | 10536 | .lea_frame, |
| 10489 | => { | 10537 | => try @as(MoveStrategy, switch (src_mcv) { |
| 10490 | const dst_alias = registerAlias(dst_reg, abi_size); | 10538 | .register_offset => |reg_off| switch (reg_off.off) { |
| 10491 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { | 10539 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), |
| | 10540 | else => .{ .move = .{ ._, .lea } }, |
| | 10541 | }, |
| | 10542 | .indirect => try self.moveStrategy(ty, false), |
| | 10543 | .load_frame => |frame_addr| try self.moveStrategy( |
| | 10544 | ty, |
| | 10545 | self.getFrameAddrAlignment(frame_addr).compare(.gte, ty.abiAlignment(mod)), |
| | 10546 | ), |
| | 10547 | .lea_frame => .{ .move = .{ ._, .lea } }, |
| | 10548 | else => unreachable, |
| | 10549 | }).read(self, registerAlias(dst_reg, abi_size), Memory.sib( |
| | 10550 | self.memPtrSize(ty), |
| | 10551 | switch (src_mcv) { |
| 10492 | .register_offset, .indirect => |reg_off| .{ | 10552 | .register_offset, .indirect => |reg_off| .{ |
| 10493 | .base = .{ .reg = reg_off.reg }, | 10553 | .base = .{ .reg = reg_off.reg }, |
| 10494 | .disp = reg_off.off, | 10554 | .disp = reg_off.off, |
| ... | @@ -10498,64 +10558,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -10498,64 +10558,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 10498 | .disp = frame_addr.off, | 10558 | .disp = frame_addr.off, |
| 10499 | }, | 10559 | }, |
| 10500 | else => unreachable, | 10560 | else => unreachable, |
| 10501 | }); | 10561 | }, |
| 10502 | switch (@as(MoveStrategy, switch (src_mcv) { | 10562 | )), |
| 10503 | .register_offset => |reg_off| switch (reg_off.off) { | | |
| 10504 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), | | |
| 10505 | else => .{ .move = .{ ._, .lea } }, | | |
| 10506 | }, | | |
| 10507 | .indirect => try self.moveStrategy(ty, false), | | |
| 10508 | .load_frame => |frame_addr| try self.moveStrategy( | | |
| 10509 | ty, | | |
| 10510 | self.getFrameAddrAlignment(frame_addr).compare(.gte, ty.abiAlignment(mod)), | | |
| 10511 | ), | | |
| 10512 | .lea_frame => .{ .move = .{ ._, .lea } }, | | |
| 10513 | else => unreachable, | | |
| 10514 | })) { | | |
| 10515 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), | | |
| 10516 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( | | |
| 10517 | ie.insert, | | |
| 10518 | dst_alias, | | |
| 10519 | src_mem, | | |
| 10520 | Immediate.u(0), | | |
| 10521 | ), | | |
| 10522 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( | | |
| 10523 | ie.insert, | | |
| 10524 | dst_alias, | | |
| 10525 | dst_alias, | | |
| 10526 | src_mem, | | |
| 10527 | Immediate.u(0), | | |
| 10528 | ), | | |
| 10529 | } | | |
| 10530 | }, | | |
| 10531 | .memory, .load_direct, .load_got, .load_tlv => { | 10563 | .memory, .load_direct, .load_got, .load_tlv => { |
| 10532 | switch (src_mcv) { | 10564 | switch (src_mcv) { |
| 10533 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| { | 10565 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| 10534 | const dst_alias = registerAlias(dst_reg, abi_size); | 10566 | return (try self.moveStrategy( |
| 10535 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 10567 | ty, |
| 10536 | .base = .{ .reg = .ds }, | 10568 | ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))), |
| 10537 | .disp = small_addr, | 10569 | )).read(self, registerAlias(dst_reg, abi_size), Memory.sib( |
| 10538 | }); | 10570 | self.memPtrSize(ty), |
| 10539 | switch (try self.moveStrategy(ty, ty.abiAlignment(mod).check( | 10571 | .{ .base = .{ .reg = .ds }, .disp = small_addr }, |
| 10540 | @as(u32, @bitCast(small_addr)), | 10572 | )), |
| 10541 | ))) { | | |
| 10542 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), | | |
| 10543 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( | | |
| 10544 | ie.insert, | | |
| 10545 | dst_alias, | | |
| 10546 | src_mem, | | |
| 10547 | Immediate.u(0), | | |
| 10548 | ), | | |
| 10549 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( | | |
| 10550 | ie.insert, | | |
| 10551 | dst_alias, | | |
| 10552 | dst_alias, | | |
| 10553 | src_mem, | | |
| 10554 | Immediate.u(0), | | |
| 10555 | ), | | |
| 10556 | } | | |
| 10557 | return; | | |
| 10558 | }, | | |
| 10559 | .load_direct => |sym_index| switch (ty.zigTypeTag(mod)) { | 10573 | .load_direct => |sym_index| switch (ty.zigTypeTag(mod)) { |
| 10560 | else => { | 10574 | else => { |
| 10561 | const atom_index = try self.owner.getSymbolIndex(self); | 10575 | const atom_index = try self.owner.getSymbolIndex(self); |
| ... | @@ -10582,26 +10596,11 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -10582,26 +10596,11 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 10582 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 10596 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 10583 | defer self.register_manager.unlockReg(addr_lock); | 10597 | defer self.register_manager.unlockReg(addr_lock); |
| 10584 | | 10598 | |
| 10585 | const dst_alias = registerAlias(dst_reg, abi_size); | 10599 | try (try self.moveStrategy(ty, false)).read( |
| 10586 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 10600 | self, |
| 10587 | .base = .{ .reg = addr_reg }, | 10601 | registerAlias(dst_reg, abi_size), |
| 10588 | }); | 10602 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }), |
| 10589 | switch (try self.moveStrategy(ty, false)) { | 10603 | ); |
| 10590 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), | | |
| 10591 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( | | |
| 10592 | ie.insert, | | |
| 10593 | dst_alias, | | |
| 10594 | src_mem, | | |
| 10595 | Immediate.u(0), | | |
| 10596 | ), | | |
| 10597 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( | | |
| 10598 | ie.insert, | | |
| 10599 | dst_alias, | | |
| 10600 | dst_alias, | | |
| 10601 | src_mem, | | |
| 10602 | Immediate.u(0), | | |
| 10603 | ), | | |
| 10604 | } | | |
| 10605 | }, | 10604 | }, |
| 10606 | .lea_direct, .lea_got => |sym_index| { | 10605 | .lea_direct, .lea_got => |sym_index| { |
| 10607 | const atom_index = try self.owner.getSymbolIndex(self); | 10606 | const atom_index = try self.owner.getSymbolIndex(self); |
| ... | @@ -10698,39 +10697,23 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -10698,39 +10697,23 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 10698 | }, | 10697 | }, |
| 10699 | }, | 10698 | }, |
| 10700 | .eflags => |cc| try self.asmSetccMemory(Memory.sib(.byte, .{ .base = base, .disp = disp }), cc), | 10699 | .eflags => |cc| try self.asmSetccMemory(Memory.sib(.byte, .{ .base = base, .disp = disp }), cc), |
| 10701 | .register => |src_reg| { | 10700 | .register => |src_reg| try (try self.moveStrategy(ty, switch (base) { |
| 10702 | const dst_mem = Memory.sib( | 10701 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| 10703 | Memory.PtrSize.fromSize(abi_size), | 10702 | .reg => |reg| switch (reg) { |
| 10704 | .{ .base = base, .disp = disp }, | 10703 | .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| 10705 | ); | 10704 | else => false, |
| 10706 | const src_alias = registerAlias(src_reg, abi_size); | 10705 | }, |
| 10707 | switch (try self.moveStrategy(ty, switch (base) { | 10706 | .frame => |frame_index| self.getFrameAddrAlignment( |
| 10708 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 10707 | .{ .index = frame_index, .off = disp }, |
| 10709 | .reg => |reg| switch (reg) { | 10708 | ).compare(.gte, ty.abiAlignment(mod)), |
| 10710 | .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 10709 | })).write( |
| 10711 | else => false, | 10710 | self, |
| 10712 | }, | 10711 | Memory.sib(self.memPtrSize(ty), .{ .base = base, .disp = disp }), |
| 10713 | .frame => |frame_index| self.getFrameAddrAlignment( | 10712 | registerAlias(src_reg, abi_size), |
| 10714 | .{ .index = frame_index, .off = disp }, | 10713 | ), |
| 10715 | ).compare(.gte, ty.abiAlignment(mod)), | | |
| 10716 | })) { | | |
| 10717 | .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias), | | |
| 10718 | .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate( | | |
| 10719 | ie.extract, | | |
| 10720 | dst_mem, | | |
| 10721 | src_alias, | | |
| 10722 | Immediate.u(0), | | |
| 10723 | ), | | |
| 10724 | } | | |
| 10725 | }, | | |
| 10726 | .register_pair => |src_regs| for (src_regs, 0..) |src_reg, src_reg_i| { | 10714 | .register_pair => |src_regs| for (src_regs, 0..) |src_reg, src_reg_i| { |
| 10727 | const part_size = @min(abi_size - src_reg_i * 8, 8); | 10715 | const part_size = @min(abi_size - src_reg_i * 8, 8); |
| 10728 | const dst_mem = Memory.sib( | 10716 | try (try self.moveStrategy(ty, switch (base) { |
| 10729 | Memory.PtrSize.fromSize(part_size), | | |
| 10730 | .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) }, | | |
| 10731 | ); | | |
| 10732 | const src_alias = registerAlias(src_reg, part_size); | | |
| 10733 | switch (try self.moveStrategy(ty, switch (base) { | | |
| 10734 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 10717 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| 10735 | .reg => |reg| switch (reg) { | 10718 | .reg => |reg| switch (reg) { |
| 10736 | .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 10719 | .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| ... | @@ -10739,15 +10722,10 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -10739,15 +10722,10 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 10739 | .frame => |frame_index| self.getFrameAddrAlignment( | 10722 | .frame => |frame_index| self.getFrameAddrAlignment( |
| 10740 | .{ .index = frame_index, .off = disp }, | 10723 | .{ .index = frame_index, .off = disp }, |
| 10741 | ).compare(.gte, ty.abiAlignment(mod)), | 10724 | ).compare(.gte, ty.abiAlignment(mod)), |
| 10742 | })) { | 10725 | })).write(self, Memory.sib( |
| 10743 | .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias), | 10726 | Memory.PtrSize.fromSize(part_size), |
| 10744 | .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate( | 10727 | .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) }, |
| 10745 | ie.extract, | 10728 | ), registerAlias(src_reg, part_size)); |
| 10746 | dst_mem, | | |
| 10747 | src_alias, | | |
| 10748 | Immediate.u(0), | | |
| 10749 | ), | | |
| 10750 | } | | |
| 10751 | }, | 10729 | }, |
| 10752 | .register_overflow => |ro| { | 10730 | .register_overflow => |ro| { |
| 10753 | try self.genSetMem( | 10731 | try self.genSetMem( |
| ... | @@ -12229,7 +12207,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12229,7 +12207,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 12229 | return self.finishAir(inst, result, buf); | 12207 | return self.finishAir(inst, result, buf); |
| 12230 | } | 12208 | } |
| 12231 | var bt = self.liveness.iterateBigTomb(inst); | 12209 | var bt = self.liveness.iterateBigTomb(inst); |
| 12232 | for (elements) |elem| self.feed(&bt, elem); | 12210 | for (elements) |elem| try self.feed(&bt, elem); |
| 12233 | return self.finishAirResult(inst, result); | 12211 | return self.finishAirResult(inst, result); |
| 12234 | } | 12212 | } |
| 12235 | | 12213 | |
| ... | @@ -12821,6 +12799,14 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { | ... | @@ -12821,6 +12799,14 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 12821 | }; | 12799 | }; |
| 12822 | } | 12800 | } |
| 12823 | | 12801 | |
| | 12802 | fn memPtrSize(self: *Self, ty: Type) Memory.PtrSize { |
| | 12803 | const mod = self.bin_file.options.module.?; |
| | 12804 | return switch (ty.zigTypeTag(mod)) { |
| | 12805 | .Float => Memory.PtrSize.fromBitSize(ty.floatBits(self.target.*)), |
| | 12806 | else => Memory.PtrSize.fromSize(@intCast(ty.abiSize(mod))), |
| | 12807 | }; |
| | 12808 | } |
| | 12809 | |
| 12824 | /// Truncates the value in the register in place. | 12810 | /// Truncates the value in the register in place. |
| 12825 | /// Clobbers any remaining bits. | 12811 | /// Clobbers any remaining bits. |
| 12826 | fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { | 12812 | fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |