authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-04 01:04:18+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-04 01:21:24+01:00
log47ed87dab8ab525fa3d284b9d0e61b244ec75f82
treefc1c0dd6d2904f05ce39606321cf113512368491
parent384b19716d097a20e3cdfb29a6f2d9c5816cbe7f

stage2: implement struct_field_val and struct_field_val_ptr

Handle function pointers in airCall

1 files changed, 51 insertions(+), 13 deletions(-)

src/arch/x86_64/CodeGen.zig+51-13
...@@ -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 {
1565fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {1565fn 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}
15701571
1571fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {1572fn 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}
1575fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void {1577
1576 _ = self;1578fn 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}
15831597
1584fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {1598fn 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}
15911623
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 {
19481980
1949fn airCall(self: *Self, inst: Air.Inst.Index) !void {1981fn 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 };
19551993
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);