| ... | @@ -717,8 +717,12 @@ pub const DeclGen = struct { | ... | @@ -717,8 +717,12 @@ pub const DeclGen = struct { |
| 717 | .bool_and => try self.airBinOpSimple(inst, .OpLogicalAnd), | 717 | .bool_and => try self.airBinOpSimple(inst, .OpLogicalAnd), |
| 718 | .bool_or => try self.airBinOpSimple(inst, .OpLogicalOr), | 718 | .bool_or => try self.airBinOpSimple(inst, .OpLogicalOr), |
| 719 | | 719 | |
| 720 | .bitcast => try self.airBitcast(inst), | 720 | .bitcast => try self.airBitcast(inst), |
| 721 | .not => try self.airNot(inst), | 721 | .not => try self.airNot(inst), |
| | 722 | .slice_ptr => try self.airSliceField(inst, 0), |
| | 723 | .slice_len => try self.airSliceField(inst, 1), |
| | 724 | .slice_elem_ptr => try self.airSliceElemPtr(inst), |
| | 725 | .slice_elem_val => try self.airSliceElemVal(inst), |
| 722 | | 726 | |
| 723 | .cmp_eq => try self.airCmp(inst, .OpFOrdEqual, .OpLogicalEqual, .OpIEqual), | 727 | .cmp_eq => try self.airCmp(inst, .OpFOrdEqual, .OpLogicalEqual, .OpIEqual), |
| 724 | .cmp_neq => try self.airCmp(inst, .OpFOrdNotEqual, .OpLogicalNotEqual, .OpINotEqual), | 728 | .cmp_neq => try self.airCmp(inst, .OpFOrdNotEqual, .OpLogicalNotEqual, .OpINotEqual), |
| ... | @@ -924,7 +928,7 @@ pub const DeclGen = struct { | ... | @@ -924,7 +928,7 @@ pub const DeclGen = struct { |
| 924 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 928 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 925 | const operand_id = try self.resolve(ty_op.operand); | 929 | const operand_id = try self.resolve(ty_op.operand); |
| 926 | const result_id = self.spv.allocId(); | 930 | const result_id = self.spv.allocId(); |
| 927 | const result_type_id = try self.resolveTypeId(Type.initTag(.bool)); | 931 | const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst)); |
| 928 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ | 932 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| 929 | .id_result_type = result_type_id, | 933 | .id_result_type = result_type_id, |
| 930 | .id_result = result_id, | 934 | .id_result = result_id, |
| ... | @@ -947,6 +951,93 @@ pub const DeclGen = struct { | ... | @@ -947,6 +951,93 @@ pub const DeclGen = struct { |
| 947 | return result_id.toRef(); | 951 | return result_id.toRef(); |
| 948 | } | 952 | } |
| 949 | | 953 | |
| | 954 | fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef { |
| | 955 | if (self.liveness.isUnused(inst)) return null; |
| | 956 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 957 | const result_id = self.spv.allocId(); |
| | 958 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ |
| | 959 | .id_result_type = try self.resolveTypeId(self.air.typeOfIndex(inst)), |
| | 960 | .id_result = result_id, |
| | 961 | .composite = try self.resolve(ty_op.operand), |
| | 962 | .indexes = &.{field}, |
| | 963 | }); |
| | 964 | return result_id.toRef(); |
| | 965 | } |
| | 966 | |
| | 967 | fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| | 968 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 969 | const slice_ty = self.air.typeOf(bin_op.lhs); |
| | 970 | if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; |
| | 971 | |
| | 972 | const slice = try self.resolve(bin_op.lhs); |
| | 973 | const index = try self.resolve(bin_op.rhs); |
| | 974 | |
| | 975 | const spv_ptr_ty = try self.resolveTypeId(self.air.typeOfIndex(inst)); |
| | 976 | |
| | 977 | const slice_ptr = blk: { |
| | 978 | const result_id = self.spv.allocId(); |
| | 979 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ |
| | 980 | .id_result_type = spv_ptr_ty, |
| | 981 | .id_result = result_id, |
| | 982 | .composite = slice, |
| | 983 | .indexes = &.{0}, |
| | 984 | }); |
| | 985 | break :blk result_id.toRef(); |
| | 986 | }; |
| | 987 | |
| | 988 | const result_id = self.spv.allocId(); |
| | 989 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| | 990 | .id_result_type = spv_ptr_ty, |
| | 991 | .id_result = result_id, |
| | 992 | .base = slice_ptr, |
| | 993 | .indexes = &.{index}, |
| | 994 | }); |
| | 995 | return result_id.toRef(); |
| | 996 | } |
| | 997 | |
| | 998 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| | 999 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 1000 | const slice_ty = self.air.typeOf(bin_op.lhs); |
| | 1001 | if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; |
| | 1002 | |
| | 1003 | const slice = try self.resolve(bin_op.lhs); |
| | 1004 | const index = try self.resolve(bin_op.rhs); |
| | 1005 | |
| | 1006 | const spv_elem_ty = try self.resolveTypeId(self.air.typeOfIndex(inst)); |
| | 1007 | var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| | 1008 | const spv_ptr_ty = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf)); |
| | 1009 | |
| | 1010 | const slice_ptr = blk: { |
| | 1011 | const result_id = self.spv.allocId(); |
| | 1012 | try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ |
| | 1013 | .id_result_type = spv_ptr_ty, |
| | 1014 | .id_result = result_id, |
| | 1015 | .composite = slice, |
| | 1016 | .indexes = &.{0}, |
| | 1017 | }); |
| | 1018 | break :blk result_id.toRef(); |
| | 1019 | }; |
| | 1020 | |
| | 1021 | const elem_ptr = blk: { |
| | 1022 | const result_id = self.spv.allocId(); |
| | 1023 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| | 1024 | .id_result_type = spv_ptr_ty, |
| | 1025 | .id_result = result_id, |
| | 1026 | .base = slice_ptr, |
| | 1027 | .indexes = &.{index}, |
| | 1028 | }); |
| | 1029 | break :blk result_id.toRef(); |
| | 1030 | }; |
| | 1031 | |
| | 1032 | const result_id = self.spv.allocId(); |
| | 1033 | try self.func.body.emit(self.spv.gpa, .OpLoad, .{ |
| | 1034 | .id_result_type = spv_elem_ty, |
| | 1035 | .id_result = result_id, |
| | 1036 | .pointer = elem_ptr, |
| | 1037 | }); |
| | 1038 | return result_id.toRef(); |
| | 1039 | } |
| | 1040 | |
| 950 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 1041 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 951 | if (self.liveness.isUnused(inst)) return null; | 1042 | if (self.liveness.isUnused(inst)) return null; |
| 952 | const ty = self.air.typeOfIndex(inst); | 1043 | const ty = self.air.typeOfIndex(inst); |