authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-18 01:00:07+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-20 03:44:02+02:00
log05c5c99a95c894d7e3241e1729e09aa7eacb6035
tree4593305c8204570abf179c260574cf775862d49f
parente5d6fe18b90cf2602e7e7712b4dd807b4e243356

stage2: air ptr_slice_len_ptr and ptr_slice_ptr_ptr


7 files changed, 77 insertions(+), 0 deletions(-)

src/Air.zig+8
......@@ -367,6 +367,12 @@ pub const Inst = struct {
367367 /// Given a slice value, return the pointer.
368368 /// Uses the `ty_op` field.
369369 slice_ptr,
370 /// Given a pointer to a slice, return a pointer to the length of the slice.
371 /// Uses the `ty_op` field.
372 ptr_slice_len_ptr,
373 /// Given a pointer to a slice, return a pointer to the pointer of the slice.
374 /// Uses the `ty_op` field.
375 ptr_slice_ptr_ptr,
370376 /// Given an array value and element index, return the element value at that index.
371377 /// Result type is the element type of the array operand.
372378 /// Uses the `bin_op` field.
......@@ -707,6 +713,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
707713 .wrap_errunion_payload,
708714 .wrap_errunion_err,
709715 .slice_ptr,
716 .ptr_slice_len_ptr,
717 .ptr_slice_ptr_ptr,
710718 .struct_field_ptr_index_0,
711719 .struct_field_ptr_index_1,
712720 .struct_field_ptr_index_2,
src/Liveness.zig+2
......@@ -300,6 +300,8 @@ fn analyzeInst(
300300 .wrap_errunion_err,
301301 .slice_ptr,
302302 .slice_len,
303 .ptr_slice_len_ptr,
304 .ptr_slice_ptr_ptr,
303305 .struct_field_ptr_index_0,
304306 .struct_field_ptr_index_1,
305307 .struct_field_ptr_index_2,
src/arch/aarch64/CodeGen.zig+15
......@@ -494,6 +494,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
494494 .slice_ptr => try self.airSlicePtr(inst),
495495 .slice_len => try self.airSliceLen(inst),
496496
497 .ptr_slice_len_ptr => try self.airPtrSliceLenPtr(inst),
498 .ptr_slice_ptr_ptr => try self.airPtrSlicePtrPtr(inst),
499
497500 .array_elem_val => try self.airArrayElemVal(inst),
498501 .slice_elem_val => try self.airSliceElemVal(inst),
499502 .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),
......@@ -1057,6 +1060,18 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
10571060 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
10581061}
10591062
1063fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
1064 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1065 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});
1066 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1067}
1068
1069fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
1070 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1071 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});
1072 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1073}
1074
10601075fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
10611076 const is_volatile = false; // TODO
10621077 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
src/codegen.zig+19
......@@ -842,6 +842,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
842842 .slice_ptr => try self.airSlicePtr(inst),
843843 .slice_len => try self.airSliceLen(inst),
844844
845 .ptr_slice_len_ptr => try self.airPtrSliceLenPtr(inst),
846 .ptr_slice_ptr_ptr => try self.airPtrSlicePtrPtr(inst),
847
845848 .array_elem_val => try self.airArrayElemVal(inst),
846849 .slice_elem_val => try self.airSliceElemVal(inst),
847850 .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),
......@@ -1498,6 +1501,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
14981501 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14991502 }
15001503
1504 fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
1505 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1506 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
1507 else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch}),
1508 };
1509 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1510 }
1511
1512 fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
1513 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1514 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (arch) {
1515 else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch}),
1516 };
1517 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1518 }
1519
15011520 fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
15021521 const is_volatile = false; // TODO
15031522 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
src/codegen/c.zig+18
......@@ -1075,6 +1075,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
10751075 .slice_ptr => try airSliceField(f, inst, ".ptr;\n"),
10761076 .slice_len => try airSliceField(f, inst, ".len;\n"),
10771077
1078 .ptr_slice_len_ptr => try airPtrSliceFieldPtr(f, inst, ".len;\n"),
1079 .ptr_slice_ptr_ptr => try airPtrSliceFieldPtr(f, inst, ".ptr;\n"),
1080
10781081 .ptr_elem_val => try airPtrElemVal(f, inst, "["),
10791082 .ptr_ptr_elem_val => try airPtrElemVal(f, inst, "[0]["),
10801083 .ptr_elem_ptr => try airPtrElemPtr(f, inst),
......@@ -1114,6 +1117,21 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue
11141117 return local;
11151118}
11161119
1120fn airPtrSliceFieldPtr(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue {
1121 if (f.liveness.isUnused(inst))
1122 return CValue.none;
1123
1124 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
1125 const operand = try f.resolveInst(ty_op.operand);
1126 const writer = f.object.writer();
1127
1128 _ = writer;
1129 _ = operand;
1130 _ = suffix;
1131
1132 return f.fail("TODO: C backend: airPtrSliceFieldPtr", .{});
1133}
1134
11171135fn airPtrElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CValue {
11181136 const is_volatile = false; // TODO
11191137 if (!is_volatile and f.liveness.isUnused(inst))
src/codegen/llvm.zig+13
......@@ -1709,6 +1709,10 @@ pub const FuncGen = struct {
17091709 .assembly => try self.airAssembly(inst),
17101710 .slice_ptr => try self.airSliceField(inst, 0),
17111711 .slice_len => try self.airSliceField(inst, 1),
1712
1713 .ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0),
1714 .ptr_slice_len_ptr => try self.airPtrSliceFieldPtr(inst, 1),
1715
17121716 .array_to_slice => try self.airArrayToSlice(inst),
17131717 .float_to_int => try self.airFloatToInt(inst),
17141718 .int_to_float => try self.airIntToFloat(inst),
......@@ -2091,6 +2095,15 @@ pub const FuncGen = struct {
20912095 return self.builder.buildExtractValue(operand, index, "");
20922096 }
20932097
2098 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value {
2099 if (self.liveness.isUnused(inst)) return null;
2100
2101 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2102 const slice_ptr = try self.resolveInst(ty_op.operand);
2103
2104 return self.builder.buildStructGEP(slice_ptr, index, "");
2105 }
2106
20942107 fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
20952108 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
20962109 const slice_ty = self.air.typeOf(bin_op.lhs);
src/print_air.zig+2
......@@ -183,6 +183,8 @@ const Writer = struct {
183183 .wrap_errunion_err,
184184 .slice_ptr,
185185 .slice_len,
186 .ptr_slice_len_ptr,
187 .ptr_slice_ptr_ptr,
186188 .struct_field_ptr_index_0,
187189 .struct_field_ptr_index_1,
188190 .struct_field_ptr_index_2,