| ... | ... | @@ -596,10 +596,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 596 | 596 | .array_to_slice => try self.airArrayToSlice(inst), |
| 597 | 597 | .int_to_float => try self.airIntToFloat(inst), |
| 598 | 598 | .float_to_int => try self.airFloatToInt(inst), |
| 599 | | .cmpxchg_strong => @panic("TODO try self.airCmpxchg(inst)"), |
| 600 | | .cmpxchg_weak => @panic("TODO try self.airCmpxchg(inst)"), |
| 601 | | .atomic_rmw => @panic("TODO try self.airAtomicRmw(inst)"), |
| 602 | | .atomic_load => @panic("TODO try self.airAtomicLoad(inst)"), |
| 599 | .cmpxchg_strong, |
| 600 | .cmpxchg_weak, |
| 601 | => try self.airCmpxchg(inst), |
| 602 | .atomic_rmw => try self.airAtomicRmw(inst), |
| 603 | .atomic_load => try self.airAtomicLoad(inst), |
| 603 | 604 | .memcpy => @panic("TODO try self.airMemcpy(inst)"), |
| 604 | 605 | .memset => try self.airMemset(inst), |
| 605 | 606 | .set_union_tag => try self.airSetUnionTag(inst), |
| ... | ... | @@ -1023,6 +1024,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1023 | 1024 | return self.finishAir(inst, mcv, .{ .none, .none, .none }); |
| 1024 | 1025 | } |
| 1025 | 1026 | |
| 1027 | fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1028 | _ = self.air.instructions.items(.data)[inst].atomic_load; |
| 1029 | |
| 1030 | return self.fail("TODO implement airAtomicLoad for {}", .{ |
| 1031 | self.target.cpu.arch, |
| 1032 | }); |
| 1033 | } |
| 1034 | |
| 1035 | fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void { |
| 1036 | _ = self.air.instructions.items(.data)[inst].pl_op; |
| 1037 | |
| 1038 | return self.fail("TODO implement airAtomicRmw for {}", .{ |
| 1039 | self.target.cpu.arch, |
| 1040 | }); |
| 1041 | } |
| 1042 | |
| 1026 | 1043 | fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 1027 | 1044 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1028 | 1045 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -1332,6 +1349,16 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 1332 | 1349 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 1333 | 1350 | } |
| 1334 | 1351 | |
| 1352 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 1353 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1354 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 1355 | _ = extra; |
| 1356 | |
| 1357 | return self.fail("TODO implement airCmpxchg for {}", .{ |
| 1358 | self.target.cpu.arch, |
| 1359 | }); |
| 1360 | } |
| 1361 | |
| 1335 | 1362 | fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 1336 | 1363 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1337 | 1364 | const condition = try self.resolveInst(pl_op.operand); |
| ... | ... | @@ -1416,6 +1443,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 1416 | 1443 | const else_value = else_values[else_idx]; |
| 1417 | 1444 | const canon_mcv = if (saved_then_branch.inst_table.fetchSwapRemove(else_key)) |then_entry| blk: { |
| 1418 | 1445 | // The instruction's MCValue is overridden in both branches. |
| 1446 | log.debug("condBr put branch table (key = %{d}, value = {})", .{ else_key, then_entry.value }); |
| 1419 | 1447 | parent_branch.inst_table.putAssumeCapacity(else_key, then_entry.value); |
| 1420 | 1448 | if (else_value == .dead) { |
| 1421 | 1449 | assert(then_entry.value == .dead); |
| ... | ... | @@ -2908,7 +2936,18 @@ fn binOpImmediate( |
| 2908 | 2936 | |
| 2909 | 2937 | const reg = try self.register_manager.allocReg(track_inst, gp); |
| 2910 | 2938 | |
| 2911 | | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); |
| 2939 | if (track_inst) |inst| { |
| 2940 | const mcv = .{ .register = reg }; |
| 2941 | log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv }); |
| 2942 | branch.inst_table.putAssumeCapacity(inst, mcv); |
| 2943 | |
| 2944 | // If we're moving a condition flag MCV to register, |
| 2945 | // mark it as free. |
| 2946 | if (lhs == .condition_flags) { |
| 2947 | assert(self.condition_flags_inst.? == inst); |
| 2948 | self.condition_flags_inst = null; |
| 2949 | } |
| 2950 | } |
| 2912 | 2951 | |
| 2913 | 2952 | break :blk reg; |
| 2914 | 2953 | }; |
| ... | ... | @@ -3035,7 +3074,18 @@ fn binOpRegister( |
| 3035 | 3074 | } else null; |
| 3036 | 3075 | |
| 3037 | 3076 | const reg = try self.register_manager.allocReg(track_inst, gp); |
| 3038 | | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); |
| 3077 | if (track_inst) |inst| { |
| 3078 | const mcv = .{ .register = reg }; |
| 3079 | log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv }); |
| 3080 | branch.inst_table.putAssumeCapacity(inst, mcv); |
| 3081 | |
| 3082 | // If we're moving a condition flag MCV to register, |
| 3083 | // mark it as free. |
| 3084 | if (lhs == .condition_flags) { |
| 3085 | assert(self.condition_flags_inst.? == inst); |
| 3086 | self.condition_flags_inst = null; |
| 3087 | } |
| 3088 | } |
| 3039 | 3089 | |
| 3040 | 3090 | break :blk reg; |
| 3041 | 3091 | }; |
| ... | ... | @@ -3048,7 +3098,18 @@ fn binOpRegister( |
| 3048 | 3098 | } else null; |
| 3049 | 3099 | |
| 3050 | 3100 | const reg = try self.register_manager.allocReg(track_inst, gp); |
| 3051 | | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); |
| 3101 | if (track_inst) |inst| { |
| 3102 | const mcv = .{ .register = reg }; |
| 3103 | log.debug("binOpRegister move rhs %{d} to register: {} -> {}", .{ inst, rhs, mcv }); |
| 3104 | branch.inst_table.putAssumeCapacity(inst, mcv); |
| 3105 | |
| 3106 | // If we're moving a condition flag MCV to register, |
| 3107 | // mark it as free. |
| 3108 | if (rhs == .condition_flags) { |
| 3109 | assert(self.condition_flags_inst.? == inst); |
| 3110 | self.condition_flags_inst = null; |
| 3111 | } |
| 3112 | } |
| 3052 | 3113 | |
| 3053 | 3114 | break :blk reg; |
| 3054 | 3115 | }; |
| ... | ... | @@ -3867,6 +3928,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 3867 | 3928 | while (true) { |
| 3868 | 3929 | i -= 1; |
| 3869 | 3930 | if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| { |
| 3931 | log.debug("getResolvedInstValue %{} => {}", .{ inst, mcv }); |
| 3870 | 3932 | assert(mcv != .dead); |
| 3871 | 3933 | return mcv; |
| 3872 | 3934 | } |
| ... | ... | @@ -4082,6 +4144,7 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void { |
| 4082 | 4144 | const prev_value = self.getResolvedInstValue(inst); |
| 4083 | 4145 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 4084 | 4146 | branch.inst_table.putAssumeCapacity(inst, .dead); |
| 4147 | log.debug("%{} death: {} -> .dead", .{ inst, prev_value }); |
| 4085 | 4148 | switch (prev_value) { |
| 4086 | 4149 | .register => |reg| { |
| 4087 | 4150 | self.register_manager.freeReg(reg); |