stage2: air ptr_slice_len_ptr and ptr_slice_ptr_ptr
This commit is contained in:
@@ -367,6 +367,12 @@ pub const Inst = struct {
|
||||
/// Given a slice value, return the pointer.
|
||||
/// Uses the `ty_op` field.
|
||||
slice_ptr,
|
||||
/// Given a pointer to a slice, return a pointer to the length of the slice.
|
||||
/// Uses the `ty_op` field.
|
||||
ptr_slice_len_ptr,
|
||||
/// Given a pointer to a slice, return a pointer to the pointer of the slice.
|
||||
/// Uses the `ty_op` field.
|
||||
ptr_slice_ptr_ptr,
|
||||
/// Given an array value and element index, return the element value at that index.
|
||||
/// Result type is the element type of the array operand.
|
||||
/// Uses the `bin_op` field.
|
||||
@@ -707,6 +713,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
|
||||
.wrap_errunion_payload,
|
||||
.wrap_errunion_err,
|
||||
.slice_ptr,
|
||||
.ptr_slice_len_ptr,
|
||||
.ptr_slice_ptr_ptr,
|
||||
.struct_field_ptr_index_0,
|
||||
.struct_field_ptr_index_1,
|
||||
.struct_field_ptr_index_2,
|
||||
|
||||
@@ -300,6 +300,8 @@ fn analyzeInst(
|
||||
.wrap_errunion_err,
|
||||
.slice_ptr,
|
||||
.slice_len,
|
||||
.ptr_slice_len_ptr,
|
||||
.ptr_slice_ptr_ptr,
|
||||
.struct_field_ptr_index_0,
|
||||
.struct_field_ptr_index_1,
|
||||
.struct_field_ptr_index_2,
|
||||
|
||||
@@ -494,6 +494,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.slice_ptr => try self.airSlicePtr(inst),
|
||||
.slice_len => try self.airSliceLen(inst),
|
||||
|
||||
.ptr_slice_len_ptr => try self.airPtrSliceLenPtr(inst),
|
||||
.ptr_slice_ptr_ptr => try self.airPtrSlicePtrPtr(inst),
|
||||
|
||||
.array_elem_val => try self.airArrayElemVal(inst),
|
||||
.slice_elem_val => try self.airSliceElemVal(inst),
|
||||
.ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),
|
||||
@@ -1057,6 +1060,18 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const is_volatile = false; // TODO
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
|
||||
@@ -842,6 +842,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
.slice_ptr => try self.airSlicePtr(inst),
|
||||
.slice_len => try self.airSliceLen(inst),
|
||||
|
||||
.ptr_slice_len_ptr => try self.airPtrSliceLenPtr(inst),
|
||||
.ptr_slice_ptr_ptr => try self.airPtrSlicePtrPtr(inst),
|
||||
|
||||
.array_elem_val => try self.airArrayElemVal(inst),
|
||||
.slice_elem_val => try self.airSliceElemVal(inst),
|
||||
.ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),
|
||||
@@ -1498,6 +1501,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
|
||||
else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch}),
|
||||
};
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
|
||||
else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch}),
|
||||
};
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const is_volatile = false; // TODO
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
|
||||
@@ -1075,6 +1075,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
|
||||
.slice_ptr => try airSliceField(f, inst, ".ptr;\n"),
|
||||
.slice_len => try airSliceField(f, inst, ".len;\n"),
|
||||
|
||||
.ptr_slice_len_ptr => try airPtrSliceFieldPtr(f, inst, ".len;\n"),
|
||||
.ptr_slice_ptr_ptr => try airPtrSliceFieldPtr(f, inst, ".ptr;\n"),
|
||||
|
||||
.ptr_elem_val => try airPtrElemVal(f, inst, "["),
|
||||
.ptr_ptr_elem_val => try airPtrElemVal(f, inst, "[0]["),
|
||||
.ptr_elem_ptr => try airPtrElemPtr(f, inst),
|
||||
@@ -1114,6 +1117,21 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airPtrSliceFieldPtr(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {
|
||||
if (f.liveness.isUnused(inst))
|
||||
return CValue.none;
|
||||
|
||||
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
|
||||
const operand = try f.resolveInst(ty_op.operand);
|
||||
const writer = f.object.writer();
|
||||
|
||||
_ = writer;
|
||||
_ = operand;
|
||||
_ = suffix;
|
||||
|
||||
return f.fail("TODO: C backend: airPtrSliceFieldPtr", .{});
|
||||
}
|
||||
|
||||
fn airPtrElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CValue {
|
||||
const is_volatile = false; // TODO
|
||||
if (!is_volatile and f.liveness.isUnused(inst))
|
||||
|
||||
@@ -1709,6 +1709,10 @@ pub const FuncGen = struct {
|
||||
.assembly => try self.airAssembly(inst),
|
||||
.slice_ptr => try self.airSliceField(inst, 0),
|
||||
.slice_len => try self.airSliceField(inst, 1),
|
||||
|
||||
.ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0),
|
||||
.ptr_slice_len_ptr => try self.airPtrSliceFieldPtr(inst, 1),
|
||||
|
||||
.array_to_slice => try self.airArrayToSlice(inst),
|
||||
.float_to_int => try self.airFloatToInt(inst),
|
||||
.int_to_float => try self.airIntToFloat(inst),
|
||||
@@ -2091,6 +2095,15 @@ pub const FuncGen = struct {
|
||||
return self.builder.buildExtractValue(operand, index, "");
|
||||
}
|
||||
|
||||
fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value {
|
||||
if (self.liveness.isUnused(inst)) return null;
|
||||
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const slice_ptr = try self.resolveInst(ty_op.operand);
|
||||
|
||||
return self.builder.buildStructGEP(slice_ptr, index, "");
|
||||
}
|
||||
|
||||
fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const slice_ty = self.air.typeOf(bin_op.lhs);
|
||||
|
||||
@@ -183,6 +183,8 @@ const Writer = struct {
|
||||
.wrap_errunion_err,
|
||||
.slice_ptr,
|
||||
.slice_len,
|
||||
.ptr_slice_len_ptr,
|
||||
.ptr_slice_ptr_ptr,
|
||||
.struct_field_ptr_index_0,
|
||||
.struct_field_ptr_index_1,
|
||||
.struct_field_ptr_index_2,
|
||||
|
||||
Reference in New Issue
Block a user