authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-22 21:10:18+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 20:16:05-07:00
logbe1cca341629b0783be6754b2d7642afce936acb
tree514f812dd4a230bd91e320927ee8a8b2e05ae256
parent95e166b2e1609e93b472324c91b2d360abd595c2

stage2 ARM: implement comparison of optional pointers


2 files changed, 31 insertions(+), 28 deletions(-)

src/arch/arm/CodeGen.zig+31-26
......@@ -3017,36 +3017,41 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
30173017 const rhs = try self.resolveInst(bin_op.rhs);
30183018 const lhs_ty = self.air.typeOf(bin_op.lhs);
30193019
3020 switch (lhs_ty.zigTypeTag()) {
3021 .Optional => return self.fail("TODO ARM cmp optionals", .{}),
3022 .Float => return self.fail("TODO ARM cmp floats", .{}),
3023 .Int, .Bool, .Pointer, .ErrorSet, .Enum => {
3024 var int_buffer: Type.Payload.Bits = undefined;
3025 const int_ty = switch (lhs_ty.zigTypeTag()) {
3026 .Enum => lhs_ty.intTagType(&int_buffer),
3027 .Int => lhs_ty,
3028 .Bool => Type.initTag(.u1),
3029 .Pointer => Type.usize,
3030 .ErrorSet => Type.initTag(.u16),
3031 else => unreachable,
3032 };
3033
3034 const int_info = int_ty.intInfo(self.target.*);
3035 if (int_info.bits <= 32) {
3036 try self.spillCompareFlagsIfOccupied();
3037 self.compare_flags_inst = inst;
3038
3039 _ = try self.binOp(.cmp_eq, inst, lhs, rhs, int_ty, int_ty);
3040
3041 break :result switch (int_info.signedness) {
3042 .signed => MCValue{ .compare_flags_signed = op },
3043 .unsigned => MCValue{ .compare_flags_unsigned = op },
3044 };
3020 var int_buffer: Type.Payload.Bits = undefined;
3021 const int_ty = switch (lhs_ty.zigTypeTag()) {
3022 .Optional => blk: {
3023 var opt_buffer: Type.Payload.ElemType = undefined;
3024 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
3025 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3026 break :blk Type.initTag(.u1);
3027 } else if (lhs_ty.isPtrLikeOptional()) {
3028 break :blk Type.usize;
30453029 } else {
3046 return self.fail("TODO ARM cmp for ints > 32 bits", .{});
3030 return self.fail("TODO ARM cmp non-pointer optionals", .{});
30473031 }
30483032 },
3033 .Float => return self.fail("TODO ARM cmp floats", .{}),
3034 .Enum => lhs_ty.intTagType(&int_buffer),
3035 .Int => lhs_ty,
3036 .Bool => Type.initTag(.u1),
3037 .Pointer => Type.usize,
3038 .ErrorSet => Type.initTag(.u16),
30493039 else => unreachable,
3040 };
3041
3042 const int_info = int_ty.intInfo(self.target.*);
3043 if (int_info.bits <= 32) {
3044 try self.spillCompareFlagsIfOccupied();
3045 self.compare_flags_inst = inst;
3046
3047 _ = try self.binOp(.cmp_eq, inst, lhs, rhs, int_ty, int_ty);
3048
3049 break :result switch (int_info.signedness) {
3050 .signed => MCValue{ .compare_flags_signed = op },
3051 .unsigned => MCValue{ .compare_flags_unsigned = op },
3052 };
3053 } else {
3054 return self.fail("TODO ARM cmp for ints > 32 bits", .{});
30503055 }
30513056 };
30523057 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
test/behavior/optional.zig-2
......@@ -33,8 +33,6 @@ test "optional pointer to size zero struct" {
3333}
3434
3535test "equality compare optional pointers" {
36 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
37
3836 try testNullPtrsEql();
3937 comptime try testNullPtrsEql();
4038}