diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 19 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 25 |
2 files changed, 41 insertions, 3 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index f09bb574af..9050499fce 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1083,6 +1083,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .ptr_elem_val => try airPtrElemVal(f, inst, "["), .ptr_elem_ptr => try airPtrElemPtr(f, inst), .slice_elem_val => try airSliceElemVal(f, inst, "["), + .slice_elem_ptr => try airSliceElemPtr(f, inst), .array_elem_val => try airArrayElemVal(f, inst), .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst), @@ -1165,6 +1166,24 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CVal return local; } +fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { + if (f.liveness.isUnused(inst)) + return CValue.none; + const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; + const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; + + const slice = try f.resolveInst(bin_op.lhs); + const index = try f.resolveInst(bin_op.rhs); + const writer = f.object.writer(); + const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); + try writer.writeAll(" = &"); + try f.writeCValue(writer, slice); + try writer.writeByte('['); + try f.writeCValue(writer, index); + try writer.writeAll("];\n"); + return local; +} + fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { if (f.liveness.isUnused(inst)) return CValue.none; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e5356582e2..a607b7a753 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1760,6 +1760,7 @@ pub const FuncGen = struct { .array_elem_val => try self.airArrayElemVal(inst), .slice_elem_val => try self.airSliceElemVal(inst), + .slice_elem_ptr => try self.airSliceElemPtr(inst), .ptr_elem_val => try self.airPtrElemVal(inst), .ptr_elem_ptr => try self.airPtrElemPtr(inst), @@ -2157,12 +2158,20 @@ pub const FuncGen = struct { const slice = try self.resolveInst(bin_op.lhs); const index = try self.resolveInst(bin_op.rhs); - const base_ptr = self.builder.buildExtractValue(slice, 0, ""); - const indices: [1]*const llvm.Value = .{index}; - const ptr = self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); + const ptr = self.sliceElemPtr(slice, index); return self.load(ptr, slice_ty); } + fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + if (self.liveness.isUnused(inst)) return null; + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; + + const slice = try self.resolveInst(bin_op.lhs); + const index = try self.resolveInst(bin_op.rhs); + return self.sliceElemPtr(slice, index); + } + fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { if (self.liveness.isUnused(inst)) return null; @@ -3575,6 +3584,16 @@ pub const FuncGen = struct { return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, ""); } + fn sliceElemPtr( + self: *FuncGen, + slice: *const llvm.Value, + index: *const llvm.Value, + ) *const llvm.Value { + const base_ptr = self.builder.buildExtractValue(slice, 0, ""); + const indices: [1]*const llvm.Value = .{index}; + return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); + } + fn getIntrinsic(self: *FuncGen, name: []const u8) *const llvm.Value { const id = llvm.lookupIntrinsicID(name.ptr, name.len); assert(id != 0); |
