| ... | @@ -514,10 +514,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -514,10 +514,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 514 | .bit_or => try self.airBinOp(inst, .bit_or), | 514 | .bit_or => try self.airBinOp(inst, .bit_or), |
| 515 | .xor => try self.airBinOp(inst, .xor), | 515 | .xor => try self.airBinOp(inst, .xor), |
| 516 | | 516 | |
| 517 | .add_sat => @panic("TODO try self.airAddSat(inst)"), | 517 | .add_sat => try self.airAddSat(inst), |
| 518 | .sub_sat => @panic("TODO try self.airSubSat(inst)"), | 518 | .sub_sat => try self.airSubSat(inst), |
| 519 | .mul_sat => @panic("TODO try self.airMulSat(inst)"), | 519 | .mul_sat => try self.airMulSat(inst), |
| 520 | .shl_sat => @panic("TODO try self.airShlSat(inst)"), | 520 | .shl_sat => try self.airShlSat(inst), |
| 521 | .min => @panic("TODO try self.airMin(inst)"), | 521 | .min => @panic("TODO try self.airMin(inst)"), |
| 522 | .max => @panic("TODO try self.airMax(inst)"), | 522 | .max => @panic("TODO try self.airMax(inst)"), |
| 523 | .rem => try self.airRem(inst), | 523 | .rem => try self.airRem(inst), |
| ... | @@ -539,7 +539,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -539,7 +539,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 539 | .round, | 539 | .round, |
| 540 | .trunc_float, | 540 | .trunc_float, |
| 541 | .neg, | 541 | .neg, |
| 542 | => @panic("TODO try self.airUnaryMath(inst)"), | 542 | => try self.airUnaryMath(inst), |
| 543 | | 543 | |
| 544 | .add_with_overflow => try self.airAddSubWithOverflow(inst), | 544 | .add_with_overflow => try self.airAddSubWithOverflow(inst), |
| 545 | .sub_with_overflow => try self.airAddSubWithOverflow(inst), | 545 | .sub_with_overflow => try self.airAddSubWithOverflow(inst), |
| ... | @@ -605,7 +605,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -605,7 +605,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 605 | .get_union_tag => @panic("TODO try self.airGetUnionTag(inst)"), | 605 | .get_union_tag => @panic("TODO try self.airGetUnionTag(inst)"), |
| 606 | .clz => try self.airClz(inst), | 606 | .clz => try self.airClz(inst), |
| 607 | .ctz => try self.airCtz(inst), | 607 | .ctz => try self.airCtz(inst), |
| 608 | .popcount => @panic("TODO try self.airPopcount(inst)"), | 608 | .popcount => try self.airPopcount(inst), |
| 609 | .byte_swap => @panic("TODO try self.airByteSwap(inst)"), | 609 | .byte_swap => @panic("TODO try self.airByteSwap(inst)"), |
| 610 | .bit_reverse => @panic("TODO try self.airBitReverse(inst)"), | 610 | .bit_reverse => @panic("TODO try self.airBitReverse(inst)"), |
| 611 | .tag_name => try self.airTagName(inst), | 611 | .tag_name => try self.airTagName(inst), |
| ... | @@ -616,7 +616,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -616,7 +616,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 616 | .reduce => @panic("TODO try self.airReduce(inst)"), | 616 | .reduce => @panic("TODO try self.airReduce(inst)"), |
| 617 | .aggregate_init => try self.airAggregateInit(inst), | 617 | .aggregate_init => try self.airAggregateInit(inst), |
| 618 | .union_init => @panic("TODO try self.airUnionInit(inst)"), | 618 | .union_init => @panic("TODO try self.airUnionInit(inst)"), |
| 619 | .prefetch => @panic("TODO try self.airPrefetch(inst)"), | 619 | .prefetch => try self.airPrefetch(inst), |
| 620 | .mul_add => @panic("TODO try self.airMulAdd(inst)"), | 620 | .mul_add => @panic("TODO try self.airMulAdd(inst)"), |
| 621 | | 621 | |
| 622 | .@"try" => try self.airTry(inst), | 622 | .@"try" => try self.airTry(inst), |
| ... | @@ -661,16 +661,16 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -661,16 +661,16 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 661 | .array_elem_val => try self.airArrayElemVal(inst), | 661 | .array_elem_val => try self.airArrayElemVal(inst), |
| 662 | .slice_elem_val => try self.airSliceElemVal(inst), | 662 | .slice_elem_val => try self.airSliceElemVal(inst), |
| 663 | .slice_elem_ptr => @panic("TODO try self.airSliceElemPtr(inst)"), | 663 | .slice_elem_ptr => @panic("TODO try self.airSliceElemPtr(inst)"), |
| 664 | .ptr_elem_val => @panic("TODO try self.airPtrElemVal(inst)"), | 664 | .ptr_elem_val => try self.airPtrElemVal(inst), |
| 665 | .ptr_elem_ptr => try self.airPtrElemPtr(inst), | 665 | .ptr_elem_ptr => try self.airPtrElemPtr(inst), |
| 666 | | 666 | |
| 667 | .constant => unreachable, // excluded from function bodies | 667 | .constant => unreachable, // excluded from function bodies |
| 668 | .const_ty => unreachable, // excluded from function bodies | 668 | .const_ty => unreachable, // excluded from function bodies |
| 669 | .unreach => self.finishAirBookkeeping(), | 669 | .unreach => self.finishAirBookkeeping(), |
| 670 | | 670 | |
| 671 | .optional_payload => @panic("TODO try self.airOptionalPayload(inst)"), | 671 | .optional_payload => try self.airOptionalPayload(inst), |
| 672 | .optional_payload_ptr => @panic("TODO try self.airOptionalPayloadPtr(inst)"), | 672 | .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), |
| 673 | .optional_payload_ptr_set => @panic("TODO try self.airOptionalPayloadPtrSet(inst)"), | 673 | .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), |
| 674 | .unwrap_errunion_err => try self.airUnwrapErrErr(inst), | 674 | .unwrap_errunion_err => try self.airUnwrapErrErr(inst), |
| 675 | .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst), | 675 | .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst), |
| 676 | .unwrap_errunion_err_ptr => @panic("TODO try self.airUnwrapErrErrPtr(inst)"), | 676 | .unwrap_errunion_err_ptr => @panic("TODO try self.airUnwrapErrErrPtr(inst)"), |
| ... | @@ -725,6 +725,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -725,6 +725,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 725 | } | 725 | } |
| 726 | } | 726 | } |
| 727 | | 727 | |
| | 728 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| | 729 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 730 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch}); |
| | 731 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| | 732 | } |
| | 733 | |
| 728 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 734 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 729 | const tag = self.air.instructions.items(.tag)[inst]; | 735 | const tag = self.air.instructions.items(.tag)[inst]; |
| 730 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 736 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -1805,6 +1811,12 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1805,6 +1811,12 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { |
| 1805 | return self.finishAir(inst, .{ .register = mod_reg }, .{ bin_op.lhs, bin_op.rhs, .none }); | 1811 | return self.finishAir(inst, .{ .register = mod_reg }, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1806 | } | 1812 | } |
| 1807 | | 1813 | |
| | 1814 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| | 1815 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 1816 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch}); |
| | 1817 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| | 1818 | } |
| | 1819 | |
| 1808 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 1820 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1809 | //const tag = self.air.instructions.items(.tag)[inst]; | 1821 | //const tag = self.air.instructions.items(.tag)[inst]; |
| 1810 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1822 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -1966,6 +1978,43 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1966,6 +1978,43 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1966 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1978 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1967 | } | 1979 | } |
| 1968 | | 1980 | |
| | 1981 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| | 1982 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 1983 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload for {}", .{self.target.cpu.arch}); |
| | 1984 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| | 1985 | } |
| | 1986 | |
| | 1987 | fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| | 1988 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 1989 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch}); |
| | 1990 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| | 1991 | } |
| | 1992 | |
| | 1993 | fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| | 1994 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 1995 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch}); |
| | 1996 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| | 1997 | } |
| | 1998 | |
| | 1999 | fn airPopcount(self: *Self, inst: Air.Inst.Index) !void { |
| | 2000 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 2001 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch}); |
| | 2002 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| | 2003 | } |
| | 2004 | |
| | 2005 | fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { |
| | 2006 | const prefetch = self.air.instructions.items(.data)[inst].prefetch; |
| | 2007 | // TODO Emit a PREFETCH/IPREFETCH as necessary, see A.7 and A.42 |
| | 2008 | return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none }); |
| | 2009 | } |
| | 2010 | |
| | 2011 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| | 2012 | const is_volatile = false; // TODO |
| | 2013 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 2014 | const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch}); |
| | 2015 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| | 2016 | } |
| | 2017 | |
| 1969 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | 2018 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1970 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 2019 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1971 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2020 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -2020,6 +2069,12 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2020,6 +2069,12 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2020 | return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none }); | 2069 | return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none }); |
| 2021 | } | 2070 | } |
| 2022 | | 2071 | |
| | 2072 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| | 2073 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 2074 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); |
| | 2075 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| | 2076 | } |
| | 2077 | |
| 2023 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | 2078 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2024 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 2079 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 2025 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2080 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -2281,6 +2336,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2281,6 +2336,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2281 | return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); | 2336 | return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); |
| 2282 | } | 2337 | } |
| 2283 | | 2338 | |
| | 2339 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| | 2340 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 2341 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch}); |
| | 2342 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| | 2343 | } |
| | 2344 | |
| 2284 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { | 2345 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 2285 | _ = inst; | 2346 | _ = inst; |
| 2286 | return self.fail("TODO implement switch for {}", .{self.target.cpu.arch}); | 2347 | return self.fail("TODO implement switch for {}", .{self.target.cpu.arch}); |
| ... | @@ -2314,6 +2375,15 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2314,6 +2375,15 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 2314 | return self.finishAir(inst, result, .{ pl_op.operand, .none, .none }); | 2375 | return self.finishAir(inst, result, .{ pl_op.operand, .none, .none }); |
| 2315 | } | 2376 | } |
| 2316 | | 2377 | |
| | 2378 | fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void { |
| | 2379 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| | 2380 | const result: MCValue = if (self.liveness.isUnused(inst)) |
| | 2381 | .dead |
| | 2382 | else |
| | 2383 | return self.fail("TODO implement airUnaryMath for {}", .{self.target.cpu.arch}); |
| | 2384 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| | 2385 | } |
| | 2386 | |
| 2317 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { | 2387 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2318 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2388 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2319 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2389 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |