authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-24 21:22:28-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
log54326cc55485fa71ce729cd553cb9af9ea816faa
tree78f0fc80d2323a7c4ecc38dab2e44bb1488a247a
parent361035fe7a74fed71303a92d15465daa647ac83e

cbe: implement field_parent_ptr


2 files changed, 41 insertions(+), 12 deletions(-)

src/codegen/c.zig+41-10
...@@ -583,12 +583,12 @@ pub const DeclGen = struct {...@@ -583,12 +583,12 @@ pub const DeclGen = struct {
583 };583 };
584 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);584 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
585585
586 var ptr_u8_pl = ptr_info;586 var u8_ptr_pl = ptr_info;
587 ptr_u8_pl.data.pointee_type = Type.u8;587 u8_ptr_pl.data.pointee_type = Type.u8;
588 const ptr_u8_ty = Type.initPayload(&ptr_u8_pl.base);588 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
589589
590 try writer.writeAll("&((");590 try writer.writeAll("&((");
591 try dg.renderTypecast(writer, ptr_u8_ty);591 try dg.renderTypecast(writer, u8_ptr_ty);
592 try writer.writeByte(')');592 try writer.writeByte(')');
593 try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);593 try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty);
594 return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)});594 return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)});
...@@ -4050,8 +4050,39 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue...@@ -4050,8 +4050,39 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
4050}4050}
40514051
4052fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {4052fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4053 _ = inst;4053 if (f.liveness.isUnused(inst)) return CValue.none;
4054 return f.fail("TODO: C backend: implement airFieldParentPtr", .{});4054
4055 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4056 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
4057
4058 const struct_ptr_ty = f.air.typeOfIndex(inst);
4059 const field_ptr_ty = f.air.typeOf(extra.field_ptr);
4060 const field_ptr_val = try f.resolveInst(extra.field_ptr);
4061
4062 const target = f.object.dg.module.getTarget();
4063 const struct_ty = struct_ptr_ty.childType();
4064 const field_offset = struct_ty.structFieldOffset(extra.field_index, target);
4065
4066 var field_offset_pl = Value.Payload.I64{
4067 .base = .{ .tag = .int_i64 },
4068 .data = -@intCast(i64, field_offset),
4069 };
4070 const field_offset_val = Value.initPayload(&field_offset_pl.base);
4071
4072 var u8_ptr_pl = field_ptr_ty.ptrInfo();
4073 u8_ptr_pl.data.pointee_type = Type.u8;
4074 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
4075
4076 const writer = f.object.writer();
4077 const local = try f.allocLocal(struct_ptr_ty, .Const);
4078 try writer.writeAll(" = (");
4079 try f.renderTypecast(writer, struct_ptr_ty);
4080 try writer.writeAll(")&((");
4081 try f.renderTypecast(writer, u8_ptr_ty);
4082 try writer.writeByte(')');
4083 try f.writeCValue(writer, field_ptr_val, .Other);
4084 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.isize, field_offset_val)});
4085 return local;
4055}4086}
40564087
4057fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue {4088fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue {
...@@ -4089,12 +4120,12 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc...@@ -4089,12 +4120,12 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
4089 };4120 };
4090 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);4121 const byte_offset_val = Value.initPayload(&byte_offset_pl.base);
40914122
4092 var ptr_u8_pl = field_ptr_info;4123 var u8_ptr_pl = field_ptr_info;
4093 ptr_u8_pl.data.pointee_type = Type.u8;4124 u8_ptr_pl.data.pointee_type = Type.u8;
4094 const ptr_u8_ty = Type.initPayload(&ptr_u8_pl.base);4125 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
40954126
4096 try writer.writeAll("&((");4127 try writer.writeAll("&((");
4097 try f.renderTypecast(writer, ptr_u8_ty);4128 try f.renderTypecast(writer, u8_ptr_ty);
4098 try writer.writeByte(')');4129 try writer.writeByte(')');
4099 try f.writeCValue(writer, struct_ptr, .Other);4130 try f.writeCValue(writer, struct_ptr, .Other);
4100 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});4131 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
test/behavior/field_parent_ptr.zig-2
...@@ -4,7 +4,6 @@ const builtin = @import("builtin");...@@ -4,7 +4,6 @@ const builtin = @import("builtin");
4test "@fieldParentPtr non-first field" {4test "@fieldParentPtr non-first field" {
5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
8 try testParentFieldPtr(&foo.c);7 try testParentFieldPtr(&foo.c);
9 comptime try testParentFieldPtr(&foo.c);8 comptime try testParentFieldPtr(&foo.c);
10}9}
...@@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" {...@@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" {
12test "@fieldParentPtr first field" {11test "@fieldParentPtr first field" {
13 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
14 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;13 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16 try testParentFieldPtrFirst(&foo.a);14 try testParentFieldPtrFirst(&foo.a);
17 comptime try testParentFieldPtrFirst(&foo.a);15 comptime try testParentFieldPtrFirst(&foo.a);
18}16}