| ... | ... | @@ -23,6 +23,7 @@ const LazySrcLoc = Module.LazySrcLoc; |
| 23 | 23 | const CType = @import("../type.zig").CType; |
| 24 | 24 | const x86_64_abi = @import("../arch/x86_64/abi.zig"); |
| 25 | 25 | const wasm_c_abi = @import("../arch/wasm/abi.zig"); |
| 26 | const aarch64_c_abi = @import("../arch/aarch64/abi.zig"); |
| 26 | 27 | |
| 27 | 28 | const Error = error{ OutOfMemory, CodegenFail }; |
| 28 | 29 | |
| ... | ... | @@ -1086,6 +1087,26 @@ pub const Object = struct { |
| 1086 | 1087 | try args.ensureUnusedCapacity(1); |
| 1087 | 1088 | args.appendAssumeCapacity(casted); |
| 1088 | 1089 | }, |
| 1090 | .float_array => { |
| 1091 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 1092 | const param_llvm_ty = try dg.lowerType(param_ty); |
| 1093 | const param = llvm_func.getParam(llvm_arg_i); |
| 1094 | llvm_arg_i += 1; |
| 1095 | |
| 1096 | const alignment = param_ty.abiAlignment(target); |
| 1097 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty); |
| 1098 | arg_ptr.setAlignment(alignment); |
| 1099 | const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), ""); |
| 1100 | _ = builder.buildStore(param, casted_ptr); |
| 1101 | |
| 1102 | if (isByRef(param_ty)) { |
| 1103 | try args.append(arg_ptr); |
| 1104 | } else { |
| 1105 | const load_inst = builder.buildLoad(arg_ptr, ""); |
| 1106 | load_inst.setAlignment(alignment); |
| 1107 | try args.append(load_inst); |
| 1108 | } |
| 1109 | }, |
| 1089 | 1110 | }; |
| 1090 | 1111 | } |
| 1091 | 1112 | |
| ... | ... | @@ -3070,6 +3091,13 @@ pub const DeclGen = struct { |
| 3070 | 3091 | .as_u16 => { |
| 3071 | 3092 | try llvm_params.append(dg.context.intType(16)); |
| 3072 | 3093 | }, |
| 3094 | .float_array => { |
| 3095 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 3096 | const float_ty = try dg.lowerType(param_ty.structFieldType(0)); |
| 3097 | const field_count = @intCast(c_uint, param_ty.structFieldCount()); |
| 3098 | const arr_ty = float_ty.arrayType(field_count); |
| 3099 | try llvm_params.append(arr_ty); |
| 3100 | }, |
| 3073 | 3101 | }; |
| 3074 | 3102 | |
| 3075 | 3103 | return llvm.functionType( |
| ... | ... | @@ -4621,6 +4649,27 @@ pub const FuncGen = struct { |
| 4621 | 4649 | const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), ""); |
| 4622 | 4650 | try llvm_args.append(casted); |
| 4623 | 4651 | }, |
| 4652 | .float_array => { |
| 4653 | const arg = args[it.zig_index - 1]; |
| 4654 | const arg_ty = self.air.typeOf(arg); |
| 4655 | var llvm_arg = try self.resolveInst(arg); |
| 4656 | if (!isByRef(arg_ty)) { |
| 4657 | const p = self.buildAlloca(llvm_arg.typeOf()); |
| 4658 | const store_inst = self.builder.buildStore(llvm_arg, p); |
| 4659 | store_inst.setAlignment(arg_ty.abiAlignment(target)); |
| 4660 | llvm_arg = store_inst; |
| 4661 | } |
| 4662 | |
| 4663 | const float_ty = try self.dg.lowerType(arg_ty.structFieldType(0)); |
| 4664 | const field_count = @intCast(u32, arg_ty.structFieldCount()); |
| 4665 | const arr_ty = float_ty.arrayType(field_count); |
| 4666 | |
| 4667 | const casted = self.builder.buildBitCast(llvm_arg, arr_ty.pointerType(0), ""); |
| 4668 | const alignment = arg_ty.abiAlignment(target); |
| 4669 | const load_inst = self.builder.buildLoad(casted, ""); |
| 4670 | load_inst.setAlignment(alignment); |
| 4671 | try llvm_args.append(load_inst); |
| 4672 | }, |
| 4624 | 4673 | }; |
| 4625 | 4674 | |
| 4626 | 4675 | const call = self.builder.buildCall( |
| ... | ... | @@ -9644,6 +9693,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 9644 | 9693 | else => return x86_64_abi.classifySystemV(fn_info.return_type, target)[0] == .memory, |
| 9645 | 9694 | }, |
| 9646 | 9695 | .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect, |
| 9696 | .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, target)[0] == .memory, |
| 9647 | 9697 | else => return false, // TODO investigate C ABI for other architectures |
| 9648 | 9698 | }, |
| 9649 | 9699 | else => return false, |
| ... | ... | @@ -9753,6 +9803,24 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm. |
| 9753 | 9803 | const abi_size = scalar_type.abiSize(target); |
| 9754 | 9804 | return dg.context.intType(@intCast(c_uint, abi_size * 8)); |
| 9755 | 9805 | }, |
| 9806 | .aarch64, .aarch64_be => { |
| 9807 | if (is_scalar) { |
| 9808 | return dg.lowerType(fn_info.return_type); |
| 9809 | } |
| 9810 | const classes = aarch64_c_abi.classifyType(fn_info.return_type, target); |
| 9811 | if (classes[0] == .memory or classes[0] == .none) { |
| 9812 | return dg.context.voidType(); |
| 9813 | } |
| 9814 | if (classes[0] == .float_array) { |
| 9815 | return dg.lowerType(fn_info.return_type); |
| 9816 | } |
| 9817 | if (classes[1] == .none) { |
| 9818 | const bit_size = fn_info.return_type.bitSize(target); |
| 9819 | return dg.context.intType(@intCast(c_uint, bit_size)); |
| 9820 | } |
| 9821 | |
| 9822 | return dg.context.intType(64).arrayType(2); |
| 9823 | }, |
| 9756 | 9824 | // TODO investigate C ABI for other architectures |
| 9757 | 9825 | else => return dg.lowerType(fn_info.return_type), |
| 9758 | 9826 | } |
| ... | ... | @@ -9780,6 +9848,7 @@ const ParamTypeIterator = struct { |
| 9780 | 9848 | multiple_llvm_float, |
| 9781 | 9849 | slice, |
| 9782 | 9850 | as_u16, |
| 9851 | float_array, |
| 9783 | 9852 | }; |
| 9784 | 9853 | |
| 9785 | 9854 | pub fn next(it: *ParamTypeIterator) ?Lowering { |
| ... | ... | @@ -9945,6 +10014,28 @@ const ParamTypeIterator = struct { |
| 9945 | 10014 | } |
| 9946 | 10015 | return .abi_sized_int; |
| 9947 | 10016 | }, |
| 10017 | .aarch64, .aarch64_be => { |
| 10018 | it.zig_index += 1; |
| 10019 | it.llvm_index += 1; |
| 10020 | if (is_scalar) { |
| 10021 | return .byval; |
| 10022 | } |
| 10023 | const classes = aarch64_c_abi.classifyType(ty, it.target); |
| 10024 | if (classes[0] == .memory) { |
| 10025 | return .byref; |
| 10026 | } |
| 10027 | if (classes[0] == .float_array) { |
| 10028 | return .float_array; |
| 10029 | } |
| 10030 | if (classes[1] == .none) { |
| 10031 | it.llvm_types_len = 1; |
| 10032 | } else { |
| 10033 | it.llvm_types_len = 2; |
| 10034 | } |
| 10035 | it.llvm_types_buffer[0] = 64; |
| 10036 | it.llvm_types_buffer[1] = 64; |
| 10037 | return .multiple_llvm_ints; |
| 10038 | }, |
| 9948 | 10039 | // TODO investigate C ABI for other architectures |
| 9949 | 10040 | else => { |
| 9950 | 10041 | it.zig_index += 1; |