authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-07 15:17:34+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-08 13:42:58+01:00
log0d556877af4d12e1e0d5c0146ab80273e91f211c
treeab7c9e6cffef99d9d705dc9d6ffda9ba3761cb48
parenta07449450f460dacd3ad4daa480e00c7bc9e9d7f

aarch64: implement .wrap_optional always saving to the stack


1 files changed, 28 insertions(+), 4 deletions(-)

src/arch/aarch64/CodeGen.zig+28-4
...@@ -3068,13 +3068,37 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {...@@ -3068,13 +3068,37 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
3068fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {3068fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3069 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3069 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3070 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3070 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3071 const payload_ty = self.air.typeOf(ty_op.operand);
3072 if (!payload_ty.hasRuntimeBits()) {
3073 break :result MCValue{ .immediate = 1 };
3074 }
3075
3071 const optional_ty = self.air.typeOfIndex(inst);3076 const optional_ty = self.air.typeOfIndex(inst);
3077 const operand = try self.resolveInst(ty_op.operand);
3078 const operand_lock: ?RegisterLock = switch (operand) {
3079 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
3080 else => null,
3081 };
3082 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
30723083
3073 // Optional with a zero-bit payload type is just a boolean true3084 if (optional_ty.isPtrLikeOptional()) {
3074 if (optional_ty.abiSize(self.target.*) == 1)3085 // TODO should we check if we can reuse the operand?
3075 break :result MCValue{ .immediate = 1 };3086 const raw_reg = try self.register_manager.allocReg(inst, gp);
3087 const reg = self.registerAlias(raw_reg, payload_ty);
3088 try self.genSetReg(payload_ty, raw_reg, operand);
3089 break :result MCValue{ .register = reg };
3090 }
30763091
3077 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});3092 const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*));
3093 const optional_abi_align = optional_ty.abiAlignment(self.target.*);
3094 const payload_abi_size = @intCast(u32, payload_ty.abiSize(self.target.*));
3095 const offset = optional_abi_size - payload_abi_size;
3096
3097 const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst);
3098 try self.genSetStack(Type.bool, stack_offset, .{ .immediate = 1 });
3099 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, offset), operand);
3100
3101 break :result MCValue{ .stack_offset = stack_offset };
3078 };3102 };
3079 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3103 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3080}3104}