diff options
| author | Robin Voetter <robin@voetter.nl> | 2023-05-19 14:17:58 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2023-05-20 17:30:23 +0200 |
| commit | 65157d30ab90de01da583dd97ee2409d8ad8aeb0 (patch) | |
| tree | 0c9767c8c174bfd55fd0d9c5525d4ddef1ec7ceb /src/codegen/spirv.zig | |
| parent | 77b8bf2b82ffa71fc8ecf85f6780130f27dbeaf3 (diff) | |
| download | zig-65157d30ab90de01da583dd97ee2409d8ad8aeb0.tar.gz zig-65157d30ab90de01da583dd97ee2409d8ad8aeb0.zip | |
spirv: ptr_elem_val
Implements the ptr_elem_val air tag. Implementation is unified
with ptr_elem_ptr.
Diffstat (limited to 'src/codegen/spirv.zig')
| -rw-r--r-- | src/codegen/spirv.zig | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 21a3dab1bd..b372a38ddf 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1765,6 +1765,7 @@ pub const DeclGen = struct { .slice_elem_ptr => try self.airSliceElemPtr(inst), .slice_elem_val => try self.airSliceElemVal(inst), .ptr_elem_ptr => try self.airPtrElemPtr(inst), + .ptr_elem_val => try self.airPtrElemVal(inst), .struct_field_val => try self.airStructFieldVal(inst), @@ -2482,29 +2483,52 @@ pub const DeclGen = struct { return try self.load(slice_ty, elem_ptr); } + fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef { + // Construct new pointer type for the resulting pointer + const elem_ty = ptr_ty.elemType2(); // use elemType() so that we get T for *[N]T. + const elem_ty_ref = try self.resolveType(elem_ty, .direct); + const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace()), 0); + if (ptr_ty.isSinglePointer()) { + // Pointer-to-array. In this case, the resulting pointer is not of the same type + // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain. + return try self.accessChain(elem_ptr_ty_ref, ptr_id, &.{index_id}); + } else { + // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain + return try self.ptrAccessChain(elem_ptr_ty_ref, ptr_id, index_id, &.{}); + } + } + fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { 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 ptr_ty = self.air.typeOf(bin_op.lhs); - const result_ty = self.air.typeOfIndex(inst); const elem_ty = ptr_ty.childType(); // TODO: Make this return a null ptr or something if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null; - const result_ty_ref = try self.resolveType(result_ty, .direct); - const base_ptr = try self.resolve(bin_op.lhs); - const rhs = try self.resolve(bin_op.rhs); + const ptr_id = try self.resolve(bin_op.lhs); + const index_id = try self.resolve(bin_op.rhs); + return try self.ptrElemPtr(ptr_ty, ptr_id, index_id); + } - if (ptr_ty.isSinglePointer()) { - // Pointer-to-array. In this case, the resulting pointer is not of the same type - // as the ptr_ty, and hence we need to use accessChain. - return try self.accessChain(result_ty_ref, base_ptr, &.{rhs}); - } else { - // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain - return try self.ptrAccessChain(result_ty_ref, base_ptr, rhs, &.{}); - } + fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const ptr_ty = self.air.typeOf(bin_op.lhs); + const ptr_id = try self.resolve(bin_op.lhs); + const index_id = try self.resolve(bin_op.rhs); + + const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id); + + // If we have a pointer-to-array, construct an element pointer to use with load() + // If we pass ptr_ty directly, it will attempt to load the entire array rather than + // just an element. + var elem_ptr_info = ptr_ty.ptrInfo(); + elem_ptr_info.data.size = .One; + const elem_ptr_ty = Type.initPayload(&elem_ptr_info.base); + + return try self.load(elem_ptr_ty, elem_ptr_id); } fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
