aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2016-09-09 11:06:01 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2016-09-09 11:06:01 +0000
commitba92b034bf561b68e1c591e17c99dbdde0485f15 (patch)
tree9738ffa262e2fa1d377704f3d2c07532e221146f /llvm/lib
parent817bc16d19447328ee9cedf51a8f85cd4fa2fc14 (diff)
downloadllvm-ba92b034bf561b68e1c591e17c99dbdde0485f15.zip
llvm-ba92b034bf561b68e1c591e17c99dbdde0485f15.tar.gz
llvm-ba92b034bf561b68e1c591e17c99dbdde0485f15.tar.bz2
Revert "[mips] Fix c.<cc>.<fmt> instruction definition."
This reverts commit r281022. Mips buildbot broke, due to unhandled register class FCC. llvm-svn: 281033
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp6
-rw-r--r--llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h1
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrFPU.td78
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrFormats.td17
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp7
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.h2
-rw-r--r--llvm/lib/Target/Mips/MipsCondMov.td217
-rw-r--r--llvm/lib/Target/Mips/MipsFastISel.cpp6
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp142
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.h3
-rw-r--r--llvm/lib/Target/Mips/MipsInstrFPU.td220
-rw-r--r--llvm/lib/Target/Mips/MipsInstrFormats.td3
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.td3
-rw-r--r--llvm/lib/Target/Mips/MipsSEInstrInfo.cpp34
-rw-r--r--llvm/lib/Target/Mips/MipsSEInstrInfo.h9
15 files changed, 209 insertions, 539 deletions
diff --git a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
index f42c4e5..49c42fd 100644
--- a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
+++ b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
@@ -192,6 +192,12 @@ printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O) {
}
void MipsInstPrinter::
+printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) {
+ const MCOperand& MO = MI->getOperand(opNum);
+ O << MipsFCCToString((Mips::CondCode)MO.getImm());
+}
+
+void MipsInstPrinter::
printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O) {
printRegName(O, MI->getOperand(opNum).getReg());
}
diff --git a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
index 95f648c..4a76b5a 100644
--- a/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
+++ b/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
@@ -97,6 +97,7 @@ private:
void printUImm(const MCInst *MI, int opNum, raw_ostream &O);
void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O);
void printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O);
+ void printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O);
void printRegisterPair(const MCInst *MI, int opNum, raw_ostream &O);
void printSHFMask(const MCInst *MI, int opNum, raw_ostream &O);
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
index 9373eeb..ed92265 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -26,6 +26,11 @@ def LUXC1_MM : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, II_LUXC1>,
def SUXC1_MM : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, II_SUXC1>,
SWXC1_FM_MM<0x188>, INSN_MIPS5_32R2_NOT_32R6_64R6;
+def FCMP_S32_MM : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>,
+ CEQS_FM_MM<0>;
+def FCMP_D32_MM : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>,
+ CEQS_FM_MM<1>;
+
def BC1F_MM : MMRel, BC1F_FT<"bc1f", brtarget_mm, II_BC1F, MIPS_BRANCH_F>,
BC1F_FM_MM<0x1c>, ISA_MIPS1_NOT_32R6_64R6;
def BC1T_MM : MMRel, BC1F_FT<"bc1t", brtarget_mm, II_BC1T, MIPS_BRANCH_T>,
@@ -162,77 +167,4 @@ let AdditionalPredicates = [InMicroMips] in {
def : LoadRegImmPat<LWC1_MM, f32, load>;
def : StoreRegImmPat<SWC1_MM, f32>;
}
-
- // Floating point comparisons
- multiclass C_COND_M_MM<string TypeStr, RegisterOperand RC, bits<2> fmt,
- InstrItinClass itin> {
- def C_F_#NAME : C_COND_FT<"f", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 0>;
- def C_UN_#NAME : C_COND_FT<"un", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 1>;
- def C_EQ_#NAME : C_COND_FT<"eq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 2>;
- def C_UEQ_#NAME : C_COND_FT<"ueq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 3>;
- def C_OLT_#NAME : C_COND_FT<"olt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 4>;
- def C_ULT_#NAME : C_COND_FT<"ult", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 5>;
- def C_OLE_#NAME : C_COND_FT<"ole", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 6>;
- def C_ULE_#NAME : C_COND_FT<"ule", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 7>;
- def C_SF_#NAME : C_COND_FT<"sf", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 8>;
- def C_NGLE_#NAME : C_COND_FT<"ngle", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 9>;
- def C_SEQ_#NAME : C_COND_FT<"seq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 10>;
- def C_NGL_#NAME : C_COND_FT<"ngl", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 11>;
- def C_LT_#NAME : C_COND_FT<"lt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 12>;
- def C_NGE_#NAME : C_COND_FT<"nge", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 13>;
- def C_LE_#NAME : C_COND_FT<"le", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 14>;
- def C_NGT_#NAME : C_COND_FT<"ngt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 15>;
- }
-
- defm S_MM : C_COND_M_MM<"s", FGR32Opnd, 0b00, II_C_CC_S>;
- defm D32_MM : C_COND_M_MM<"d", AFGR64Opnd, 0b01, II_C_CC_D>, FGR_32;
-
- // Floating point branch patterns
- defm S_MM : FPBrcondPats<FGR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
- defm D32_MM : FPBrcondPats<AFGR64Opnd>, FGR_32, ISA_MIPS1_NOT_32R6_64R6;
-
- // Floating point setcc
- defm S_MM : FPSetccPats<MOVT_I_MM, MOVF_I_MM, (LI16_MM 1), FGR32Opnd>;
- defm D32_MM : FPSetccPats<MOVT_I_MM, MOVF_I_MM, (LI16_MM 1), AFGR64Opnd>,
- FGR_32;
-
- // Floating point select patterns
- defm : FPSelectPats<FGR32Opnd, FGR32Opnd, "S_MM", MOVT_S, MOVF_S_MM>,
- ISA_MIPS1_NOT_32R6_64R6;
- defm : FPSelectPats<FGR32Opnd, AFGR64Opnd, "S_MM", MOVT_D32, MOVF_D32_MM>,
- FGR_32, ISA_MIPS1_NOT_32R6_64R6;
-
- defm : FPSelectPats<AFGR64Opnd, AFGR64Opnd, "D32_MM", MOVT_D32, MOVF_D32_MM>,
- FGR_32, ISA_MIPS1_NOT_32R6_64R6;
- defm : FPSelectPats<AFGR64Opnd, FGR32Opnd, "D32_MM", MOVT_S, MOVF_S_MM>,
- FGR_32, ISA_MIPS1_NOT_32R6_64R6;
-
- defm : FPSelectPats<FGR32Opnd, GPR32Opnd, "S_MM", MOVT_I, MOVF_I_MM>,
- ISA_MIPS1_NOT_32R6_64R6;
- defm : FPSelectPats<AFGR64Opnd, GPR32Opnd, "D32_MM", MOVT_I, MOVF_I_MM>,
- FGR_32, ISA_MIPS1_NOT_32R6_64R6;
-}
-
-//===----------------------------------------------------------------------===//
-// Instruction aliases.
-//===----------------------------------------------------------------------===//
-let AdditionalPredicates = [InMicroMips] in {
- defm S_MM : FPCAliases<FGR32Opnd, "s">;
- defm D32_MM : FPCAliases<AFGR64Opnd, "d">;
}
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td
index bf785ad..68f7fcf 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td
@@ -722,23 +722,6 @@ class ADDS_FM_MM<bits<2> fmt, bits<8> funct> : MMArch {
list<dag> Pattern = [];
}
-class C_COND_FM_MM<bits<2> fmt, bits<4> cond> : MMArch {
- bits <5> ft;
- bits <5> fs;
- bits <3> cc;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010101;
- let Inst{25-21} = ft;
- let Inst{20-16} = fs;
- let Inst{15-13} = cc;
- let Inst{12} = 0;
- let Inst{11-10} = fmt;
- let Inst{9-6} = cond;
- let Inst{5-0} = 0b111100;
-}
-
class LWXC1_FM_MM<bits<9> funct> : MMArch {
bits<5> fd;
bits<5> base;
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 23454a6..7519c30 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -661,6 +661,13 @@ printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
}
void MipsAsmPrinter::
+printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier) {
+ const MachineOperand &MO = MI->getOperand(opNum);
+ O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
+}
+
+void MipsAsmPrinter::
printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
if (i != opNum) O << ", ";
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.h b/llvm/lib/Target/Mips/MipsAsmPrinter.h
index 2b0623e..f30141f 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.h
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.h
@@ -136,6 +136,8 @@ public:
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier = nullptr);
void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O);
void EmitStartOfAsmFile(Module &M) override;
void EmitEndOfAsmFile(Module &M) override;
diff --git a/llvm/lib/Target/Mips/MipsCondMov.td b/llvm/lib/Target/Mips/MipsCondMov.td
index 96c9ca4..fd4517f 100644
--- a/llvm/lib/Target/Mips/MipsCondMov.td
+++ b/llvm/lib/Target/Mips/MipsCondMov.td
@@ -261,220 +261,22 @@ defm : MovnPats<GPR32, FGR64, MOVN_I_D64, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
FGR_64;
-multiclass FPSetccPats<Instruction MOVT, Instruction MOVF, dag ADD,
- RegisterOperand RC> {
- def : MipsPat<(seteq RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setgt RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setge RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setlt RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setle RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setne RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setoeq RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setogt RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setoge RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setolt RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setole RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setone RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(seto RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_UN_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setuo RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_UN_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setueq RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setugt RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setuge RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setult RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setule RC:$lhs, RC:$rhs),
- (MOVF ZERO, (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
- def : MipsPat<(setune RC:$lhs, RC:$rhs),
- (MOVT ZERO, (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs),
- ADD)>;
-}
-
-let AdditionalPredicates = [NotInMicroMips] in {
- defm S : FPSetccPats<MOVT_I, MOVF_I, (ADDiu ZERO, 1), FGR32Opnd>,
- INSN_MIPS4_32_NOT_32R6_64R6;
- defm D32 : FPSetccPats<MOVT_I, MOVF_I, (ADDiu ZERO, 1), AFGR64Opnd>, FGR_32,
- INSN_MIPS4_32_NOT_32R6_64R6;
- defm D64 : FPSetccPats<MOVT_I, MOVF_I, (ADDiu ZERO, 1), FGR64Opnd>, FGR_64,
- INSN_MIPS4_32_NOT_32R6_64R6;
-}
-
-multiclass FPSelectPats<RegisterOperand RC, RegisterOperand RO, string Type,
- Instruction MOVT, Instruction MOVF> {
- // Ordered
- def : MipsPat<(select (i32 (setoeq RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_EQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setogt RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_ULE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setoge RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_ULT_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setolt RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_OLT_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setole RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_OLE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setone RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_UEQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (seto RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_UN_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- // Unordered
- def : MipsPat<(select (i32 (setuo RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_UN_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setueq RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_UEQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setugt RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_ULE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setuge RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_ULE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setult RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_ULT_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setule RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_ULE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setune RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_UEQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setuo RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_EQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- // Unspecified ordering - treated as ordered.
- def : MipsPat<(select (i32 (seteq RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_EQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setgt RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_OLE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setge RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_LT_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setlt RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_LT_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setle RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVT RO:$t, (!cast<Instruction>("C_OLE_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
- def : MipsPat<(select (i32 (setne RC:$lhs, RC:$rhs)), RO:$t, RO:$f),
- (MOVF RO:$t, (!cast<Instruction>("C_EQ_"#Type) RC:$lhs,
- RC:$rhs),
- RO:$f)>;
-}
-
-let AdditionalPredicates = [NotInMicroMips] in {
- defm : FPSelectPats<FGR32Opnd, FGR32Opnd, "S", MOVT_S, MOVF_S>,
- INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<FGR32Opnd, AFGR64Opnd, "S", MOVT_D32, MOVF_D32>,
- FGR_32, INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<FGR32Opnd, FGR64Opnd, "S", MOVT_D64, MOVF_D64>,
- FGR_64, INSN_MIPS4_32_NOT_32R6_64R6;
-
- defm : FPSelectPats<AFGR64Opnd, AFGR64Opnd, "D32", MOVT_D32, MOVF_D32>,
- FGR_32, INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<AFGR64Opnd, FGR32Opnd, "D32", MOVT_S, MOVF_S>,
- FGR_32, INSN_MIPS4_32_NOT_32R6_64R6;
-
-
- defm : FPSelectPats<FGR64Opnd, FGR64Opnd, "D64", MOVT_D64, MOVF_D64>,
- FGR_64, INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<FGR64Opnd, FGR32Opnd, "D64", MOVT_S, MOVF_S>,
- FGR_64, INSN_MIPS4_32_NOT_32R6_64R6;
-
- defm : FPSelectPats<FGR32Opnd, GPR32Opnd, "S", MOVT_I, MOVF_I>,
- INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<AFGR64Opnd, GPR32Opnd, "D32", MOVT_I, MOVF_I>,
- FGR_32, INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<FGR64Opnd, GPR32Opnd, "D64", MOVT_I, MOVF_I>,
- FGR_64, INSN_MIPS4_32_NOT_32R6_64R6;
-
- defm : FPSelectPats<FGR32Opnd, GPR64Opnd,"S", MOVT_I64, MOVF_I64>,
- INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<AFGR64Opnd, GPR64Opnd, "D32", MOVT_I64, MOVF_I64>,
- FGR_32, INSN_MIPS4_32_NOT_32R6_64R6;
- defm : FPSelectPats<FGR64Opnd, GPR64Opnd, "D64", MOVT_I64, MOVF_I64>,
- FGR_64, INSN_MIPS4_32_NOT_32R6_64R6;
-}
-
// For targets that don't have conditional-move instructions
// we have to match SELECT nodes with pseudo instructions.
let usesCustomInserter = 1 in {
class Select_Pseudo<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins RC:$T, GPR32Opnd:$cond, RC:$F),
+ PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
[(set RC:$dst, (select GPR32Opnd:$cond, RC:$T, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
class SelectFP_Pseudo_T<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins RC:$T, FCC:$cond, RC:$F),
- [(set RC:$dst, (MipsCMovFP_T RC:$T, FCC:$cond, RC:$F))]>,
+ PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
+ [(set RC:$dst, (MipsCMovFP_T RC:$T, GPR32Opnd:$cond, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
class SelectFP_Pseudo_F<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins RC:$T, FCC:$cond, RC:$F),
- [(set RC:$dst, (MipsCMovFP_F RC:$T, FCC:$cond, RC:$F))]>,
+ PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
+ [(set RC:$dst, (MipsCMovFP_F RC:$T, GPR32Opnd:$cond, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
}
@@ -495,12 +297,3 @@ def PseudoSELECTFP_F_I64 : SelectFP_Pseudo_F<GPR64Opnd>;
def PseudoSELECTFP_F_S : SelectFP_Pseudo_F<FGR32Opnd>;
def PseudoSELECTFP_F_D32 : SelectFP_Pseudo_F<AFGR64Opnd>, FGR_32;
def PseudoSELECTFP_F_D64 : SelectFP_Pseudo_F<FGR64Opnd>, FGR_64;
-
-let AdditionalPredicates = [NotInMicroMips] in {
- defm : FPSelectPats<FGR32Opnd, FGR32Opnd, "S", PseudoSELECTFP_T_S,
- PseudoSELECTFP_F_S>, ISA_MIPS1_NOT_4_32;
- defm : FPSelectPats<AFGR64Opnd, AFGR64Opnd, "D32", PseudoSELECTFP_T_D32,
- PseudoSELECTFP_F_D32>, FGR_32, ISA_MIPS1_NOT_4_32;
- defm : FPSelectPats<FGR64Opnd, FGR64Opnd, "D64", PseudoSELECTFP_T_D64,
- PseudoSELECTFP_F_D64>, FGR_64, ISA_MIPS1_NOT_4_32;
-}
diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp
index 58a53a0..9453164 100644
--- a/llvm/lib/Target/Mips/MipsFastISel.cpp
+++ b/llvm/lib/Target/Mips/MipsFastISel.cpp
@@ -709,10 +709,8 @@ bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass);
emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);
emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);
- emitInst(Opc)
- .addReg(Mips::FCC0, RegState::Define)
- .addReg(LeftReg)
- .addReg(RightReg);
+ emitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg(
+ Mips::FCC0, RegState::ImplicitDefine);
emitInst(CondMovOpc, ResultReg)
.addReg(RegWithOne)
.addReg(Mips::FCC0)
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 371a4fe..417eb8d 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -144,7 +144,6 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::Sync: return "MipsISD::Sync";
case MipsISD::Ext: return "MipsISD::Ext";
case MipsISD::Ins: return "MipsISD::Ins";
- case MipsISD::PseudoReadFCC: return "MipsISD::PseudoReadFCC";
case MipsISD::LWL: return "MipsISD::LWL";
case MipsISD::LWR: return "MipsISD::LWR";
case MipsISD::SWL: return "MipsISD::SWL";
@@ -275,6 +274,12 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+ setOperationAction(ISD::SELECT, MVT::f32, Custom);
+ setOperationAction(ISD::SELECT, MVT::f64, Custom);
+ setOperationAction(ISD::SELECT, MVT::i32, Custom);
+ setOperationAction(ISD::SETCC, MVT::f32, Custom);
+ setOperationAction(ISD::SETCC, MVT::f64, Custom);
+ setOperationAction(ISD::BRCOND, MVT::Other, Custom);
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
@@ -285,6 +290,7 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
+ setOperationAction(ISD::SELECT, MVT::i64, Custom);
setOperationAction(ISD::LOAD, MVT::i64, Custom);
setOperationAction(ISD::STORE, MVT::i64, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
@@ -501,6 +507,79 @@ static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+static Mips::CondCode condCodeToFCC(ISD::CondCode CC) {
+ switch (CC) {
+ default: llvm_unreachable("Unknown fp condition code!");
+ case ISD::SETEQ:
+ case ISD::SETOEQ: return Mips::FCOND_OEQ;
+ case ISD::SETUNE: return Mips::FCOND_UNE;
+ case ISD::SETLT:
+ case ISD::SETOLT: return Mips::FCOND_OLT;
+ case ISD::SETGT:
+ case ISD::SETOGT: return Mips::FCOND_OGT;
+ case ISD::SETLE:
+ case ISD::SETOLE: return Mips::FCOND_OLE;
+ case ISD::SETGE:
+ case ISD::SETOGE: return Mips::FCOND_OGE;
+ case ISD::SETULT: return Mips::FCOND_ULT;
+ case ISD::SETULE: return Mips::FCOND_ULE;
+ case ISD::SETUGT: return Mips::FCOND_UGT;
+ case ISD::SETUGE: return Mips::FCOND_UGE;
+ case ISD::SETUO: return Mips::FCOND_UN;
+ case ISD::SETO: return Mips::FCOND_OR;
+ case ISD::SETNE:
+ case ISD::SETONE: return Mips::FCOND_ONE;
+ case ISD::SETUEQ: return Mips::FCOND_UEQ;
+ }
+}
+
+
+/// This function returns true if the floating point conditional branches and
+/// conditional moves which use condition code CC should be inverted.
+static bool invertFPCondCodeUser(Mips::CondCode CC) {
+ if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT)
+ return false;
+
+ assert((CC >= Mips::FCOND_T && CC <= Mips::FCOND_GT) &&
+ "Illegal Condition Code");
+
+ return true;
+}
+
+// Creates and returns an FPCmp node from a setcc node.
+// Returns Op if setcc is not a floating point comparison.
+static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) {
+ // must be a SETCC node
+ if (Op.getOpcode() != ISD::SETCC)
+ return Op;
+
+ SDValue LHS = Op.getOperand(0);
+
+ if (!LHS.getValueType().isFloatingPoint())
+ return Op;
+
+ SDValue RHS = Op.getOperand(1);
+ SDLoc DL(Op);
+
+ // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of
+ // node if necessary.
+ ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+
+ return DAG.getNode(MipsISD::FPCmp, DL, MVT::Glue, LHS, RHS,
+ DAG.getConstant(condCodeToFCC(CC), DL, MVT::i32));
+}
+
+// Creates and returns a CMovFPT/F node.
+static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True,
+ SDValue False, const SDLoc &DL) {
+ ConstantSDNode *CC = cast<ConstantSDNode>(Cond.getOperand(2));
+ bool invert = invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue());
+ SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);
+
+ return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL,
+ True.getValueType(), True, FCC0, False, Cond);
+}
+
static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) {
@@ -822,11 +901,14 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
switch (Op.getOpcode())
{
case ISD::BR_JT: return lowerBR_JT(Op, DAG);
+ case ISD::BRCOND: return lowerBRCOND(Op, DAG);
case ISD::ConstantPool: return lowerConstantPool(Op, DAG);
case ISD::GlobalAddress: return lowerGlobalAddress(Op, DAG);
case ISD::BlockAddress: return lowerBlockAddress(Op, DAG);
case ISD::GlobalTLSAddress: return lowerGlobalTLSAddress(Op, DAG);
case ISD::JumpTable: return lowerJumpTable(Op, DAG);
+ case ISD::SELECT: return lowerSELECT(Op, DAG);
+ case ISD::SETCC: return lowerSETCC(Op, DAG);
case ISD::VASTART: return lowerVASTART(Op, DAG);
case ISD::VAARG: return lowerVAARG(Op, DAG);
case ISD::FCOPYSIGN: return lowerFCOPYSIGN(Op, DAG);
@@ -1618,6 +1700,58 @@ SDValue MipsTargetLowering::lowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
return DAG.getNode(ISD::BRIND, DL, MVT::Other, Chain, Addr);
}
+SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
+ // The first operand is the chain, the second is the condition, the third is
+ // the block to branch to if the condition is true.
+ SDValue Chain = Op.getOperand(0);
+ SDValue Dest = Op.getOperand(2);
+ SDLoc DL(Op);
+
+ assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
+ SDValue CondRes = createFPCmp(DAG, Op.getOperand(1));
+
+ // Return if flag is not set by a floating point comparison.
+ if (CondRes.getOpcode() != MipsISD::FPCmp)
+ return Op;
+
+ SDValue CCNode = CondRes.getOperand(2);
+ Mips::CondCode CC =
+ (Mips::CondCode)cast<ConstantSDNode>(CCNode)->getZExtValue();
+ unsigned Opc = invertFPCondCodeUser(CC) ? Mips::BRANCH_F : Mips::BRANCH_T;
+ SDValue BrCode = DAG.getConstant(Opc, DL, MVT::i32);
+ SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);
+ return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode,
+ FCC0, Dest, CondRes);
+}
+
+SDValue MipsTargetLowering::
+lowerSELECT(SDValue Op, SelectionDAG &DAG) const
+{
+ assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
+ SDValue Cond = createFPCmp(DAG, Op.getOperand(0));
+
+ // Return if flag is not set by a floating point comparison.
+ if (Cond.getOpcode() != MipsISD::FPCmp)
+ return Op;
+
+ return createCMovFP(DAG, Cond, Op.getOperand(1), Op.getOperand(2),
+ SDLoc(Op));
+}
+
+SDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const {
+ assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
+ SDValue Cond = createFPCmp(DAG, Op);
+
+ assert(Cond.getOpcode() == MipsISD::FPCmp &&
+ "Floating point operand expected.");
+
+ SDLoc DL(Op);
+ SDValue True = DAG.getConstant(1, DL, MVT::i32);
+ SDValue False = DAG.getConstant(0, DL, MVT::i32);
+
+ return createCMovFP(DAG, Cond, True, False, DL);
+}
+
SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
SelectionDAG &DAG) const {
EVT Ty = Op.getValueType();
@@ -3852,12 +3986,12 @@ MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,
if (isFPCmp) {
// bc1[tf] cc, sinkMBB
BuildMI(BB, DL, TII->get(Opc))
- .addReg(MI.getOperand(2).getReg())
+ .addReg(MI.getOperand(1).getReg())
.addMBB(sinkMBB);
} else {
// bne rs, $0, sinkMBB
BuildMI(BB, DL, TII->get(Opc))
- .addReg(MI.getOperand(2).getReg())
+ .addReg(MI.getOperand(1).getReg())
.addReg(Mips::ZERO)
.addMBB(sinkMBB);
}
@@ -3876,7 +4010,7 @@ MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,
BB = sinkMBB;
BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
- .addReg(MI.getOperand(1).getReg())
+ .addReg(MI.getOperand(2).getReg())
.addMBB(thisMBB)
.addReg(MI.getOperand(3).getReg())
.addMBB(copy0MBB);
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 2d9d511..767eee7 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -108,9 +108,6 @@ namespace llvm {
Ext,
Ins,
- // Pseudo Node used to read the FCC registers.
- PseudoReadFCC,
-
// EXTR.W instrinsic nodes.
EXTP,
EXTPDP,
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index 9544bd5..6bbbd51 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -23,6 +23,12 @@
// - 32 32-bit registers (within single-only mode)
//===----------------------------------------------------------------------===//
+// Floating Point Compare and Branch
+def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisInt<0>,
+ SDTCisVT<1, i32>,
+ SDTCisVT<2, OtherVT>]>;
+def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>,
+ SDTCisVT<2, i32>]>;
def SDT_MipsCMovFP : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisVT<2, i32>,
SDTCisSameAs<1, 3>]>;
def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
@@ -33,15 +39,19 @@ def SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
SDTCisVT<1, f64>,
SDTCisVT<2, i32>]>;
+def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp, [SDNPOutGlue]>;
def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>;
def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>;
+def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond,
+ [SDNPHasChain, SDNPOptInGlue]>;
def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>;
def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>;
// Operand for printing out a condition code.
-def invertbit : Operand<i1>;
+let PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in
+ def condcode : Operand<i32>;
//===----------------------------------------------------------------------===//
// Feature predicates.
@@ -202,23 +212,31 @@ class SWXC1_FT<string opstr, RegisterOperand DRC,
class BC1F_FT<string opstr, DAGOperand opnd, InstrItinClass Itin,
SDPatternOperator Op = null_frag, bit DelaySlot = 1> :
InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
- !strconcat(opstr, "\t$fcc, $offset"), [], Itin, FrmFI, opstr>,
- HARDFLOAT {
+ !strconcat(opstr, "\t$fcc, $offset"),
+ [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin,
+ FrmFI, opstr>, HARDFLOAT {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = DelaySlot;
let Defs = [AT];
}
-class C_COND_FT<string CondStr, string Typestr, RegisterOperand RC,
- InstrItinClass itin> :
- InstSE<(outs FCCRegsOpnd:$fcc), (ins RC:$fs, RC:$ft),
- !strconcat("c.", CondStr, ".", Typestr, "\t$fcc, $fs, $ft"),
- [(set FCCRegsOpnd:$fcc, (null_frag RC:$fs, RC:$ft))], itin,
- FrmFR>, HARDFLOAT {
- let BaseOpcode = !strconcat("c.", CondStr, ".", Typestr);
+class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin,
+ SDPatternOperator OpNode = null_frag> :
+ InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond),
+ !strconcat("c.$cond.", typestr, "\t$fs, $ft"),
+ [(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR,
+ !strconcat("c.$cond.", typestr)>, HARDFLOAT {
+ let Defs = [FCC0];
+ let isCodeGenOnly = 1;
}
+class C_COND_FT<string CondStr, string Typestr, RegisterOperand RC,
+ InstrItinClass itin> :
+ InstSE<(outs), (ins RC:$fs, RC:$ft),
+ !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], itin,
+ FrmFR>, HARDFLOAT;
+
multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt,
InstrItinClass itin> {
def C_F_#NAME : C_COND_FT<"f", TypeStr, RC, itin>, C_COND_FM<fmt, 0>;
@@ -240,11 +258,11 @@ multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt,
}
defm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>, ISA_MIPS1_NOT_32R6_64R6;
-defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>,
- ISA_MIPS1_NOT_32R6_64R6, FGR_32;
+defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
+ FGR_32;
let DecoderNamespace = "Mips64" in
-defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>,
- ISA_MIPS1_NOT_32R6_64R6, FGR_64;
+defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
+ FGR_64;
//===----------------------------------------------------------------------===//
// Floating Point Instructions
@@ -518,60 +536,16 @@ def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, II_BC1T, MIPS_BRANCH_T>,
def BC1TL : MMRel, BC1F_FT<"bc1tl", brtarget, II_BC1TL, MIPS_BRANCH_T, 0>,
BC1F_FM<1, 1>, ISA_MIPS2_NOT_32R6_64R6;
-// Compare and branch patterns
-multiclass FPBrcondPats<RegisterOperand RC> {
- // Ordered
- def : MipsPat<(brcond (i32 (setoeq RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setogt RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setoge RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_LT_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setolt RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_LT_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setole RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setone RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (seto RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_UN_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- // Unordered
- def : MipsPat<(brcond (i32 (setuo RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_UN_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setueq RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setugt RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setult RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setune RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setuo RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- // Unspecified ordering - treated as ordered.
- def : MipsPat<(brcond (i32 (seteq RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setgt RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_LT_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setlt RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_LT_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1T (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
- def : MipsPat<(brcond (i32 (setne RC:$lhs, RC:$rhs)), bb:$dst),
- (BC1F (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs), bb:$dst)>;
-}
-
+/// Floating Point Compare
let AdditionalPredicates = [NotInMicroMips] in {
- defm S : FPBrcondPats<FGR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
- defm D32 : FPBrcondPats<AFGR64Opnd>, FGR_32, ISA_MIPS1_NOT_32R6_64R6;
- defm D64 : FPBrcondPats<FGR64Opnd>, FGR_64, ISA_MIPS1_NOT_32R6_64R6;
+ def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>,
+ ISA_MIPS1_NOT_32R6_64R6;
+ def FCMP_D32 : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>,
+ ISA_MIPS1_NOT_32R6_64R6, FGR_32;
}
+let DecoderNamespace = "Mips64" in
+def FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>,
+ ISA_MIPS1_NOT_32R6_64R6, FGR_64;
//===----------------------------------------------------------------------===//
// Floating Point Pseudo-Instructions
@@ -615,78 +589,6 @@ def PseudoTRUNC_W_D : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
"trunc.w.d\t$fd, $fs, $rs">,
FGR_64, HARDFLOAT;
-// Pseudo instructions to read $fcc0 - $fcc7
-def PseudoReadFCC :
- PseudoSE<(outs GPR32Opnd:$rd), (ins invertbit:$invert, FCC:$fcc),
- [], II_CFC1>;
-
-multiclass Mips3ReadFCC<RegisterOperand RC> {
- def : MipsPat<(seteq RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setgt RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setge RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setlt RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setle RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setne RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setoeq RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setogt RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setoge RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setolt RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setole RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setone RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(seto RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_UN_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setuo RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_UN_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setueq RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_UEQ_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setugt RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_OLE_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setuge RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_OLT_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setult RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_ULT_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setule RC:$lhs, RC:$rhs),
- (PseudoReadFCC 0,
- (!cast<Instruction>("C_ULE_"#NAME) RC:$lhs, RC:$rhs))>;
- def : MipsPat<(setune RC:$lhs, RC:$rhs),
- (PseudoReadFCC 1,
- (!cast<Instruction>("C_EQ_"#NAME) RC:$lhs, RC:$rhs))>;
-}
-
-defm S : Mips3ReadFCC<FGR32Opnd>, ISA_MIPS1_NOT_4_32;
-defm D32 : Mips3ReadFCC<AFGR64Opnd>, FGR_32, ISA_MIPS1_NOT_4_32;
-defm D64 : Mips3ReadFCC<FGR64Opnd>, FGR_64, ISA_MIPS1_NOT_4_32;
-
//===----------------------------------------------------------------------===//
// InstAliases.
//===----------------------------------------------------------------------===//
@@ -718,48 +620,6 @@ def : MipsInstAlias
def : MipsInstAlias
<"l.d $fd, $addr", (LDC164 FGR64Opnd:$fd, mem_simm16:$addr), 0>,
FGR_64, ISA_MIPS2, HARDFLOAT;
-
-multiclass FPCAliases<RegisterOperand RC, string TypeString> {
- def : MipsInstAlias<!strconcat("c.f.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_F_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.un.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_UN_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.eq.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_EQ_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ueq.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_UEQ_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.olt.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_OLT_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ult.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_ULT_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ole.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_OLE_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ule.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_ULE_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.sf.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_SF_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ngle.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_NGLE_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.seq.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_SEQ_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ngl.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_NGL_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.lt.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_LT_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.nge.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_NGE_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.le.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_LE_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
- def : MipsInstAlias<!strconcat("c.ngt.", TypeString, " $rs, $rt"),
- (!cast<Instruction>("C_NGT_"#NAME) FCC0, RC:$rs, RC:$rt), 1>;
-}
-
-let AdditionalPredicates = [NotInMicroMips] in {
- defm S : FPCAliases<FGR32Opnd, "s">, HARDFLOAT, ISA_MIPS1_NOT_32R6_64R6;
- defm D32 : FPCAliases<AFGR64Opnd, "d">, HARDFLOAT, ISA_MIPS1_NOT_32R6_64R6;
- defm D64 : FPCAliases<FGR64Opnd, "d">, HARDFLOAT, ISA_MIPS1_NOT_32R6_64R6;
-}
-
//===----------------------------------------------------------------------===//
// Floating Point Patterns
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/MipsInstrFormats.td b/llvm/lib/Target/Mips/MipsInstrFormats.td
index ded3e32..1437fb7 100644
--- a/llvm/lib/Target/Mips/MipsInstrFormats.td
+++ b/llvm/lib/Target/Mips/MipsInstrFormats.td
@@ -829,7 +829,6 @@ class BC1F_FM<bit nd, bit tf> : StdArch {
class CEQS_FM<bits<5> fmt> : StdArch {
bits<5> fs;
bits<5> ft;
- bits<3> fcc;
bits<4> cond;
bits<32> Inst;
@@ -838,7 +837,7 @@ class CEQS_FM<bits<5> fmt> : StdArch {
let Inst{25-21} = fmt;
let Inst{20-16} = ft;
let Inst{15-11} = fs;
- let Inst{10-8} = fcc;
+ let Inst{10-8} = 0; // cc
let Inst{7-4} = 0x3;
let Inst{3-0} = cond;
}
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td
index b0c961d..cfce7c8 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.td
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td
@@ -393,7 +393,8 @@ def CCR : RegisterClass<"Mips", [i32], 32, (sequence "FCR%u", 0, 31)>,
Unallocatable;
// FP condition code registers.
-def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>;
+def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>,
+ Unallocatable;
// MIPS32r6/MIPS64r6 store FPU condition codes in normal FGR registers.
// This class allows us to represent this in codegen patterns.
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index 0637887..ea703d0 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -377,9 +377,6 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
case Mips::PseudoCVT_D64_W:
expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true);
break;
- case Mips::PseudoReadFCC:
- expandReadFCC(MBB, MI);
- break;
case Mips::PseudoCVT_D64_L:
expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
break;
@@ -627,37 +624,6 @@ void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,
BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill);
}
-void MipsSEInstrInfo::expandReadFCC(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const {
- assert(I->getOperand(1).isImm() && "Malformed PseudoReadFCC Node");
-
- bool Invert = (I->getOperand(1).getImm()) == 1;
- const MachineOperand &Dest = I->getOperand(0), &Src = I->getOperand(2);
- unsigned DstReg = Dest.getReg(), SrcReg = Src.getReg();
-
- DebugLoc DL = I->getDebugLoc();
- BuildMI(MBB, I, DL, get(Mips::CFC1), DstReg).addReg(Mips::FCR31);
- unsigned Shift = 0;
- switch (SrcReg) {
- case Mips::FCC0: Shift = 23; break;
- case Mips::FCC1: Shift = 25; break;
- case Mips::FCC2: Shift = 26; break;
- case Mips::FCC3: Shift = 27; break;
- case Mips::FCC4: Shift = 28; break;
- case Mips::FCC5: Shift = 29; break;
- case Mips::FCC6: Shift = 30; break;
- case Mips::FCC7: Shift = 31; break;
- default:
- llvm_unreachable("Unknown $fcc register for expandReadFCC!");
- }
- BuildMI(MBB, I, DL, get(Mips::SRL), DstReg).addReg(DstReg).addImm(Shift);
-
- if (Invert)
- BuildMI(MBB, I, DL, get(Mips::NOR), DstReg).addReg(DstReg).addReg(DstReg);
-
- BuildMI(MBB, I, DL, get(Mips::ANDi), DstReg).addReg(DstReg).addImm(1);
-}
-
void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
bool FP64) const {
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.h b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
index 2e0bc09..b356909 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.h
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
@@ -106,15 +106,6 @@ private:
void expandCvtFPInt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned CvtOpc, unsigned MovOpc, bool IsI64) const;
- /// Expand pseudo ReadFCC(I) instructions like so:
- ///
- /// cfc1 $dst, $fcr25
- /// srl $dst, $dst, (register number if not $fcc0)
- /// nor $dst, $dst, $dst (if inverted)
- /// andi $dst, $dst, 1
- ///
- void expandReadFCC(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const;
void expandExtractElementF64(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, bool FP64) const;
void expandBuildPairF64(MachineBasicBlock &MBB,