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 3908228..0c98205 100644
--- a/lib/Target/X86/X86FloatingPoint.cpp
+++ b/lib/Target/X86/X86FloatingPoint.cpp
@@ -982,7 +982,21 @@
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 2ae904f..bc7def4 100644
--- a/lib/Target/X86/X86InstrFPStack.td
+++ b/lib/Target/X86/X86InstrFPStack.td
@@ -151,6 +151,12 @@
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 dfd299b..9416b7a 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -1753,19 +1753,20 @@
// 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;