stage2 ARM: implement comparison of optional pointers

This commit is contained in:
joachimschmidt557
2022-03-22 21:10:18 +01:00
committed by Andrew Kelley
parent 95e166b2e1
commit be1cca3416
2 changed files with 31 additions and 28 deletions

View File

@@ -3017,36 +3017,41 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const rhs = try self.resolveInst(bin_op.rhs);
const lhs_ty = self.air.typeOf(bin_op.lhs);
switch (lhs_ty.zigTypeTag()) {
.Optional => return self.fail("TODO ARM cmp optionals", .{}),
.Float => return self.fail("TODO ARM cmp floats", .{}),
.Int, .Bool, .Pointer, .ErrorSet, .Enum => {
var int_buffer: Type.Payload.Bits = undefined;
const int_ty = switch (lhs_ty.zigTypeTag()) {
.Enum => lhs_ty.intTagType(&int_buffer),
.Int => lhs_ty,
.Bool => Type.initTag(.u1),
.Pointer => Type.usize,
.ErrorSet => Type.initTag(.u16),
else => unreachable,
};
const int_info = int_ty.intInfo(self.target.*);
if (int_info.bits <= 32) {
try self.spillCompareFlagsIfOccupied();
self.compare_flags_inst = inst;
_ = try self.binOp(.cmp_eq, inst, lhs, rhs, int_ty, int_ty);
break :result switch (int_info.signedness) {
.signed => MCValue{ .compare_flags_signed = op },
.unsigned => MCValue{ .compare_flags_unsigned = op },
};
var int_buffer: Type.Payload.Bits = undefined;
const int_ty = switch (lhs_ty.zigTypeTag()) {
.Optional => blk: {
var opt_buffer: Type.Payload.ElemType = undefined;
const payload_ty = lhs_ty.optionalChild(&opt_buffer);
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
break :blk Type.initTag(.u1);
} else if (lhs_ty.isPtrLikeOptional()) {
break :blk Type.usize;
} else {
return self.fail("TODO ARM cmp for ints > 32 bits", .{});
return self.fail("TODO ARM cmp non-pointer optionals", .{});
}
},
.Float => return self.fail("TODO ARM cmp floats", .{}),
.Enum => lhs_ty.intTagType(&int_buffer),
.Int => lhs_ty,
.Bool => Type.initTag(.u1),
.Pointer => Type.usize,
.ErrorSet => Type.initTag(.u16),
else => unreachable,
};
const int_info = int_ty.intInfo(self.target.*);
if (int_info.bits <= 32) {
try self.spillCompareFlagsIfOccupied();
self.compare_flags_inst = inst;
_ = try self.binOp(.cmp_eq, inst, lhs, rhs, int_ty, int_ty);
break :result switch (int_info.signedness) {
.signed => MCValue{ .compare_flags_signed = op },
.unsigned => MCValue{ .compare_flags_unsigned = op },
};
} else {
return self.fail("TODO ARM cmp for ints > 32 bits", .{});
}
};
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });

View File

@@ -33,8 +33,6 @@ test "optional pointer to size zero struct" {
}
test "equality compare optional pointers" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
try testNullPtrsEql();
comptime try testNullPtrsEql();
}