From: Evan Cheng Date: Mon, 9 Feb 2009 23:32:07 +0000 (+0000) Subject: Implement FpSET_ST1_*. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a0eedac226e79d818ce1124fe500a6e354e3444a;p=oota-llvm.git Implement FpSET_ST1_*. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64186 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index 39082284aad..0c98205980d 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -982,7 +982,21 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) { case X86::FpSET_ST0_32: case X86::FpSET_ST0_64: case X86::FpSET_ST0_80: - assert(StackTop == 1 && "Stack should have one element on it to return!"); + assert((StackTop == 1 || StackTop == 2) + && "Stack should have one or two element on it to return!"); + --StackTop; // "Forget" we have something on the top of stack! + break; + case X86::FpSET_ST1_32: + case X86::FpSET_ST1_64: + case X86::FpSET_ST1_80: + // StackTop can be 1 if a FpSET_ST0_* was before this. Exchange them. + if (StackTop == 1) { + BuildMI(*MBB, I, TII->get(X86::XCH_F)).addReg(X86::ST1); + NumFXCH++; + StackTop = 0; + break; + } + assert(StackTop == 2 && "Stack should have two element on it to return!"); --StackTop; // "Forget" we have something on the top of stack! break; case X86::MOV_Fp3232: diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td index 2ae904f3243..bc7def457c0 100644 --- a/lib/Target/X86/X86InstrFPStack.td +++ b/lib/Target/X86/X86InstrFPStack.td @@ -151,6 +151,12 @@ def FpSET_ST0_64 : FpI_<(outs), (ins RFP64:$src), SpecialFP, []>; // ST(0) = FPR def FpSET_ST0_80 : FpI_<(outs), (ins RFP80:$src), SpecialFP, []>; // ST(0) = FPR } +let Defs = [ST1] in { +def FpSET_ST1_32 : FpI_<(outs), (ins RFP32:$src), SpecialFP, []>; // ST(1) = FPR +def FpSET_ST1_64 : FpI_<(outs), (ins RFP64:$src), SpecialFP, []>; // ST(1) = FPR +def FpSET_ST1_80 : FpI_<(outs), (ins RFP80:$src), SpecialFP, []>; // ST(1) = FPR +} + // FpIf32, FpIf64 - Floating Point Psuedo Instruction template. // f32 instructions can use SSE1 and are predicated on FPStackf32 == !SSE1. // f64 instructions can use SSE2 and are predicated on FPStackf64 == !SSE2. diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index dfd299b799b..9416b7a50d6 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1753,19 +1753,20 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB, // Moving to ST(0) turns into FpSET_ST0_32 etc. if (DestRC == &X86::RSTRegClass) { - // Copying to ST(0). FIXME: handle ST(1) also - if (DestReg != X86::ST0) + // Copying to ST(0) / ST(1). + if (DestReg != X86::ST0 && DestReg != X86::ST1) // Can only copy to TOS right now return false; + bool isST0 = DestReg == X86::ST0; unsigned Opc; if (SrcRC == &X86::RFP32RegClass) - Opc = X86::FpSET_ST0_32; + Opc = isST0 ? X86::FpSET_ST0_32 : X86::FpSET_ST1_32; else if (SrcRC == &X86::RFP64RegClass) - Opc = X86::FpSET_ST0_64; + Opc = isST0 ? X86::FpSET_ST0_64 : X86::FpSET_ST1_64; else { if (SrcRC != &X86::RFP80RegClass) return false; - Opc = X86::FpSET_ST0_80; + Opc = isST0 ? X86::FpSET_ST0_80 : X86::FpSET_ST1_80; } BuildMI(MBB, MI, get(Opc)).addReg(SrcReg); return true; diff --git a/test/CodeGen/X86/fp-stack-set-st1.ll b/test/CodeGen/X86/fp-stack-set-st1.ll new file mode 100644 index 00000000000..00a73aeb416 --- /dev/null +++ b/test/CodeGen/X86/fp-stack-set-st1.ll @@ -0,0 +1,7 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep fxch | count 2 + +define i32 @main() nounwind { +entry: + %asmtmp = tail call { double, double } asm sideeffect "fmul\09%st(1),%st\0A\09fst\09%st(1)\0A\09frndint\0A\09fxch %st(1)\0A\09fsub\09%st(1),%st\0A\09f2xm1\0A\09", "={st},={st(1)},0,1,~{dirflag},~{fpsr},~{flags}"(double 0x4030FEFBD582097D, double 4.620000e+01) nounwind ; <{ double, double }> [#uses=0] + unreachable +}