| ... | ... | @@ -1565,28 +1565,60 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1565 | 1565 | fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1566 | 1566 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1567 | 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 | 1572 | fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 1572 | 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 { |
| 1576 | | _ = self; |
| 1577 | | _ = operand; |
| 1578 | | _ = ty; |
| 1579 | | _ = index; |
| 1580 | | return self.fail("TODO implement codegen struct_field_ptr", .{}); |
| 1581 | | //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); |
| 1577 | |
| 1578 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 1579 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 1580 | const mcv = try self.resolveInst(operand); |
| 1581 | const struct_ty = self.air.typeOf(operand).childType(); |
| 1582 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| 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 | 1598 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1585 | 1599 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1586 | 1600 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 1587 | | _ = extra; |
| 1588 | | return self.fail("TODO implement codegen struct_field_val", .{}); |
| 1589 | | //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); |
| 1601 | const operand = extra.struct_operand; |
| 1602 | const index = extra.field_index; |
| 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 | 1624 | /// Perform "binary" operators, excluding comparisons. |
| ... | ... | @@ -1948,10 +1980,16 @@ fn airFence(self: *Self) !void { |
| 1948 | 1980 | |
| 1949 | 1981 | fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 1950 | 1982 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1951 | | const fn_ty = self.air.typeOf(pl_op.operand); |
| 1952 | 1983 | const callee = pl_op.operand; |
| 1953 | 1984 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 1954 | 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 | 1994 | var info = try self.resolveCallingConventionValues(fn_ty); |
| 1957 | 1995 | defer info.deinit(self); |