| ... | ... | @@ -1016,7 +1016,7 @@ const DeclGen = struct { |
| 1016 | 1016 | const elem_ty = Type.fromInterned(array_type.child); |
| 1017 | 1017 | const elem_ty_ref = try self.resolveType(elem_ty, .indirect); |
| 1018 | 1018 | |
| 1019 | | const constituents = try self.gpa.alloc(IdRef, @as(u32, @intCast(ty.arrayLenIncludingSentinel(mod)))); |
| 1019 | const constituents = try self.gpa.alloc(IdRef, @intCast(ty.arrayLenIncludingSentinel(mod))); |
| 1020 | 1020 | defer self.gpa.free(constituents); |
| 1021 | 1021 | |
| 1022 | 1022 | switch (aggregate.storage) { |
| ... | ... | @@ -1736,7 +1736,6 @@ const DeclGen = struct { |
| 1736 | 1736 | .EnumLiteral, |
| 1737 | 1737 | .ComptimeFloat, |
| 1738 | 1738 | .ComptimeInt, |
| 1739 | | .Type, |
| 1740 | 1739 | => unreachable, // Must be comptime. |
| 1741 | 1740 | |
| 1742 | 1741 | else => |tag| return self.todo("Implement zig type '{}'", .{tag}), |
| ... | ... | @@ -2316,21 +2315,23 @@ const DeclGen = struct { |
| 2316 | 2315 | .sub, .sub_wrap, .sub_optimized => try self.airArithOp(inst, .OpFSub, .OpISub, .OpISub), |
| 2317 | 2316 | .mul, .mul_wrap, .mul_optimized => try self.airArithOp(inst, .OpFMul, .OpIMul, .OpIMul), |
| 2318 | 2317 | |
| 2318 | |
| 2319 | 2319 | .abs => try self.airAbs(inst), |
| 2320 | .floor => try self.airFloor(inst), |
| 2321 | |
| 2322 | .div_floor => try self.airDivFloor(inst), |
| 2320 | 2323 | |
| 2321 | 2324 | .div_float, |
| 2322 | 2325 | .div_float_optimized, |
| 2323 | | // TODO: Check that this is the right operation. |
| 2324 | 2326 | .div_trunc, |
| 2325 | | .div_trunc_optimized, |
| 2326 | | => try self.airArithOp(inst, .OpFDiv, .OpSDiv, .OpUDiv), |
| 2327 | | // TODO: Check if this is the right operation |
| 2328 | | .rem, |
| 2329 | | .rem_optimized, |
| 2330 | | => try self.airArithOp(inst, .OpFRem, .OpSRem, .OpSRem), |
| 2327 | .div_trunc_optimized => try self.airArithOp(inst, .OpFDiv, .OpSDiv, .OpUDiv), |
| 2328 | .rem, .rem_optimized => try self.airArithOp(inst, .OpFRem, .OpSRem, .OpSRem), |
| 2329 | .mod, .mod_optimized => try self.airArithOp(inst, .OpFMod, .OpSMod, .OpSMod), |
| 2330 | |
| 2331 | 2331 | |
| 2332 | 2332 | .add_with_overflow => try self.airAddSubOverflow(inst, .OpIAdd, .OpULessThan, .OpSLessThan), |
| 2333 | 2333 | .sub_with_overflow => try self.airAddSubOverflow(inst, .OpISub, .OpUGreaterThan, .OpSGreaterThan), |
| 2334 | .mul_with_overflow => try self.airMulOverflow(inst), |
| 2334 | 2335 | .shl_with_overflow => try self.airShlOverflow(inst), |
| 2335 | 2336 | |
| 2336 | 2337 | .mul_add => try self.airMulAdd(inst), |
| ... | ... | @@ -2340,7 +2341,7 @@ const DeclGen = struct { |
| 2340 | 2341 | |
| 2341 | 2342 | .splat => try self.airSplat(inst), |
| 2342 | 2343 | .reduce, .reduce_optimized => try self.airReduce(inst), |
| 2343 | | .shuffle => try self.airShuffle(inst), |
| 2344 | .shuffle => try self.airShuffle(inst), |
| 2344 | 2345 | |
| 2345 | 2346 | .ptr_add => try self.airPtrAdd(inst), |
| 2346 | 2347 | .ptr_sub => try self.airPtrSub(inst), |
| ... | ... | @@ -2661,6 +2662,95 @@ const DeclGen = struct { |
| 2661 | 2662 | } |
| 2662 | 2663 | } |
| 2663 | 2664 | |
| 2665 | fn airDivFloor(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2666 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2667 | const lhs_id = try self.resolve(bin_op.lhs); |
| 2668 | const rhs_id = try self.resolve(bin_op.rhs); |
| 2669 | const ty = self.typeOfIndex(inst); |
| 2670 | const ty_ref = try self.resolveType(ty, .direct); |
| 2671 | const info = self.arithmeticTypeInfo(ty); |
| 2672 | switch (info.class) { |
| 2673 | .composite_integer => unreachable, // TODO |
| 2674 | .integer, .strange_integer => { |
| 2675 | const zero_id = try self.constInt(ty_ref, 0); |
| 2676 | const one_id = try self.constInt(ty_ref, 1); |
| 2677 | |
| 2678 | // (a ^ b) > 0 |
| 2679 | const bin_bitwise_id = try self.binOpSimple(ty, lhs_id, rhs_id, .OpBitwiseXor); |
| 2680 | const is_positive_id = try self.cmp(.gt, Type.bool, ty, bin_bitwise_id, zero_id); |
| 2681 | |
| 2682 | // a / b |
| 2683 | const positive_div_id = try self.arithOp(ty, lhs_id, rhs_id, .OpFDiv, .OpSDiv, .OpUDiv); |
| 2684 | |
| 2685 | // - (abs(a) + abs(b) - 1) / abs(b) |
| 2686 | const lhs_abs = try self.abs(ty, ty, lhs_id); |
| 2687 | const rhs_abs = try self.abs(ty, ty, rhs_id); |
| 2688 | const negative_div_lhs = try self.arithOp( |
| 2689 | ty, |
| 2690 | try self.arithOp(ty, lhs_abs, rhs_abs, .OpFAdd, .OpIAdd, .OpIAdd), |
| 2691 | one_id, |
| 2692 | .OpFSub, |
| 2693 | .OpISub, |
| 2694 | .OpISub, |
| 2695 | ); |
| 2696 | const negative_div_id = try self.arithOp(ty, negative_div_lhs, rhs_abs, .OpFDiv, .OpSDiv, .OpUDiv); |
| 2697 | const negated_negative_div_id = self.spv.allocId(); |
| 2698 | try self.func.body.emit(self.spv.gpa, .OpSNegate, .{ |
| 2699 | .id_result_type = self.typeId(ty_ref), |
| 2700 | .id_result = negated_negative_div_id, |
| 2701 | .operand = negative_div_id, |
| 2702 | }); |
| 2703 | |
| 2704 | const result_id = self.spv.allocId(); |
| 2705 | try self.func.body.emit(self.spv.gpa, .OpSelect, .{ |
| 2706 | .id_result_type = self.typeId(ty_ref), |
| 2707 | .id_result = result_id, |
| 2708 | .condition = is_positive_id, |
| 2709 | .object_1 = positive_div_id, |
| 2710 | .object_2 = negated_negative_div_id, |
| 2711 | }); |
| 2712 | return result_id; |
| 2713 | }, |
| 2714 | .float => { |
| 2715 | const div_id = try self.arithOp(ty, lhs_id, rhs_id, .OpFDiv, .OpSDiv, .OpUDiv); |
| 2716 | return try self.floor(ty, div_id); |
| 2717 | }, |
| 2718 | .bool => unreachable, |
| 2719 | } |
| 2720 | } |
| 2721 | |
| 2722 | fn airFloor(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2723 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2724 | const operand_id = try self.resolve(un_op); |
| 2725 | const result_ty = self.typeOfIndex(inst); |
| 2726 | return try self.floor(result_ty, operand_id); |
| 2727 | } |
| 2728 | |
| 2729 | fn floor(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef { |
| 2730 | const target = self.getTarget(); |
| 2731 | const ty_ref = try self.resolveType(ty, .direct); |
| 2732 | const ext_inst: Word = switch (target.os.tag) { |
| 2733 | .opencl => 25, |
| 2734 | .vulkan => 8, |
| 2735 | else => unreachable, |
| 2736 | }; |
| 2737 | const set_id = switch (target.os.tag) { |
| 2738 | .opencl => try self.spv.importInstructionSet(.@"OpenCL.std"), |
| 2739 | .vulkan => try self.spv.importInstructionSet(.@"GLSL.std.450"), |
| 2740 | else => unreachable, |
| 2741 | }; |
| 2742 | |
| 2743 | const result_id = self.spv.allocId(); |
| 2744 | try self.func.body.emit(self.spv.gpa, .OpExtInst, .{ |
| 2745 | .id_result_type = self.typeId(ty_ref), |
| 2746 | .id_result = result_id, |
| 2747 | .set = set_id, |
| 2748 | .instruction = .{ .inst = ext_inst }, |
| 2749 | .id_ref_4 = &.{operand_id}, |
| 2750 | }); |
| 2751 | return result_id; |
| 2752 | } |
| 2753 | |
| 2664 | 2754 | fn airArithOp( |
| 2665 | 2755 | self: *DeclGen, |
| 2666 | 2756 | inst: Air.Inst.Index, |
| ... | ... | @@ -2668,7 +2758,6 @@ const DeclGen = struct { |
| 2668 | 2758 | comptime sop: Opcode, |
| 2669 | 2759 | comptime uop: Opcode, |
| 2670 | 2760 | ) !?IdRef { |
| 2671 | | |
| 2672 | 2761 | // LHS and RHS are guaranteed to have the same type, and AIR guarantees |
| 2673 | 2762 | // the result to be the same as the LHS and RHS, which matches SPIR-V. |
| 2674 | 2763 | const ty = self.typeOfIndex(inst); |
| ... | ... | @@ -2700,8 +2789,8 @@ const DeclGen = struct { |
| 2700 | 2789 | return self.todo("binary operations for composite integers", .{}); |
| 2701 | 2790 | }, |
| 2702 | 2791 | .integer, .strange_integer => switch (info.signedness) { |
| 2703 | | .signed => @as(usize, 1), |
| 2704 | | .unsigned => @as(usize, 2), |
| 2792 | .signed => 1, |
| 2793 | .unsigned => 2, |
| 2705 | 2794 | }, |
| 2706 | 2795 | .float => 0, |
| 2707 | 2796 | .bool => unreachable, |
| ... | ... | @@ -2737,12 +2826,16 @@ const DeclGen = struct { |
| 2737 | 2826 | } |
| 2738 | 2827 | |
| 2739 | 2828 | fn airAbs(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2740 | | const target = self.getTarget(); |
| 2741 | 2829 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2742 | 2830 | const operand_id = try self.resolve(ty_op.operand); |
| 2743 | 2831 | // Note: operand_ty may be signed, while ty is always unsigned! |
| 2744 | 2832 | const operand_ty = self.typeOf(ty_op.operand); |
| 2745 | 2833 | const result_ty = self.typeOfIndex(inst); |
| 2834 | return try self.abs(result_ty, operand_ty, operand_id); |
| 2835 | } |
| 2836 | |
| 2837 | fn abs(self: *DeclGen, result_ty: Type, operand_ty: Type, operand_id: IdRef) !IdRef { |
| 2838 | const target = self.getTarget(); |
| 2746 | 2839 | const operand_info = self.arithmeticTypeInfo(operand_ty); |
| 2747 | 2840 | |
| 2748 | 2841 | var wip = try self.elementWise(result_ty, false); |
| ... | ... | @@ -2907,6 +3000,61 @@ const DeclGen = struct { |
| 2907 | 3000 | ); |
| 2908 | 3001 | } |
| 2909 | 3002 | |
| 3003 | fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3004 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3005 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3006 | const lhs = try self.resolve(extra.lhs); |
| 3007 | const rhs = try self.resolve(extra.rhs); |
| 3008 | |
| 3009 | const result_ty = self.typeOfIndex(inst); |
| 3010 | const operand_ty = self.typeOf(extra.lhs); |
| 3011 | const ov_ty = result_ty.structFieldType(1, self.module); |
| 3012 | |
| 3013 | const info = self.arithmeticTypeInfo(operand_ty); |
| 3014 | switch (info.class) { |
| 3015 | .composite_integer => return self.todo("overflow ops for composite integers", .{}), |
| 3016 | .strange_integer, .integer => {}, |
| 3017 | .float, .bool => unreachable, |
| 3018 | } |
| 3019 | |
| 3020 | var wip_result = try self.elementWise(operand_ty, true); |
| 3021 | defer wip_result.deinit(); |
| 3022 | var wip_ov = try self.elementWise(ov_ty, true); |
| 3023 | defer wip_ov.deinit(); |
| 3024 | |
| 3025 | const zero_id = try self.constInt(wip_result.ty_ref, 0); |
| 3026 | const zero_ov_id = try self.constInt(wip_ov.ty_ref, 0); |
| 3027 | const one_ov_id = try self.constInt(wip_ov.ty_ref, 1); |
| 3028 | |
| 3029 | for (wip_result.results, wip_ov.results, 0..) |*result_id, *ov_id, i| { |
| 3030 | const lhs_elem_id = try wip_result.elementAt(operand_ty, lhs, i); |
| 3031 | const rhs_elem_id = try wip_result.elementAt(operand_ty, rhs, i); |
| 3032 | |
| 3033 | result_id.* = try self.arithOp(wip_result.ty, lhs_elem_id, rhs_elem_id, .OpFMul, .OpIMul, .OpIMul); |
| 3034 | |
| 3035 | // (a != 0) and (x / a != b) |
| 3036 | const not_zero_id = try self.cmp(.neq, Type.bool, wip_result.ty, lhs_elem_id, zero_id); |
| 3037 | const res_rhs_id = try self.arithOp(wip_result.ty, result_id.*, lhs_elem_id, .OpFDiv, .OpSDiv, .OpUDiv); |
| 3038 | const res_rhs_not_rhs_id = try self.cmp(.neq, Type.bool, wip_result.ty, res_rhs_id, rhs_elem_id); |
| 3039 | const cond_id = try self.binOpSimple(Type.bool, not_zero_id, res_rhs_not_rhs_id, .OpLogicalAnd); |
| 3040 | |
| 3041 | ov_id.* = self.spv.allocId(); |
| 3042 | try self.func.body.emit(self.spv.gpa, .OpSelect, .{ |
| 3043 | .id_result_type = wip_ov.ty_id, |
| 3044 | .id_result = ov_id.*, |
| 3045 | .condition = cond_id, |
| 3046 | .object_1 = one_ov_id, |
| 3047 | .object_2 = zero_ov_id, |
| 3048 | }); |
| 3049 | } |
| 3050 | |
| 3051 | return try self.constructStruct( |
| 3052 | result_ty, |
| 3053 | &.{ operand_ty, ov_ty }, |
| 3054 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, |
| 3055 | ); |
| 3056 | } |
| 3057 | |
| 2910 | 3058 | fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2911 | 3059 | const mod = self.module; |
| 2912 | 3060 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | ... | @@ -3692,19 +3840,22 @@ const DeclGen = struct { |
| 3692 | 3840 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3693 | 3841 | const operand_ty = self.typeOf(ty_op.operand); |
| 3694 | 3842 | const operand_id = try self.resolve(ty_op.operand); |
| 3695 | | const operand_info = self.arithmeticTypeInfo(operand_ty); |
| 3696 | | const dest_ty = self.typeOfIndex(inst); |
| 3697 | | const dest_ty_id = try self.resolveTypeId(dest_ty); |
| 3843 | const result_ty = self.typeOfIndex(inst); |
| 3844 | const result_ty_ref = try self.resolveType(result_ty, .direct); |
| 3845 | return try self.floatFromInt(result_ty_ref, operand_ty, operand_id); |
| 3846 | } |
| 3698 | 3847 | |
| 3848 | fn floatFromInt(self: *DeclGen, result_ty_ref: CacheRef, operand_ty: Type, operand_id: IdRef) !IdRef { |
| 3849 | const operand_info = self.arithmeticTypeInfo(operand_ty); |
| 3699 | 3850 | const result_id = self.spv.allocId(); |
| 3700 | 3851 | switch (operand_info.signedness) { |
| 3701 | 3852 | .signed => try self.func.body.emit(self.spv.gpa, .OpConvertSToF, .{ |
| 3702 | | .id_result_type = dest_ty_id, |
| 3853 | .id_result_type = self.typeId(result_ty_ref), |
| 3703 | 3854 | .id_result = result_id, |
| 3704 | 3855 | .signed_value = operand_id, |
| 3705 | 3856 | }), |
| 3706 | 3857 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertUToF, .{ |
| 3707 | | .id_result_type = dest_ty_id, |
| 3858 | .id_result_type = self.typeId(result_ty_ref), |
| 3708 | 3859 | .id_result = result_id, |
| 3709 | 3860 | .unsigned_value = operand_id, |
| 3710 | 3861 | }), |
| ... | ... | @@ -3715,19 +3866,22 @@ const DeclGen = struct { |
| 3715 | 3866 | fn airIntFromFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3716 | 3867 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3717 | 3868 | const operand_id = try self.resolve(ty_op.operand); |
| 3718 | | const dest_ty = self.typeOfIndex(inst); |
| 3719 | | const dest_info = self.arithmeticTypeInfo(dest_ty); |
| 3720 | | const dest_ty_id = try self.resolveTypeId(dest_ty); |
| 3869 | const result_ty = self.typeOfIndex(inst); |
| 3870 | return try self.intFromFloat(result_ty, operand_id); |
| 3871 | } |
| 3721 | 3872 | |
| 3873 | fn intFromFloat(self: *DeclGen, result_ty: Type, operand_id: IdRef) !IdRef { |
| 3874 | const result_info = self.arithmeticTypeInfo(result_ty); |
| 3875 | const result_ty_ref = try self.resolveType(result_ty, .direct); |
| 3722 | 3876 | const result_id = self.spv.allocId(); |
| 3723 | | switch (dest_info.signedness) { |
| 3877 | switch (result_info.signedness) { |
| 3724 | 3878 | .signed => try self.func.body.emit(self.spv.gpa, .OpConvertFToS, .{ |
| 3725 | | .id_result_type = dest_ty_id, |
| 3879 | .id_result_type = self.typeId(result_ty_ref), |
| 3726 | 3880 | .id_result = result_id, |
| 3727 | 3881 | .float_value = operand_id, |
| 3728 | 3882 | }), |
| 3729 | 3883 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertFToU, .{ |
| 3730 | | .id_result_type = dest_ty_id, |
| 3884 | .id_result_type = self.typeId(result_ty_ref), |
| 3731 | 3885 | .id_result = result_id, |
| 3732 | 3886 | .float_value = operand_id, |
| 3733 | 3887 | }), |
| ... | ... | @@ -5237,20 +5391,21 @@ const DeclGen = struct { |
| 5237 | 5391 | |
| 5238 | 5392 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 5239 | 5393 | const mod = self.module; |
| 5394 | const target = self.getTarget(); |
| 5240 | 5395 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5241 | 5396 | const cond_ty = self.typeOf(pl_op.operand); |
| 5242 | 5397 | const cond = try self.resolve(pl_op.operand); |
| 5243 | | const cond_indirect = try self.convertToIndirect(cond_ty, cond); |
| 5398 | var cond_indirect = try self.convertToIndirect(cond_ty, cond); |
| 5244 | 5399 | const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload); |
| 5245 | 5400 | |
| 5246 | 5401 | const cond_words: u32 = switch (cond_ty.zigTypeTag(mod)) { |
| 5247 | | .Bool => 1, |
| 5402 | .Bool, .ErrorSet => 1, |
| 5248 | 5403 | .Int => blk: { |
| 5249 | 5404 | const bits = cond_ty.intInfo(mod).bits; |
| 5250 | 5405 | const backing_bits = self.backingIntBits(bits) orelse { |
| 5251 | 5406 | return self.todo("implement composite int switch", .{}); |
| 5252 | 5407 | }; |
| 5253 | | break :blk if (backing_bits <= 32) @as(u32, 1) else 2; |
| 5408 | break :blk if (backing_bits <= 32) 1 else 2; |
| 5254 | 5409 | }, |
| 5255 | 5410 | .Enum => blk: { |
| 5256 | 5411 | const int_ty = cond_ty.intTagType(mod); |
| ... | ... | @@ -5258,10 +5413,14 @@ const DeclGen = struct { |
| 5258 | 5413 | const backing_bits = self.backingIntBits(int_info.bits) orelse { |
| 5259 | 5414 | return self.todo("implement composite int switch", .{}); |
| 5260 | 5415 | }; |
| 5261 | | break :blk if (backing_bits <= 32) @as(u32, 1) else 2; |
| 5416 | break :blk if (backing_bits <= 32) 1 else 2; |
| 5417 | }, |
| 5418 | .Pointer => blk: { |
| 5419 | cond_indirect = try self.intFromPtr(cond_indirect); |
| 5420 | break :blk target.ptrBitWidth() / 32; |
| 5262 | 5421 | }, |
| 5263 | | .ErrorSet => 1, |
| 5264 | | else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag(mod))}), // TODO: Figure out which types apply here, and work around them as we can only do integers. |
| 5422 | // TODO: Figure out which types apply here, and work around them as we can only do integers. |
| 5423 | else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag(mod))}), |
| 5265 | 5424 | }; |
| 5266 | 5425 | |
| 5267 | 5426 | const num_cases = switch_br.data.cases_len; |
| ... | ... | @@ -5308,7 +5467,7 @@ const DeclGen = struct { |
| 5308 | 5467 | for (0..num_cases) |case_i| { |
| 5309 | 5468 | // SPIR-V needs a literal here, which' width depends on the case condition. |
| 5310 | 5469 | const case = self.air.extraData(Air.SwitchBr.Case, extra_index); |
| 5311 | | const items = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[case.end..][0..case.data.items_len])); |
| 5470 | const items: []const Air.Inst.Ref = @ptrCast(self.air.extra[case.end..][0..case.data.items_len]); |
| 5312 | 5471 | const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len]; |
| 5313 | 5472 | extra_index = case.end + case.data.items_len + case_body.len; |
| 5314 | 5473 | |
| ... | ... | @@ -5316,13 +5475,14 @@ const DeclGen = struct { |
| 5316 | 5475 | |
| 5317 | 5476 | for (items) |item| { |
| 5318 | 5477 | const value = (try self.air.value(item, mod)) orelse unreachable; |
| 5319 | | const int_val = switch (cond_ty.zigTypeTag(mod)) { |
| 5320 | | .Bool, .Int => if (cond_ty.isSignedInt(mod)) @as(u64, @bitCast(value.toSignedInt(mod))) else value.toUnsignedInt(mod), |
| 5478 | const int_val: u64 = switch (cond_ty.zigTypeTag(mod)) { |
| 5479 | .Bool, .Int => if (cond_ty.isSignedInt(mod)) @bitCast(value.toSignedInt(mod)) else value.toUnsignedInt(mod), |
| 5321 | 5480 | .Enum => blk: { |
| 5322 | 5481 | // TODO: figure out of cond_ty is correct (something with enum literals) |
| 5323 | 5482 | break :blk (try value.intFromEnum(cond_ty, mod)).toUnsignedInt(mod); // TODO: composite integer constants |
| 5324 | 5483 | }, |
| 5325 | 5484 | .ErrorSet => value.getErrorInt(mod), |
| 5485 | .Pointer => value.toUnsignedInt(mod), |
| 5326 | 5486 | else => unreachable, |
| 5327 | 5487 | }; |
| 5328 | 5488 | const int_lit: spec.LiteralContextDependentNumber = switch (cond_words) { |
| ... | ... | @@ -5438,14 +5598,14 @@ const DeclGen = struct { |
| 5438 | 5598 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 5439 | 5599 | |
| 5440 | 5600 | const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0; |
| 5441 | | const clobbers_len = @as(u31, @truncate(extra.data.flags)); |
| 5601 | const clobbers_len: u31 = @truncate(extra.data.flags); |
| 5442 | 5602 | |
| 5443 | 5603 | if (!is_volatile and self.liveness.isUnused(inst)) return null; |
| 5444 | 5604 | |
| 5445 | 5605 | var extra_i: usize = extra.end; |
| 5446 | | const outputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len])); |
| 5606 | const outputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]); |
| 5447 | 5607 | extra_i += outputs.len; |
| 5448 | | const inputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len])); |
| 5608 | const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]); |
| 5449 | 5609 | extra_i += inputs.len; |
| 5450 | 5610 | |
| 5451 | 5611 | if (outputs.len > 1) { |
| ... | ... | @@ -5567,7 +5727,7 @@ const DeclGen = struct { |
| 5567 | 5727 | const mod = self.module; |
| 5568 | 5728 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5569 | 5729 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 5570 | | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len])); |
| 5730 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 5571 | 5731 | const callee_ty = self.typeOf(pl_op.operand); |
| 5572 | 5732 | const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { |
| 5573 | 5733 | .Fn => callee_ty, |