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