| ... | ... | @@ -1018,7 +1018,7 @@ const NavGen = struct { |
| 1018 | 1018 | const comp_ty_id = try self.resolveType(ty, .direct); |
| 1019 | 1019 | return try self.constructComposite(comp_ty_id, constituents.items); |
| 1020 | 1020 | }, |
| 1021 | | .tuple_type => unreachable, // TODO |
| 1021 | .tuple_type => return self.todo("implement tuple types", .{}), |
| 1022 | 1022 | else => unreachable, |
| 1023 | 1023 | }, |
| 1024 | 1024 | .un => |un| { |
| ... | ... | @@ -1255,6 +1255,7 @@ const NavGen = struct { |
| 1255 | 1255 | |
| 1256 | 1256 | fn ptrType(self: *NavGen, child_ty: Type, storage_class: StorageClass, child_repr: Repr) !IdRef { |
| 1257 | 1257 | const zcu = self.pt.zcu; |
| 1258 | const ip = &zcu.intern_pool; |
| 1258 | 1259 | const key = .{ child_ty.toIntern(), storage_class, child_repr }; |
| 1259 | 1260 | const entry = try self.ptr_types.getOrPut(self.gpa, key); |
| 1260 | 1261 | if (entry.found_existing) { |
| ... | ... | @@ -1285,7 +1286,12 @@ const NavGen = struct { |
| 1285 | 1286 | } |
| 1286 | 1287 | } |
| 1287 | 1288 | |
| 1288 | | try self.spv.decorate(result_id, .{ .ArrayStride = .{ .array_stride = @intCast(child_ty.abiSize(zcu)) } }); |
| 1289 | switch (ip.indexToKey(child_ty.toIntern())) { |
| 1290 | .func_type, .opaque_type => {}, |
| 1291 | else => { |
| 1292 | try self.spv.decorate(result_id, .{ .ArrayStride = .{ .array_stride = @intCast(child_ty.abiSize(zcu)) } }); |
| 1293 | }, |
| 1294 | } |
| 1289 | 1295 | } |
| 1290 | 1296 | |
| 1291 | 1297 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{ |
| ... | ... | @@ -1704,7 +1710,10 @@ const NavGen = struct { |
| 1704 | 1710 | return result_id; |
| 1705 | 1711 | }, |
| 1706 | 1712 | .@"union" => return try self.resolveUnionType(ty), |
| 1707 | | .error_set => return try self.resolveType(Type.u16, repr), |
| 1713 | .error_set => { |
| 1714 | const err_int_ty = try pt.errorIntType(); |
| 1715 | return try self.resolveType(err_int_ty, repr); |
| 1716 | }, |
| 1708 | 1717 | .error_union => { |
| 1709 | 1718 | const payload_ty = ty.errorUnionPayload(zcu); |
| 1710 | 1719 | const error_ty_id = try self.resolveType(Type.anyerror, .indirect); |
| ... | ... | @@ -2329,7 +2338,7 @@ const NavGen = struct { |
| 2329 | 2338 | // NOTE: Vulkan's FMA instruction does *NOT* produce the right values! |
| 2330 | 2339 | // its precision guarantees do NOT match zigs and it does NOT match OpenCLs! |
| 2331 | 2340 | // it needs to be emulated! |
| 2332 | | .vulkan, .opengl => unreachable, // TODO: See above |
| 2341 | .vulkan, .opengl => return self.todo("implement fma operation for {s} os", .{@tagName(target.os.tag)}), |
| 2333 | 2342 | else => unreachable, |
| 2334 | 2343 | }; |
| 2335 | 2344 | |
| ... | ... | @@ -2529,12 +2538,12 @@ const NavGen = struct { |
| 2529 | 2538 | .vulkan, .opengl => switch (op) { |
| 2530 | 2539 | .i_abs => 5, // SAbs |
| 2531 | 2540 | .f_abs => 4, // FAbs |
| 2532 | | .clz => unreachable, // TODO |
| 2533 | | .ctz => unreachable, // TODO |
| 2534 | 2541 | .floor => 8, // Floor |
| 2535 | 2542 | .ceil => 9, // Ceil |
| 2536 | 2543 | .trunc => 3, // Trunc |
| 2537 | 2544 | .round => 1, // Round |
| 2545 | .clz, |
| 2546 | .ctz, |
| 2538 | 2547 | .sqrt, |
| 2539 | 2548 | .sin, |
| 2540 | 2549 | .cos, |
| ... | ... | @@ -2544,7 +2553,7 @@ const NavGen = struct { |
| 2544 | 2553 | .log, |
| 2545 | 2554 | .log2, |
| 2546 | 2555 | .log10, |
| 2547 | | => unreachable, // TODO |
| 2556 | => return self.todo("implement unary operation '{s}' for {s} os", .{ @tagName(op), @tagName(target.os.tag) }), |
| 2548 | 2557 | else => unreachable, |
| 2549 | 2558 | }, |
| 2550 | 2559 | else => unreachable, |
| ... | ... | @@ -2810,6 +2819,8 @@ const NavGen = struct { |
| 2810 | 2819 | /// TODO is to also write out the error as a function call parameter, and to somehow fetch |
| 2811 | 2820 | /// the name of an error in the text executor. |
| 2812 | 2821 | fn generateTestEntryPoint(self: *NavGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void { |
| 2822 | const target = self.spv.target; |
| 2823 | |
| 2813 | 2824 | const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct); |
| 2814 | 2825 | const ptr_anyerror_ty = try self.pt.ptrType(.{ |
| 2815 | 2826 | .child = Type.anyerror.toIntern(), |
| ... | ... | @@ -2819,12 +2830,12 @@ const NavGen = struct { |
| 2819 | 2830 | |
| 2820 | 2831 | const spv_decl_index = try self.spv.allocDecl(.func); |
| 2821 | 2832 | const kernel_id = self.spv.declPtr(spv_decl_index).result_id; |
| 2822 | | // for some reason we don't need to decorate the push constant here... |
| 2823 | | try self.spv.declareDeclDeps(spv_decl_index, &.{spv_test_decl_index}); |
| 2824 | 2833 | |
| 2825 | | const section = &self.spv.sections.functions; |
| 2834 | var decl_deps = std.ArrayList(SpvModule.Decl.Index).init(self.gpa); |
| 2835 | defer decl_deps.deinit(); |
| 2836 | try decl_deps.append(spv_test_decl_index); |
| 2826 | 2837 | |
| 2827 | | const target = self.spv.target; |
| 2838 | const section = &self.spv.sections.functions; |
| 2828 | 2839 | |
| 2829 | 2840 | const p_error_id = self.spv.allocId(); |
| 2830 | 2841 | switch (target.os.tag) { |
| ... | ... | @@ -2904,6 +2915,7 @@ const NavGen = struct { |
| 2904 | 2915 | |
| 2905 | 2916 | const spv_err_decl_index = self.object.error_push_constant.?.push_constant_ptr; |
| 2906 | 2917 | const push_constant_id = self.spv.declPtr(spv_err_decl_index).result_id; |
| 2918 | try decl_deps.append(spv_err_decl_index); |
| 2907 | 2919 | |
| 2908 | 2920 | const zero_id = try self.constInt(Type.u32, 0); |
| 2909 | 2921 | // We cannot use OpInBoundsAccessChain to dereference cross-storage class, so we have to use |
| ... | ... | @@ -2953,6 +2965,7 @@ const NavGen = struct { |
| 2953 | 2965 | else => unreachable, |
| 2954 | 2966 | }; |
| 2955 | 2967 | |
| 2968 | try self.spv.declareDeclDeps(spv_decl_index, decl_deps.items); |
| 2956 | 2969 | try self.spv.declareEntryPoint(spv_decl_index, test_name, execution_mode); |
| 2957 | 2970 | } |
| 2958 | 2971 | |
| ... | ... | @@ -3372,6 +3385,7 @@ const NavGen = struct { |
| 3372 | 3385 | .switch_br => return self.airSwitchBr(inst), |
| 3373 | 3386 | .unreach, .trap => return self.airUnreach(), |
| 3374 | 3387 | |
| 3388 | .dbg_empty_stmt => return, |
| 3375 | 3389 | .dbg_stmt => return self.airDbgStmt(inst), |
| 3376 | 3390 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 3377 | 3391 | .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => return self.airDbgVar(inst), |
| ... | ... | @@ -3651,6 +3665,7 @@ const NavGen = struct { |
| 3651 | 3665 | } |
| 3652 | 3666 | |
| 3653 | 3667 | fn abs(self: *NavGen, result_ty: Type, value: Temporary) !Temporary { |
| 3668 | const zcu = self.pt.zcu; |
| 3654 | 3669 | const operand_info = self.arithmeticTypeInfo(value.ty); |
| 3655 | 3670 | |
| 3656 | 3671 | switch (operand_info.class) { |
| ... | ... | @@ -3658,11 +3673,9 @@ const NavGen = struct { |
| 3658 | 3673 | .integer, .strange_integer => { |
| 3659 | 3674 | const abs_value = try self.buildUnary(.i_abs, value); |
| 3660 | 3675 | |
| 3661 | | // TODO: We may need to bitcast the result to a uint |
| 3662 | | // depending on the result type. Do that when |
| 3663 | | // bitCast is implemented for vectors. |
| 3664 | | // This is only relevant for Vulkan |
| 3665 | | assert(self.spv.hasFeature(.kernel)); // TODO |
| 3676 | if (value.ty.intInfo(zcu).signedness == .signed and self.spv.hasFeature(.shader)) { |
| 3677 | return self.todo("perform bitcast after @abs", .{}); |
| 3678 | } |
| 3666 | 3679 | |
| 3667 | 3680 | return try self.normalize(abs_value, self.arithmeticTypeInfo(result_ty)); |
| 3668 | 3681 | }, |
| ... | ... | @@ -3980,8 +3993,6 @@ const NavGen = struct { |
| 3980 | 3993 | .float, .bool => unreachable, |
| 3981 | 3994 | } |
| 3982 | 3995 | |
| 3983 | | assert(self.spv.hasFeature(.kernel)); // TODO |
| 3984 | | |
| 3985 | 3996 | const count = try self.buildUnary(op, operand); |
| 3986 | 3997 | |
| 3987 | 3998 | // Result of OpenCL ctz/clz returns operand.ty, and we want result_ty. |
| ... | ... | @@ -4307,7 +4318,8 @@ const NavGen = struct { |
| 4307 | 4318 | }, |
| 4308 | 4319 | .error_set => { |
| 4309 | 4320 | assert(!is_vector); |
| 4310 | | return try self.cmp(op, lhs.pun(Type.u16), rhs.pun(Type.u16)); |
| 4321 | const err_int_ty = try pt.errorIntType(); |
| 4322 | return try self.cmp(op, lhs.pun(err_int_ty), rhs.pun(err_int_ty)); |
| 4311 | 4323 | }, |
| 4312 | 4324 | .pointer => { |
| 4313 | 4325 | assert(!is_vector); |
| ... | ... | @@ -4411,7 +4423,7 @@ const NavGen = struct { |
| 4411 | 4423 | else => unreachable, |
| 4412 | 4424 | }; |
| 4413 | 4425 | }, |
| 4414 | | else => unreachable, |
| 4426 | else => |ty| return self.todo("implement cmp operation for '{s}' type", .{@tagName(ty)}), |
| 4415 | 4427 | } |
| 4416 | 4428 | |
| 4417 | 4429 | const info = self.arithmeticTypeInfo(scalar_ty); |
| ... | ... | @@ -5233,13 +5245,13 @@ const NavGen = struct { |
| 5233 | 5245 | return self.accessChain(result_ty_id, object_ptr, &.{field_index}); |
| 5234 | 5246 | }, |
| 5235 | 5247 | .@"struct" => switch (object_ty.containerLayout(zcu)) { |
| 5236 | | .@"packed" => unreachable, // TODO |
| 5248 | .@"packed" => return self.todo("implement field access for packed structs", .{}), |
| 5237 | 5249 | else => { |
| 5238 | 5250 | return try self.accessChain(result_ty_id, object_ptr, &.{field_index}); |
| 5239 | 5251 | }, |
| 5240 | 5252 | }, |
| 5241 | 5253 | .@"union" => switch (object_ty.containerLayout(zcu)) { |
| 5242 | | .@"packed" => unreachable, // TODO |
| 5254 | .@"packed" => return self.todo("implement field access for packed unions", .{}), |
| 5243 | 5255 | else => { |
| 5244 | 5256 | const layout = self.unionLayout(object_ty); |
| 5245 | 5257 | if (!layout.has_payload) { |