X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrFPU.td;h=6b23057c9cdb0910425ebfef3541764bfd690367;hb=cd6c57917db22a3913a2cdbadfa79fed3547bdec;hp=df45df46ac3c314fb85e5794f0d9846bdd062f9c;hpb=72e9b6aeb48d9496bac9db8b02c88a618b464588;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index df45df46ac3..6b23057c9cd 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -86,271 +86,320 @@ def fpimm0neg : PatLeaf<(fpimm), [{ // Only S32 and D32 are supported right now. //===----------------------------------------------------------------------===// -// FP load. -let DecoderMethod = "DecodeFMem" in { -class FPLoad op, string opstr, RegisterClass RC, Operand MemOpnd>: - FMem; - -// FP store. -class FPStore op, string opstr, RegisterClass RC, Operand MemOpnd>: - FMem; -} -// FP indexed load. -class FPIdxLoad funct, string opstr, RegisterClass DRC, - RegisterClass PRC, SDPatternOperator FOp = null_frag>: - FFMemIdx { - let fs = 0; -} - -// FP indexed store. -class FPIdxStore funct, string opstr, RegisterClass DRC, - RegisterClass PRC, SDPatternOperator FOp= null_frag>: - FFMemIdx { - let fd = 0; -} - -// Instructions that convert an FP value to 32-bit fixed point. -multiclass FFR1_W_M funct, string opstr> { - def _S : FFR1; - def _D32 : FFR1, - Requires<[NotFP64bit, HasStandardEncoding]>; - def _D64 : FFR1, - Requires<[IsFP64bit, HasStandardEncoding]> { - let DecoderNamespace = "Mips64"; +class ADDS_FT : + InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft), + !strconcat(opstr, "\t$fd, $fs, $ft"), + [(set RC:$fd, (OpNode RC:$fs, RC:$ft))], Itin, FrmFR> { + let isCommutable = IsComm; +} + +multiclass ADDS_M { + def _D32 : ADDS_FT, + Requires<[NotFP64bit, HasStdEnc]>; + def _D64 : ADDS_FT, + Requires<[IsFP64bit, HasStdEnc]> { + string DecoderNamespace = "Mips64"; } } -// Instructions that convert an FP value to 64-bit fixed point. -let Predicates = [IsFP64bit, HasStandardEncoding], DecoderNamespace = "Mips64" in -multiclass FFR1_L_M funct, string opstr> { - def _S : FFR1; - def _D64 : FFR1; -} +class ABSS_FT : + InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"), + [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR>, + NeverHasSideEffects; -// FP-to-FP conversion instructions. -multiclass FFR1P_M funct, string opstr, SDNode OpNode> { - def _S : FFR1P; - def _D32 : FFR1P, - Requires<[NotFP64bit, HasStandardEncoding]>; - def _D64 : FFR1P, - Requires<[IsFP64bit, HasStandardEncoding]> { - let DecoderNamespace = "Mips64"; +multiclass ABSS_M { + def _D32 : ABSS_FT, + Requires<[NotFP64bit, HasStdEnc]>; + def _D64 : ABSS_FT, + Requires<[IsFP64bit, HasStdEnc]> { + string DecoderNamespace = "Mips64"; } } -multiclass FFR2P_M funct, string opstr, SDNode OpNode, bit isComm = 0> { - let isCommutable = isComm in { - def _S : FFR2P; - def _D32 : FFR2P, - Requires<[NotFP64bit, HasStandardEncoding]>; - def _D64 : FFR2P, - Requires<[IsFP64bit, HasStandardEncoding]> { +multiclass ROUND_M { + def _D32 : ABSS_FT, + Requires<[NotFP64bit, HasStdEnc]>; + def _D64 : ABSS_FT, + Requires<[IsFP64bit, HasStdEnc]> { let DecoderNamespace = "Mips64"; } } -} - -// FP madd/msub/nmadd/nmsub instruction classes. -class FMADDSUB funct, bits<3> fmt, string opstr, string fmtstr, - SDNode OpNode, RegisterClass RC> : - FFMADDSUB; -class FNMADDSUB funct, bits<3> fmt, string opstr, string fmtstr, - SDNode OpNode, RegisterClass RC> : - FFMADDSUB; +class MFC1_FT : + InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), + [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>; + +class MTC1_FT : + InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), + [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>; + +class MFC1_FT_CCR : + InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), + [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>; + +class MTC1_FT_CCR : + InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), + [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>; + +class LW_FT : + InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> { + let DecoderMethod = "DecodeFMem"; +} + +class SW_FT : + InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> { + let DecoderMethod = "DecodeFMem"; +} + +class MADDS_FT : + InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), + !strconcat(opstr, "\t$fd, $fr, $fs, $ft"), + [(set RC:$fd, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr))], Itin, FrmFR>; + +class NMADDS_FT : + InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), + !strconcat(opstr, "\t$fd, $fr, $fs, $ft"), + [(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))], + Itin, FrmFR>; + +class LWXC1_FT : + InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index), + !strconcat(opstr, "\t$fd, ${index}(${base})"), + [(set DRC:$fd, (OpNode (add PRC:$base, PRC:$index)))], Itin, FrmFI> { + let AddedComplexity = 20; +} + +class SWXC1_FT : + InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index), + !strconcat(opstr, "\t$fs, ${index}(${base})"), + [(OpNode DRC:$fs, (add PRC:$base, PRC:$index))], Itin, FrmFI> { + let AddedComplexity = 20; +} + +class BC1F_FT : + InstSE<(outs), (ins brtarget:$offset), !strconcat(opstr, "\t$offset"), + [(MipsFPBrcond Op, bb:$offset)], Itin, FrmFI> { + let isBranch = 1; + let isTerminator = 1; + let hasDelaySlot = 1; + let Defs = [AT]; + let Uses = [FCR31]; +} + +class CEQS_FT : + 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> { + let Defs = [FCR31]; +} //===----------------------------------------------------------------------===// // Floating Point Instructions //===----------------------------------------------------------------------===// -defm ROUND_W : FFR1_W_M<0xc, "round">; -defm ROUND_L : FFR1_L_M<0x8, "round">; -defm TRUNC_W : FFR1_W_M<0xd, "trunc">; -defm TRUNC_L : FFR1_L_M<0x9, "trunc">; -defm CEIL_W : FFR1_W_M<0xe, "ceil">; -defm CEIL_L : FFR1_L_M<0xa, "ceil">; -defm FLOOR_W : FFR1_W_M<0xf, "floor">; -defm FLOOR_L : FFR1_L_M<0xb, "floor">; -defm CVT_W : FFR1_W_M<0x24, "cvt">; -//defm CVT_L : FFR1_L_M<0x25, "cvt">; - -def CVT_S_W : FFR1<0x20, 20, "cvt", "s.w", FGR32, FGR32>; -def CVT_L_S : FFR1<0x25, 16, "cvt", "l.s", FGR64, FGR32>; -def CVT_L_D64: FFR1<0x25, 17, "cvt", "l.d", FGR64, FGR64>; - -let Predicates = [NotFP64bit, HasStandardEncoding] in { - def CVT_S_D32 : FFR1<0x20, 17, "cvt", "s.d", FGR32, AFGR64>; - def CVT_D32_W : FFR1<0x21, 20, "cvt", "d.w", AFGR64, FGR32>; - def CVT_D32_S : FFR1<0x21, 16, "cvt", "d.s", AFGR64, FGR32>; -} - -let Predicates = [IsFP64bit, HasStandardEncoding], DecoderNamespace = "Mips64" in { - def CVT_S_D64 : FFR1<0x20, 17, "cvt", "s.d", FGR32, FGR64>; - def CVT_S_L : FFR1<0x20, 21, "cvt", "s.l", FGR32, FGR64>; - def CVT_D64_W : FFR1<0x21, 20, "cvt", "d.w", FGR64, FGR32>; - def CVT_D64_S : FFR1<0x21, 16, "cvt", "d.s", FGR64, FGR32>; - def CVT_D64_L : FFR1<0x21, 21, "cvt", "d.l", FGR64, FGR64>; -} - -let Predicates = [NoNaNsFPMath, HasStandardEncoding] in { - defm FABS : FFR1P_M<0x5, "abs", fabs>; - defm FNEG : FFR1P_M<0x7, "neg", fneg>; -} -defm FSQRT : FFR1P_M<0x4, "sqrt", fsqrt>; +def ROUND_W_S : ABSS_FT<"round.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xc, 16>; +def TRUNC_W_S : ABSS_FT<"trunc.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xd, 16>; +def CEIL_W_S : ABSS_FT<"ceil.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xe, 16>; +def FLOOR_W_S : ABSS_FT<"floor.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xf, 16>; +def CVT_W_S : ABSS_FT<"cvt.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0x24, 16>; + +defm ROUND_W : ROUND_M<"round.w.d", IIFcvt>, ABSS_FM<0xc, 17>; +defm TRUNC_W : ROUND_M<"trunc.w.d", IIFcvt>, ABSS_FM<0xd, 17>; +defm CEIL_W : ROUND_M<"ceil.w.d", IIFcvt>, ABSS_FM<0xe, 17>; +defm FLOOR_W : ROUND_M<"floor.w.d", IIFcvt>, ABSS_FM<0xf, 17>; +defm CVT_W : ROUND_M<"cvt.w.d", IIFcvt>, ABSS_FM<0x24, 17>; + +let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { + def ROUND_L_S : ABSS_FT<"round.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x8, 16>; + def ROUND_L_D64 : ABSS_FT<"round.l.d", FGR64, FGR64, IIFcvt>, + ABSS_FM<0x8, 17>; + def TRUNC_L_S : ABSS_FT<"trunc.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x9, 16>; + def TRUNC_L_D64 : ABSS_FT<"trunc.l.d", FGR64, FGR64, IIFcvt>, + ABSS_FM<0x9, 17>; + def CEIL_L_S : ABSS_FT<"ceil.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0xa, 16>; + def CEIL_L_D64 : ABSS_FT<"ceil.l.d", FGR64, FGR64, IIFcvt>, ABSS_FM<0xa, 17>; + def FLOOR_L_S : ABSS_FT<"floor.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0xb, 16>; + def FLOOR_L_D64 : ABSS_FT<"floor.l.d", FGR64, FGR64, IIFcvt>, + ABSS_FM<0xb, 17>; +} + +def CVT_S_W : ABSS_FT<"cvt.s.w", FGR32, FGR32, IIFcvt>, ABSS_FM<0x20, 20>; +def CVT_L_S : ABSS_FT<"cvt.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x25, 16>; +def CVT_L_D64: ABSS_FT<"cvt.l.d", FGR64, FGR64, IIFcvt>, ABSS_FM<0x25, 17>; + +let Predicates = [NotFP64bit, HasStdEnc] in { + def CVT_S_D32 : ABSS_FT<"cvt.s.d", FGR32, AFGR64, IIFcvt>, ABSS_FM<0x20, 17>; + def CVT_D32_W : ABSS_FT<"cvt.d.w", AFGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>; + def CVT_D32_S : ABSS_FT<"cvt.d.s", AFGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>; +} + +let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { + def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 17>; + def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 21>; + def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>; + def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>; + def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64, FGR64, IIFcvt>, ABSS_FM<0x21, 21>; +} + +let Predicates = [NoNaNsFPMath, HasStdEnc] in { + def FABS_S : ABSS_FT<"abs.s", FGR32, FGR32, IIFcvt, fabs>, ABSS_FM<0x5, 16>; + def FNEG_S : ABSS_FT<"neg.s", FGR32, FGR32, IIFcvt, fneg>, ABSS_FM<0x7, 16>; + defm FABS : ABSS_M<"abs.d", IIFcvt, fabs>, ABSS_FM<0x5, 17>; + defm FNEG : ABSS_M<"neg.d", IIFcvt, fneg>, ABSS_FM<0x7, 17>; +} + +def FSQRT_S : ABSS_FT<"sqrt.s", FGR32, FGR32, IIFsqrtSingle, fsqrt>, + ABSS_FM<0x4, 16>; +defm FSQRT : ABSS_M<"sqrt.d", IIFsqrtDouble, fsqrt>, ABSS_FM<0x4, 17>; // The odd-numbered registers are only referenced when doing loads, // stores, and moves between floating-point and integer registers. // When defining instructions, we reference all 32-bit registers, // regardless of register aliasing. -class FFRGPR _fmt, dag outs, dag ins, string asmstr, list pattern>: - FFR<0x11, 0x0, _fmt, outs, ins, asmstr, pattern> { - bits<5> rt; - let ft = rt; - let fd = 0; -} - /// Move Control Registers From/To CPU Registers -def CFC1 : FFRGPR<0x2, (outs CPURegs:$rt), (ins CCR:$fs), - "cfc1\t$rt, $fs", []>; - -def CTC1 : FFRGPR<0x6, (outs CCR:$fs), (ins CPURegs:$rt), - "ctc1\t$rt, $fs", []>; - -def MFC1 : FFRGPR<0x00, (outs CPURegs:$rt), (ins FGR32:$fs), - "mfc1\t$rt, $fs", - [(set CPURegs:$rt, (bitconvert FGR32:$fs))]>; - -def MTC1 : FFRGPR<0x04, (outs FGR32:$fs), (ins CPURegs:$rt), - "mtc1\t$rt, $fs", - [(set FGR32:$fs, (bitconvert CPURegs:$rt))]>; - -def DMFC1 : FFRGPR<0x01, (outs CPU64Regs:$rt), (ins FGR64:$fs), - "dmfc1\t$rt, $fs", - [(set CPU64Regs:$rt, (bitconvert FGR64:$fs))]>; - -def DMTC1 : FFRGPR<0x05, (outs FGR64:$fs), (ins CPU64Regs:$rt), - "dmtc1\t$rt, $fs", - [(set FGR64:$fs, (bitconvert CPU64Regs:$rt))]>; - -def FMOV_S : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>; -def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>, - Requires<[NotFP64bit, HasStandardEncoding]>; -def FMOV_D64 : FFR1<0x6, 17, "mov", "d", FGR64, FGR64>, - Requires<[IsFP64bit, HasStandardEncoding]> { +def CFC1 : MFC1_FT_CCR<"cfc1", CPURegs, CCROpnd, IIFmove>, MFC1_FM<2>; +def CTC1 : MTC1_FT_CCR<"ctc1", CCROpnd, CPURegs, IIFmove>, MFC1_FM<6>; +def MFC1 : MFC1_FT<"mfc1", CPURegs, FGR32, IIFmove, bitconvert>, MFC1_FM<0>; +def MTC1 : MTC1_FT<"mtc1", FGR32, CPURegs, IIFmove, bitconvert>, MFC1_FM<4>; +def DMFC1 : MFC1_FT<"dmfc1", CPU64Regs, FGR64, IIFmove, bitconvert>, MFC1_FM<1>; +def DMTC1 : MTC1_FT<"dmtc1", FGR64, CPU64Regs, IIFmove, bitconvert>, MFC1_FM<5>; + +def FMOV_S : ABSS_FT<"mov.s", FGR32, FGR32, IIFmove>, ABSS_FM<0x6, 16>; +def FMOV_D32 : ABSS_FT<"mov.d", AFGR64, AFGR64, IIFmove>, ABSS_FM<0x6, 17>, + Requires<[NotFP64bit, HasStdEnc]>; +def FMOV_D64 : ABSS_FT<"mov.d", FGR64, FGR64, IIFmove>, ABSS_FM<0x6, 17>, + Requires<[IsFP64bit, HasStdEnc]> { let DecoderNamespace = "Mips64"; } /// Floating Point Memory Instructions -let Predicates = [IsN64, HasStandardEncoding], DecoderNamespace = "Mips64" in { - def LWC1_P8 : FPLoad<0x31, "lwc1", FGR32, mem64>; - def SWC1_P8 : FPStore<0x39, "swc1", FGR32, mem64>; - def LDC164_P8 : FPLoad<0x35, "ldc1", FGR64, mem64> { +let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in { + def LWC1_P8 : LW_FT<"lwc1", FGR32, IILoad, mem64, load>, LW_FM<0x31>; + def SWC1_P8 : SW_FT<"swc1", FGR32, IIStore, mem64, store>, LW_FM<0x39>; + def LDC164_P8 : LW_FT<"ldc1", FGR64, IILoad, mem64, load>, LW_FM<0x35> { let isCodeGenOnly =1; } - def SDC164_P8 : FPStore<0x3d, "sdc1", FGR64, mem64> { + def SDC164_P8 : SW_FT<"sdc1", FGR64, IIStore, mem64, store>, LW_FM<0x3d> { let isCodeGenOnly =1; } } -let Predicates = [NotN64, HasStandardEncoding] in { - def LWC1 : FPLoad<0x31, "lwc1", FGR32, mem>; - def SWC1 : FPStore<0x39, "swc1", FGR32, mem>; +let Predicates = [NotN64, HasStdEnc] in { + def LWC1 : LW_FT<"lwc1", FGR32, IILoad, mem, load>, LW_FM<0x31>; + def SWC1 : SW_FT<"swc1", FGR32, IIStore, mem, store>, LW_FM<0x39>; } -let Predicates = [NotN64, HasMips64, HasStandardEncoding], +let Predicates = [NotN64, HasMips64, HasStdEnc], DecoderNamespace = "Mips64" in { - def LDC164 : FPLoad<0x35, "ldc1", FGR64, mem>; - def SDC164 : FPStore<0x3d, "sdc1", FGR64, mem>; + def LDC164 : LW_FT<"ldc1", FGR64, IILoad, mem, load>, LW_FM<0x35>; + def SDC164 : SW_FT<"sdc1", FGR64, IIStore, mem, store>, LW_FM<0x3d>; } -let Predicates = [NotN64, NotMips64, HasStandardEncoding] in { - def LDC1 : FPLoad<0x35, "ldc1", AFGR64, mem>; - def SDC1 : FPStore<0x3d, "sdc1", AFGR64, mem>; +let Predicates = [NotN64, NotMips64, HasStdEnc] in { + def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem, load>, LW_FM<0x35>; + def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem, store>, LW_FM<0x3d>; } // Indexed loads and stores. -let Predicates = [HasMips32r2Or64, HasStandardEncoding] in { - def LWXC1 : FPIdxLoad<0x0, "lwxc1", FGR32, CPURegs, load_a>; - def SWXC1 : FPIdxStore<0x8, "swxc1", FGR32, CPURegs, store_a>; +let Predicates = [HasFPIdx, HasStdEnc] in { + def LWXC1 : LWXC1_FT<"lwxc1", FGR32, CPURegs, IILoad, load>, LWXC1_FM<0>; + def SWXC1 : SWXC1_FT<"swxc1", FGR32, CPURegs, IIStore, store>, SWXC1_FM<8>; } -let Predicates = [HasMips32r2, NotMips64, HasStandardEncoding] in { - def LDXC1 : FPIdxLoad<0x1, "ldxc1", AFGR64, CPURegs, load_a>; - def SDXC1 : FPIdxStore<0x9, "sdxc1", AFGR64, CPURegs, store_a>; +let Predicates = [HasMips32r2, NotMips64, HasStdEnc] in { + def LDXC1 : LWXC1_FT<"ldxc1", AFGR64, CPURegs, IILoad, load>, LWXC1_FM<1>; + def SDXC1 : SWXC1_FT<"sdxc1", AFGR64, CPURegs, IIStore, store>, SWXC1_FM<9>; } -let Predicates = [HasMips64, NotN64, HasStandardEncoding], DecoderNamespace="Mips64" in { - def LDXC164 : FPIdxLoad<0x1, "ldxc1", FGR64, CPURegs, load_a>; - def SDXC164 : FPIdxStore<0x9, "sdxc1", FGR64, CPURegs, store_a>; +let Predicates = [HasMips64, NotN64, HasStdEnc], DecoderNamespace="Mips64" in { + def LDXC164 : LWXC1_FT<"ldxc1", FGR64, CPURegs, IILoad, load>, LWXC1_FM<1>; + def SDXC164 : SWXC1_FT<"sdxc1", FGR64, CPURegs, IIStore, store>, SWXC1_FM<9>; } // n64 -let Predicates = [IsN64, HasStandardEncoding], isCodeGenOnly=1 in { - def LWXC1_P8 : FPIdxLoad<0x0, "lwxc1", FGR32, CPU64Regs, load_a>; - def LDXC164_P8 : FPIdxLoad<0x1, "ldxc1", FGR64, CPU64Regs, load_a>; - def SWXC1_P8 : FPIdxStore<0x8, "swxc1", FGR32, CPU64Regs, store_a>; - def SDXC164_P8 : FPIdxStore<0x9, "sdxc1", FGR64, CPU64Regs, store_a>; +let Predicates = [IsN64, HasStdEnc], isCodeGenOnly=1 in { + def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32, CPU64Regs, IILoad, load>, LWXC1_FM<0>; + def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64, CPU64Regs, IILoad, load>, + LWXC1_FM<1>; + def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32, CPU64Regs, IIStore, store>, + SWXC1_FM<8>; + def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64, CPU64Regs, IIStore, store>, + SWXC1_FM<9>; } // Load/store doubleword indexed unaligned. -let Predicates = [NotMips64, HasStandardEncoding] in { - def LUXC1 : FPIdxLoad<0x5, "luxc1", AFGR64, CPURegs>; - def SUXC1 : FPIdxStore<0xd, "suxc1", AFGR64, CPURegs>; +let Predicates = [NotMips64, HasStdEnc] in { + def LUXC1 : LWXC1_FT<"luxc1", AFGR64, CPURegs, IILoad>, LWXC1_FM<0x5>; + def SUXC1 : SWXC1_FT<"suxc1", AFGR64, CPURegs, IIStore>, SWXC1_FM<0xd>; } -let Predicates = [HasMips64, HasStandardEncoding], +let Predicates = [HasMips64, HasStdEnc], DecoderNamespace="Mips64" in { - def LUXC164 : FPIdxLoad<0x5, "luxc1", FGR64, CPURegs>; - def SUXC164 : FPIdxStore<0xd, "suxc1", FGR64, CPURegs>; + def LUXC164 : LWXC1_FT<"luxc1", FGR64, CPURegs, IILoad>, LWXC1_FM<0x5>; + def SUXC164 : SWXC1_FT<"suxc1", FGR64, CPURegs, IIStore>, SWXC1_FM<0xd>; } /// Floating-point Aritmetic -defm FADD : FFR2P_M<0x00, "add", fadd, 1>; -defm FDIV : FFR2P_M<0x03, "div", fdiv>; -defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>; -defm FSUB : FFR2P_M<0x01, "sub", fsub>; +def FADD_S : ADDS_FT<"add.s", FGR32, IIFadd, 1, fadd>, ADDS_FM<0x00, 16>; +defm FADD : ADDS_M<"add.d", IIFadd, 1, fadd>, ADDS_FM<0x00, 17>; +def FDIV_S : ADDS_FT<"div.s", FGR32, IIFdivSingle, 0, fdiv>, ADDS_FM<0x03, 16>; +defm FDIV : ADDS_M<"div.d", IIFdivDouble, 0, fdiv>, ADDS_FM<0x03, 17>; +def FMUL_S : ADDS_FT<"mul.s", FGR32, IIFmulSingle, 1, fmul>, ADDS_FM<0x02, 16>; +defm FMUL : ADDS_M<"mul.d", IIFmulDouble, 1, fmul>, ADDS_FM<0x02, 17>; +def FSUB_S : ADDS_FT<"sub.s", FGR32, IIFadd, 0, fsub>, ADDS_FM<0x01, 16>; +defm FSUB : ADDS_M<"sub.d", IIFadd, 0, fsub>, ADDS_FM<0x01, 17>; -let Predicates = [HasMips32r2, HasStandardEncoding] in { - def MADD_S : FMADDSUB<0x4, 0, "madd", "s", fadd, FGR32>; - def MSUB_S : FMADDSUB<0x5, 0, "msub", "s", fsub, FGR32>; +let Predicates = [HasMips32r2, HasStdEnc] in { + def MADD_S : MADDS_FT<"madd.s", FGR32, IIFmulSingle, fadd>, MADDS_FM<4, 0>; + def MSUB_S : MADDS_FT<"msub.s", FGR32, IIFmulSingle, fsub>, MADDS_FM<5, 0>; } -let Predicates = [HasMips32r2, NoNaNsFPMath, HasStandardEncoding] in { - def NMADD_S : FNMADDSUB<0x6, 0, "nmadd", "s", fadd, FGR32>; - def NMSUB_S : FNMADDSUB<0x7, 0, "nmsub", "s", fsub, FGR32>; +let Predicates = [HasMips32r2, NoNaNsFPMath, HasStdEnc] in { + def NMADD_S : NMADDS_FT<"nmadd.s", FGR32, IIFmulSingle, fadd>, MADDS_FM<6, 0>; + def NMSUB_S : NMADDS_FT<"nmsub.s", FGR32, IIFmulSingle, fsub>, MADDS_FM<7, 0>; } -let Predicates = [HasMips32r2, NotFP64bit, HasStandardEncoding] in { - def MADD_D32 : FMADDSUB<0x4, 1, "madd", "d", fadd, AFGR64>; - def MSUB_D32 : FMADDSUB<0x5, 1, "msub", "d", fsub, AFGR64>; +let Predicates = [HasMips32r2, NotFP64bit, HasStdEnc] in { + def MADD_D32 : MADDS_FT<"madd.d", AFGR64, IIFmulDouble, fadd>, MADDS_FM<4, 1>; + def MSUB_D32 : MADDS_FT<"msub.d", AFGR64, IIFmulDouble, fsub>, MADDS_FM<5, 1>; } -let Predicates = [HasMips32r2, NotFP64bit, NoNaNsFPMath, HasStandardEncoding] in { - def NMADD_D32 : FNMADDSUB<0x6, 1, "nmadd", "d", fadd, AFGR64>; - def NMSUB_D32 : FNMADDSUB<0x7, 1, "nmsub", "d", fsub, AFGR64>; +let Predicates = [HasMips32r2, NotFP64bit, NoNaNsFPMath, HasStdEnc] in { + def NMADD_D32 : NMADDS_FT<"nmadd.d", AFGR64, IIFmulDouble, fadd>, + MADDS_FM<6, 1>; + def NMSUB_D32 : NMADDS_FT<"nmsub.d", AFGR64, IIFmulDouble, fsub>, + MADDS_FM<7, 1>; } -let Predicates = [HasMips32r2, IsFP64bit, HasStandardEncoding], isCodeGenOnly=1 in { - def MADD_D64 : FMADDSUB<0x4, 1, "madd", "d", fadd, FGR64>; - def MSUB_D64 : FMADDSUB<0x5, 1, "msub", "d", fsub, FGR64>; +let Predicates = [HasMips32r2, IsFP64bit, HasStdEnc], isCodeGenOnly=1 in { + def MADD_D64 : MADDS_FT<"madd.d", FGR64, IIFmulDouble, fadd>, MADDS_FM<4, 1>; + def MSUB_D64 : MADDS_FT<"msub.d", FGR64, IIFmulDouble, fsub>, MADDS_FM<5, 1>; } -let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStandardEncoding], +let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStdEnc], isCodeGenOnly=1 in { - def NMADD_D64 : FNMADDSUB<0x6, 1, "nmadd", "d", fadd, FGR64>; - def NMSUB_D64 : FNMADDSUB<0x7, 1, "nmsub", "d", fsub, FGR64>; + def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64, IIFmulDouble, fadd>, + MADDS_FM<6, 1>; + def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64, IIFmulDouble, fsub>, + MADDS_FM<7, 1>; } //===----------------------------------------------------------------------===// @@ -361,19 +410,9 @@ let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStandardEncoding], def MIPS_BRANCH_F : PatLeaf<(i32 0)>; def MIPS_BRANCH_T : PatLeaf<(i32 1)>; -/// Floating Point Branch of False/True (Likely) -let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in - class FBRANCH nd, bits<1> tf, PatLeaf op, string asmstr> : - FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"), - [(MipsFPBrcond op, bb:$dst)]> { - let Inst{20-18} = 0; - let Inst{17} = nd; - let Inst{16} = tf; -} - let DecoderMethod = "DecodeBC1" in { -def BC1F : FBRANCH<0, 0, MIPS_BRANCH_F, "bc1f">; -def BC1T : FBRANCH<0, 1, MIPS_BRANCH_T, "bc1t">; +def BC1F : BC1F_FT<"bc1f", IIBranch, MIPS_BRANCH_F>, BC1F_FM<0, 0>; +def BC1T : BC1F_FT<"bc1t", IIBranch, MIPS_BRANCH_T>, BC1F_FM<0, 1>; } //===----------------------------------------------------------------------===// // Floating Point Flag Conditions @@ -397,33 +436,24 @@ def MIPS_FCOND_NGE : PatLeaf<(i32 13)>; def MIPS_FCOND_LE : PatLeaf<(i32 14)>; def MIPS_FCOND_NGT : PatLeaf<(i32 15)>; -class FCMP fmt, RegisterClass RC, string typestr> : - FCC; - /// Floating Point Compare -let Defs=[FCR31] in { - def FCMP_S32 : FCMP<0x10, FGR32, "s">; - def FCMP_D32 : FCMP<0x11, AFGR64, "d">, - Requires<[NotFP64bit, HasStandardEncoding]>; - def FCMP_D64 : FCMP<0x11, FGR64, "d">, - Requires<[IsFP64bit, HasStandardEncoding]> { - let DecoderNamespace = "Mips64"; - } -} +def FCMP_S32 : CEQS_FT<"s", FGR32, IIFcmp, MipsFPCmp>, CEQS_FM<16>; +def FCMP_D32 : CEQS_FT<"d", AFGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, + Requires<[NotFP64bit, HasStdEnc]>; +let DecoderNamespace = "Mips64" in +def FCMP_D64 : CEQS_FT<"d", FGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, + Requires<[IsFP64bit, HasStdEnc]>; //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions //===----------------------------------------------------------------------===// -def MOVCCRToCCR : PseudoSE<(outs CCR:$dst), (ins CCR:$src), - "# MOVCCRToCCR", []>; +def MOVCCRToCCR : PseudoSE<(outs CCR:$dst), (ins CCROpnd:$src), []>; // This pseudo instr gets expanded into 2 mtc1 instrs after register // allocation. def BuildPairF64 : PseudoSE<(outs AFGR64:$dst), - (ins CPURegs:$lo, CPURegs:$hi), "", + (ins CPURegs:$lo, CPURegs:$hi), [(set AFGR64:$dst, (MipsBuildPairF64 CPURegs:$lo, CPURegs:$hi))]>; // This pseudo instr gets expanded into 2 mfc1 instrs after register @@ -431,7 +461,7 @@ def BuildPairF64 : // if n is 0, lower part of src is extracted. // if n is 1, higher part of src is extracted. def ExtractElementF64 : - PseudoSE<(outs CPURegs:$dst), (ins AFGR64:$src, i32imm:$n), "", + PseudoSE<(outs CPURegs:$dst), (ins AFGR64:$src, i32imm:$n), [(set CPURegs:$dst, (MipsExtractElementF64 AFGR64:$src, imm:$n))]>; //===----------------------------------------------------------------------===// @@ -443,7 +473,7 @@ def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (CVT_S_W (MTC1 CPURegs:$src))>; def : MipsPat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S FGR32:$src))>; -let Predicates = [NotFP64bit, HasStandardEncoding] in { +let Predicates = [NotFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), (CVT_D32_W (MTC1 CPURegs:$src))>; def : MipsPat<(i32 (fp_to_sint AFGR64:$src)), @@ -452,7 +482,7 @@ let Predicates = [NotFP64bit, HasStandardEncoding] in { def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D32_S FGR32:$src)>; } -let Predicates = [IsFP64bit, HasStandardEncoding] in { +let Predicates = [IsFP64bit, HasStdEnc] in { def : MipsPat<(f64 fpimm0), (DMTC1 ZERO_64)>; def : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>; @@ -472,3 +502,28 @@ let Predicates = [IsFP64bit, HasStandardEncoding] in { def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_D64 FGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>; } + +// Patterns for loads/stores with a reg+imm operand. +let AddedComplexity = 40 in { + let Predicates = [IsN64, HasStdEnc] in { + def : LoadRegImmPat; + def : StoreRegImmPat; + def : LoadRegImmPat; + def : StoreRegImmPat; + } + + let Predicates = [NotN64, HasStdEnc] in { + def : LoadRegImmPat; + def : StoreRegImmPat; + } + + let Predicates = [NotN64, HasMips64, HasStdEnc] in { + def : LoadRegImmPat; + def : StoreRegImmPat; + } + + let Predicates = [NotN64, NotMips64, HasStdEnc] in { + def : LoadRegImmPat; + def : StoreRegImmPat; + } +}