| ... | @@ -1565,28 +1565,60 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1565,28 +1565,60 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1565 | fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { | 1565 | fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1566 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1566 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1567 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 1567 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 1568 | return self.structFieldPtr(extra.struct_operand, ty_pl.ty, extra.field_index); | 1568 | const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index); |
| | 1569 | return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); |
| 1569 | } | 1570 | } |
| 1570 | | 1571 | |
| 1571 | fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | 1572 | fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 1572 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1573 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1573 | return self.structFieldPtr(ty_op.operand, ty_op.ty, index); | 1574 | const result = try self.structFieldPtr(inst, ty_op.operand, index); |
| | 1575 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1574 | } | 1576 | } |
| 1575 | fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void { | 1577 | |
| 1576 | _ = self; | 1578 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 1577 | _ = operand; | 1579 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 1578 | _ = ty; | 1580 | const mcv = try self.resolveInst(operand); |
| 1579 | _ = index; | 1581 | const struct_ty = self.air.typeOf(operand).childType(); |
| 1580 | return self.fail("TODO implement codegen struct_field_ptr", .{}); | 1582 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| 1581 | //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); | 1583 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| | 1584 | const struct_field_ty = struct_ty.structFieldType(index); |
| | 1585 | const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); |
| | 1586 | |
| | 1587 | switch (mcv) { |
| | 1588 | .ptr_stack_offset => |off| { |
| | 1589 | break :result MCValue{ |
| | 1590 | .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size, |
| | 1591 | }; |
| | 1592 | }, |
| | 1593 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), |
| | 1594 | } |
| | 1595 | }; |
| 1582 | } | 1596 | } |
| 1583 | | 1597 | |
| 1584 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | 1598 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1585 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 1599 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1586 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 1600 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 1587 | _ = extra; | 1601 | const operand = extra.struct_operand; |
| 1588 | return self.fail("TODO implement codegen struct_field_val", .{}); | 1602 | const index = extra.field_index; |
| 1589 | //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); | 1603 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| | 1604 | const mcv = try self.resolveInst(operand); |
| | 1605 | const struct_ty = self.air.typeOf(operand); |
| | 1606 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| | 1607 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| | 1608 | const struct_field_ty = struct_ty.structFieldType(index); |
| | 1609 | const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); |
| | 1610 | |
| | 1611 | switch (mcv) { |
| | 1612 | .stack_offset => |off| { |
| | 1613 | break :result MCValue{ |
| | 1614 | .stack_offset = off + struct_size - struct_field_offset - struct_field_size, |
| | 1615 | }; |
| | 1616 | }, |
| | 1617 | else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}), |
| | 1618 | } |
| | 1619 | }; |
| | 1620 | |
| | 1621 | return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none }); |
| 1590 | } | 1622 | } |
| 1591 | | 1623 | |
| 1592 | /// Perform "binary" operators, excluding comparisons. | 1624 | /// Perform "binary" operators, excluding comparisons. |
| ... | @@ -1948,10 +1980,16 @@ fn airFence(self: *Self) !void { | ... | @@ -1948,10 +1980,16 @@ fn airFence(self: *Self) !void { |
| 1948 | | 1980 | |
| 1949 | fn airCall(self: *Self, inst: Air.Inst.Index) !void { | 1981 | fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 1950 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 1982 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1951 | const fn_ty = self.air.typeOf(pl_op.operand); | | |
| 1952 | const callee = pl_op.operand; | 1983 | const callee = pl_op.operand; |
| 1953 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 1984 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 1954 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]); | 1985 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]); |
| | 1986 | const ty = self.air.typeOf(callee); |
| | 1987 | |
| | 1988 | const fn_ty = switch (ty.zigTypeTag()) { |
| | 1989 | .Fn => ty, |
| | 1990 | .Pointer => ty.childType(), |
| | 1991 | else => unreachable, |
| | 1992 | }; |
| 1955 | | 1993 | |
| 1956 | var info = try self.resolveCallingConventionValues(fn_ty); | 1994 | var info = try self.resolveCallingConventionValues(fn_ty); |
| 1957 | defer info.deinit(self); | 1995 | defer info.deinit(self); |