authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-07 11:54:06+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-08 13:42:58+01:00
log0de56d1722a50435696d7bdc8900ca4206e12d70
tree40fb310cef423a80775f18cc42e722dd49d23207
parentcd7cbed651524cdbdddcb69436ce348b1aa7a036

aarch64: partially implement optionalPayload()


1 files changed, 33 insertions(+), 1 deletions(-)

src/arch/aarch64/CodeGen.zig+33-1
...@@ -2882,10 +2882,42 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -2882,10 +2882,42 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
28822882
2883fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {2883fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
2884 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2884 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2885 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload for {}", .{self.target.cpu.arch});2885 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2886 const optional_ty = self.air.typeOf(ty_op.operand);
2887 const mcv = try self.resolveInst(ty_op.operand);
2888 break :result try self.optionalPayload(inst, mcv, optional_ty);
2889 };
2886 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });2890 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
2887}2891}
28882892
2893fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {
2894 var opt_buf: Type.Payload.ElemType = undefined;
2895 const payload_ty = optional_ty.optionalChild(&opt_buf);
2896 if (!payload_ty.hasRuntimeBits()) return MCValue.none;
2897 if (optional_ty.isPtrLikeOptional()) {
2898 // TODO should we reuse the operand here?
2899 const raw_reg = try self.register_manager.allocReg(inst, gp);
2900 const reg = self.registerAlias(raw_reg, payload_ty);
2901 try self.genSetReg(payload_ty, reg, mcv);
2902 return MCValue{ .register = reg };
2903 }
2904
2905 const offset = @intCast(u32, optional_ty.abiSize(self.target.*) - payload_ty.abiSize(self.target.*));
2906 switch (mcv) {
2907 .register => return self.fail("TODO optionalPayload for registers", .{}),
2908 .stack_argument_offset => |off| {
2909 return MCValue{ .stack_argument_offset = off + offset };
2910 },
2911 .stack_offset => |off| {
2912 return MCValue{ .stack_offset = off - offset };
2913 },
2914 .memory => |addr| {
2915 return MCValue{ .memory = addr + offset };
2916 },
2917 else => unreachable, // invalid MCValue for an error union
2918 }
2919}
2920
2889fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {2921fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
2890 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2922 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2891 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});2923 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});