| author | |
| committer | |
| log | 36bfe4b7efedd1b030c335151b2d6a61bbeab1eb |
| tree | 026c5e3204905780be6984bd5e372c17d8493b9f |
| parent | 18d61d691c0c28405a521422a590e6ea84d13c61 |
4 files changed, 52 insertions(+), 1 deletions(-)
src/arch/sparc64/CodeGen.zig+24-1| ... | @@ -578,7 +578,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -578,7 +578,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 578 | .breakpoint => try self.airBreakpoint(), | 578 | .breakpoint => try self.airBreakpoint(), |
| 579 | .ret_addr => @panic("TODO try self.airRetAddr(inst)"), | 579 | .ret_addr => @panic("TODO try self.airRetAddr(inst)"), |
| 580 | .frame_addr => @panic("TODO try self.airFrameAddress(inst)"), | 580 | .frame_addr => @panic("TODO try self.airFrameAddress(inst)"), |
| 581 | .fence => @panic("TODO try self.airFence()"), | 581 | .fence => try self.airFence(inst), |
| 582 | .cond_br => try self.airCondBr(inst), | 582 | .cond_br => try self.airCondBr(inst), |
| 583 | .dbg_stmt => try self.airDbgStmt(inst), | 583 | .dbg_stmt => try self.airDbgStmt(inst), |
| 584 | .fptrunc => @panic("TODO try self.airFptrunc(inst)"), | 584 | .fptrunc => @panic("TODO try self.airFptrunc(inst)"), |
| ... | @@ -1442,6 +1442,29 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1442,6 +1442,29 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void { |
| 1442 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1442 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1443 | } | 1443 | } |
| 1444 | 1444 | ||
| 1445 | fn airFence(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1446 | // TODO weaken this as needed, currently this implements the strongest membar form | ||
| 1447 | const fence = self.air.instructions.items(.data)[inst].fence; | ||
| 1448 | _ = fence; | ||
| 1449 | |||
| 1450 | // membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad | ||
| 1451 | _ = try self.addInst(.{ | ||
| 1452 | .tag = .membar, | ||
| 1453 | .data = .{ | ||
| 1454 | .membar_mask = .{ | ||
| 1455 | .mmask = .{ | ||
| 1456 | .store_store = true, | ||
| 1457 | .store_load = true, | ||
| 1458 | .load_store = true, | ||
| 1459 | .load_load = true, | ||
| 1460 | }, | ||
| 1461 | }, | ||
| 1462 | }, | ||
| 1463 | }); | ||
| 1464 | |||
| 1465 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | ||
| 1466 | } | ||
| 1467 | |||
| 1445 | fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { | 1468 | fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1446 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 1469 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 1447 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1470 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
src/arch/sparc64/Emit.zig+13| ... | @@ -98,6 +98,8 @@ pub fn emitMir( | ... | @@ -98,6 +98,8 @@ pub fn emitMir( |
| 98 | .xor => try emit.mirArithmetic3Op(inst), | 98 | .xor => try emit.mirArithmetic3Op(inst), |
| 99 | .xnor => try emit.mirArithmetic3Op(inst), | 99 | .xnor => try emit.mirArithmetic3Op(inst), |
| 100 | 100 | ||
| 101 | .membar => try emit.mirMembar(inst), | ||
| 102 | |||
| 101 | .movcc => try emit.mirConditionalMove(inst), | 103 | .movcc => try emit.mirConditionalMove(inst), |
| 102 | 104 | ||
| 103 | .movr => @panic("TODO implement sparc64 movr"), | 105 | .movr => @panic("TODO implement sparc64 movr"), |
| ... | @@ -342,6 +344,17 @@ fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -342,6 +344,17 @@ fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 342 | } | 344 | } |
| 343 | } | 345 | } |
| 344 | 346 | ||
| 347 | fn mirMembar(emit: *Emit, inst: Mir.Inst.Index) !void { | ||
| 348 | const tag = emit.mir.instructions.items(.tag)[inst]; | ||
| 349 | const mask = emit.mir.instructions.items(.data)[inst].membar_mask; | ||
| 350 | assert(tag == .membar); | ||
| 351 | |||
| 352 | try emit.writeInstruction(Instruction.membar( | ||
| 353 | mask.cmask, | ||
| 354 | mask.mmask, | ||
| 355 | )); | ||
| 356 | } | ||
| 357 | |||
| 345 | fn mirNop(emit: *Emit) !void { | 358 | fn mirNop(emit: *Emit) !void { |
| 346 | try emit.writeInstruction(Instruction.nop()); | 359 | try emit.writeInstruction(Instruction.nop()); |
| 347 | } | 360 | } |
src/arch/sparc64/Mir.zig+11| ... | @@ -78,6 +78,10 @@ pub const Inst = struct { | ... | @@ -78,6 +78,10 @@ pub const Inst = struct { |
| 78 | xor, | 78 | xor, |
| 79 | xnor, | 79 | xnor, |
| 80 | 80 | ||
| 81 | /// A.32 Memory Barrier | ||
| 82 | /// This uses the membar_mask field. | ||
| 83 | membar, | ||
| 84 | |||
| 81 | /// A.35 Move Integer Register on Condition (MOVcc) | 85 | /// A.35 Move Integer Register on Condition (MOVcc) |
| 82 | /// This uses the conditional_move_int field. | 86 | /// This uses the conditional_move_int field. |
| 83 | movcc, | 87 | movcc, |
| ... | @@ -236,6 +240,13 @@ pub const Inst = struct { | ... | @@ -236,6 +240,13 @@ pub const Inst = struct { |
| 236 | inst: Index, | 240 | inst: Index, |
| 237 | }, | 241 | }, |
| 238 | 242 | ||
| 243 | /// Membar mask, controls the barrier behavior | ||
| 244 | /// Used by e.g. membar | ||
| 245 | membar_mask: struct { | ||
| 246 | mmask: Instruction.MemOrderingConstraint = .{}, | ||
| 247 | cmask: Instruction.MemCompletionConstraint = .{}, | ||
| 248 | }, | ||
| 249 | |||
| 239 | /// Conditional move, checking the integer status code | 250 | /// Conditional move, checking the integer status code |
| 240 | /// if is_imm true then it uses the imm field of rs2_or_imm, | 251 | /// if is_imm true then it uses the imm field of rs2_or_imm, |
| 241 | /// otherwise it uses rs2 field. | 252 | /// otherwise it uses rs2 field. |
src/arch/sparc64/bits.zig+4| ... | @@ -1261,6 +1261,10 @@ pub const Instruction = union(enum) { | ... | @@ -1261,6 +1261,10 @@ pub const Instruction = union(enum) { |
| 1261 | }; | 1261 | }; |
| 1262 | } | 1262 | } |
| 1263 | 1263 | ||
| 1264 | pub fn membar(cmask: MemCompletionConstraint, mmask: MemOrderingConstraint) Instruction { | ||
| 1265 | return format3h(cmask, mmask); | ||
| 1266 | } | ||
| 1267 | |||
| 1264 | pub fn movcc(comptime s2: type, cond: Condition, ccr: CCR, rs2: s2, rd: Register) Instruction { | 1268 | pub fn movcc(comptime s2: type, cond: Condition, ccr: CCR, rs2: s2, rd: Register) Instruction { |
| 1265 | return switch (s2) { | 1269 | return switch (s2) { |
| 1266 | Register => format4c(0b10_1100, cond, ccr, rs2, rd), | 1270 | Register => format4c(0b10_1100, cond, ccr, rs2, rd), |