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 {...@@ -367,6 +367,12 @@ pub const Inst = struct {
367 /// Given a slice value, return the pointer.367 /// Given a slice value, return the pointer.
368 /// Uses the `ty_op` field.368 /// Uses the `ty_op` field.
369 slice_ptr,369 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,
370 /// Given an array value and element index, return the element value at that index.376 /// Given an array value and element index, return the element value at that index.
371 /// Result type is the element type of the array operand.377 /// Result type is the element type of the array operand.
372 /// Uses the `bin_op` field.378 /// Uses the `bin_op` field.
...@@ -707,6 +713,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -707,6 +713,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
707 .wrap_errunion_payload,713 .wrap_errunion_payload,
708 .wrap_errunion_err,714 .wrap_errunion_err,
709 .slice_ptr,715 .slice_ptr,
716 .ptr_slice_len_ptr,
717 .ptr_slice_ptr_ptr,
710 .struct_field_ptr_index_0,718 .struct_field_ptr_index_0,
711 .struct_field_ptr_index_1,719 .struct_field_ptr_index_1,
712 .struct_field_ptr_index_2,720 .struct_field_ptr_index_2,
src/Liveness.zig+2
...@@ -300,6 +300,8 @@ fn analyzeInst(...@@ -300,6 +300,8 @@ fn analyzeInst(
300 .wrap_errunion_err,300 .wrap_errunion_err,
301 .slice_ptr,301 .slice_ptr,
302 .slice_len,302 .slice_len,
303 .ptr_slice_len_ptr,
304 .ptr_slice_ptr_ptr,
303 .struct_field_ptr_index_0,305 .struct_field_ptr_index_0,
304 .struct_field_ptr_index_1,306 .struct_field_ptr_index_1,
305 .struct_field_ptr_index_2,307 .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 {...@@ -494,6 +494,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
494 .slice_ptr => try self.airSlicePtr(inst),494 .slice_ptr => try self.airSlicePtr(inst),
495 .slice_len => try self.airSliceLen(inst),495 .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
497 .array_elem_val => try self.airArrayElemVal(inst),500 .array_elem_val => try self.airArrayElemVal(inst),
498 .slice_elem_val => try self.airSliceElemVal(inst),501 .slice_elem_val => try self.airSliceElemVal(inst),
499 .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),502 .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),
...@@ -1057,6 +1060,18 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -1057,6 +1060,18 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
1057 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1060 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1058}1061}
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
1060fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {1075fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
1061 const is_volatile = false; // TODO1076 const is_volatile = false; // TODO
1062 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1077 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 {...@@ -842,6 +842,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
842 .slice_ptr => try self.airSlicePtr(inst),842 .slice_ptr => try self.airSlicePtr(inst),
843 .slice_len => try self.airSliceLen(inst),843 .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
845 .array_elem_val => try self.airArrayElemVal(inst),848 .array_elem_val => try self.airArrayElemVal(inst),
846 .slice_elem_val => try self.airSliceElemVal(inst),849 .slice_elem_val => try self.airSliceElemVal(inst),
847 .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),850 .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst),
...@@ -1498,6 +1501,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1498,6 +1501,22 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1498 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1501 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1499 }1502 }
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
1501 fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {1520 fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
1502 const is_volatile = false; // TODO1521 const is_volatile = false; // TODO
1503 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1522 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...@@ -1075,6 +1075,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1075 .slice_ptr => try airSliceField(f, inst, ".ptr;\n"),1075 .slice_ptr => try airSliceField(f, inst, ".ptr;\n"),
1076 .slice_len => try airSliceField(f, inst, ".len;\n"),1076 .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
1078 .ptr_elem_val => try airPtrElemVal(f, inst, "["),1081 .ptr_elem_val => try airPtrElemVal(f, inst, "["),
1079 .ptr_ptr_elem_val => try airPtrElemVal(f, inst, "[0]["),1082 .ptr_ptr_elem_val => try airPtrElemVal(f, inst, "[0]["),
1080 .ptr_elem_ptr => try airPtrElemPtr(f, inst),1083 .ptr_elem_ptr => try airPtrElemPtr(f, inst),
...@@ -1114,6 +1117,21 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue...@@ -1114,6 +1117,21 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue
1114 return local;1117 return local;
1115}1118}
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
1117fn airPtrElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CValue {1135fn airPtrElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CValue {
1118 const is_volatile = false; // TODO1136 const is_volatile = false; // TODO
1119 if (!is_volatile and f.liveness.isUnused(inst))1137 if (!is_volatile and f.liveness.isUnused(inst))
src/codegen/llvm.zig+13
...@@ -1709,6 +1709,10 @@ pub const FuncGen = struct {...@@ -1709,6 +1709,10 @@ pub const FuncGen = struct {
1709 .assembly => try self.airAssembly(inst),1709 .assembly => try self.airAssembly(inst),
1710 .slice_ptr => try self.airSliceField(inst, 0),1710 .slice_ptr => try self.airSliceField(inst, 0),
1711 .slice_len => try self.airSliceField(inst, 1),1711 .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
1712 .array_to_slice => try self.airArrayToSlice(inst),1716 .array_to_slice => try self.airArrayToSlice(inst),
1713 .float_to_int => try self.airFloatToInt(inst),1717 .float_to_int => try self.airFloatToInt(inst),
1714 .int_to_float => try self.airIntToFloat(inst),1718 .int_to_float => try self.airIntToFloat(inst),
...@@ -2091,6 +2095,15 @@ pub const FuncGen = struct {...@@ -2091,6 +2095,15 @@ pub const FuncGen = struct {
2091 return self.builder.buildExtractValue(operand, index, "");2095 return self.builder.buildExtractValue(operand, index, "");
2092 }2096 }
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
2094 fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {2107 fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
2095 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2108 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2096 const slice_ty = self.air.typeOf(bin_op.lhs);2109 const slice_ty = self.air.typeOf(bin_op.lhs);
src/print_air.zig+2
...@@ -183,6 +183,8 @@ const Writer = struct {...@@ -183,6 +183,8 @@ const Writer = struct {
183 .wrap_errunion_err,183 .wrap_errunion_err,
184 .slice_ptr,184 .slice_ptr,
185 .slice_len,185 .slice_len,
186 .ptr_slice_len_ptr,
187 .ptr_slice_ptr_ptr,
186 .struct_field_ptr_index_0,188 .struct_field_ptr_index_0,
187 .struct_field_ptr_index_1,189 .struct_field_ptr_index_1,
188 .struct_field_ptr_index_2,190 .struct_field_ptr_index_2,