authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-07 10:51:52+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-08 13:42:58+01:00
logcd7cbed651524cdbdddcb69436ce348b1aa7a036
treed02d20f7a3ef16a54d2bacddff1cf98cf9c6049a
parent7d48cb11389f5dfe73d25e59c1038398a8ba9ca9

aarch64: partially implement isNull()


1 files changed, 23 insertions(+), 16 deletions(-)

src/arch/aarch64/CodeGen.zig+23-16
...@@ -4562,18 +4562,21 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4562,18 +4562,21 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4562 return self.finishAir(inst, .unreach, .{ .none, .none, .none });4562 return self.finishAir(inst, .unreach, .{ .none, .none, .none });
4563}4563}
45644564
4565fn isNull(self: *Self, operand: MCValue) !MCValue {4565fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
4566 _ = operand;4566 if (operand_ty.isPtrLikeOptional()) {
4567 // Here you can specialize this instruction if it makes sense to, otherwise the default4567 assert(operand_ty.abiSize(self.target.*) == 8);
4568 // will call isNonNull and invert the result.4568
4569 return self.fail("TODO call isNonNull and invert the result", .{});4569 const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };
4570 return self.cmp(operand_bind, imm_bind, Type.usize, .eq);
4571 } else {
4572 return self.fail("TODO implement non-pointer optionals", .{});
4573 }
4570}4574}
45714575
4572fn isNonNull(self: *Self, operand: MCValue) !MCValue {4576fn isNonNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
4573 _ = operand;4577 const is_null_res = try self.isNull(operand_bind, operand_ty);
4574 // Here you can specialize this instruction if it makes sense to, otherwise the default4578 assert(is_null_res.compare_flags == .eq);
4575 // will call isNull and invert the result.4579 return MCValue{ .compare_flags = is_null_res.compare_flags.negate() };
4576 return self.fail("TODO call isNull and invert the result", .{});
4577}4580}
45784581
4579fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {4582fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
...@@ -4605,8 +4608,10 @@ fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue {...@@ -4605,8 +4608,10 @@ fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
4605fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {4608fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
4606 const un_op = self.air.instructions.items(.data)[inst].un_op;4609 const un_op = self.air.instructions.items(.data)[inst].un_op;
4607 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4610 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4608 const operand = try self.resolveInst(un_op);4611 const operand_bind: ReadArg.Bind = .{ .inst = un_op };
4609 break :result try self.isNull(operand);4612 const operand_ty = self.air.typeOf(un_op);
4613
4614 break :result try self.isNull(operand_bind, operand_ty);
4610 };4615 };
4611 return self.finishAir(inst, result, .{ un_op, .none, .none });4616 return self.finishAir(inst, result, .{ un_op, .none, .none });
4612}4617}
...@@ -4621,7 +4626,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4621,7 +4626,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4621 const operand = try self.allocRegOrMem(elem_ty, true, null);4626 const operand = try self.allocRegOrMem(elem_ty, true, null);
4622 try self.load(operand, operand_ptr, ptr_ty);4627 try self.load(operand, operand_ptr, ptr_ty);
46234628
4624 break :result try self.isNull(operand);4629 break :result try self.isNull(.{ .mcv = operand }, elem_ty);
4625 };4630 };
4626 return self.finishAir(inst, result, .{ un_op, .none, .none });4631 return self.finishAir(inst, result, .{ un_op, .none, .none });
4627}4632}
...@@ -4629,8 +4634,10 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4629,8 +4634,10 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4629fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {4634fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
4630 const un_op = self.air.instructions.items(.data)[inst].un_op;4635 const un_op = self.air.instructions.items(.data)[inst].un_op;
4631 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4636 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4632 const operand = try self.resolveInst(un_op);4637 const operand_bind: ReadArg.Bind = .{ .inst = un_op };
4633 break :result try self.isNonNull(operand);4638 const operand_ty = self.air.typeOf(un_op);
4639
4640 break :result try self.isNonNull(operand_bind, operand_ty);
4634 };4641 };
4635 return self.finishAir(inst, result, .{ un_op, .none, .none });4642 return self.finishAir(inst, result, .{ un_op, .none, .none });
4636}4643}
...@@ -4645,7 +4652,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4645,7 +4652,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4645 const operand = try self.allocRegOrMem(elem_ty, true, null);4652 const operand = try self.allocRegOrMem(elem_ty, true, null);
4646 try self.load(operand, operand_ptr, ptr_ty);4653 try self.load(operand, operand_ptr, ptr_ty);
46474654
4648 break :result try self.isNonNull(operand);4655 break :result try self.isNonNull(.{ .mcv = operand }, elem_ty);
4649 };4656 };
4650 return self.finishAir(inst, result, .{ un_op, .none, .none });4657 return self.finishAir(inst, result, .{ un_op, .none, .none });
4651}4658}