| ... | ... | @@ -6459,6 +6459,34 @@ pub const FuncGen = struct { |
| 6459 | 6459 | return vector; |
| 6460 | 6460 | }, |
| 6461 | 6461 | .Struct => { |
| 6462 | if (result_ty.containerLayout() == .Packed) { |
| 6463 | const struct_obj = result_ty.castTag(.@"struct").?.data; |
| 6464 | const big_bits = struct_obj.packedIntegerBits(target); |
| 6465 | const int_llvm_ty = self.dg.context.intType(big_bits); |
| 6466 | const fields = struct_obj.fields.values(); |
| 6467 | comptime assert(Type.packed_struct_layout_version == 2); |
| 6468 | var running_int: *const llvm.Value = int_llvm_ty.constNull(); |
| 6469 | var running_bits: u16 = 0; |
| 6470 | for (elements) |elem, i| { |
| 6471 | const field = fields[i]; |
| 6472 | if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 6473 | |
| 6474 | const non_int_val = try self.resolveInst(elem); |
| 6475 | const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); |
| 6476 | const small_int_ty = self.dg.context.intType(ty_bit_size); |
| 6477 | const small_int_val = self.builder.buildBitCast(non_int_val, small_int_ty, ""); |
| 6478 | const shift_rhs = int_llvm_ty.constInt(running_bits, .False); |
| 6479 | // If the field is as large as the entire packed struct, this |
| 6480 | // zext would go from, e.g. i16 to i16. This is legal with |
| 6481 | // constZExtOrBitCast but not legal with constZExt. |
| 6482 | const extended_int_val = self.builder.buildZExtOrBitCast(small_int_val, int_llvm_ty, ""); |
| 6483 | const shifted = self.builder.buildShl(extended_int_val, shift_rhs, ""); |
| 6484 | running_int = self.builder.buildOr(running_int, shifted, ""); |
| 6485 | running_bits += ty_bit_size; |
| 6486 | } |
| 6487 | return running_int; |
| 6488 | } |
| 6489 | |
| 6462 | 6490 | var ptr_ty_buf: Type.Payload.Pointer = undefined; |
| 6463 | 6491 | |
| 6464 | 6492 | if (isByRef(result_ty)) { |