| ... | ... | @@ -712,6 +712,7 @@ pub const Object = struct { |
| 712 | 712 | .byval => { |
| 713 | 713 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 714 | 714 | const param = llvm_func.getParam(llvm_arg_i); |
| 715 | try args.ensureUnusedCapacity(1); |
| 715 | 716 | |
| 716 | 717 | if (isByRef(param_ty)) { |
| 717 | 718 | const alignment = param_ty.abiAlignment(target); |
| ... | ... | @@ -720,9 +721,9 @@ pub const Object = struct { |
| 720 | 721 | arg_ptr.setAlignment(alignment); |
| 721 | 722 | const store_inst = builder.buildStore(param, arg_ptr); |
| 722 | 723 | store_inst.setAlignment(alignment); |
| 723 | | try args.append(arg_ptr); |
| 724 | args.appendAssumeCapacity(arg_ptr); |
| 724 | 725 | } else { |
| 725 | | try args.append(param); |
| 726 | args.appendAssumeCapacity(param); |
| 726 | 727 | |
| 727 | 728 | if (param_ty.isPtrAtRuntime()) { |
| 728 | 729 | const ptr_info = param_ty.ptrInfo().data; |
| ... | ... | @@ -756,13 +757,15 @@ pub const Object = struct { |
| 756 | 757 | |
| 757 | 758 | llvm_arg_i += 1; |
| 758 | 759 | |
| 760 | try args.ensureUnusedCapacity(1); |
| 761 | |
| 759 | 762 | if (isByRef(param_ty)) { |
| 760 | | try args.append(param); |
| 763 | args.appendAssumeCapacity(param); |
| 761 | 764 | } else { |
| 762 | 765 | const alignment = param_ty.abiAlignment(target); |
| 763 | 766 | const load_inst = builder.buildLoad(param, ""); |
| 764 | 767 | load_inst.setAlignment(alignment); |
| 765 | | try args.append(load_inst); |
| 768 | args.appendAssumeCapacity(load_inst); |
| 766 | 769 | } |
| 767 | 770 | }, |
| 768 | 771 | .abi_sized_int => { |
| ... | ... | @@ -784,14 +787,44 @@ pub const Object = struct { |
| 784 | 787 | const store_inst = builder.buildStore(param, casted_ptr); |
| 785 | 788 | store_inst.setAlignment(alignment); |
| 786 | 789 | |
| 790 | try args.ensureUnusedCapacity(1); |
| 791 | |
| 787 | 792 | if (isByRef(param_ty)) { |
| 788 | | try args.append(arg_ptr); |
| 793 | args.appendAssumeCapacity(arg_ptr); |
| 789 | 794 | } else { |
| 790 | 795 | const load_inst = builder.buildLoad(arg_ptr, ""); |
| 791 | 796 | load_inst.setAlignment(alignment); |
| 792 | | try args.append(load_inst); |
| 797 | args.appendAssumeCapacity(load_inst); |
| 793 | 798 | } |
| 794 | 799 | }, |
| 800 | .slice => { |
| 801 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 802 | const ptr_info = param_ty.ptrInfo().data; |
| 803 | |
| 804 | if (math.cast(u5, it.zig_index - 1)) |i| { |
| 805 | if (@truncate(u1, fn_info.noalias_bits >> i) != 0) { |
| 806 | dg.addArgAttr(llvm_func, llvm_arg_i, "noalias"); |
| 807 | } |
| 808 | } |
| 809 | dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull"); |
| 810 | if (!ptr_info.mutable) { |
| 811 | dg.addArgAttr(llvm_func, llvm_arg_i, "readonly"); |
| 812 | } |
| 813 | if (ptr_info.@"align" != 0) { |
| 814 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| 815 | } else { |
| 816 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); |
| 817 | } |
| 818 | const ptr_param = llvm_func.getParam(llvm_arg_i); |
| 819 | llvm_arg_i += 1; |
| 820 | const len_param = llvm_func.getParam(llvm_arg_i); |
| 821 | llvm_arg_i += 1; |
| 822 | |
| 823 | const slice_llvm_ty = try dg.lowerType(param_ty); |
| 824 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); |
| 825 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); |
| 826 | try args.append(aggregate); |
| 827 | }, |
| 795 | 828 | .multiple_llvm_ints => { |
| 796 | 829 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 797 | 830 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; |
| ... | ... | @@ -2743,6 +2776,17 @@ pub const DeclGen = struct { |
| 2743 | 2776 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); |
| 2744 | 2777 | try llvm_params.append(dg.context.intType(abi_size * 8)); |
| 2745 | 2778 | }, |
| 2779 | .slice => { |
| 2780 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 2781 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 2782 | const ptr_ty = param_ty.slicePtrFieldType(&buf); |
| 2783 | const ptr_llvm_ty = try dg.lowerType(ptr_ty); |
| 2784 | const len_llvm_ty = try dg.lowerType(Type.usize); |
| 2785 | |
| 2786 | try llvm_params.ensureUnusedCapacity(2); |
| 2787 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); |
| 2788 | llvm_params.appendAssumeCapacity(len_llvm_ty); |
| 2789 | }, |
| 2746 | 2790 | .multiple_llvm_ints => { |
| 2747 | 2791 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 2748 | 2792 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; |
| ... | ... | @@ -4205,6 +4249,15 @@ pub const FuncGen = struct { |
| 4205 | 4249 | try llvm_args.append(load_inst); |
| 4206 | 4250 | } |
| 4207 | 4251 | }, |
| 4252 | .slice => { |
| 4253 | const arg = args[it.zig_index - 1]; |
| 4254 | const llvm_arg = try self.resolveInst(arg); |
| 4255 | const ptr = self.builder.buildExtractValue(llvm_arg, 0, ""); |
| 4256 | const len = self.builder.buildExtractValue(llvm_arg, 1, ""); |
| 4257 | try llvm_args.ensureUnusedCapacity(2); |
| 4258 | llvm_args.appendAssumeCapacity(ptr); |
| 4259 | llvm_args.appendAssumeCapacity(len); |
| 4260 | }, |
| 4208 | 4261 | .multiple_llvm_ints => { |
| 4209 | 4262 | const arg = args[it.zig_index - 1]; |
| 4210 | 4263 | const param_ty = self.air.typeOf(arg); |
| ... | ... | @@ -8811,6 +8864,7 @@ const ParamTypeIterator = struct { |
| 8811 | 8864 | byref, |
| 8812 | 8865 | abi_sized_int, |
| 8813 | 8866 | multiple_llvm_ints, |
| 8867 | slice, |
| 8814 | 8868 | }; |
| 8815 | 8869 | |
| 8816 | 8870 | fn next(it: *ParamTypeIterator) ?Lowering { |
| ... | ... | @@ -8826,7 +8880,9 @@ const ParamTypeIterator = struct { |
| 8826 | 8880 | .Unspecified, .Inline => { |
| 8827 | 8881 | it.zig_index += 1; |
| 8828 | 8882 | it.llvm_index += 1; |
| 8829 | | if (isByRef(ty)) { |
| 8883 | if (ty.isSlice()) { |
| 8884 | return .slice; |
| 8885 | } else if (isByRef(ty)) { |
| 8830 | 8886 | return .byref; |
| 8831 | 8887 | } else { |
| 8832 | 8888 | return .byval; |