| ... | @@ -457,14 +457,8 @@ pub const DeclGen = struct { | ... | @@ -457,14 +457,8 @@ pub const DeclGen = struct { |
| 457 | const members = spv_composite_ty.payload(.@"struct").members; | 457 | const members = spv_composite_ty.payload(.@"struct").members; |
| 458 | for (constituents, members, 0..) |constitent_id, member, index| { | 458 | for (constituents, members, 0..) |constitent_id, member, index| { |
| 459 | const index_id = try self.constInt(index_ty_ref, index); | 459 | const index_id = try self.constInt(index_ty_ref, index); |
| 460 | const ptr_id = self.spv.allocId(); | | |
| 461 | const ptr_member_ty_ref = try self.spv.ptrType(member.ty, .Generic, 0); | 460 | const ptr_member_ty_ref = try self.spv.ptrType(member.ty, .Generic, 0); |
| 462 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ | 461 | const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{index_id}); |
| 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 | }); | | |
| 468 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | 462 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| 469 | .pointer = ptr_id, | 463 | .pointer = ptr_id, |
| 470 | .object = constitent_id, | 464 | .object = constitent_id, |
| ... | @@ -2089,6 +2083,44 @@ pub const DeclGen = struct { | ... | @@ -2089,6 +2083,44 @@ pub const DeclGen = struct { |
| 2089 | return result_id; | 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 | fn cmp( | 2124 | fn cmp( |
| 2093 | self: *DeclGen, | 2125 | self: *DeclGen, |
| 2094 | comptime op: std.math.CompareOperator, | 2126 | comptime op: std.math.CompareOperator, |
| ... | @@ -2353,12 +2385,12 @@ pub const DeclGen = struct { | ... | @@ -2353,12 +2385,12 @@ pub const DeclGen = struct { |
| 2353 | const slice = try self.resolve(bin_op.lhs); | 2385 | const slice = try self.resolve(bin_op.lhs); |
| 2354 | const index = try self.resolve(bin_op.rhs); | 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 | const slice_ptr = blk: { | 2390 | const slice_ptr = blk: { |
| 2359 | const result_id = self.spv.allocId(); | 2391 | const result_id = self.spv.allocId(); |
| 2360 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ | 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 | .id_result = result_id, | 2394 | .id_result = result_id, |
| 2363 | .composite = slice, | 2395 | .composite = slice, |
| 2364 | .indexes = &.{0}, | 2396 | .indexes = &.{0}, |
| ... | @@ -2366,14 +2398,7 @@ pub const DeclGen = struct { | ... | @@ -2366,14 +2398,7 @@ pub const DeclGen = struct { |
| 2366 | break :blk result_id; | 2398 | break :blk result_id; |
| 2367 | }; | 2399 | }; |
| 2368 | | 2400 | |
| 2369 | const result_id = self.spv.allocId(); | 2401 | return try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index, &.{}); |
| 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; | | |
| 2377 | } | 2402 | } |
| 2378 | | 2403 | |
| 2379 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2404 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | @@ -2385,12 +2410,12 @@ pub const DeclGen = struct { | ... | @@ -2385,12 +2410,12 @@ pub const DeclGen = struct { |
| 2385 | const index = try self.resolve(bin_op.rhs); | 2410 | const index = try self.resolve(bin_op.rhs); |
| 2386 | | 2411 | |
| 2387 | var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 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 | const slice_ptr = blk: { | 2415 | const slice_ptr = blk: { |
| 2391 | const result_id = self.spv.allocId(); | 2416 | const result_id = self.spv.allocId(); |
| 2392 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ | 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 | .id_result = result_id, | 2419 | .id_result = result_id, |
| 2395 | .composite = slice, | 2420 | .composite = slice, |
| 2396 | .indexes = &.{0}, | 2421 | .indexes = &.{0}, |
| ... | @@ -2398,17 +2423,7 @@ pub const DeclGen = struct { | ... | @@ -2398,17 +2423,7 @@ pub const DeclGen = struct { |
| 2398 | break :blk result_id; | 2423 | break :blk result_id; |
| 2399 | }; | 2424 | }; |
| 2400 | | 2425 | |
| 2401 | const elem_ptr = blk: { | 2426 | const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index, &.{}); |
| 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 | | | |
| 2412 | return try self.load(slice_ty, elem_ptr); | 2427 | return try self.load(slice_ty, elem_ptr); |
| 2413 | } | 2428 | } |
| 2414 | | 2429 | |
| ... | @@ -2423,19 +2438,18 @@ pub const DeclGen = struct { | ... | @@ -2423,19 +2438,18 @@ pub const DeclGen = struct { |
| 2423 | // TODO: Make this return a null ptr or something | 2438 | // TODO: Make this return a null ptr or something |
| 2424 | if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null; | 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 | const base_ptr = try self.resolve(bin_op.lhs); | 2442 | const base_ptr = try self.resolve(bin_op.lhs); |
| 2428 | const rhs = try self.resolve(bin_op.rhs); | 2443 | const rhs = try self.resolve(bin_op.rhs); |
| 2429 | | 2444 | |
| 2430 | const result_id = self.spv.allocId(); | 2445 | if (ptr_ty.isSinglePointer()) { |
| 2431 | const indexes = [_]IdRef{rhs}; | 2446 | // Pointer-to-array. In this case, the resulting pointer is not of the same type |
| 2432 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ | 2447 | // as the ptr_ty, and hence we need to use accessChain. |
| 2433 | .id_result_type = result_type_id, | 2448 | return try self.accessChain(result_ty_ref, base_ptr, &.{rhs}); |
| 2434 | .id_result = result_id, | 2449 | } else { |
| 2435 | .base = base_ptr, | 2450 | // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain |
| 2436 | .indexes = &indexes, | 2451 | return try self.ptrAccessChain(result_ty_ref, base_ptr, rhs, &.{}); |
| 2437 | }); | 2452 | } |
| 2438 | return result_id; | | |
| 2439 | } | 2453 | } |
| 2440 | | 2454 | |
| 2441 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2455 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | @@ -2480,16 +2494,8 @@ pub const DeclGen = struct { | ... | @@ -2480,16 +2494,8 @@ pub const DeclGen = struct { |
| 2480 | const u32_ty_id = self.typeId(try self.intType(.unsigned, 32)); | 2494 | const u32_ty_id = self.typeId(try self.intType(.unsigned, 32)); |
| 2481 | const field_index_id = self.spv.allocId(); | 2495 | const field_index_id = self.spv.allocId(); |
| 2482 | try self.spv.emitConstant(u32_ty_id, field_index_id, .{ .uint32 = field_index }); | 2496 | try self.spv.emitConstant(u32_ty_id, field_index_id, .{ .uint32 = field_index }); |
| 2483 | const result_id = self.spv.allocId(); | 2497 | const result_ty_ref = try self.resolveType(result_ptr_ty, .direct); |
| 2484 | const result_type_id = try self.resolveTypeId(result_ptr_ty); | 2498 | return try self.accessChain(result_ty_ref, object_ptr, &.{field_index_id}); |
| 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; | | |
| 2493 | }, | 2499 | }, |
| 2494 | }, | 2500 | }, |
| 2495 | else => unreachable, // TODO | 2501 | else => unreachable, // TODO |