| ... | ... | @@ -3017,36 +3017,41 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 3017 | 3017 | const rhs = try self.resolveInst(bin_op.rhs); |
| 3018 | 3018 | const lhs_ty = self.air.typeOf(bin_op.lhs); |
| 3019 | 3019 | |
| 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; |
| 3045 | 3029 | } else { |
| 3046 | | return self.fail("TODO ARM cmp for ints > 32 bits", .{}); |
| 3030 | return self.fail("TODO ARM cmp non-pointer optionals", .{}); |
| 3047 | 3031 | } |
| 3048 | 3032 | }, |
| 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), |
| 3049 | 3039 | 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", .{}); |
| 3050 | 3055 | } |
| 3051 | 3056 | }; |
| 3052 | 3057 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |