| ... | @@ -1049,60 +1049,20 @@ pub const Object = struct { | ... | @@ -1049,60 +1049,20 @@ pub const Object = struct { |
| 1049 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); | 1049 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); |
| 1050 | try args.append(aggregate); | 1050 | try args.append(aggregate); |
| 1051 | }, | 1051 | }, |
| 1052 | .multiple_llvm_ints => { | 1052 | .multiple_llvm_types => { |
| 1053 | assert(!it.byval_attr); | 1053 | assert(!it.byval_attr); |
| 1054 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; | 1054 | const field_types = it.llvm_types_buffer[0..it.llvm_types_len]; |
| 1055 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 1055 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 1056 | const param_llvm_ty = try dg.lowerType(param_ty); | 1056 | const param_llvm_ty = try dg.lowerType(param_ty); |
| 1057 | const param_alignment = param_ty.abiAlignment(target); | 1057 | const param_alignment = param_ty.abiAlignment(target); |
| 1058 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target); | 1058 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target); |
| 1059 | var field_types_buf: [8]*llvm.Type = undefined; | 1059 | const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); |
| 1060 | const field_types = field_types_buf[0..llvm_ints.len]; | 1060 | const casted_ptr = builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), ""); |
| 1061 | for (llvm_ints) |int_bits, i| { | 1061 | for (field_types) |_, field_i_usize| { |
| 1062 | field_types[i] = dg.context.intType(int_bits); | | |
| 1063 | } | | |
| 1064 | const ints_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); | | |
| 1065 | const casted_ptr = builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), ""); | | |
| 1066 | for (llvm_ints) |_, field_i_usize| { | | |
| 1067 | const field_i = @intCast(c_uint, field_i_usize); | 1062 | const field_i = @intCast(c_uint, field_i_usize); |
| 1068 | const param = llvm_func.getParam(llvm_arg_i); | 1063 | const param = llvm_func.getParam(llvm_arg_i); |
| 1069 | llvm_arg_i += 1; | 1064 | llvm_arg_i += 1; |
| 1070 | const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, field_i, ""); | 1065 | const field_ptr = builder.buildStructGEP(llvm_ty, casted_ptr, field_i, ""); |
| 1071 | const store_inst = builder.buildStore(param, field_ptr); | | |
| 1072 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | | |
| 1073 | } | | |
| 1074 | | | |
| 1075 | const is_by_ref = isByRef(param_ty); | | |
| 1076 | const loaded = if (is_by_ref) arg_ptr else l: { | | |
| 1077 | const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, ""); | | |
| 1078 | load_inst.setAlignment(param_alignment); | | |
| 1079 | break :l load_inst; | | |
| 1080 | }; | | |
| 1081 | try args.append(loaded); | | |
| 1082 | }, | | |
| 1083 | .multiple_llvm_float => { | | |
| 1084 | assert(!it.byval_attr); | | |
| 1085 | const llvm_floats = it.llvm_types_buffer[0..it.llvm_types_len]; | | |
| 1086 | const param_ty = fn_info.param_types[it.zig_index - 1]; | | |
| 1087 | const param_llvm_ty = try dg.lowerType(param_ty); | | |
| 1088 | const param_alignment = param_ty.abiAlignment(target); | | |
| 1089 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target); | | |
| 1090 | var field_types_buf: [8]*llvm.Type = undefined; | | |
| 1091 | const field_types = field_types_buf[0..llvm_floats.len]; | | |
| 1092 | for (llvm_floats) |float_bits, i| { | | |
| 1093 | switch (float_bits) { | | |
| 1094 | 64 => field_types[i] = dg.context.doubleType(), | | |
| 1095 | 80 => field_types[i] = dg.context.x86FP80Type(), | | |
| 1096 | else => {}, | | |
| 1097 | } | | |
| 1098 | } | | |
| 1099 | const floats_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); | | |
| 1100 | const casted_ptr = builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), ""); | | |
| 1101 | for (llvm_floats) |_, field_i_usize| { | | |
| 1102 | const field_i = @intCast(c_uint, field_i_usize); | | |
| 1103 | const param = llvm_func.getParam(llvm_arg_i); | | |
| 1104 | llvm_arg_i += 1; | | |
| 1105 | const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, field_i, ""); | | |
| 1106 | const store_inst = builder.buildStore(param, field_ptr); | 1066 | const store_inst = builder.buildStore(param, field_ptr); |
| 1107 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | 1067 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 1108 | } | 1068 | } |
| ... | @@ -2626,8 +2586,7 @@ pub const DeclGen = struct { | ... | @@ -2626,8 +2586,7 @@ pub const DeclGen = struct { |
| 2626 | // No attributes needed for these. | 2586 | // No attributes needed for these. |
| 2627 | .no_bits, | 2587 | .no_bits, |
| 2628 | .abi_sized_int, | 2588 | .abi_sized_int, |
| 2629 | .multiple_llvm_ints, | 2589 | .multiple_llvm_types, |
| 2630 | .multiple_llvm_float, | | |
| 2631 | .as_u16, | 2590 | .as_u16, |
| 2632 | .float_array, | 2591 | .float_array, |
| 2633 | .i32_array, | 2592 | .i32_array, |
| ... | @@ -3167,25 +3126,8 @@ pub const DeclGen = struct { | ... | @@ -3167,25 +3126,8 @@ pub const DeclGen = struct { |
| 3167 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); | 3126 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); |
| 3168 | llvm_params.appendAssumeCapacity(len_llvm_ty); | 3127 | llvm_params.appendAssumeCapacity(len_llvm_ty); |
| 3169 | }, | 3128 | }, |
| 3170 | .multiple_llvm_ints => { | 3129 | .multiple_llvm_types => { |
| 3171 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; | 3130 | try llvm_params.appendSlice(it.llvm_types_buffer[0..it.llvm_types_len]); |
| 3172 | try llvm_params.ensureUnusedCapacity(it.llvm_types_len); | | |
| 3173 | for (llvm_ints) |int_bits| { | | |
| 3174 | const big_int_ty = dg.context.intType(int_bits); | | |
| 3175 | llvm_params.appendAssumeCapacity(big_int_ty); | | |
| 3176 | } | | |
| 3177 | }, | | |
| 3178 | .multiple_llvm_float => { | | |
| 3179 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; | | |
| 3180 | try llvm_params.ensureUnusedCapacity(it.llvm_types_len); | | |
| 3181 | for (llvm_ints) |float_bits| { | | |
| 3182 | const float_ty = switch (float_bits) { | | |
| 3183 | 64 => dg.context.doubleType(), | | |
| 3184 | 80 => dg.context.x86FP80Type(), | | |
| 3185 | else => unreachable, | | |
| 3186 | }; | | |
| 3187 | llvm_params.appendAssumeCapacity(float_ty); | | |
| 3188 | } | | |
| 3189 | }, | 3131 | }, |
| 3190 | .as_u16 => { | 3132 | .as_u16 => { |
| 3191 | try llvm_params.append(dg.context.intType(16)); | 3133 | try llvm_params.append(dg.context.intType(16)); |
| ... | @@ -4824,10 +4766,10 @@ pub const FuncGen = struct { | ... | @@ -4824,10 +4766,10 @@ pub const FuncGen = struct { |
| 4824 | llvm_args.appendAssumeCapacity(ptr); | 4766 | llvm_args.appendAssumeCapacity(ptr); |
| 4825 | llvm_args.appendAssumeCapacity(len); | 4767 | llvm_args.appendAssumeCapacity(len); |
| 4826 | }, | 4768 | }, |
| 4827 | .multiple_llvm_ints => { | 4769 | .multiple_llvm_types => { |
| 4828 | const arg = args[it.zig_index - 1]; | 4770 | const arg = args[it.zig_index - 1]; |
| 4829 | const param_ty = self.air.typeOf(arg); | 4771 | const param_ty = self.air.typeOf(arg); |
| 4830 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; | 4772 | const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len]; |
| 4831 | const llvm_arg = try self.resolveInst(arg); | 4773 | const llvm_arg = try self.resolveInst(arg); |
| 4832 | const is_by_ref = isByRef(param_ty); | 4774 | const is_by_ref = isByRef(param_ty); |
| 4833 | const arg_ptr = if (is_by_ref) llvm_arg else p: { | 4775 | const arg_ptr = if (is_by_ref) llvm_arg else p: { |
| ... | @@ -4837,51 +4779,13 @@ pub const FuncGen = struct { | ... | @@ -4837,51 +4779,13 @@ pub const FuncGen = struct { |
| 4837 | break :p p; | 4779 | break :p p; |
| 4838 | }; | 4780 | }; |
| 4839 | | 4781 | |
| 4840 | var field_types_buf: [8]*llvm.Type = undefined; | 4782 | const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False); |
| 4841 | const field_types = field_types_buf[0..llvm_ints.len]; | 4783 | const casted_ptr = self.builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), ""); |
| 4842 | for (llvm_ints) |int_bits, i| { | | |
| 4843 | field_types[i] = self.dg.context.intType(int_bits); | | |
| 4844 | } | | |
| 4845 | const ints_llvm_ty = self.dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); | | |
| 4846 | const casted_ptr = self.builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), ""); | | |
| 4847 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); | 4784 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); |
| 4848 | for (llvm_ints) |_, i_usize| { | 4785 | for (llvm_types) |field_ty, i_usize| { |
| 4849 | const i = @intCast(c_uint, i_usize); | 4786 | const i = @intCast(c_uint, i_usize); |
| 4850 | const field_ptr = self.builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, ""); | 4787 | const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, ""); |
| 4851 | const load_inst = self.builder.buildLoad(field_types[i], field_ptr, ""); | 4788 | const load_inst = self.builder.buildLoad(field_ty, field_ptr, ""); |
| 4852 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | | |
| 4853 | llvm_args.appendAssumeCapacity(load_inst); | | |
| 4854 | } | | |
| 4855 | }, | | |
| 4856 | .multiple_llvm_float => { | | |
| 4857 | const arg = args[it.zig_index - 1]; | | |
| 4858 | const param_ty = self.air.typeOf(arg); | | |
| 4859 | const llvm_floats = it.llvm_types_buffer[0..it.llvm_types_len]; | | |
| 4860 | const llvm_arg = try self.resolveInst(arg); | | |
| 4861 | const is_by_ref = isByRef(param_ty); | | |
| 4862 | const arg_ptr = if (is_by_ref) llvm_arg else p: { | | |
| 4863 | const p = self.buildAlloca(llvm_arg.typeOf(), null); | | |
| 4864 | const store_inst = self.builder.buildStore(llvm_arg, p); | | |
| 4865 | store_inst.setAlignment(param_ty.abiAlignment(target)); | | |
| 4866 | break :p p; | | |
| 4867 | }; | | |
| 4868 | | | |
| 4869 | var field_types_buf: [8]*llvm.Type = undefined; | | |
| 4870 | const field_types = field_types_buf[0..llvm_floats.len]; | | |
| 4871 | for (llvm_floats) |float_bits, i| { | | |
| 4872 | switch (float_bits) { | | |
| 4873 | 64 => field_types[i] = self.dg.context.doubleType(), | | |
| 4874 | 80 => field_types[i] = self.dg.context.x86FP80Type(), | | |
| 4875 | else => {}, | | |
| 4876 | } | | |
| 4877 | } | | |
| 4878 | const floats_llvm_ty = self.dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); | | |
| 4879 | const casted_ptr = self.builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), ""); | | |
| 4880 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); | | |
| 4881 | for (llvm_floats) |_, i_usize| { | | |
| 4882 | const i = @intCast(c_uint, i_usize); | | |
| 4883 | const field_ptr = self.builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, ""); | | |
| 4884 | const load_inst = self.builder.buildLoad(field_types[i], field_ptr, ""); | | |
| 4885 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); | 4789 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 4886 | llvm_args.appendAssumeCapacity(load_inst); | 4790 | llvm_args.appendAssumeCapacity(load_inst); |
| 4887 | } | 4791 | } |
| ... | @@ -10473,7 +10377,7 @@ const ParamTypeIterator = struct { | ... | @@ -10473,7 +10377,7 @@ const ParamTypeIterator = struct { |
| 10473 | llvm_index: u32, | 10377 | llvm_index: u32, |
| 10474 | target: std.Target, | 10378 | target: std.Target, |
| 10475 | llvm_types_len: u32, | 10379 | llvm_types_len: u32, |
| 10476 | llvm_types_buffer: [8]u16, | 10380 | llvm_types_buffer: [8]*llvm.Type, |
| 10477 | byval_attr: bool, | 10381 | byval_attr: bool, |
| 10478 | | 10382 | |
| 10479 | const Lowering = union(enum) { | 10383 | const Lowering = union(enum) { |
| ... | @@ -10481,8 +10385,7 @@ const ParamTypeIterator = struct { | ... | @@ -10481,8 +10385,7 @@ const ParamTypeIterator = struct { |
| 10481 | byval, | 10385 | byval, |
| 10482 | byref, | 10386 | byref, |
| 10483 | abi_sized_int, | 10387 | abi_sized_int, |
| 10484 | multiple_llvm_ints, | 10388 | multiple_llvm_types, |
| 10485 | multiple_llvm_float, | | |
| 10486 | slice, | 10389 | slice, |
| 10487 | as_u16, | 10390 | as_u16, |
| 10488 | float_array: u8, | 10391 | float_array: u8, |
| ... | @@ -10515,7 +10418,7 @@ const ParamTypeIterator = struct { | ... | @@ -10515,7 +10418,7 @@ const ParamTypeIterator = struct { |
| 10515 | it.zig_index += 1; | 10418 | it.zig_index += 1; |
| 10516 | return .no_bits; | 10419 | return .no_bits; |
| 10517 | } | 10420 | } |
| 10518 | | 10421 | const dg = it.dg; |
| 10519 | switch (it.fn_info.cc) { | 10422 | switch (it.fn_info.cc) { |
| 10520 | .Unspecified, .Inline => { | 10423 | .Unspecified, .Inline => { |
| 10521 | it.zig_index += 1; | 10424 | it.zig_index += 1; |
| ... | @@ -10584,28 +10487,28 @@ const ParamTypeIterator = struct { | ... | @@ -10584,28 +10487,28 @@ const ParamTypeIterator = struct { |
| 10584 | it.llvm_index += 1; | 10487 | it.llvm_index += 1; |
| 10585 | return .byval; | 10488 | return .byval; |
| 10586 | } | 10489 | } |
| 10587 | var llvm_types_buffer: [8]u16 = undefined; | 10490 | var llvm_types_buffer: [8]*llvm.Type = undefined; |
| 10588 | var llvm_types_index: u32 = 0; | 10491 | var llvm_types_index: u32 = 0; |
| 10589 | for (classes) |class| { | 10492 | for (classes) |class| { |
| 10590 | switch (class) { | 10493 | switch (class) { |
| 10591 | .integer => { | 10494 | .integer => { |
| 10592 | llvm_types_buffer[llvm_types_index] = 64; | 10495 | llvm_types_buffer[llvm_types_index] = dg.context.intType(64); |
| 10593 | llvm_types_index += 1; | 10496 | llvm_types_index += 1; |
| 10594 | }, | 10497 | }, |
| 10595 | .sse => { | 10498 | .sse => { |
| 10596 | llvm_types_buffer[llvm_types_index] = 64; | 10499 | llvm_types_buffer[llvm_types_index] = dg.context.doubleType(); |
| 10597 | llvm_types_index += 1; | 10500 | llvm_types_index += 1; |
| 10598 | }, | 10501 | }, |
| 10599 | .sseup => { | 10502 | .sseup => { |
| 10600 | llvm_types_buffer[llvm_types_index] = 64; | 10503 | llvm_types_buffer[llvm_types_index] = dg.context.doubleType(); |
| 10601 | llvm_types_index += 1; | 10504 | llvm_types_index += 1; |
| 10602 | }, | 10505 | }, |
| 10603 | .x87 => { | 10506 | .x87 => { |
| 10604 | llvm_types_buffer[llvm_types_index] = 80; | 10507 | llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type(); |
| 10605 | llvm_types_index += 1; | 10508 | llvm_types_index += 1; |
| 10606 | }, | 10509 | }, |
| 10607 | .x87up => { | 10510 | .x87up => { |
| 10608 | llvm_types_buffer[llvm_types_index] = 80; | 10511 | llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type(); |
| 10609 | llvm_types_index += 1; | 10512 | llvm_types_index += 1; |
| 10610 | }, | 10513 | }, |
| 10611 | .complex_x87 => { | 10514 | .complex_x87 => { |
| ... | @@ -10625,7 +10528,7 @@ const ParamTypeIterator = struct { | ... | @@ -10625,7 +10528,7 @@ const ParamTypeIterator = struct { |
| 10625 | it.llvm_types_len = llvm_types_index; | 10528 | it.llvm_types_len = llvm_types_index; |
| 10626 | it.llvm_index += llvm_types_index; | 10529 | it.llvm_index += llvm_types_index; |
| 10627 | it.zig_index += 1; | 10530 | it.zig_index += 1; |
| 10628 | return if (classes[0] == .integer) .multiple_llvm_ints else .multiple_llvm_float; | 10531 | return .multiple_llvm_types; |
| 10629 | }, | 10532 | }, |
| 10630 | }, | 10533 | }, |
| 10631 | .wasm32 => { | 10534 | .wasm32 => { |
| ... | @@ -10649,8 +10552,8 @@ const ParamTypeIterator = struct { | ... | @@ -10649,8 +10552,8 @@ const ParamTypeIterator = struct { |
| 10649 | .byval => return .byval, | 10552 | .byval => return .byval, |
| 10650 | .integer => { | 10553 | .integer => { |
| 10651 | it.llvm_types_len = 1; | 10554 | it.llvm_types_len = 1; |
| 10652 | it.llvm_types_buffer[0] = 64; | 10555 | it.llvm_types_buffer[0] = dg.context.intType(64); |
| 10653 | return .multiple_llvm_ints; | 10556 | return .multiple_llvm_types; |
| 10654 | }, | 10557 | }, |
| 10655 | .double_integer => return Lowering{ .i64_array = 2 }, | 10558 | .double_integer => return Lowering{ .i64_array = 2 }, |
| 10656 | } | 10559 | } |