| ... | ... | @@ -514,10 +514,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 514 | 514 | .bit_or => try self.airBinOp(inst, .bit_or), |
| 515 | 515 | .xor => try self.airBinOp(inst, .xor), |
| 516 | 516 | |
| 517 | | .add_sat => @panic("TODO try self.airAddSat(inst)"), |
| 518 | | .sub_sat => @panic("TODO try self.airSubSat(inst)"), |
| 519 | | .mul_sat => @panic("TODO try self.airMulSat(inst)"), |
| 520 | | .shl_sat => @panic("TODO try self.airShlSat(inst)"), |
| 517 | .add_sat => try self.airAddSat(inst), |
| 518 | .sub_sat => try self.airSubSat(inst), |
| 519 | .mul_sat => try self.airMulSat(inst), |
| 520 | .shl_sat => try self.airShlSat(inst), |
| 521 | 521 | .min => @panic("TODO try self.airMin(inst)"), |
| 522 | 522 | .max => @panic("TODO try self.airMax(inst)"), |
| 523 | 523 | .rem => try self.airRem(inst), |
| ... | ... | @@ -539,7 +539,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 539 | 539 | .round, |
| 540 | 540 | .trunc_float, |
| 541 | 541 | .neg, |
| 542 | | => @panic("TODO try self.airUnaryMath(inst)"), |
| 542 | => try self.airUnaryMath(inst), |
| 543 | 543 | |
| 544 | 544 | .add_with_overflow => try self.airAddSubWithOverflow(inst), |
| 545 | 545 | .sub_with_overflow => try self.airAddSubWithOverflow(inst), |
| ... | ... | @@ -605,7 +605,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 605 | 605 | .get_union_tag => @panic("TODO try self.airGetUnionTag(inst)"), |
| 606 | 606 | .clz => try self.airClz(inst), |
| 607 | 607 | .ctz => try self.airCtz(inst), |
| 608 | | .popcount => @panic("TODO try self.airPopcount(inst)"), |
| 608 | .popcount => try self.airPopcount(inst), |
| 609 | 609 | .byte_swap => @panic("TODO try self.airByteSwap(inst)"), |
| 610 | 610 | .bit_reverse => @panic("TODO try self.airBitReverse(inst)"), |
| 611 | 611 | .tag_name => try self.airTagName(inst), |
| ... | ... | @@ -616,7 +616,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 616 | 616 | .reduce => @panic("TODO try self.airReduce(inst)"), |
| 617 | 617 | .aggregate_init => try self.airAggregateInit(inst), |
| 618 | 618 | .union_init => @panic("TODO try self.airUnionInit(inst)"), |
| 619 | | .prefetch => @panic("TODO try self.airPrefetch(inst)"), |
| 619 | .prefetch => try self.airPrefetch(inst), |
| 620 | 620 | .mul_add => @panic("TODO try self.airMulAdd(inst)"), |
| 621 | 621 | |
| 622 | 622 | .@"try" => try self.airTry(inst), |
| ... | ... | @@ -661,16 +661,16 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 661 | 661 | .array_elem_val => try self.airArrayElemVal(inst), |
| 662 | 662 | .slice_elem_val => try self.airSliceElemVal(inst), |
| 663 | 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 | 665 | .ptr_elem_ptr => try self.airPtrElemPtr(inst), |
| 666 | 666 | |
| 667 | 667 | .constant => unreachable, // excluded from function bodies |
| 668 | 668 | .const_ty => unreachable, // excluded from function bodies |
| 669 | 669 | .unreach => self.finishAirBookkeeping(), |
| 670 | 670 | |
| 671 | | .optional_payload => @panic("TODO try self.airOptionalPayload(inst)"), |
| 672 | | .optional_payload_ptr => @panic("TODO try self.airOptionalPayloadPtr(inst)"), |
| 673 | | .optional_payload_ptr_set => @panic("TODO try self.airOptionalPayloadPtrSet(inst)"), |
| 671 | .optional_payload => try self.airOptionalPayload(inst), |
| 672 | .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), |
| 673 | .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), |
| 674 | 674 | .unwrap_errunion_err => try self.airUnwrapErrErr(inst), |
| 675 | 675 | .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst), |
| 676 | 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 | 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 | 734 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 729 | 735 | const tag = self.air.instructions.items(.tag)[inst]; |
| 730 | 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 | 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 | 1820 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1809 | 1821 | //const tag = self.air.instructions.items(.tag)[inst]; |
| 1810 | 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 | 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 | 2018 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1970 | 2019 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1971 | 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 | 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 | 2078 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2024 | 2079 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 2025 | 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 | 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 | 2345 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 2285 | 2346 | _ = inst; |
| 2286 | 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 | 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 | 2387 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2318 | 2388 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2319 | 2389 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |