From be1cca341629b0783be6754b2d7642afce936acb Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Tue, 22 Mar 2022 21:10:18 +0100 Subject: [PATCH] stage2 ARM: implement comparison of optional pointers --- src/arch/arm/CodeGen.zig | 57 +++++++++++++++++++++----------------- test/behavior/optional.zig | 2 -- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 87f6b9eb10..1e736a6e86 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -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 }); diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index d9c16da066..10d829a2c0 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -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(); }