stage2: implement fieldParentPtr

This commit is contained in:
Veikka Tuominen
2022-02-24 19:47:42 +02:00
parent 6249a24e81
commit b034c45b2b
16 changed files with 161 additions and 20 deletions

View File

@@ -1734,6 +1734,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
.struct_field_ptr_index_2 => try airStructFieldPtrIndex(f, inst, 2),
.struct_field_ptr_index_3 => try airStructFieldPtrIndex(f, inst, 3),
.field_parent_ptr => try airFieldParentPtr(f, inst),
.struct_field_val => try airStructFieldVal(f, inst),
.slice_ptr => try airSliceField(f, inst, ".ptr;\n"),
.slice_len => try airSliceField(f, inst, ".len;\n"),
@@ -3026,6 +3028,11 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
return structFieldPtr(f, inst, struct_ptr_ty, struct_ptr, index);
}
fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
_ = inst;
return f.fail("TODO: C backend: implement airFieldParentPtr", .{});
}
fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue {
const writer = f.object.writer();
const struct_ty = struct_ptr_ty.elemType();

View File

@@ -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;