| ... | @@ -2007,6 +2007,7 @@ const DeclGen = struct { | ... | @@ -2007,6 +2007,7 @@ const DeclGen = struct { |
| 2007 | .array_to_slice => try self.airArrayToSlice(inst), | 2007 | .array_to_slice => try self.airArrayToSlice(inst), |
| 2008 | .slice => try self.airSlice(inst), | 2008 | .slice => try self.airSlice(inst), |
| 2009 | .aggregate_init => try self.airAggregateInit(inst), | 2009 | .aggregate_init => try self.airAggregateInit(inst), |
| | 2010 | .memcpy => return self.airMemcpy(inst), |
| 2010 | | 2011 | |
| 2011 | .slice_ptr => try self.airSliceField(inst, 0), | 2012 | .slice_ptr => try self.airSliceField(inst, 0), |
| 2012 | .slice_len => try self.airSliceField(inst, 1), | 2013 | .slice_len => try self.airSliceField(inst, 1), |
| ... | @@ -2016,7 +2017,7 @@ const DeclGen = struct { | ... | @@ -2016,7 +2017,7 @@ const DeclGen = struct { |
| 2016 | .ptr_elem_val => try self.airPtrElemVal(inst), | 2017 | .ptr_elem_val => try self.airPtrElemVal(inst), |
| 2017 | .array_elem_val => try self.airArrayElemVal(inst), | 2018 | .array_elem_val => try self.airArrayElemVal(inst), |
| 2018 | | 2019 | |
| 2019 | .set_union_tag => return try self.airSetUnionTag(inst), | 2020 | .set_union_tag => return self.airSetUnionTag(inst), |
| 2020 | .get_union_tag => try self.airGetUnionTag(inst), | 2021 | .get_union_tag => try self.airGetUnionTag(inst), |
| 2021 | .union_init => try self.airUnionInit(inst), | 2022 | .union_init => try self.airUnionInit(inst), |
| 2022 | | 2023 | |
| ... | @@ -3150,6 +3151,46 @@ const DeclGen = struct { | ... | @@ -3150,6 +3151,46 @@ const DeclGen = struct { |
| 3150 | } | 3151 | } |
| 3151 | } | 3152 | } |
| 3152 | | 3153 | |
| | 3154 | fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef { |
| | 3155 | const mod = self.module; |
| | 3156 | switch (ty.ptrSize(mod)) { |
| | 3157 | .Slice => return self.extractField(Type.usize, operand_id, 1), |
| | 3158 | .One => { |
| | 3159 | const array_ty = ty.childType(mod); |
| | 3160 | const elem_ty = array_ty.childType(mod); |
| | 3161 | const abi_size = elem_ty.abiSize(mod); |
| | 3162 | const usize_ty_ref = try self.resolveType(Type.usize, .direct); |
| | 3163 | return self.spv.constInt(usize_ty_ref, array_ty.arrayLenIncludingSentinel(mod) * abi_size); |
| | 3164 | }, |
| | 3165 | .Many, .C => unreachable, |
| | 3166 | } |
| | 3167 | } |
| | 3168 | |
| | 3169 | fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef { |
| | 3170 | const mod = self.module; |
| | 3171 | if (ty.isSlice(mod)) { |
| | 3172 | const ptr_ty = ty.slicePtrFieldType(mod); |
| | 3173 | return self.extractField(ptr_ty, operand_id, 0); |
| | 3174 | } |
| | 3175 | return operand_id; |
| | 3176 | } |
| | 3177 | |
| | 3178 | fn airMemcpy(self: *DeclGen, inst: Air.Inst.Index) !void { |
| | 3179 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 3180 | const dest_slice = try self.resolve(bin_op.lhs); |
| | 3181 | const src_slice = try self.resolve(bin_op.rhs); |
| | 3182 | const dest_ty = self.typeOf(bin_op.lhs); |
| | 3183 | const src_ty = self.typeOf(bin_op.rhs); |
| | 3184 | const dest_ptr = try self.sliceOrArrayPtr(dest_slice, dest_ty); |
| | 3185 | const src_ptr = try self.sliceOrArrayPtr(src_slice, src_ty); |
| | 3186 | const len = try self.sliceOrArrayLen(dest_slice, dest_ty); |
| | 3187 | try self.func.body.emit(self.spv.gpa, .OpCopyMemorySized, .{ |
| | 3188 | .target = dest_ptr, |
| | 3189 | .source = src_ptr, |
| | 3190 | .size = len, |
| | 3191 | }); |
| | 3192 | } |
| | 3193 | |
| 3153 | fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef { | 3194 | fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef { |
| 3154 | if (self.liveness.isUnused(inst)) return null; | 3195 | if (self.liveness.isUnused(inst)) return null; |
| 3155 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 3196 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |