aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-24 15:52:56 -0500
committerGitHub <noreply@github.com>2022-02-24 15:52:56 -0500
commite06cb31659ff5afd1e0b846fbaa852df2f5a0af4 (patch)
tree18e085201d076dea7320365f47d79ebc00c589eb /src/codegen/llvm.zig
parent5ab5e2e6731a9f1198df6c53134545ccc6a6bbd3 (diff)
parentcbd5d6c704c03177be90a891fc8fd48e6966487b (diff)
downloadzig-e06cb31659ff5afd1e0b846fbaa852df2f5a0af4.tar.gz
zig-e06cb31659ff5afd1e0b846fbaa852df2f5a0af4.zip
Merge pull request #10982 from Vexu/stage2
stage2: implement fieldParentPtr
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 1679ee6d97..51bb713ed5 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2191,6 +2191,8 @@ pub const FuncGen = struct {
.struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2),
.struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3),
+ .field_parent_ptr => try self.airFieldParentPtr(inst),
+
.array_elem_val => try self.airArrayElemVal(inst),
.slice_elem_val => try self.airSliceElemVal(inst),
.slice_elem_ptr => try self.airSliceElemPtr(inst),
@@ -2853,6 +2855,29 @@ pub const FuncGen = struct {
}
}
+ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
+ if (self.liveness.isUnused(inst)) return null;
+
+ const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+ const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
+
+ const field_ptr = try self.resolveInst(extra.field_ptr);
+
+ const target = self.dg.module.getTarget();
+ const struct_ty = self.air.getRefType(ty_pl.ty).childType();
+ const field_offset = struct_ty.structFieldOffset(extra.field_index, target);
+
+ const res_ty = try self.dg.llvmType(self.air.getRefType(ty_pl.ty));
+ if (field_offset == 0) {
+ return self.builder.buildBitCast(field_ptr, res_ty, "");
+ }
+ const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
+
+ const field_ptr_int = self.builder.buildPtrToInt(field_ptr, llvm_usize_ty, "");
+ const base_ptr_int = self.builder.buildNUWSub(field_ptr_int, llvm_usize_ty.constInt(field_offset, .False), "");
+ return self.builder.buildIntToPtr(base_ptr_int, res_ty, "");
+ }
+
fn airNot(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
if (self.liveness.isUnused(inst))
return null;