| author | |
| committer | |
| log | 05c5c99a95c894d7e3241e1729e09aa7eacb6035 |
| tree | 4593305c8204570abf179c260574cf775862d49f |
| parent | e5d6fe18b90cf2602e7e7712b4dd807b4e243356 |
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), |
| 496 | 496 | ||
| 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 | } |
| 1059 | 1062 | ||
| 1063 | fn 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 | |||
| 1069 | fn 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 | |||
| 1060 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | 1075 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1061 | const is_volatile = false; // TODO | 1076 | 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), |
| 844 | 844 | ||
| 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 | } |
| 1500 | 1503 | ||
| 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; // TODO | 1521 | 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"), |
| 1077 | 1077 | ||
| 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 | } |
| 1116 | 1119 | ||
| 1120 | fn 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 | |||
| 1117 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CValue { | 1135 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CValue { |
| 1118 | const is_volatile = false; // TODO | 1136 | 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 | } |
| 2093 | 2097 | ||
| 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, |