authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-04 19:54:00+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-05 10:37:08+02:00
logff00bbf4de0c6a91a1e98076ceb68d4cec127aee
treeb8f1c5edf4ad32c5c6da31fd29bd5e0d53e0b0b7
parent6da420419d79a735e88416056587c154b3cb3acd

x64: lower try and try_ptr


1 files changed, 68 insertions(+), 13 deletions(-)

src/arch/x86_64/CodeGen.zig+68-13
...@@ -681,8 +681,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -681,8 +681,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
681 .prefetch => try self.airPrefetch(inst),681 .prefetch => try self.airPrefetch(inst),
682 .mul_add => try self.airMulAdd(inst),682 .mul_add => try self.airMulAdd(inst),
683683
684 .@"try" => @panic("TODO"),684 .@"try" => try self.airTry(inst),
685 .try_ptr => @panic("TODO"),685 .try_ptr => try self.airTryPtr(inst),
686686
687 .dbg_var_ptr,687 .dbg_var_ptr,
688 .dbg_var_val,688 .dbg_var_val,
...@@ -1807,14 +1807,24 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -1807,14 +1807,24 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
1807 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1807 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
1808 }1808 }
1809 const err_union_ty = self.air.typeOf(ty_op.operand);1809 const err_union_ty = self.air.typeOf(ty_op.operand);
1810 const operand = try self.resolveInst(ty_op.operand);
1811 const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, operand);
1812 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1813}
1814
1815fn genUnwrapErrorUnionPayloadMir(
1816 self: *Self,
1817 maybe_inst: ?Air.Inst.Index,
1818 err_union_ty: Type,
1819 err_union: MCValue,
1820) !MCValue {
1810 const payload_ty = err_union_ty.errorUnionPayload();1821 const payload_ty = err_union_ty.errorUnionPayload();
1811 const err_ty = err_union_ty.errorUnionSet();1822 const err_ty = err_union_ty.errorUnionSet();
1812 const operand = try self.resolveInst(ty_op.operand);
18131823
1814 const result: MCValue = result: {1824 const result: MCValue = result: {
1815 if (err_ty.errorSetCardinality() == .zero) {1825 if (err_ty.errorSetCardinality() == .zero) {
1816 // TODO check if we can reuse1826 // TODO check if we can reuse
1817 break :result operand;1827 break :result err_union;
1818 }1828 }
18191829
1820 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1830 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
...@@ -1822,7 +1832,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -1822,7 +1832,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
1822 }1832 }
18231833
1824 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);1834 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
1825 switch (operand) {1835 switch (err_union) {
1826 .stack_offset => |off| {1836 .stack_offset => |off| {
1827 const offset = off - @intCast(i32, payload_off);1837 const offset = off - @intCast(i32, payload_off);
1828 break :result MCValue{ .stack_offset = offset };1838 break :result MCValue{ .stack_offset = offset };
...@@ -1831,19 +1841,23 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -1831,19 +1841,23 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
1831 // TODO reuse operand1841 // TODO reuse operand
1832 const lock = self.register_manager.lockRegAssumeUnused(reg);1842 const lock = self.register_manager.lockRegAssumeUnused(reg);
1833 defer self.register_manager.unlockReg(lock);1843 defer self.register_manager.unlockReg(lock);
1834 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);1844 const result_reg: Register = if (maybe_inst) |inst|
1845 (try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union)).register
1846 else
1847 try self.copyToTmpRegister(err_union_ty, err_union);
1835 if (payload_off > 0) {1848 if (payload_off > 0) {
1836 const shift = @intCast(u6, payload_off * 8);1849 const shift = @intCast(u6, payload_off * 8);
1837 try self.genShiftBinOpMir(.shr, err_union_ty, result.register, .{ .immediate = shift });1850 try self.genShiftBinOpMir(.shr, err_union_ty, result_reg, .{ .immediate = shift });
1838 } else {1851 } else {
1839 try self.truncateRegister(payload_ty, result.register);1852 try self.truncateRegister(payload_ty, result_reg);
1840 }1853 }
1841 break :result result;1854 break :result MCValue{ .register = result_reg };
1842 },1855 },
1843 else => return self.fail("TODO implement unwrap_err_payload for {}", .{operand}),1856 else => return self.fail("TODO implement genUnwrapErrorUnionPayloadMir for {}", .{err_union}),
1844 }1857 }
1845 };1858 };
1846 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1859
1860 return result;
1847}1861}
18481862
1849// *(E!T) -> E1863// *(E!T) -> E
...@@ -4231,6 +4245,45 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -4231,6 +4245,45 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
4231 return self.finishAir(inst, result, .{ un_op, .none, .none });4245 return self.finishAir(inst, result, .{ un_op, .none, .none });
4232}4246}
42334247
4248fn airTry(self: *Self, inst: Air.Inst.Index) !void {
4249 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
4250 const extra = self.air.extraData(Air.Try, pl_op.payload);
4251 const body = self.air.extra[extra.end..][0..extra.data.body_len];
4252 const err_union_ty = self.air.typeOf(pl_op.operand);
4253 const err_union = try self.resolveInst(pl_op.operand);
4254 const result = try self.genTry(inst, err_union, body, err_union_ty, false);
4255 return self.finishAir(inst, result, .{ pl_op.operand, .none, .none });
4256}
4257
4258fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
4259 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4260 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
4261 const body = self.air.extra[extra.end..][0..extra.data.body_len];
4262 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
4263 const err_union_ptr = try self.resolveInst(extra.data.ptr);
4264 const result = try self.genTry(inst, err_union_ptr, body, err_union_ty, true);
4265 return self.finishAir(inst, result, .{ extra.data.ptr, .none, .none });
4266}
4267
4268fn genTry(
4269 self: *Self,
4270 inst: Air.Inst.Index,
4271 err_union: MCValue,
4272 body: []const Air.Inst.Index,
4273 err_union_ty: Type,
4274 operand_is_ptr: bool,
4275) !MCValue {
4276 if (operand_is_ptr) {
4277 return self.fail("TODO genTry for pointers", .{});
4278 }
4279 const is_err_mcv = try self.isErr(null, err_union_ty, err_union);
4280 const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv);
4281 try self.genBody(body);
4282 try self.performReloc(reloc);
4283 const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, err_union);
4284 return result;
4285}
4286
4234fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {4287fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
4235 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;4288 const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
4236 const payload = try self.addExtra(Mir.DbgLineColumn{4289 const payload = try self.addExtra(Mir.DbgLineColumn{
...@@ -4596,7 +4649,7 @@ fn isNonNull(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCV...@@ -4596,7 +4649,7 @@ fn isNonNull(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCV
4596 return MCValue{ .eflags = is_null_res.eflags.negate() };4649 return MCValue{ .eflags = is_null_res.eflags.negate() };
4597}4650}
45984651
4599fn isErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {4652fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {
4600 const err_type = ty.errorUnionSet();4653 const err_type = ty.errorUnionSet();
46014654
4602 if (err_type.errorSetCardinality() == .zero) {4655 if (err_type.errorSetCardinality() == .zero) {
...@@ -4604,7 +4657,9 @@ fn isErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue...@@ -4604,7 +4657,9 @@ fn isErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue
4604 }4657 }
46054658
4606 try self.spillEflagsIfOccupied();4659 try self.spillEflagsIfOccupied();
4607 self.eflags_inst = inst;4660 if (maybe_inst) |inst| {
4661 self.eflags_inst = inst;
4662 }
46084663
4609 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), self.target.*);4664 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), self.target.*);
4610 switch (operand) {4665 switch (operand) {