summaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsInstrFPU.td
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsInstrFPU.td')
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td119
1 files changed, 84 insertions, 35 deletions
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index 0333fe6520fab..c817391153732 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -39,6 +39,9 @@ def SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
SDTCisVT<1, f64>,
SDTCisVT<2, i32>]>;
+def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
+ SDTCisVT<1, 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]>;
@@ -49,6 +52,8 @@ def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>;
+def MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
+
// Operand for printing out a condition code.
let PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in
def condcode : Operand<i32>;
@@ -114,7 +119,7 @@ multiclass ADDS_M<string opstr, InstrItinClass Itin, bit IsComm,
SDPatternOperator OpNode = null_frag> {
def _D32 : MMRel, ADDS_FT<opstr, AFGR64Opnd, Itin, IsComm, OpNode>, FGR_32;
def _D64 : ADDS_FT<opstr, FGR64Opnd, Itin, IsComm, OpNode>, FGR_64 {
- string DecoderNamespace = "Mips64";
+ string DecoderNamespace = "MipsFP64";
}
}
@@ -130,14 +135,14 @@ multiclass ABSS_M<string opstr, InstrItinClass Itin,
def _D32 : MMRel, ABSS_FT<opstr, AFGR64Opnd, AFGR64Opnd, Itin, OpNode>,
FGR_32;
def _D64 : ABSS_FT<opstr, FGR64Opnd, FGR64Opnd, Itin, OpNode>, FGR_64 {
- string DecoderNamespace = "Mips64";
+ string DecoderNamespace = "MipsFP64";
}
}
multiclass ROUND_M<string opstr, InstrItinClass Itin> {
def _D32 : MMRel, ABSS_FT<opstr, FGR32Opnd, AFGR64Opnd, Itin>, FGR_32;
def _D64 : StdMMR6Rel, ABSS_FT<opstr, FGR32Opnd, FGR64Opnd, Itin>, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
}
@@ -210,14 +215,25 @@ class SWXC1_FT<string opstr, RegisterOperand DRC,
}
class BC1F_FT<string opstr, DAGOperand opnd, InstrItinClass Itin,
- SDPatternOperator Op = null_frag, bit DelaySlot = 1> :
+ SDPatternOperator Op = null_frag> :
InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
!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 hasDelaySlot = 1;
+ let Defs = [AT];
+ let hasFCCRegOperand = 1;
+}
+
+class BC1XL_FT<string opstr, DAGOperand opnd, InstrItinClass Itin> :
+ InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
+ !strconcat(opstr, "\t$fcc, $offset"), [], Itin,
+ FrmFI, opstr>, HARDFLOAT {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let hasDelaySlot = 1;
let Defs = [AT];
let hasFCCRegOperand = 1;
}
@@ -326,7 +342,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
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;
-let DecoderNamespace = "Mips64" in
+let DecoderNamespace = "MipsFP64" in
defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
FGR_64;
}
@@ -353,14 +369,26 @@ defm CVT_W : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>;
let AdditionalPredicates = [NotInMicroMips] in {
def RECIP_S : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd, II_RECIP_S>,
ABSS_FM<0b010101, 0x10>, INSN_MIPS4_32R2;
- def RECIP_D : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd, II_RECIP_D>,
- ABSS_FM<0b010101, 0x11>, INSN_MIPS4_32R2;
+ def RECIP_D32 : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd, II_RECIP_D>,
+ ABSS_FM<0b010101, 0x11>, INSN_MIPS4_32R2, FGR_32 {
+ let BaseOpcode = "RECIP_D32";
+ }
+ let DecoderNamespace = "MipsFP64" in
+ def RECIP_D64 : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd,
+ II_RECIP_D>, ABSS_FM<0b010101, 0x11>,
+ INSN_MIPS4_32R2, FGR_64;
def RSQRT_S : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd, II_RSQRT_S>,
ABSS_FM<0b010110, 0x10>, INSN_MIPS4_32R2;
- def RSQRT_D : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd, II_RSQRT_D>,
- ABSS_FM<0b010110, 0x11>, INSN_MIPS4_32R2;
+ def RSQRT_D32 : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd, II_RSQRT_D>,
+ ABSS_FM<0b010110, 0x11>, INSN_MIPS4_32R2, FGR_32 {
+ let BaseOpcode = "RSQRT_D32";
+ }
+ let DecoderNamespace = "MipsFP64" in
+ def RSQRT_D64 : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd,
+ II_RSQRT_D>, ABSS_FM<0b010110, 0x11>,
+ INSN_MIPS4_32R2, FGR_64;
}
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
let AdditionalPredicates = [NotInMicroMips] in {
def ROUND_L_S : ABSS_FT<"round.l.s", FGR64Opnd, FGR32Opnd, II_ROUND>,
ABSS_FM<0x8, 16>, FGR_64;
@@ -397,7 +425,7 @@ def CVT_D32_W : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>,
def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>,
ABSS_FM<0x21, 16>, FGR_32;
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>,
ABSS_FM<0x20, 17>, FGR_64;
let AdditionalPredicates = [NotInMicroMips] in{
@@ -420,11 +448,14 @@ let isPseudo = 1, isCodeGenOnly = 1 in {
def PseudoCVT_D64_L : ABSS_FT<"", FGR64Opnd, GPR64Opnd, II_CVT>;
}
-def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
- ABSS_FM<0x5, 16>;
+let AdditionalPredicates = [NotInMicroMips] in {
+ def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
+ ABSS_FM<0x5, 16>;
+ defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>;
+}
+
def FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>,
ABSS_FM<0x7, 16>;
-defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>;
defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>;
def FSQRT_S : MMRel, StdMMR6Rel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd,
@@ -445,13 +476,13 @@ def MFC1 : MMRel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, II_MFC1,
bitconvert>, MFC1_FM<0>;
def MFC1_D64 : MFC1_FT<"mfc1", GPR32Opnd, FGR64Opnd, II_MFC1>, MFC1_FM<0>,
FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
def MTC1 : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, II_MTC1,
bitconvert>, MFC1_FM<4>;
def MTC1_D64 : MTC1_FT<"mtc1", FGR64Opnd, GPR32Opnd, II_MTC1>, MFC1_FM<4>,
FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
let AdditionalPredicates = [NotInMicroMips] in {
@@ -459,7 +490,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
MFC1_FM<3>, ISA_MIPS32R2, FGR_32;
def MFHC1_D64 : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>,
MFC1_FM<3>, ISA_MIPS32R2, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
}
let AdditionalPredicates = [NotInMicroMips] in {
@@ -467,7 +498,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
MFC1_FM<7>, ISA_MIPS32R2, FGR_32;
def MTHC1_D64 : MTC1_64_FT<"mthc1", FGR64Opnd, GPR32Opnd, II_MTHC1>,
MFC1_FM<7>, ISA_MIPS32R2, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
}
let AdditionalPredicates = [NotInMicroMips] in {
@@ -483,7 +514,7 @@ def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>,
ABSS_FM<0x6, 17>, FGR_32;
def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>,
ABSS_FM<0x6, 17>, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
/// Floating Point Memory Instructions
@@ -494,7 +525,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
LW_FM<0x39>;
}
-let DecoderNamespace = "Mips64", AdditionalPredicates = [NotInMicroMips] in {
+let DecoderNamespace = "MipsFP64", AdditionalPredicates = [NotInMicroMips] in {
def LDC164 : StdMMR6Rel, LW_FT<"ldc1", FGR64Opnd, mem_simm16, II_LDC1, load>,
LW_FM<0x35>, ISA_MIPS2, FGR_64 {
let BaseOpcode = "LDC164";
@@ -529,7 +560,7 @@ let AdditionalPredicates = [NotInMicroMips, IsNotNaCl] in {
INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
}
-let DecoderNamespace="Mips64" in {
+let DecoderNamespace="MipsFP64" in {
def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, II_LDXC1, load>, LWXC1_FM<1>,
INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, II_SDXC1, store>, SWXC1_FM<9>,
@@ -537,6 +568,7 @@ let DecoderNamespace="Mips64" in {
}
// Load/store doubleword indexed unaligned.
+// FIXME: This instruction should not be defined for FGR_32.
let AdditionalPredicates = [IsNotNaCl] in {
def LUXC1 : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>,
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32;
@@ -544,7 +576,7 @@ let AdditionalPredicates = [IsNotNaCl] in {
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32;
}
-let DecoderNamespace="Mips64" in {
+let DecoderNamespace="MipsFP64" in {
def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>,
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_64;
def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, II_SUXC1>, SWXC1_FM<0xd>,
@@ -589,7 +621,7 @@ let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in {
MADDS_FM<7, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
}
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
def MADD_D64 : MADDS_FT<"madd.d", FGR64Opnd, II_MADD_D, fadd>,
MADDS_FM<4, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64, MADD4;
def MSUB_D64 : MADDS_FT<"msub.d", FGR64Opnd, II_MSUB_D, fsub>,
@@ -597,7 +629,7 @@ let DecoderNamespace = "Mips64" in {
}
let AdditionalPredicates = [NoNaNsFPMath, HasMadd4],
- DecoderNamespace = "Mips64" in {
+ DecoderNamespace = "MipsFP64" in {
def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64Opnd, II_NMADD_D, fadd>,
MADDS_FM<6, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64Opnd, II_NMSUB_D, fsub>,
@@ -612,17 +644,17 @@ let AdditionalPredicates = [NoNaNsFPMath, HasMadd4],
def MIPS_BRANCH_F : PatLeaf<(i32 0)>;
def MIPS_BRANCH_T : PatLeaf<(i32 1)>;
-def BC1F : MMRel, BC1F_FT<"bc1f", brtarget, II_BC1F, MIPS_BRANCH_F>,
- BC1F_FM<0, 0>, ISA_MIPS1_NOT_32R6_64R6;
-def BC1FL : MMRel, BC1F_FT<"bc1fl", brtarget, II_BC1FL, MIPS_BRANCH_F, 0>,
- BC1F_FM<1, 0>, ISA_MIPS2_NOT_32R6_64R6;
-def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, II_BC1T, MIPS_BRANCH_T>,
- BC1F_FM<0, 1>, ISA_MIPS1_NOT_32R6_64R6;
-def BC1TL : MMRel, BC1F_FT<"bc1tl", brtarget, II_BC1TL, MIPS_BRANCH_T, 0>,
- BC1F_FM<1, 1>, ISA_MIPS2_NOT_32R6_64R6;
+let AdditionalPredicates = [NotInMicroMips] in {
+ def BC1F : MMRel, BC1F_FT<"bc1f", brtarget, II_BC1F, MIPS_BRANCH_F>,
+ BC1F_FM<0, 0>, ISA_MIPS1_NOT_32R6_64R6;
+ def BC1FL : MMRel, BC1XL_FT<"bc1fl", brtarget, II_BC1FL>,
+ BC1F_FM<1, 0>, ISA_MIPS2_NOT_32R6_64R6;
+ def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, II_BC1T, MIPS_BRANCH_T>,
+ BC1F_FM<0, 1>, ISA_MIPS1_NOT_32R6_64R6;
+ def BC1TL : MMRel, BC1XL_FT<"bc1tl", brtarget, II_BC1TL>,
+ BC1F_FM<1, 1>, ISA_MIPS2_NOT_32R6_64R6;
/// Floating Point Compare
-let AdditionalPredicates = [NotInMicroMips] in {
def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>,
ISA_MIPS1_NOT_32R6_64R6 {
@@ -639,7 +671,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
bits<3> fcc = 0;
}
}
-let DecoderNamespace = "Mips64" in
+let DecoderNamespace = "MipsFP64" in
def FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>,
ISA_MIPS1_NOT_32R6_64R6, FGR_64 {
// FIXME: This is a required to work around the fact that thiese instructions
@@ -820,6 +852,9 @@ def : MipsPat<(f32 (sint_to_fp GPR32Opnd:$src)),
def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
(TRUNC_W_S FGR32Opnd:$src)>;
+def : MipsPat<(MipsMTC1_D64 GPR32Opnd:$src),
+ (MTC1_D64 GPR32Opnd:$src)>, FGR_64;
+
def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
(PseudoCVT_D32_W GPR32Opnd:$src)>, FGR_32;
def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src),
@@ -851,6 +886,20 @@ def : MipsPat<(f32 (fpround FGR64Opnd:$src)),
def : MipsPat<(f64 (fpextend FGR32Opnd:$src)),
(CVT_D64_S FGR32Opnd:$src)>, FGR_64;
+// To generate NMADD and NMSUB instructions when fneg node is present
+multiclass NMADD_NMSUB<Instruction Nmadd, Instruction Nmsub, RegisterOperand RC> {
+ def : MipsPat<(fneg (fadd (fmul RC:$fs, RC:$ft), RC:$fr)),
+ (Nmadd RC:$fr, RC:$fs, RC:$ft)>;
+ def : MipsPat<(fneg (fsub (fmul RC:$fs, RC:$ft), RC:$fr)),
+ (Nmsub RC:$fr, RC:$fs, RC:$ft)>;
+}
+
+let AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips] in {
+ defm : NMADD_NMSUB<NMADD_S, NMSUB_S, FGR32Opnd>, INSN_MIPS4_32R2_NOT_32R6_64R6;
+ defm : NMADD_NMSUB<NMADD_D32, NMSUB_D32, AFGR64Opnd>, FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6;
+ defm : NMADD_NMSUB<NMADD_D64, NMSUB_D64, FGR64Opnd>, FGR_64, INSN_MIPS4_32R2_NOT_32R6_64R6;
+}
+
// Patterns for loads/stores with a reg+imm operand.
let AdditionalPredicates = [NotInMicroMips] in {
let AddedComplexity = 40 in {