Commit 8ea80fdf7a

Koakuma <koachan@protonmail.com>
2022-05-16 18:03:50
stage2: sparc64: Implement airLoop
1 parent e4a725c
Changed files (1)
src
arch
sparc64
src/arch/sparc64/CodeGen.zig
@@ -564,7 +564,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
             .is_err          => try self.airIsErr(inst),
             .is_err_ptr      => @panic("TODO try self.airIsErrPtr(inst)"),
             .load            => try self.airLoad(inst),
-            .loop            => @panic("TODO try self.airLoop(inst)"),
+            .loop            => try self.airLoop(inst),
             .not             => @panic("TODO try self.airNot(inst)"),
             .ptrtoint        => @panic("TODO try self.airPtrToInt(inst)"),
             .ret             => try self.airRet(inst),
@@ -1342,6 +1342,17 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
     return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
 }
 
+fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
+    // A loop is a setup to be able to jump back to the beginning.
+    const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+    const loop = self.air.extraData(Air.Block, ty_pl.payload);
+    const body = self.air.extra[loop.end .. loop.end + loop.data.body_len];
+    const start = @intCast(u32, self.mir_instructions.len);
+    try self.genBody(body);
+    try self.jump(start);
+    return self.finishAirBookkeeping();
+}
+
 fn airRet(self: *Self, inst: Air.Inst.Index) !void {
     const un_op = self.air.instructions.items(.data)[inst].un_op;
     const operand = try self.resolveInst(un_op);
@@ -2231,6 +2242,26 @@ fn iterateBigTomb(self: *Self, inst: Air.Inst.Index, operand_count: usize) !BigT
     };
 }
 
+/// Send control flow to `inst`.
+fn jump(self: *Self, inst: Mir.Inst.Index) !void {
+    _ = try self.addInst(.{
+        .tag = .bpcc,
+        .data = .{
+            .branch_predict_int = .{
+                .cond = .al,
+                .ccr = .xcc,
+                .inst = inst,
+            },
+        },
+    });
+
+    // TODO find out a way to fill this delay slot
+    _ = try self.addInst(.{
+        .tag = .nop,
+        .data = .{ .nop = {} },
+    });
+}
+
 fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
     const elem_ty = ptr_ty.elemType();
     const elem_size = elem_ty.abiSize(self.target.*);