authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-11-13 14:35:55+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-12-10 21:11:14+07:00
logfb9357f06c39622534e5a85fa3f1442deec84dc3
tree0c30cb552bbec2f026e2c5bd88836dc4127e132c
parent219b5f0ad6eada2174c20147a34b51986c8f44d5

stage2: sparc64: Implement atomic ops


3 files changed, 72 insertions(+), 7 deletions(-)

src/arch/sparc64/CodeGen.zig+70-7
......@@ -596,10 +596,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
596596 .array_to_slice => try self.airArrayToSlice(inst),
597597 .int_to_float => try self.airIntToFloat(inst),
598598 .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),
603604 .memcpy => @panic("TODO try self.airMemcpy(inst)"),
604605 .memset => try self.airMemset(inst),
605606 .set_union_tag => try self.airSetUnionTag(inst),
......@@ -1023,6 +1024,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
10231024 return self.finishAir(inst, mcv, .{ .none, .none, .none });
10241025}
10251026
1027fn 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
1035fn 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
10261043fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
10271044 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
10281045 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -1332,6 +1349,16 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
13321349 return self.finishAir(inst, result, .{ un_op, .none, .none });
13331350}
13341351
1352fn 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
13351362fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
13361363 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
13371364 const condition = try self.resolveInst(pl_op.operand);
......@@ -1416,6 +1443,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
14161443 const else_value = else_values[else_idx];
14171444 const canon_mcv = if (saved_then_branch.inst_table.fetchSwapRemove(else_key)) |then_entry| blk: {
14181445 // The instruction's MCValue is overridden in both branches.
1446 log.debug("condBr put branch table (key = %{d}, value = {})", .{ else_key, then_entry.value });
14191447 parent_branch.inst_table.putAssumeCapacity(else_key, then_entry.value);
14201448 if (else_value == .dead) {
14211449 assert(then_entry.value == .dead);
......@@ -2908,7 +2936,18 @@ fn binOpImmediate(
29082936
29092937 const reg = try self.register_manager.allocReg(track_inst, gp);
29102938
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 }
29122951
29132952 break :blk reg;
29142953 };
......@@ -3035,7 +3074,18 @@ fn binOpRegister(
30353074 } else null;
30363075
30373076 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 }
30393089
30403090 break :blk reg;
30413091 };
......@@ -3048,7 +3098,18 @@ fn binOpRegister(
30483098 } else null;
30493099
30503100 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 }
30523113
30533114 break :blk reg;
30543115 };
......@@ -3867,6 +3928,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
38673928 while (true) {
38683929 i -= 1;
38693930 if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| {
3931 log.debug("getResolvedInstValue %{} => {}", .{ inst, mcv });
38703932 assert(mcv != .dead);
38713933 return mcv;
38723934 }
......@@ -4082,6 +4144,7 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {
40824144 const prev_value = self.getResolvedInstValue(inst);
40834145 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
40844146 branch.inst_table.putAssumeCapacity(inst, .dead);
4147 log.debug("%{} death: {} -> .dead", .{ inst, prev_value });
40854148 switch (prev_value) {
40864149 .register => |reg| {
40874150 self.register_manager.freeReg(reg);
test/behavior/bugs/13159.zig+1
......@@ -9,6 +9,7 @@ const Bar = packed struct {
99};
1010
1111test {
12 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1213 var foo = Bar.Baz.fizz;
1314 try expect(foo == .fizz);
1415}
test/behavior/type.zig+1
......@@ -261,6 +261,7 @@ test "Type.Struct" {
261261 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
262262 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
263263 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
264 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
264265
265266 const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
266267 const infoA = @typeInfo(A).Struct;