diff options
Diffstat (limited to 'lib/Target/Mips/MipsInstrFPU.td')
| -rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 119 |
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 { |
