stage2: implement fieldParentPtr
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user