| ... | ... | @@ -630,7 +630,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 630 | 630 | |
| 631 | 631 | .switch_br => try self.airSwitch(inst), |
| 632 | 632 | .slice_ptr => @panic("TODO try self.airSlicePtr(inst)"), |
| 633 | | .slice_len => @panic("TODO try self.airSliceLen(inst)"), |
| 633 | .slice_len => try self.airSliceLen(inst), |
| 634 | 634 | |
| 635 | 635 | .ptr_slice_len_ptr => @panic("TODO try self.airPtrSliceLenPtr(inst)"), |
| 636 | 636 | .ptr_slice_ptr_ptr => @panic("TODO try self.airPtrSlicePtrPtr(inst)"), |
| ... | ... | @@ -1385,6 +1385,27 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1385 | 1385 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1386 | 1386 | } |
| 1387 | 1387 | |
| 1388 | fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 1389 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1390 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1391 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 1392 | const ptr_bytes = @divExact(ptr_bits, 8); |
| 1393 | const mcv = try self.resolveInst(ty_op.operand); |
| 1394 | switch (mcv) { |
| 1395 | .dead, .unreach, .none => unreachable, |
| 1396 | .register => unreachable, // a slice doesn't fit in one register |
| 1397 | .stack_offset => |off| { |
| 1398 | break :result MCValue{ .stack_offset = off - ptr_bytes }; |
| 1399 | }, |
| 1400 | .memory => |addr| { |
| 1401 | break :result MCValue{ .memory = addr + ptr_bytes }; |
| 1402 | }, |
| 1403 | else => return self.fail("TODO implement slice_len for {}", .{mcv}), |
| 1404 | } |
| 1405 | }; |
| 1406 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1407 | } |
| 1408 | |
| 1388 | 1409 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 1389 | 1410 | _ = self; |
| 1390 | 1411 | _ = inst; |