Commit be6718b796

Koakuma <koachan@protonmail.com>
2022-06-19 05:38:00
stage2: sparc64: Implement airIsNull/airIsNonNull
1 parent 4d15284
Changed files (1)
src
arch
sparc64
src/arch/sparc64/CodeGen.zig
@@ -586,9 +586,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
             .intcast         => try self.airIntCast(inst),
             .trunc           => @panic("TODO try self.airTrunc(inst)"),
             .bool_to_int     => @panic("TODO try self.airBoolToInt(inst)"),
-            .is_non_null     => @panic("TODO try self.airIsNonNull(inst)"),
+            .is_non_null     => try self.airIsNonNull(inst),
             .is_non_null_ptr => @panic("TODO try self.airIsNonNullPtr(inst)"),
-            .is_null         => @panic("TODO try self.airIsNull(inst)"),
+            .is_null         => try self.airIsNull(inst),
             .is_null_ptr     => @panic("TODO try self.airIsNullPtr(inst)"),
             .is_non_err      => try self.airIsNonErr(inst),
             .is_non_err_ptr  => @panic("TODO try self.airIsNonErrPtr(inst)"),
@@ -1503,6 +1503,24 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
     return self.finishAir(inst, result, .{ un_op, .none, .none });
 }
 
+fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
+    const un_op = self.air.instructions.items(.data)[inst].un_op;
+    const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
+        const operand = try self.resolveInst(un_op);
+        break :result try self.isNull(operand);
+    };
+    return self.finishAir(inst, result, .{ un_op, .none, .none });
+}
+
+fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
+    const un_op = self.air.instructions.items(.data)[inst].un_op;
+    const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
+        const operand = try self.resolveInst(un_op);
+        break :result try self.isNonNull(operand);
+    };
+    return self.finishAir(inst, result, .{ un_op, .none, .none });
+}
+
 fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
     const ty_op = self.air.instructions.items(.data)[inst].ty_op;
     const elem_ty = self.air.typeOfIndex(inst);
@@ -3290,6 +3308,28 @@ fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
     }
 }
 
+fn isNull(self: *Self, operand: MCValue) !MCValue {
+    _ = operand;
+    // Here you can specialize this instruction if it makes sense to, otherwise the default
+    // will call isNonNull and invert the result.
+    return self.fail("TODO call isNonNull and invert the result", .{});
+}
+
+fn isNonNull(self: *Self, operand: MCValue) !MCValue {
+    // Call isNull, then negate the result.
+    const is_null_result = try self.isNull(operand);
+    switch (is_null_result) {
+        .condition_flags => |op| {
+            return MCValue{ .condition_flags = .{ .cond = op.cond.negate(), .ccr = op.ccr } };
+        },
+        .immediate => |imm| {
+            assert(imm == 0);
+            return MCValue{ .immediate = 1 };
+        },
+        else => unreachable,
+    }
+}
+
 fn iterateBigTomb(self: *Self, inst: Air.Inst.Index, operand_count: usize) !BigTomb {
     try self.ensureProcessDeathCapacity(operand_count + 1);
     return BigTomb{