| ... | ... | @@ -4802,7 +4802,7 @@ pub const FuncGen = struct { |
| 4802 | 4802 | const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(target)); |
| 4803 | 4803 | const rt_int_bits = compilerRtIntBits(operand_bits); |
| 4804 | 4804 | const rt_int_ty = self.context.intType(rt_int_bits); |
| 4805 | | const extended = e: { |
| 4805 | var extended = e: { |
| 4806 | 4806 | if (operand_scalar_ty.isSignedInt()) { |
| 4807 | 4807 | break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, ""); |
| 4808 | 4808 | } else { |
| ... | ... | @@ -4819,7 +4819,16 @@ pub const FuncGen = struct { |
| 4819 | 4819 | compiler_rt_operand_abbrev, |
| 4820 | 4820 | compiler_rt_dest_abbrev, |
| 4821 | 4821 | }) catch unreachable; |
| 4822 | | const param_types = [1]*const llvm.Type{rt_int_ty}; |
| 4822 | |
| 4823 | var param_types = [1]*const llvm.Type{rt_int_ty}; |
| 4824 | if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) { |
| 4825 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard |
| 4826 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. |
| 4827 | const v2i64 = self.context.intType(64).vectorType(2); |
| 4828 | extended = self.builder.buildBitCast(extended, v2i64, ""); |
| 4829 | param_types = [1]*const llvm.Type{v2i64}; |
| 4830 | } |
| 4831 | |
| 4823 | 4832 | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 4824 | 4833 | const params = [1]*const llvm.Value{extended}; |
| 4825 | 4834 | |
| ... | ... | @@ -4851,7 +4860,12 @@ pub const FuncGen = struct { |
| 4851 | 4860 | } |
| 4852 | 4861 | |
| 4853 | 4862 | const rt_int_bits = compilerRtIntBits(@intCast(u16, dest_scalar_ty.bitSize(target))); |
| 4854 | | const libc_ret_ty = self.context.intType(rt_int_bits); |
| 4863 | const ret_ty = self.context.intType(rt_int_bits); |
| 4864 | const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: { |
| 4865 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard |
| 4866 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. |
| 4867 | break :b self.context.intType(64).vectorType(2); |
| 4868 | } else ret_ty; |
| 4855 | 4869 | |
| 4856 | 4870 | const operand_bits = operand_scalar_ty.floatBits(target); |
| 4857 | 4871 | const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); |
| ... | ... | @@ -4871,13 +4885,11 @@ pub const FuncGen = struct { |
| 4871 | 4885 | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 4872 | 4886 | const params = [1]*const llvm.Value{operand}; |
| 4873 | 4887 | |
| 4874 | | const result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 4875 | | |
| 4876 | | if (libc_ret_ty == dest_llvm_ty) { |
| 4877 | | return result; |
| 4878 | | } |
| 4888 | var result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 4879 | 4889 | |
| 4880 | | return self.builder.buildTrunc(result, dest_llvm_ty, ""); |
| 4890 | if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, ""); |
| 4891 | if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, ""); |
| 4892 | return result; |
| 4881 | 4893 | } |
| 4882 | 4894 | |
| 4883 | 4895 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value { |
| ... | ... | @@ -6490,8 +6502,15 @@ pub const FuncGen = struct { |
| 6490 | 6502 | const one = int_llvm_ty.constInt(1, .False); |
| 6491 | 6503 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); |
| 6492 | 6504 | const sign_mask = one.constShl(shift_amt); |
| 6493 | | const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, ""); |
| 6494 | | const result = self.builder.buildXor(bitcasted_operand, sign_mask, ""); |
| 6505 | const result = if (ty.zigTypeTag() == .Vector) blk: { |
| 6506 | const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(), sign_mask, ""); |
| 6507 | const cast_ty = int_llvm_ty.vectorType(ty.vectorLen()); |
| 6508 | const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, ""); |
| 6509 | break :blk self.builder.buildXor(bitcasted_operand, splat_sign_mask, ""); |
| 6510 | } else blk: { |
| 6511 | const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, ""); |
| 6512 | break :blk self.builder.buildXor(bitcasted_operand, sign_mask, ""); |
| 6513 | }; |
| 6495 | 6514 | return self.builder.buildBitCast(result, llvm_ty, ""); |
| 6496 | 6515 | }, |
| 6497 | 6516 | .add, .sub, .div, .mul => FloatOpStrat{ |