| ... | @@ -23,6 +23,7 @@ const LazySrcLoc = Module.LazySrcLoc; | ... | @@ -23,6 +23,7 @@ const LazySrcLoc = Module.LazySrcLoc; |
| 23 | const CType = @import("../type.zig").CType; | 23 | const CType = @import("../type.zig").CType; |
| 24 | const x86_64_abi = @import("../arch/x86_64/abi.zig"); | 24 | const x86_64_abi = @import("../arch/x86_64/abi.zig"); |
| 25 | const wasm_c_abi = @import("../arch/wasm/abi.zig"); | 25 | const wasm_c_abi = @import("../arch/wasm/abi.zig"); |
| | 26 | const aarch64_c_abi = @import("../arch/aarch64/abi.zig"); |
| 26 | | 27 | |
| 27 | const Error = error{ OutOfMemory, CodegenFail }; | 28 | const Error = error{ OutOfMemory, CodegenFail }; |
| 28 | | 29 | |
| ... | @@ -1086,6 +1087,26 @@ pub const Object = struct { | ... | @@ -1086,6 +1087,26 @@ pub const Object = struct { |
| 1086 | try args.ensureUnusedCapacity(1); | 1087 | try args.ensureUnusedCapacity(1); |
| 1087 | args.appendAssumeCapacity(casted); | 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,6 +3091,13 @@ pub const DeclGen = struct { |
| 3070 | .as_u16 => { | 3091 | .as_u16 => { |
| 3071 | try llvm_params.append(dg.context.intType(16)); | 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 | return llvm.functionType( | 3103 | return llvm.functionType( |
| ... | @@ -4621,6 +4649,27 @@ pub const FuncGen = struct { | ... | @@ -4621,6 +4649,27 @@ pub const FuncGen = struct { |
| 4621 | const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), ""); | 4649 | const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), ""); |
| 4622 | try llvm_args.append(casted); | 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 | const call = self.builder.buildCall( | 4675 | const call = self.builder.buildCall( |
| ... | @@ -9644,6 +9693,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool | ... | @@ -9644,6 +9693,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 9644 | else => return x86_64_abi.classifySystemV(fn_info.return_type, target)[0] == .memory, | 9693 | else => return x86_64_abi.classifySystemV(fn_info.return_type, target)[0] == .memory, |
| 9645 | }, | 9694 | }, |
| 9646 | .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect, | 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 | else => return false, // TODO investigate C ABI for other architectures | 9697 | else => return false, // TODO investigate C ABI for other architectures |
| 9648 | }, | 9698 | }, |
| 9649 | else => return false, | 9699 | else => return false, |
| ... | @@ -9753,6 +9803,24 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm. | ... | @@ -9753,6 +9803,24 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm. |
| 9753 | const abi_size = scalar_type.abiSize(target); | 9803 | const abi_size = scalar_type.abiSize(target); |
| 9754 | return dg.context.intType(@intCast(c_uint, abi_size * 8)); | 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 | // TODO investigate C ABI for other architectures | 9824 | // TODO investigate C ABI for other architectures |
| 9757 | else => return dg.lowerType(fn_info.return_type), | 9825 | else => return dg.lowerType(fn_info.return_type), |
| 9758 | } | 9826 | } |
| ... | @@ -9780,6 +9848,7 @@ const ParamTypeIterator = struct { | ... | @@ -9780,6 +9848,7 @@ const ParamTypeIterator = struct { |
| 9780 | multiple_llvm_float, | 9848 | multiple_llvm_float, |
| 9781 | slice, | 9849 | slice, |
| 9782 | as_u16, | 9850 | as_u16, |
| | 9851 | float_array, |
| 9783 | }; | 9852 | }; |
| 9784 | | 9853 | |
| 9785 | pub fn next(it: *ParamTypeIterator) ?Lowering { | 9854 | pub fn next(it: *ParamTypeIterator) ?Lowering { |
| ... | @@ -9945,6 +10014,28 @@ const ParamTypeIterator = struct { | ... | @@ -9945,6 +10014,28 @@ const ParamTypeIterator = struct { |
| 9945 | } | 10014 | } |
| 9946 | return .abi_sized_int; | 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 | // TODO investigate C ABI for other architectures | 10039 | // TODO investigate C ABI for other architectures |
| 9949 | else => { | 10040 | else => { |
| 9950 | it.zig_index += 1; | 10041 | it.zig_index += 1; |