return;
}
- case X86::WIN_FTOL_32:
- case X86::WIN_FTOL_64: {
- // Push the operand into ST0.
- MachineOperand &Op = MI->getOperand(0);
- assert(Op.isUse() && Op.isReg() &&
- Op.getReg() >= X86::FP0 && Op.getReg() <= X86::FP6);
- unsigned FPReg = getFPReg(Op);
- if (Op.isKill())
- moveToTop(FPReg, Inst);
- else
- duplicateToTop(FPReg, ScratchFPReg, Inst);
-
- // Emit the call. This will pop the operand.
- BuildMI(*MBB, Inst, MI->getDebugLoc(), TII->get(X86::CALLpcrel32))
- .addExternalSymbol("_ftol2")
- .addReg(X86::ST0, RegState::ImplicitKill)
- .addReg(X86::ECX, RegState::ImplicitDefine)
- .addReg(X86::EAX, RegState::Define | RegState::Implicit)
- .addReg(X86::EDX, RegState::Define | RegState::Implicit)
- .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
- --StackTop;
-
- break;
- }
-
case X86::RETQ:
case X86::RETL:
case X86::RETIL:
Requires<[In64BitMode]>;
}
-// The MSVC runtime contains an _ftol2 routine for converting floating-point
-// to integer values. It has a strange calling convention: the input is
-// popped from the x87 stack, and the return value is given in EDX:EAX. ECX is
-// used as a temporary register. No other registers (aside from flags) are
-// touched.
-// Microsoft toolchains do not support 80-bit precision, so a WIN_FTOL_80
-// variant is unnecessary.
-
-let Defs = [EAX, EDX, ECX, EFLAGS], FPForm = SpecialFP in {
- def WIN_FTOL_32 : I<0, Pseudo, (outs), (ins RFP32:$src),
- "# win32 fptoui",
- [(X86WinFTOL RFP32:$src)]>,
- Requires<[Not64BitMode]>;
-
- def WIN_FTOL_64 : I<0, Pseudo, (outs), (ins RFP64:$src),
- "# win32 fptoui",
- [(X86WinFTOL RFP64:$src)]>,
- Requires<[Not64BitMode]>;
-}
-
//===----------------------------------------------------------------------===//
// EH Pseudo Instructions
//
def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
-def SDT_X86WIN_FTOL : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
-
def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
-def X86WinFTOL : SDNode<"X86ISD::WIN_FTOL", SDT_X86WIN_FTOL,
- [SDNPHasChain, SDNPOutGlue]>;
-
//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
//
+++ /dev/null
-; RUN: llc < %s -mtriple=i686-pc-win32 -mcpu=generic | FileCheck %s -check-prefix=COMPILERRT
-; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT
-; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=COMPILERRT
-; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=COMPILERRT
-; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT
-; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s -check-prefix=COMPILERRT
-; RUN: llc < %s -mattr=-sse -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=COMPILERRT
-
-; This test originally used the FTOL and FTOL_2 checks for the i686-pc-win32
-; triples, under the assumption that Win32 targets should use the MSVCRT
-; _ftol2 runtime function for fptoui to i64. That usage was incorrect,
-; as _ftol2 performs conversion to signed i64. As of the compiler fix,
-; the FTOL/FTOL_2 checks are no longer used, which basically renders
-; this test meaningless.
-
-define i64 @double_ui64(double %x) nounwind {
-entry:
-; COMPILERRT: @double_ui64
-; COMPILERRT-NOT: calll __ftol2
-; FTOL: @double_ui64
-; FTOL: fldl
-; FTOL: calll __ftol2
-; FTOL-NOT: fstp
- %0 = fptoui double %x to i64
- ret i64 %0
-}
-
-define i64 @float_ui64(float %x) nounwind {
-entry:
-; COMPILERRT: @float_ui64
-; COMPILERRT-NOT: calll __ftol2
-; FTOL: @float_ui64
-; FTOL: flds
-; FTOL: calll __ftol2
-; FTOL-NOT: fstp
- %0 = fptoui float %x to i64
- ret i64 %0
-}
-
-define i64 @double_ui64_2(double %x, double %y, double %z) nounwind {
-; COMPILERRT: @double_ui64_2
-; FTOL: @double_ui64_2
-; FTOL_2: @double_ui64_2
-;; stack is empty
-; FTOL_2: fldl
-;; stack is %z
-; FTOL_2: fldl
-;; stack is %y %z
-; FTOL_2: fldl
-;; stack is %x %y %z
-; FTOL_2: fdiv %st(0), %st(1)
-;; stack is %x %1 %z
-; FTOL_2: fsubp %st(2)
-;; stack is %1 %2
-; FTOL_2: fxch
-; FTOL_2-NOT: fld
-; FTOL_2-NOT: fst
-;; stack is %2 %1
-; FTOL_2: calll __ftol2
-; FTOL_2-NOT: fxch
-; FTOL_2-NOT: fld
-; FTOL_2-NOT: fst
-; FTOL_2: calll __ftol2
-;; stack is empty
-
- %1 = fdiv double %x, %y
- %2 = fsub double %x, %z
- %3 = fptoui double %2 to i64
- %4 = fptoui double %1 to i64
- %5 = sub i64 %4, %3
- ret i64 %5
-}
-
-define i64 @double_ui64_3(double %x, double %y, double %z) nounwind {
-; COMPILERRT: @double_ui64_3
-; FTOL: @double_ui64_3
-; FTOL_2: @double_ui64_3
-;; stack is empty
-; FTOL_2: fldl
-;; stack is %z
-; FTOL_2: fldl
-;; stack is %y %z
-; FTOL_2: fldl
-;; stack is %x %y %z
-; FTOL_2: fdiv %st(0), %st(1)
-;; stack is %x %1 %z
-; FTOL_2: fsubp %st(2)
-;; stack is %1 %2
-; FTOL_2-NOT: fxch
-; FTOL_2-NOT: fld
-; FTOL_2-NOT: fst
-;; stack is %1 %2 (still)
-; FTOL_2: calll __ftol2
-; FTOL_2-NOT: fxch
-; FTOL_2-NOT: fld
-; FTOL_2-NOT: fst
-; FTOL_2: calll __ftol2
-;; stack is empty
-
- %1 = fdiv double %x, %y
- %2 = fsub double %x, %z
- %3 = fptoui double %1 to i64
- %4 = fptoui double %2 to i64
- %5 = sub i64 %4, %3
- ret i64 %5
-}
-
-define {double, i64} @double_ui64_4(double %x, double %y) nounwind {
-; COMPILERRT: @double_ui64_4
-; FTOL: @double_ui64_4
-; FTOL_2: @double_ui64_4
-;; stack is empty
-; FTOL_2: fldl
-;; stack is %y
-; FTOL_2: fldl
-;; stack is %x %y
-; FTOL_2: fxch
-;; stack is %y %x
-; FTOL_2: calll __ftol2
-;; stack is %x
-; FTOL_2: fld %st(0)
-;; stack is %x %x
-; FTOL_2: calll __ftol2
-;; stack is %x
-
- %1 = fptoui double %y to i64
- %2 = fptoui double %x to i64
- %3 = sub i64 %2, %1
- %4 = insertvalue {double, i64} undef, double %x, 0
- %5 = insertvalue {double, i64} %4, i64 %3, 1
- ret {double, i64} %5
-}
-
-define i32 @double_ui32_5(double %X) {
-; FTOL: @double_ui32_5
-; FTOL: calll __ftol2
- %tmp.1 = fptoui double %X to i32
- ret i32 %tmp.1
-}
-
-define i64 @double_ui64_5(double %X) {
-; FTOL: @double_ui64_5
-; FTOL: calll __ftol2
- %tmp.1 = fptoui double %X to i64
- ret i64 %tmp.1
-}
-
-define double @pr23957_32(double %A) {
-; FTOL-LABEL: @pr23957_32
-; FTOL: fldl
-; FTOL-NEXT: fld %st(0)
-; FTOL-NEXT: calll __ftol2
- %B = fptoui double %A to i32
- %C = uitofp i32 %B to double
- %D = fsub double %C, %A
- ret double %D
-}
-
-define double @pr23957_64(double %A) {
-; FTOL-LABEL: @pr23957_64
-; FTOL: fldl
-; FTOL-NEXT: fld %st(0)
-; FTOL-NEXT: calll __ftol2
- %B = fptoui double %A to i64
- %C = uitofp i64 %B to double
- %D = fsub double %C, %A
- ret double %D
-}