| ... | ... | @@ -457,14 +457,8 @@ pub const DeclGen = struct { |
| 457 | 457 | const members = spv_composite_ty.payload(.@"struct").members; |
| 458 | 458 | for (constituents, members, 0..) |constitent_id, member, index| { |
| 459 | 459 | const index_id = try self.constInt(index_ty_ref, index); |
| 460 | | const ptr_id = self.spv.allocId(); |
| 461 | 460 | const ptr_member_ty_ref = try self.spv.ptrType(member.ty, .Generic, 0); |
| 462 | | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| 463 | | .id_result_type = self.typeId(ptr_member_ty_ref), |
| 464 | | .id_result = ptr_id, |
| 465 | | .base = ptr_composite_id, |
| 466 | | .indexes = &.{index_id}, |
| 467 | | }); |
| 461 | const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{index_id}); |
| 468 | 462 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| 469 | 463 | .pointer = ptr_id, |
| 470 | 464 | .object = constitent_id, |
| ... | ... | @@ -2089,6 +2083,44 @@ pub const DeclGen = struct { |
| 2089 | 2083 | return result_id; |
| 2090 | 2084 | } |
| 2091 | 2085 | |
| 2086 | /// AccessChain is essentially PtrAccessChain with 0 as initial argument. The effective |
| 2087 | /// difference lies in whether the resulting type of the first dereference will be the |
| 2088 | /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain |
| 2089 | /// is the latter and PtrAccessChain is the former. |
| 2090 | fn accessChain( |
| 2091 | self: *DeclGen, |
| 2092 | result_ty_ref: SpvType.Ref, |
| 2093 | base: IdRef, |
| 2094 | indexes: []const IdRef, |
| 2095 | ) !IdRef { |
| 2096 | const result_id = self.spv.allocId(); |
| 2097 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| 2098 | .id_result_type = self.typeId(result_ty_ref), |
| 2099 | .id_result = result_id, |
| 2100 | .base = base, |
| 2101 | .indexes = indexes, |
| 2102 | }); |
| 2103 | return result_id; |
| 2104 | } |
| 2105 | |
| 2106 | fn ptrAccessChain( |
| 2107 | self: *DeclGen, |
| 2108 | result_ty_ref: SpvType.Ref, |
| 2109 | base: IdRef, |
| 2110 | element: IdRef, |
| 2111 | indexes: []const IdRef, |
| 2112 | ) !IdRef { |
| 2113 | const result_id = self.spv.allocId(); |
| 2114 | try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ |
| 2115 | .id_result_type = self.typeId(result_ty_ref), |
| 2116 | .id_result = result_id, |
| 2117 | .base = base, |
| 2118 | .element = element, |
| 2119 | .indexes = indexes, |
| 2120 | }); |
| 2121 | return result_id; |
| 2122 | } |
| 2123 | |
| 2092 | 2124 | fn cmp( |
| 2093 | 2125 | self: *DeclGen, |
| 2094 | 2126 | comptime op: std.math.CompareOperator, |
| ... | ... | @@ -2353,12 +2385,12 @@ pub const DeclGen = struct { |
| 2353 | 2385 | const slice = try self.resolve(bin_op.lhs); |
| 2354 | 2386 | const index = try self.resolve(bin_op.rhs); |
| 2355 | 2387 | |
| 2356 | | const spv_ptr_ty = try self.resolveTypeId(self.air.typeOfIndex(inst)); |
| 2388 | const ptr_ty_ref = try self.resolveType(self.air.typeOfIndex(inst), .direct); |
| 2357 | 2389 | |
| 2358 | 2390 | const slice_ptr = blk: { |
| 2359 | 2391 | const result_id = self.spv.allocId(); |
| 2360 | 2392 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ |
| 2361 | | .id_result_type = spv_ptr_ty, |
| 2393 | .id_result_type = self.typeId(ptr_ty_ref), |
| 2362 | 2394 | .id_result = result_id, |
| 2363 | 2395 | .composite = slice, |
| 2364 | 2396 | .indexes = &.{0}, |
| ... | ... | @@ -2366,14 +2398,7 @@ pub const DeclGen = struct { |
| 2366 | 2398 | break :blk result_id; |
| 2367 | 2399 | }; |
| 2368 | 2400 | |
| 2369 | | const result_id = self.spv.allocId(); |
| 2370 | | try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ |
| 2371 | | .id_result_type = spv_ptr_ty, |
| 2372 | | .id_result = result_id, |
| 2373 | | .base = slice_ptr, |
| 2374 | | .element = index, |
| 2375 | | }); |
| 2376 | | return result_id; |
| 2401 | return try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index, &.{}); |
| 2377 | 2402 | } |
| 2378 | 2403 | |
| 2379 | 2404 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | ... | @@ -2385,12 +2410,12 @@ pub const DeclGen = struct { |
| 2385 | 2410 | const index = try self.resolve(bin_op.rhs); |
| 2386 | 2411 | |
| 2387 | 2412 | var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 2388 | | const ptr_ty_id = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf)); |
| 2413 | const ptr_ty_ref = try self.resolveType(slice_ty.slicePtrFieldType(&slice_buf), .direct); |
| 2389 | 2414 | |
| 2390 | 2415 | const slice_ptr = blk: { |
| 2391 | 2416 | const result_id = self.spv.allocId(); |
| 2392 | 2417 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ |
| 2393 | | .id_result_type = ptr_ty_id, |
| 2418 | .id_result_type = self.typeId(ptr_ty_ref), |
| 2394 | 2419 | .id_result = result_id, |
| 2395 | 2420 | .composite = slice, |
| 2396 | 2421 | .indexes = &.{0}, |
| ... | ... | @@ -2398,17 +2423,7 @@ pub const DeclGen = struct { |
| 2398 | 2423 | break :blk result_id; |
| 2399 | 2424 | }; |
| 2400 | 2425 | |
| 2401 | | const elem_ptr = blk: { |
| 2402 | | const result_id = self.spv.allocId(); |
| 2403 | | try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ |
| 2404 | | .id_result_type = ptr_ty_id, |
| 2405 | | .id_result = result_id, |
| 2406 | | .base = slice_ptr, |
| 2407 | | .element = index, |
| 2408 | | }); |
| 2409 | | break :blk result_id; |
| 2410 | | }; |
| 2411 | | |
| 2426 | const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index, &.{}); |
| 2412 | 2427 | return try self.load(slice_ty, elem_ptr); |
| 2413 | 2428 | } |
| 2414 | 2429 | |
| ... | ... | @@ -2423,19 +2438,18 @@ pub const DeclGen = struct { |
| 2423 | 2438 | // TODO: Make this return a null ptr or something |
| 2424 | 2439 | if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null; |
| 2425 | 2440 | |
| 2426 | | const result_type_id = try self.resolveTypeId(result_ty); |
| 2441 | const result_ty_ref = try self.resolveType(result_ty, .direct); |
| 2427 | 2442 | const base_ptr = try self.resolve(bin_op.lhs); |
| 2428 | 2443 | const rhs = try self.resolve(bin_op.rhs); |
| 2429 | 2444 | |
| 2430 | | const result_id = self.spv.allocId(); |
| 2431 | | const indexes = [_]IdRef{rhs}; |
| 2432 | | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| 2433 | | .id_result_type = result_type_id, |
| 2434 | | .id_result = result_id, |
| 2435 | | .base = base_ptr, |
| 2436 | | .indexes = &indexes, |
| 2437 | | }); |
| 2438 | | return result_id; |
| 2445 | if (ptr_ty.isSinglePointer()) { |
| 2446 | // Pointer-to-array. In this case, the resulting pointer is not of the same type |
| 2447 | // as the ptr_ty, and hence we need to use accessChain. |
| 2448 | return try self.accessChain(result_ty_ref, base_ptr, &.{rhs}); |
| 2449 | } else { |
| 2450 | // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain |
| 2451 | return try self.ptrAccessChain(result_ty_ref, base_ptr, rhs, &.{}); |
| 2452 | } |
| 2439 | 2453 | } |
| 2440 | 2454 | |
| 2441 | 2455 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | ... | @@ -2480,16 +2494,8 @@ pub const DeclGen = struct { |
| 2480 | 2494 | const u32_ty_id = self.typeId(try self.intType(.unsigned, 32)); |
| 2481 | 2495 | const field_index_id = self.spv.allocId(); |
| 2482 | 2496 | try self.spv.emitConstant(u32_ty_id, field_index_id, .{ .uint32 = field_index }); |
| 2483 | | const result_id = self.spv.allocId(); |
| 2484 | | const result_type_id = try self.resolveTypeId(result_ptr_ty); |
| 2485 | | const indexes = [_]IdRef{field_index_id}; |
| 2486 | | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| 2487 | | .id_result_type = result_type_id, |
| 2488 | | .id_result = result_id, |
| 2489 | | .base = object_ptr, |
| 2490 | | .indexes = &indexes, |
| 2491 | | }); |
| 2492 | | return result_id; |
| 2497 | const result_ty_ref = try self.resolveType(result_ptr_ty, .direct); |
| 2498 | return try self.accessChain(result_ty_ref, object_ptr, &.{field_index_id}); |
| 2493 | 2499 | }, |
| 2494 | 2500 | }, |
| 2495 | 2501 | else => unreachable, // TODO |