| ... | @@ -988,6 +988,25 @@ pub const Object = struct { | ... | @@ -988,6 +988,25 @@ pub const Object = struct { |
| 988 | args.appendAssumeCapacity(load_inst); | 988 | args.appendAssumeCapacity(load_inst); |
| 989 | } | 989 | } |
| 990 | }, | 990 | }, |
| | 991 | .byref_mut => { |
| | 992 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| | 993 | const param_llvm_ty = try dg.lowerType(param_ty); |
| | 994 | const param = llvm_func.getParam(llvm_arg_i); |
| | 995 | const alignment = param_ty.abiAlignment(target); |
| | 996 | |
| | 997 | dg.addArgAttr(llvm_func, llvm_arg_i, "noundef"); |
| | 998 | llvm_arg_i += 1; |
| | 999 | |
| | 1000 | try args.ensureUnusedCapacity(1); |
| | 1001 | |
| | 1002 | if (isByRef(param_ty)) { |
| | 1003 | args.appendAssumeCapacity(param); |
| | 1004 | } else { |
| | 1005 | const load_inst = builder.buildLoad(param_llvm_ty, param, ""); |
| | 1006 | load_inst.setAlignment(alignment); |
| | 1007 | args.appendAssumeCapacity(load_inst); |
| | 1008 | } |
| | 1009 | }, |
| 991 | .abi_sized_int => { | 1010 | .abi_sized_int => { |
| 992 | assert(!it.byval_attr); | 1011 | assert(!it.byval_attr); |
| 993 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 1012 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| ... | @@ -2583,6 +2602,9 @@ pub const DeclGen = struct { | ... | @@ -2583,6 +2602,9 @@ pub const DeclGen = struct { |
| 2583 | const alignment = param_ty.abiAlignment(target); | 2602 | const alignment = param_ty.abiAlignment(target); |
| 2584 | dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 2603 | dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 2585 | }, | 2604 | }, |
| | 2605 | .byref_mut => { |
| | 2606 | dg.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef"); |
| | 2607 | }, |
| 2586 | // No attributes needed for these. | 2608 | // No attributes needed for these. |
| 2587 | .no_bits, | 2609 | .no_bits, |
| 2588 | .abi_sized_int, | 2610 | .abi_sized_int, |
| ... | @@ -3101,7 +3123,7 @@ pub const DeclGen = struct { | ... | @@ -3101,7 +3123,7 @@ pub const DeclGen = struct { |
| 3101 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 3123 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 3102 | try llvm_params.append(try dg.lowerType(param_ty)); | 3124 | try llvm_params.append(try dg.lowerType(param_ty)); |
| 3103 | }, | 3125 | }, |
| 3104 | .byref => { | 3126 | .byref, .byref_mut => { |
| 3105 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 3127 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 3106 | const raw_llvm_ty = try dg.lowerType(param_ty); | 3128 | const raw_llvm_ty = try dg.lowerType(param_ty); |
| 3107 | try llvm_params.append(raw_llvm_ty.pointerType(0)); | 3129 | try llvm_params.append(raw_llvm_ty.pointerType(0)); |
| ... | @@ -4726,6 +4748,27 @@ pub const FuncGen = struct { | ... | @@ -4726,6 +4748,27 @@ pub const FuncGen = struct { |
| 4726 | try llvm_args.append(arg_ptr); | 4748 | try llvm_args.append(arg_ptr); |
| 4727 | } | 4749 | } |
| 4728 | }, | 4750 | }, |
| | 4751 | .byref_mut => { |
| | 4752 | const arg = args[it.zig_index - 1]; |
| | 4753 | const param_ty = self.air.typeOf(arg); |
| | 4754 | const llvm_arg = try self.resolveInst(arg); |
| | 4755 | |
| | 4756 | const alignment = param_ty.abiAlignment(target); |
| | 4757 | const param_llvm_ty = try self.dg.lowerType(param_ty); |
| | 4758 | const arg_ptr = self.buildAlloca(param_llvm_ty, alignment); |
| | 4759 | if (isByRef(param_ty)) { |
| | 4760 | const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, ""); |
| | 4761 | load_inst.setAlignment(alignment); |
| | 4762 | |
| | 4763 | const store_inst = self.builder.buildStore(load_inst, arg_ptr); |
| | 4764 | store_inst.setAlignment(alignment); |
| | 4765 | try llvm_args.append(arg_ptr); |
| | 4766 | } else { |
| | 4767 | const store_inst = self.builder.buildStore(llvm_arg, arg_ptr); |
| | 4768 | store_inst.setAlignment(alignment); |
| | 4769 | try llvm_args.append(arg_ptr); |
| | 4770 | } |
| | 4771 | }, |
| 4729 | .abi_sized_int => { | 4772 | .abi_sized_int => { |
| 4730 | const arg = args[it.zig_index - 1]; | 4773 | const arg = args[it.zig_index - 1]; |
| 4731 | const param_ty = self.air.typeOf(arg); | 4774 | const param_ty = self.air.typeOf(arg); |
| ... | @@ -10384,6 +10427,7 @@ const ParamTypeIterator = struct { | ... | @@ -10384,6 +10427,7 @@ const ParamTypeIterator = struct { |
| 10384 | no_bits, | 10427 | no_bits, |
| 10385 | byval, | 10428 | byval, |
| 10386 | byref, | 10429 | byref, |
| | 10430 | byref_mut, |
| 10387 | abi_sized_int, | 10431 | abi_sized_int, |
| 10388 | multiple_llvm_types, | 10432 | multiple_llvm_types, |
| 10389 | slice, | 10433 | slice, |
| ... | @@ -10547,7 +10591,7 @@ const ParamTypeIterator = struct { | ... | @@ -10547,7 +10591,7 @@ const ParamTypeIterator = struct { |
| 10547 | it.zig_index += 1; | 10591 | it.zig_index += 1; |
| 10548 | it.llvm_index += 1; | 10592 | it.llvm_index += 1; |
| 10549 | switch (aarch64_c_abi.classifyType(ty, it.target)) { | 10593 | switch (aarch64_c_abi.classifyType(ty, it.target)) { |
| 10550 | .memory => return .byref, | 10594 | .memory => return .byref_mut, |
| 10551 | .float_array => |len| return Lowering{ .float_array = len }, | 10595 | .float_array => |len| return Lowering{ .float_array = len }, |
| 10552 | .byval => return .byval, | 10596 | .byval => return .byval, |
| 10553 | .integer => { | 10597 | .integer => { |
| ... | @@ -10578,9 +10622,7 @@ const ParamTypeIterator = struct { | ... | @@ -10578,9 +10622,7 @@ const ParamTypeIterator = struct { |
| 10578 | return .as_u16; | 10622 | return .as_u16; |
| 10579 | } | 10623 | } |
| 10580 | switch (riscv_c_abi.classifyType(ty, it.target)) { | 10624 | switch (riscv_c_abi.classifyType(ty, it.target)) { |
| 10581 | .memory => { | 10625 | .memory => return .byref_mut, |
| 10582 | return .byref; | | |
| 10583 | }, | | |
| 10584 | .byval => return .byval, | 10626 | .byval => return .byval, |
| 10585 | .integer => return .abi_sized_int, | 10627 | .integer => return .abi_sized_int, |
| 10586 | .double_integer => return Lowering{ .i64_array = 2 }, | 10628 | .double_integer => return Lowering{ .i64_array = 2 }, |