xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/Mips/MipsInstrFPU.td (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg//===-- MipsInstrFPU.td - Mips FPU Instruction Information -*- tablegen -*-===//
27330f729Sjoerg//
37330f729Sjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg// See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg//
77330f729Sjoerg//===----------------------------------------------------------------------===//
87330f729Sjoerg//
97330f729Sjoerg// This file describes the Mips FPU instruction set.
107330f729Sjoerg//
117330f729Sjoerg//===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg//===----------------------------------------------------------------------===//
147330f729Sjoerg// Floating Point Instructions
157330f729Sjoerg// ------------------------
167330f729Sjoerg// * 64bit fp:
177330f729Sjoerg//    - 32 64-bit registers (default mode)
187330f729Sjoerg//    - 16 even 32-bit registers (32-bit compatible mode) for
197330f729Sjoerg//      single and double access.
207330f729Sjoerg// * 32bit fp:
217330f729Sjoerg//    - 16 even 32-bit registers - single and double (aliased)
227330f729Sjoerg//    - 32 32-bit registers (within single-only mode)
237330f729Sjoerg//===----------------------------------------------------------------------===//
247330f729Sjoerg
257330f729Sjoerg// Floating Point Compare and Branch
267330f729Sjoergdef SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisInt<0>,
277330f729Sjoerg                                            SDTCisVT<1, i32>,
287330f729Sjoerg                                            SDTCisVT<2, OtherVT>]>;
297330f729Sjoergdef SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>,
307330f729Sjoerg                                         SDTCisVT<2, i32>]>;
317330f729Sjoergdef SDT_MipsCMovFP : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisVT<2, i32>,
327330f729Sjoerg                                          SDTCisSameAs<1, 3>]>;
337330f729Sjoergdef SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
347330f729Sjoergdef SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
357330f729Sjoerg                                                SDTCisVT<1, i32>,
367330f729Sjoerg                                                SDTCisSameAs<1, 2>]>;
377330f729Sjoergdef SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
387330f729Sjoerg                                                     SDTCisVT<1, f64>,
397330f729Sjoerg                                                     SDTCisVT<2, i32>]>;
407330f729Sjoerg
417330f729Sjoergdef SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
427330f729Sjoerg                                            SDTCisVT<1, i32>]>;
437330f729Sjoerg
447330f729Sjoergdef MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp, [SDNPOutGlue]>;
457330f729Sjoergdef MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>;
467330f729Sjoergdef MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>;
477330f729Sjoergdef MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond,
487330f729Sjoerg                          [SDNPHasChain, SDNPOptInGlue]>;
497330f729Sjoergdef MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>;
507330f729Sjoergdef MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
51*82d56013Sjoergdef : GINodeEquiv<G_MERGE_VALUES, MipsBuildPairF64>;
527330f729Sjoergdef MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
537330f729Sjoerg                                   SDT_MipsExtractElementF64>;
547330f729Sjoerg
557330f729Sjoergdef MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
567330f729Sjoerg
577330f729Sjoerg// Operand for printing out a condition code.
587330f729Sjoerglet PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in
597330f729Sjoerg  def condcode : Operand<i32>;
607330f729Sjoerg
617330f729Sjoerg//===----------------------------------------------------------------------===//
627330f729Sjoerg// Feature predicates.
637330f729Sjoerg//===----------------------------------------------------------------------===//
647330f729Sjoerg
657330f729Sjoergdef IsFP64bit        : Predicate<"Subtarget->isFP64bit()">,
66*82d56013Sjoerg                       AssemblerPredicate<(all_of FeatureFP64Bit)>;
677330f729Sjoergdef NotFP64bit       : Predicate<"!Subtarget->isFP64bit()">,
68*82d56013Sjoerg                       AssemblerPredicate<(all_of (not FeatureFP64Bit))>;
697330f729Sjoergdef IsSingleFloat    : Predicate<"Subtarget->isSingleFloat()">,
70*82d56013Sjoerg                       AssemblerPredicate<(all_of FeatureSingleFloat)>;
717330f729Sjoergdef IsNotSingleFloat : Predicate<"!Subtarget->isSingleFloat()">,
72*82d56013Sjoerg                       AssemblerPredicate<(all_of (not FeatureSingleFloat))>;
737330f729Sjoergdef IsNotSoftFloat   : Predicate<"!Subtarget->useSoftFloat()">,
74*82d56013Sjoerg                       AssemblerPredicate<(all_of (not FeatureSoftFloat))>;
75*82d56013Sjoergdef HasMips3D        : Predicate<"Subtarget->has3D()">,
76*82d56013Sjoerg                       AssemblerPredicate<(all_of FeatureMips3D)>;
777330f729Sjoerg
787330f729Sjoerg//===----------------------------------------------------------------------===//
797330f729Sjoerg// Mips FGR size adjectives.
807330f729Sjoerg// They are mutually exclusive.
817330f729Sjoerg//===----------------------------------------------------------------------===//
827330f729Sjoerg
837330f729Sjoergclass FGR_32 { list<Predicate> FGRPredicates = [NotFP64bit]; }
847330f729Sjoergclass FGR_64 { list<Predicate> FGRPredicates = [IsFP64bit]; }
857330f729Sjoergclass HARDFLOAT { list<Predicate> HardFloatPredicate = [IsNotSoftFloat]; }
867330f729Sjoerg
877330f729Sjoerg//===----------------------------------------------------------------------===//
887330f729Sjoerg
897330f729Sjoerg// FP immediate patterns.
907330f729Sjoergdef fpimm0 : PatLeaf<(fpimm), [{
917330f729Sjoerg  return N->isExactlyValue(+0.0);
927330f729Sjoerg}]>;
937330f729Sjoerg
947330f729Sjoergdef fpimm0neg : PatLeaf<(fpimm), [{
957330f729Sjoerg  return N->isExactlyValue(-0.0);
967330f729Sjoerg}]>;
977330f729Sjoerg
987330f729Sjoerg//===----------------------------------------------------------------------===//
997330f729Sjoerg// Instruction Class Templates
1007330f729Sjoerg//
1017330f729Sjoerg// A set of multiclasses is used to address the register usage.
1027330f729Sjoerg//
1037330f729Sjoerg// S32 - single precision in 16 32bit even fp registers
1047330f729Sjoerg//       single precision in 32 32bit fp registers in SingleOnly mode
1057330f729Sjoerg// S64 - single precision in 32 64bit fp registers (In64BitMode)
1067330f729Sjoerg// D32 - double precision in 16 32bit even fp registers
1077330f729Sjoerg// D64 - double precision in 32 64bit fp registers (In64BitMode)
1087330f729Sjoerg//
1097330f729Sjoerg// Only S32 and D32 are supported right now.
1107330f729Sjoerg//===----------------------------------------------------------------------===//
1117330f729Sjoergclass ADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, bit IsComm,
1127330f729Sjoerg              SDPatternOperator OpNode= null_frag> :
1137330f729Sjoerg  InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft),
1147330f729Sjoerg         !strconcat(opstr, "\t$fd, $fs, $ft"),
1157330f729Sjoerg         [(set RC:$fd, (OpNode RC:$fs, RC:$ft))], Itin, FrmFR, opstr>,
1167330f729Sjoerg  HARDFLOAT {
1177330f729Sjoerg  let isCommutable = IsComm;
1187330f729Sjoerg}
1197330f729Sjoerg
1207330f729Sjoergmulticlass ADDS_M<string opstr, InstrItinClass Itin, bit IsComm,
1217330f729Sjoerg                  SDPatternOperator OpNode = null_frag> {
1227330f729Sjoerg  def _D32 : MMRel, ADDS_FT<opstr, AFGR64Opnd, Itin, IsComm, OpNode>, FGR_32;
1237330f729Sjoerg  def _D64 : ADDS_FT<opstr, FGR64Opnd, Itin, IsComm, OpNode>, FGR_64 {
1247330f729Sjoerg    string DecoderNamespace = "MipsFP64";
1257330f729Sjoerg  }
1267330f729Sjoerg}
1277330f729Sjoerg
1287330f729Sjoergclass ABSS_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
1297330f729Sjoerg              InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
1307330f729Sjoerg  InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"),
1317330f729Sjoerg         [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>,
1327330f729Sjoerg  HARDFLOAT,
1337330f729Sjoerg  NeverHasSideEffects;
1347330f729Sjoerg
135*82d56013Sjoergclass CVT_PS_S_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
136*82d56013Sjoerg                  InstrItinClass Itin, bit IsComm,
1377330f729Sjoerg                  SDPatternOperator OpNode = null_frag> :
1387330f729Sjoerg  InstSE<(outs DstRC:$fd), (ins SrcRC:$fs, SrcRC:$ft),
1397330f729Sjoerg         !strconcat(opstr, "\t$fd, $fs, $ft"),
1407330f729Sjoerg         [(set DstRC:$fd, (OpNode SrcRC:$fs, SrcRC:$ft))], Itin, FrmFR, opstr>,
1417330f729Sjoerg  HARDFLOAT {
1427330f729Sjoerg  let isCommutable = IsComm;
1437330f729Sjoerg}
1447330f729Sjoerg
1457330f729Sjoergmulticlass ABSS_M<string opstr, InstrItinClass Itin,
1467330f729Sjoerg                  SDPatternOperator OpNode= null_frag> {
1477330f729Sjoerg  def _D32 : MMRel, ABSS_FT<opstr, AFGR64Opnd, AFGR64Opnd, Itin, OpNode>,
1487330f729Sjoerg             FGR_32;
149*82d56013Sjoerg  def _D64 : StdMMR6Rel, ABSS_FT<opstr, FGR64Opnd, FGR64Opnd, Itin, OpNode>,
150*82d56013Sjoerg             FGR_64 {
1517330f729Sjoerg    string DecoderNamespace = "MipsFP64";
1527330f729Sjoerg  }
1537330f729Sjoerg}
1547330f729Sjoerg
1557330f729Sjoergmulticlass ROUND_M<string opstr, InstrItinClass Itin> {
1567330f729Sjoerg  def _D32 : MMRel, ABSS_FT<opstr, FGR32Opnd, AFGR64Opnd, Itin>, FGR_32;
1577330f729Sjoerg  def _D64 : StdMMR6Rel, ABSS_FT<opstr, FGR32Opnd, FGR64Opnd, Itin>, FGR_64 {
1587330f729Sjoerg    let DecoderNamespace = "MipsFP64";
1597330f729Sjoerg  }
1607330f729Sjoerg}
1617330f729Sjoerg
1627330f729Sjoergclass MFC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
1637330f729Sjoerg              InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
1647330f729Sjoerg  InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"),
1657330f729Sjoerg         [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>, HARDFLOAT {
1667330f729Sjoerg  let isMoveReg = 1;
1677330f729Sjoerg}
1687330f729Sjoerg
1697330f729Sjoergclass MTC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
1707330f729Sjoerg              InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
1717330f729Sjoerg  InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"),
1727330f729Sjoerg         [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR, opstr>, HARDFLOAT {
1737330f729Sjoerg  let isMoveReg = 1;
1747330f729Sjoerg}
1757330f729Sjoerg
1767330f729Sjoergclass MTC1_64_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
1777330f729Sjoerg                 InstrItinClass Itin> :
1787330f729Sjoerg  InstSE<(outs DstRC:$fs), (ins DstRC:$fs_in, SrcRC:$rt),
1797330f729Sjoerg         !strconcat(opstr, "\t$rt, $fs"), [], Itin, FrmFR, opstr>, HARDFLOAT {
1807330f729Sjoerg  // $fs_in is part of a white lie to work around a widespread bug in the FPU
1817330f729Sjoerg  // implementation. See expandBuildPairF64 for details.
1827330f729Sjoerg  let Constraints = "$fs = $fs_in";
1837330f729Sjoerg}
1847330f729Sjoerg
1857330f729Sjoergclass LW_FT<string opstr, RegisterOperand RC, DAGOperand MO,
1867330f729Sjoerg            InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
1877330f729Sjoerg  InstSE<(outs RC:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1887330f729Sjoerg         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr>,
1897330f729Sjoerg  HARDFLOAT {
1907330f729Sjoerg  let DecoderMethod = "DecodeFMem";
1917330f729Sjoerg  let mayLoad = 1;
1927330f729Sjoerg}
1937330f729Sjoerg
1947330f729Sjoergclass SW_FT<string opstr, RegisterOperand RC, DAGOperand MO,
1957330f729Sjoerg            InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
1967330f729Sjoerg  InstSE<(outs), (ins RC:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1977330f729Sjoerg         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr>, HARDFLOAT {
1987330f729Sjoerg  let DecoderMethod = "DecodeFMem";
1997330f729Sjoerg  let mayStore = 1;
2007330f729Sjoerg}
2017330f729Sjoerg
2027330f729Sjoergclass MADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
2037330f729Sjoerg               SDPatternOperator OpNode = null_frag> :
2047330f729Sjoerg  InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft),
2057330f729Sjoerg         !strconcat(opstr, "\t$fd, $fr, $fs, $ft"),
2067330f729Sjoerg         [(set RC:$fd, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr))], Itin,
2077330f729Sjoerg         FrmFR, opstr>, HARDFLOAT;
2087330f729Sjoerg
2097330f729Sjoergclass NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
2107330f729Sjoerg                SDPatternOperator OpNode = null_frag> :
2117330f729Sjoerg  InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft),
2127330f729Sjoerg         !strconcat(opstr, "\t$fd, $fr, $fs, $ft"),
2137330f729Sjoerg         [(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))],
2147330f729Sjoerg         Itin, FrmFR, opstr>, HARDFLOAT;
2157330f729Sjoerg
2167330f729Sjoergclass LWXC1_FT<string opstr, RegisterOperand DRC,
2177330f729Sjoerg               InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
2187330f729Sjoerg  InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index),
2197330f729Sjoerg         !strconcat(opstr, "\t$fd, ${index}(${base})"),
2207330f729Sjoerg         [(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin,
2217330f729Sjoerg         FrmFI, opstr>, HARDFLOAT {
2227330f729Sjoerg  let AddedComplexity = 20;
2237330f729Sjoerg}
2247330f729Sjoerg
2257330f729Sjoergclass SWXC1_FT<string opstr, RegisterOperand DRC,
2267330f729Sjoerg               InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
2277330f729Sjoerg  InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index),
2287330f729Sjoerg         !strconcat(opstr, "\t$fs, ${index}(${base})"),
2297330f729Sjoerg         [(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin,
2307330f729Sjoerg         FrmFI, opstr>, HARDFLOAT {
2317330f729Sjoerg  let AddedComplexity = 20;
2327330f729Sjoerg}
2337330f729Sjoerg
2347330f729Sjoergclass BC1F_FT<string opstr, DAGOperand opnd, InstrItinClass Itin,
2357330f729Sjoerg              SDPatternOperator Op = null_frag> :
2367330f729Sjoerg  InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
2377330f729Sjoerg         !strconcat(opstr, "\t$fcc, $offset"),
2387330f729Sjoerg         [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin,
2397330f729Sjoerg         FrmFI, opstr>, HARDFLOAT {
2407330f729Sjoerg  let isBranch = 1;
2417330f729Sjoerg  let isTerminator = 1;
2427330f729Sjoerg  let hasDelaySlot = 1;
2437330f729Sjoerg  let Defs = [AT];
2447330f729Sjoerg  let hasFCCRegOperand = 1;
2457330f729Sjoerg}
2467330f729Sjoerg
2477330f729Sjoergclass BC1XL_FT<string opstr, DAGOperand opnd, InstrItinClass Itin> :
2487330f729Sjoerg  InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
2497330f729Sjoerg         !strconcat(opstr, "\t$fcc, $offset"), [], Itin,
2507330f729Sjoerg         FrmFI, opstr>, HARDFLOAT {
2517330f729Sjoerg  let isBranch = 1;
2527330f729Sjoerg  let isTerminator = 1;
2537330f729Sjoerg  let hasDelaySlot = 1;
2547330f729Sjoerg  let Defs = [AT];
2557330f729Sjoerg  let hasFCCRegOperand = 1;
2567330f729Sjoerg}
2577330f729Sjoerg
2587330f729Sjoergclass CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin,
2597330f729Sjoerg              SDPatternOperator OpNode = null_frag>  :
2607330f729Sjoerg  InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond),
2617330f729Sjoerg         !strconcat("c.$cond.", typestr, "\t$fs, $ft"),
2627330f729Sjoerg         [(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR,
2637330f729Sjoerg         !strconcat("c.$cond.", typestr)>, HARDFLOAT {
2647330f729Sjoerg  let Defs = [FCC0];
2657330f729Sjoerg  let isCodeGenOnly = 1;
2667330f729Sjoerg  let hasFCCRegOperand = 1;
2677330f729Sjoerg}
2687330f729Sjoerg
2697330f729Sjoerg
2707330f729Sjoerg// Note: MIPS-IV introduced $fcc1-$fcc7 and renamed FCSR31[23] $fcc0. Rather
2717330f729Sjoerg//       duplicating the instruction definition for MIPS1 - MIPS3, we expand
2727330f729Sjoerg//       c.cond.ft if necessary, and reject it after constructing the
2737330f729Sjoerg//       instruction if the ISA doesn't support it.
2747330f729Sjoergclass C_COND_FT<string CondStr, string Typestr, RegisterOperand RC,
2757330f729Sjoerg                InstrItinClass itin>  :
2767330f729Sjoerg   InstSE<(outs FCCRegsOpnd:$fcc), (ins RC:$fs, RC:$ft),
2777330f729Sjoerg          !strconcat("c.", CondStr, ".", Typestr, "\t$fcc, $fs, $ft"), [], itin,
2787330f729Sjoerg          FrmFR>, HARDFLOAT {
2797330f729Sjoerg  let isCompare = 1;
2807330f729Sjoerg  let hasFCCRegOperand = 1;
2817330f729Sjoerg}
2827330f729Sjoerg
2837330f729Sjoerg
2847330f729Sjoergmulticlass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt,
2857330f729Sjoerg                    InstrItinClass itin> {
2867330f729Sjoerg  def C_F_#NAME : MMRel, C_COND_FT<"f", TypeStr, RC, itin>,
2877330f729Sjoerg                  C_COND_FM<fmt, 0> {
2887330f729Sjoerg    let BaseOpcode = "c.f."#NAME;
2897330f729Sjoerg    let isCommutable = 1;
2907330f729Sjoerg  }
2917330f729Sjoerg  def C_UN_#NAME : MMRel, C_COND_FT<"un", TypeStr, RC, itin>,
2927330f729Sjoerg                   C_COND_FM<fmt, 1> {
2937330f729Sjoerg    let BaseOpcode = "c.un."#NAME;
2947330f729Sjoerg    let isCommutable = 1;
2957330f729Sjoerg  }
2967330f729Sjoerg  def C_EQ_#NAME : MMRel, C_COND_FT<"eq", TypeStr, RC, itin>,
2977330f729Sjoerg                   C_COND_FM<fmt, 2> {
2987330f729Sjoerg    let BaseOpcode = "c.eq."#NAME;
2997330f729Sjoerg    let isCommutable = 1;
3007330f729Sjoerg  }
3017330f729Sjoerg  def C_UEQ_#NAME : MMRel, C_COND_FT<"ueq", TypeStr, RC, itin>,
3027330f729Sjoerg                    C_COND_FM<fmt, 3> {
3037330f729Sjoerg    let BaseOpcode = "c.ueq."#NAME;
3047330f729Sjoerg    let isCommutable = 1;
3057330f729Sjoerg  }
3067330f729Sjoerg  def C_OLT_#NAME : MMRel, C_COND_FT<"olt", TypeStr, RC, itin>,
3077330f729Sjoerg                    C_COND_FM<fmt, 4> {
3087330f729Sjoerg    let BaseOpcode = "c.olt."#NAME;
3097330f729Sjoerg  }
3107330f729Sjoerg  def C_ULT_#NAME : MMRel, C_COND_FT<"ult", TypeStr, RC, itin>,
3117330f729Sjoerg                    C_COND_FM<fmt, 5> {
3127330f729Sjoerg    let BaseOpcode = "c.ult."#NAME;
3137330f729Sjoerg  }
3147330f729Sjoerg  def C_OLE_#NAME : MMRel, C_COND_FT<"ole", TypeStr, RC, itin>,
3157330f729Sjoerg                    C_COND_FM<fmt, 6> {
3167330f729Sjoerg    let BaseOpcode = "c.ole."#NAME;
3177330f729Sjoerg  }
3187330f729Sjoerg  def C_ULE_#NAME : MMRel, C_COND_FT<"ule", TypeStr, RC, itin>,
3197330f729Sjoerg                     C_COND_FM<fmt, 7> {
3207330f729Sjoerg    let BaseOpcode = "c.ule."#NAME;
3217330f729Sjoerg  }
3227330f729Sjoerg  def C_SF_#NAME : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
3237330f729Sjoerg                   C_COND_FM<fmt, 8> {
3247330f729Sjoerg    let BaseOpcode = "c.sf."#NAME;
3257330f729Sjoerg    let isCommutable = 1;
3267330f729Sjoerg  }
3277330f729Sjoerg  def C_NGLE_#NAME : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
3287330f729Sjoerg                     C_COND_FM<fmt, 9> {
3297330f729Sjoerg    let BaseOpcode = "c.ngle."#NAME;
3307330f729Sjoerg  }
3317330f729Sjoerg  def C_SEQ_#NAME : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
3327330f729Sjoerg                    C_COND_FM<fmt, 10> {
3337330f729Sjoerg    let BaseOpcode = "c.seq."#NAME;
3347330f729Sjoerg    let isCommutable = 1;
3357330f729Sjoerg  }
3367330f729Sjoerg  def C_NGL_#NAME : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
3377330f729Sjoerg                    C_COND_FM<fmt, 11> {
3387330f729Sjoerg    let BaseOpcode = "c.ngl."#NAME;
3397330f729Sjoerg  }
3407330f729Sjoerg  def C_LT_#NAME : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
3417330f729Sjoerg                   C_COND_FM<fmt, 12> {
3427330f729Sjoerg    let BaseOpcode = "c.lt."#NAME;
3437330f729Sjoerg  }
3447330f729Sjoerg  def C_NGE_#NAME : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
3457330f729Sjoerg                    C_COND_FM<fmt, 13> {
3467330f729Sjoerg    let BaseOpcode = "c.nge."#NAME;
3477330f729Sjoerg  }
3487330f729Sjoerg  def C_LE_#NAME : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
3497330f729Sjoerg                   C_COND_FM<fmt, 14> {
3507330f729Sjoerg    let BaseOpcode = "c.le."#NAME;
3517330f729Sjoerg  }
3527330f729Sjoerg  def C_NGT_#NAME : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
3537330f729Sjoerg                    C_COND_FM<fmt, 15> {
3547330f729Sjoerg    let BaseOpcode = "c.ngt."#NAME;
3557330f729Sjoerg  }
3567330f729Sjoerg}
3577330f729Sjoerg
3587330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
3597330f729Sjoergdefm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>, ISA_MIPS1_NOT_32R6_64R6;
3607330f729Sjoergdefm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
3617330f729Sjoerg           FGR_32;
3627330f729Sjoerglet DecoderNamespace = "MipsFP64" in
3637330f729Sjoergdefm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
3647330f729Sjoerg           FGR_64;
3657330f729Sjoerg}
3667330f729Sjoerg//===----------------------------------------------------------------------===//
3677330f729Sjoerg// Floating Point Instructions
3687330f729Sjoerg//===----------------------------------------------------------------------===//
3697330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
370*82d56013Sjoerg  def ROUND_W_S : MMRel, StdMMR6Rel,
371*82d56013Sjoerg                  ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, II_ROUND>,
3727330f729Sjoerg                  ABSS_FM<0xc, 16>, ISA_MIPS2;
3737330f729Sjoerg  defm ROUND_W  : ROUND_M<"round.w.d", II_ROUND>, ABSS_FM<0xc, 17>, ISA_MIPS2;
374*82d56013Sjoerg  def TRUNC_W_S : MMRel, StdMMR6Rel,
375*82d56013Sjoerg                  ABSS_FT<"trunc.w.s", FGR32Opnd, FGR32Opnd, II_TRUNC>,
3767330f729Sjoerg                  ABSS_FM<0xd, 16>, ISA_MIPS2;
377*82d56013Sjoerg  def CEIL_W_S  : MMRel, StdMMR6Rel,
378*82d56013Sjoerg                  ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
3797330f729Sjoerg                  ABSS_FM<0xe, 16>, ISA_MIPS2;
380*82d56013Sjoerg  def FLOOR_W_S : MMRel, StdMMR6Rel,
381*82d56013Sjoerg                  ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, II_FLOOR>,
3827330f729Sjoerg                  ABSS_FM<0xf, 16>, ISA_MIPS2;
3837330f729Sjoerg  def CVT_W_S   : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>,
3847330f729Sjoerg                  ABSS_FM<0x24, 16>, ISA_MIPS1;
3857330f729Sjoerg
3867330f729Sjoerg  defm TRUNC_W : ROUND_M<"trunc.w.d", II_TRUNC>, ABSS_FM<0xd, 17>, ISA_MIPS2;
3877330f729Sjoerg  defm CEIL_W  : ROUND_M<"ceil.w.d", II_CEIL>, ABSS_FM<0xe, 17>, ISA_MIPS2;
3887330f729Sjoerg  defm FLOOR_W : ROUND_M<"floor.w.d", II_FLOOR>, ABSS_FM<0xf, 17>, ISA_MIPS2;
3897330f729Sjoerg  defm CVT_W   : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>, ISA_MIPS1;
3907330f729Sjoerg}
3917330f729Sjoerg
3927330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
3937330f729Sjoerg  def RECIP_S : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd, II_RECIP_S>,
3947330f729Sjoerg                ABSS_FM<0b010101, 0x10>, INSN_MIPS4_32R2;
3957330f729Sjoerg  def RECIP_D32 : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd, II_RECIP_D>,
3967330f729Sjoerg                  ABSS_FM<0b010101, 0x11>, INSN_MIPS4_32R2, FGR_32 {
3977330f729Sjoerg    let BaseOpcode = "RECIP_D32";
3987330f729Sjoerg  }
3997330f729Sjoerg  let DecoderNamespace = "MipsFP64" in
4007330f729Sjoerg    def RECIP_D64 : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd,
4017330f729Sjoerg                                   II_RECIP_D>, ABSS_FM<0b010101, 0x11>,
4027330f729Sjoerg                    INSN_MIPS4_32R2, FGR_64;
4037330f729Sjoerg  def RSQRT_S : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd, II_RSQRT_S>,
4047330f729Sjoerg                ABSS_FM<0b010110, 0x10>, INSN_MIPS4_32R2;
4057330f729Sjoerg  def RSQRT_D32 : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd, II_RSQRT_D>,
4067330f729Sjoerg                  ABSS_FM<0b010110, 0x11>, INSN_MIPS4_32R2, FGR_32 {
4077330f729Sjoerg    let BaseOpcode = "RSQRT_D32";
4087330f729Sjoerg  }
4097330f729Sjoerg  let DecoderNamespace = "MipsFP64" in
4107330f729Sjoerg    def RSQRT_D64 : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd,
4117330f729Sjoerg                                   II_RSQRT_D>, ABSS_FM<0b010110, 0x11>,
4127330f729Sjoerg                    INSN_MIPS4_32R2, FGR_64;
4137330f729Sjoerg}
4147330f729Sjoerglet DecoderNamespace = "MipsFP64" in {
4157330f729Sjoerg  let AdditionalPredicates = [NotInMicroMips] in {
4167330f729Sjoerg  def ROUND_L_S : ABSS_FT<"round.l.s", FGR64Opnd, FGR32Opnd, II_ROUND>,
4177330f729Sjoerg                  ABSS_FM<0x8, 16>, ISA_MIPS2, FGR_64;
4187330f729Sjoerg  def ROUND_L_D64 : ABSS_FT<"round.l.d", FGR64Opnd, FGR64Opnd, II_ROUND>,
4197330f729Sjoerg                    ABSS_FM<0x8, 17>, INSN_MIPS3_32, FGR_64;
4207330f729Sjoerg  def TRUNC_L_S : ABSS_FT<"trunc.l.s", FGR64Opnd, FGR32Opnd, II_TRUNC>,
4217330f729Sjoerg                  ABSS_FM<0x9, 16>, ISA_MIPS2, FGR_64;
4227330f729Sjoerg  def TRUNC_L_D64 : ABSS_FT<"trunc.l.d", FGR64Opnd, FGR64Opnd, II_TRUNC>,
4237330f729Sjoerg                    ABSS_FM<0x9, 17>, INSN_MIPS3_32, FGR_64;
4247330f729Sjoerg  def CEIL_L_S  : ABSS_FT<"ceil.l.s", FGR64Opnd, FGR32Opnd, II_CEIL>,
4257330f729Sjoerg                  ABSS_FM<0xa, 16>, ISA_MIPS2, FGR_64;
4267330f729Sjoerg  def CEIL_L_D64 : ABSS_FT<"ceil.l.d", FGR64Opnd, FGR64Opnd, II_CEIL>,
4277330f729Sjoerg                   ABSS_FM<0xa, 17>, INSN_MIPS3_32, FGR_64;
4287330f729Sjoerg  def FLOOR_L_S : ABSS_FT<"floor.l.s", FGR64Opnd, FGR32Opnd, II_FLOOR>,
4297330f729Sjoerg                  ABSS_FM<0xb, 16>, ISA_MIPS2, FGR_64;
4307330f729Sjoerg  def FLOOR_L_D64 : ABSS_FT<"floor.l.d", FGR64Opnd, FGR64Opnd, II_FLOOR>,
4317330f729Sjoerg                    ABSS_FM<0xb, 17>, INSN_MIPS3_32, FGR_64;
4327330f729Sjoerg  }
4337330f729Sjoerg}
4347330f729Sjoerg
4357330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in{
4367330f729Sjoerg  def CVT_S_W : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>,
4377330f729Sjoerg                ABSS_FM<0x20, 20>, ISA_MIPS1;
4387330f729Sjoerg  def CVT_L_S : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>,
4397330f729Sjoerg                ABSS_FM<0x25, 16>, INSN_MIPS3_32R2;
4407330f729Sjoerg  def CVT_L_D64: MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, II_CVT>,
4417330f729Sjoerg                 ABSS_FM<0x25, 17>, INSN_MIPS3_32R2;
4427330f729Sjoerg}
4437330f729Sjoerg
4447330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
4457330f729Sjoerg  def CVT_S_D32 : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
4467330f729Sjoerg                  ABSS_FM<0x20, 17>, ISA_MIPS1, FGR_32;
4477330f729Sjoerg  def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>,
4487330f729Sjoerg                  ABSS_FM<0x21, 16>, ISA_MIPS1, FGR_32;
4497330f729Sjoerg  def CVT_D32_W : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>,
4507330f729Sjoerg                  ABSS_FM<0x21, 20>, ISA_MIPS1, FGR_32;
4517330f729Sjoerg}
4527330f729Sjoerg
4537330f729Sjoerglet DecoderNamespace = "MipsFP64" in {
4547330f729Sjoerg  let AdditionalPredicates = [NotInMicroMips] in {
455*82d56013Sjoerg    def FADD_PS64   : ADDS_FT<"add.ps", FGR64Opnd, II_ADD_PS, 0>,
456*82d56013Sjoerg                      ADDS_FM<0x0, 22>,
457*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
458*82d56013Sjoerg    def FMUL_PS64   : ADDS_FT<"mul.ps", FGR64Opnd, II_MUL_PS, 0>,
459*82d56013Sjoerg                      ADDS_FM<0x2, 22>,
460*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
4617330f729Sjoerg    def PLL_PS64    : ADDS_FT<"pll.ps", FGR64Opnd, II_CVT, 0>,
4627330f729Sjoerg                      ADDS_FM<0x2C, 22>,
4637330f729Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
4647330f729Sjoerg    def PLU_PS64    : ADDS_FT<"plu.ps", FGR64Opnd, II_CVT, 0>,
4657330f729Sjoerg                      ADDS_FM<0x2D, 22>,
4667330f729Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
467*82d56013Sjoerg    def PUL_PS64    : ADDS_FT<"pul.ps", FGR64Opnd, II_CVT, 0>,
468*82d56013Sjoerg                      ADDS_FM<0x2E, 22>,
469*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
470*82d56013Sjoerg    def PUU_PS64    : ADDS_FT<"puu.ps", FGR64Opnd, II_CVT, 0>,
471*82d56013Sjoerg                      ADDS_FM<0x2F, 22>,
472*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
473*82d56013Sjoerg    def FSUB_PS64   : ADDS_FT<"sub.ps", FGR64Opnd, II_SUB_PS, 0>,
474*82d56013Sjoerg                      ADDS_FM<0x1, 22>,
475*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
4767330f729Sjoerg
4777330f729Sjoerg    def CVT_S_PU64  : ABSS_FT<"cvt.s.pu", FGR32Opnd, FGR64Opnd, II_CVT>,
4787330f729Sjoerg                      ABSS_FM<0x20, 22>,
4797330f729Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
4807330f729Sjoerg    def CVT_S_PL64  : ABSS_FT<"cvt.s.pl", FGR32Opnd, FGR64Opnd, II_CVT>,
4817330f729Sjoerg                      ABSS_FM<0x28, 22>,
4827330f729Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
4837330f729Sjoerg
4847330f729Sjoerg    def CVT_PS_S64  : CVT_PS_S_FT<"cvt.ps.s", FGR64Opnd, FGR32Opnd, II_CVT, 0>,
4857330f729Sjoerg                      ADDS_FM<0x26, 16>,
4867330f729Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
4877330f729Sjoerg  }
4887330f729Sjoerg}
4897330f729Sjoerg
4907330f729Sjoerglet DecoderNamespace = "MipsFP64" in {
491*82d56013Sjoerg  let AdditionalPredicates = [HasMips3D] in {
492*82d56013Sjoerg    def ADDR_PS64   : ADDS_FT<"addr.ps", FGR64Opnd, II_ADDR_PS, 0>,
493*82d56013Sjoerg                      ADDS_FM<0x18, 22>, ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
494*82d56013Sjoerg    def MULR_PS64   : ADDS_FT<"mulr.ps", FGR64Opnd, II_MULR_PS, 0>,
495*82d56013Sjoerg                      ADDS_FM<0x1a, 22>, ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
496*82d56013Sjoerg    def CVT_PS_PW64 : ABSS_FT<"cvt.ps.pw", FGR64Opnd, FGR64Opnd, II_CVT>,
497*82d56013Sjoerg                      ABSS_FM<0x26, 20>,
498*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
499*82d56013Sjoerg    def CVT_PW_PS64 : ABSS_FT<"cvt.pw.ps", FGR64Opnd, FGR64Opnd, II_CVT>,
500*82d56013Sjoerg                      ABSS_FM<0x24, 22>,
501*82d56013Sjoerg                      ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
502*82d56013Sjoerg  }
503*82d56013Sjoerg}
504*82d56013Sjoerg
505*82d56013Sjoerglet DecoderNamespace = "MipsFP64" in {
5067330f729Sjoerg  let AdditionalPredicates = [NotInMicroMips] in {
5077330f729Sjoerg    def CVT_S_L   : ABSS_FT<"cvt.s.l", FGR32Opnd, FGR64Opnd, II_CVT>,
5087330f729Sjoerg                    ABSS_FM<0x20, 21>, INSN_MIPS3_32R2, FGR_64;
5097330f729Sjoerg    def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>,
5107330f729Sjoerg                    ABSS_FM<0x20, 17>, ISA_MIPS1, FGR_64;
5117330f729Sjoerg    def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64Opnd, FGR32Opnd, II_CVT>,
5127330f729Sjoerg                    ABSS_FM<0x21, 20>, ISA_MIPS1, FGR_64;
5137330f729Sjoerg    def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64Opnd, FGR32Opnd, II_CVT>,
5147330f729Sjoerg                    ABSS_FM<0x21, 16>, ISA_MIPS1, FGR_64;
5157330f729Sjoerg    def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64Opnd, FGR64Opnd, II_CVT>,
5167330f729Sjoerg                    ABSS_FM<0x21, 21>, INSN_MIPS3_32R2, FGR_64;
5177330f729Sjoerg  }
5187330f729Sjoerg}
5197330f729Sjoerg
5207330f729Sjoerglet isPseudo = 1, isCodeGenOnly = 1 in {
5217330f729Sjoerg  def PseudoCVT_S_W : ABSS_FT<"", FGR32Opnd, GPR32Opnd, II_CVT>;
5227330f729Sjoerg  def PseudoCVT_D32_W : ABSS_FT<"", AFGR64Opnd, GPR32Opnd, II_CVT>;
5237330f729Sjoerg  def PseudoCVT_S_L : ABSS_FT<"", FGR64Opnd, GPR64Opnd, II_CVT>;
5247330f729Sjoerg  def PseudoCVT_D64_W : ABSS_FT<"", FGR64Opnd, GPR32Opnd, II_CVT>;
5257330f729Sjoerg  def PseudoCVT_D64_L : ABSS_FT<"", FGR64Opnd, GPR64Opnd, II_CVT>;
5267330f729Sjoerg}
5277330f729Sjoerg
5287330f729Sjoerglet AdditionalPredicates = [NotInMicroMips, UseAbs] in {
5297330f729Sjoerg  def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
5307330f729Sjoerg               ABSS_FM<0x5, 16>, ISA_MIPS1;
5317330f729Sjoerg  defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>, ISA_MIPS1;
5327330f729Sjoerg}
5337330f729Sjoerg
5347330f729Sjoergdef FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>,
5357330f729Sjoerg             ABSS_FM<0x7, 16>, ISA_MIPS1;
5367330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
5377330f729Sjoerg  defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>, ISA_MIPS1;
5387330f729Sjoerg}
5397330f729Sjoerg
5407330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
5417330f729Sjoerg  def FSQRT_S : MMRel, StdMMR6Rel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd,
5427330f729Sjoerg                II_SQRT_S, fsqrt>, ABSS_FM<0x4, 16>, ISA_MIPS2;
5437330f729Sjoerg  defm FSQRT : ABSS_M<"sqrt.d", II_SQRT_D, fsqrt>, ABSS_FM<0x4, 17>, ISA_MIPS2;
5447330f729Sjoerg}
5457330f729Sjoerg
5467330f729Sjoerg// The odd-numbered registers are only referenced when doing loads,
5477330f729Sjoerg// stores, and moves between floating-point and integer registers.
5487330f729Sjoerg// When defining instructions, we reference all 32-bit registers,
5497330f729Sjoerg// regardless of register aliasing.
5507330f729Sjoerg
5517330f729Sjoerg/// Move Control Registers From/To CPU Registers
5527330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
5537330f729Sjoerg  def CFC1 : MMRel, MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, II_CFC1>, MFC1_FM<2>,
5547330f729Sjoerg             ISA_MIPS1;
5557330f729Sjoerg  def CTC1 : MMRel, MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, II_CTC1>, MFC1_FM<6>,
5567330f729Sjoerg             ISA_MIPS1;
5577330f729Sjoerg
5587330f729Sjoerg  def MFC1 : MMRel, StdMMR6Rel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, II_MFC1,
5597330f729Sjoerg                                        bitconvert>, MFC1_FM<0>, ISA_MIPS1;
5607330f729Sjoerg  def MFC1_D64 : MFC1_FT<"mfc1", GPR32Opnd, FGR64Opnd, II_MFC1>, MFC1_FM<0>,
5617330f729Sjoerg                 ISA_MIPS1, FGR_64 {
5627330f729Sjoerg    let DecoderNamespace = "MipsFP64";
5637330f729Sjoerg  }
5647330f729Sjoerg  def MTC1 : MMRel, StdMMR6Rel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, II_MTC1,
5657330f729Sjoerg                                        bitconvert>, MFC1_FM<4>, ISA_MIPS1;
5667330f729Sjoerg  def MTC1_D64 : MTC1_FT<"mtc1", FGR64Opnd, GPR32Opnd, II_MTC1>, MFC1_FM<4>,
5677330f729Sjoerg                 ISA_MIPS1, FGR_64 {
5687330f729Sjoerg    let DecoderNamespace = "MipsFP64";
5697330f729Sjoerg  }
5707330f729Sjoerg
5717330f729Sjoerg  def MFHC1_D32 : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
5727330f729Sjoerg                  MFC1_FM<3>, ISA_MIPS32R2, FGR_32;
5737330f729Sjoerg  def MFHC1_D64 : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>,
5747330f729Sjoerg                  MFC1_FM<3>, ISA_MIPS32R2, FGR_64 {
5757330f729Sjoerg    let DecoderNamespace = "MipsFP64";
5767330f729Sjoerg  }
5777330f729Sjoerg
578*82d56013Sjoerg  def MTHC1_D32 : MMRel, StdMMR6Rel,
579*82d56013Sjoerg                  MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
5807330f729Sjoerg                  MFC1_FM<7>, ISA_MIPS32R2, FGR_32;
5817330f729Sjoerg  def MTHC1_D64 : MTC1_64_FT<"mthc1", FGR64Opnd, GPR32Opnd, II_MTHC1>,
5827330f729Sjoerg                  MFC1_FM<7>, ISA_MIPS32R2, FGR_64 {
5837330f729Sjoerg    let DecoderNamespace = "MipsFP64";
5847330f729Sjoerg  }
5857330f729Sjoerg
5867330f729Sjoerg  def DMTC1 : MTC1_FT<"dmtc1", FGR64Opnd, GPR64Opnd, II_DMTC1,
5877330f729Sjoerg              bitconvert>, MFC1_FM<5>, ISA_MIPS3;
5887330f729Sjoerg  def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, II_DMFC1,
5897330f729Sjoerg                      bitconvert>, MFC1_FM<1>, ISA_MIPS3;
5907330f729Sjoerg  let isMoveReg = 1 in {
5917330f729Sjoerg    def FMOV_S   : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
5927330f729Sjoerg                   ABSS_FM<0x6, 16>, ISA_MIPS1;
5937330f729Sjoerg    defm FMOV : ABSS_M<"mov.d", II_MOV_D>, ABSS_FM<0x6, 17>, ISA_MIPS1;
5947330f729Sjoerg  } // isMoveReg
5957330f729Sjoerg}
5967330f729Sjoerg
5977330f729Sjoerg/// Floating Point Memory Instructions
5987330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
5997330f729Sjoerg  def LWC1 : MMRel, LW_FT<"lwc1", FGR32Opnd, mem_simm16, II_LWC1, load>,
6007330f729Sjoerg             LW_FM<0x31>, ISA_MIPS1;
6017330f729Sjoerg  def SWC1 : MMRel, SW_FT<"swc1", FGR32Opnd, mem_simm16, II_SWC1, store>,
6027330f729Sjoerg             LW_FM<0x39>, ISA_MIPS1;
6037330f729Sjoerg}
6047330f729Sjoerg
6057330f729Sjoerglet DecoderNamespace = "MipsFP64", AdditionalPredicates = [NotInMicroMips] in {
6067330f729Sjoerg  def LDC164 : StdMMR6Rel, LW_FT<"ldc1", FGR64Opnd, mem_simm16, II_LDC1, load>,
6077330f729Sjoerg               LW_FM<0x35>, ISA_MIPS2, FGR_64 {
6087330f729Sjoerg    let BaseOpcode = "LDC164";
6097330f729Sjoerg  }
6107330f729Sjoerg  def SDC164 : StdMMR6Rel, SW_FT<"sdc1", FGR64Opnd, mem_simm16, II_SDC1, store>,
6117330f729Sjoerg               LW_FM<0x3d>, ISA_MIPS2, FGR_64;
6127330f729Sjoerg}
6137330f729Sjoerg
6147330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
6157330f729Sjoerg  def LDC1 : MMRel, StdMMR6Rel, LW_FT<"ldc1", AFGR64Opnd, mem_simm16, II_LDC1,
6167330f729Sjoerg                                      load>, LW_FM<0x35>, ISA_MIPS2, FGR_32 {
6177330f729Sjoerg    let BaseOpcode = "LDC132";
6187330f729Sjoerg  }
6197330f729Sjoerg  def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, mem_simm16, II_SDC1, store>,
6207330f729Sjoerg             LW_FM<0x3d>, ISA_MIPS2, FGR_32;
6217330f729Sjoerg}
6227330f729Sjoerg
6237330f729Sjoerg// Indexed loads and stores.
6247330f729Sjoerg// Base register + offset register addressing mode (indicated by "x" in the
6257330f729Sjoerg// instruction mnemonic) is disallowed under NaCl.
6267330f729Sjoerglet AdditionalPredicates = [IsNotNaCl] in {
6277330f729Sjoerg  def LWXC1 : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>, LWXC1_FM<0>,
6287330f729Sjoerg              INSN_MIPS4_32R2_NOT_32R6_64R6;
6297330f729Sjoerg  def SWXC1 : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, II_SWXC1, store>, SWXC1_FM<8>,
6307330f729Sjoerg              INSN_MIPS4_32R2_NOT_32R6_64R6;
6317330f729Sjoerg}
6327330f729Sjoerg
6337330f729Sjoerglet AdditionalPredicates = [NotInMicroMips, IsNotNaCl] in {
6347330f729Sjoerg  def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, II_LDXC1, load>, LWXC1_FM<1>,
6357330f729Sjoerg              INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
6367330f729Sjoerg  def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, II_SDXC1, store>, SWXC1_FM<9>,
6377330f729Sjoerg              INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
6387330f729Sjoerg}
6397330f729Sjoerg
6407330f729Sjoerglet DecoderNamespace="MipsFP64" in {
6417330f729Sjoerg  def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, II_LDXC1, load>, LWXC1_FM<1>,
6427330f729Sjoerg                INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
6437330f729Sjoerg  def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, II_SDXC1, store>, SWXC1_FM<9>,
6447330f729Sjoerg                INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
6457330f729Sjoerg}
6467330f729Sjoerg
6477330f729Sjoerg// Load/store doubleword indexed unaligned.
6487330f729Sjoerg// FIXME: This instruction should not be defined for FGR_32.
6497330f729Sjoerglet AdditionalPredicates = [IsNotNaCl, NotInMicroMips] in {
6507330f729Sjoerg  def LUXC1 : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>,
6517330f729Sjoerg              INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32;
6527330f729Sjoerg  def SUXC1 : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, II_SUXC1>, SWXC1_FM<0xd>,
6537330f729Sjoerg              INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32;
6547330f729Sjoerg}
6557330f729Sjoerg
6567330f729Sjoerglet AdditionalPredicates = [IsNotNaCl, NotInMicroMips],
6577330f729Sjoerg    DecoderNamespace="MipsFP64" in {
6587330f729Sjoerg  def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>,
6597330f729Sjoerg                INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_64;
6607330f729Sjoerg  def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, II_SUXC1>, SWXC1_FM<0xd>,
6617330f729Sjoerg                INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_64;
6627330f729Sjoerg}
6637330f729Sjoerg
664*82d56013Sjoerg/// Floating-point Arithmetic
6657330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
6667330f729Sjoerg  def FADD_S : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>,
6677330f729Sjoerg               ADDS_FM<0x00, 16>, ISA_MIPS1;
6687330f729Sjoerg  defm FADD :  ADDS_M<"add.d", II_ADD_D, 1, fadd>, ADDS_FM<0x00, 17>,
6697330f729Sjoerg               ISA_MIPS1;
6707330f729Sjoerg  def FDIV_S : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>,
6717330f729Sjoerg               ADDS_FM<0x03, 16>, ISA_MIPS1;
6727330f729Sjoerg  defm FDIV :  ADDS_M<"div.d", II_DIV_D, 0, fdiv>, ADDS_FM<0x03, 17>,
6737330f729Sjoerg               ISA_MIPS1;
6747330f729Sjoerg  def FMUL_S : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>,
6757330f729Sjoerg               ADDS_FM<0x02, 16>, ISA_MIPS1;
6767330f729Sjoerg  defm FMUL :  ADDS_M<"mul.d", II_MUL_D, 1, fmul>, ADDS_FM<0x02, 17>,
6777330f729Sjoerg               ISA_MIPS1;
6787330f729Sjoerg  def FSUB_S : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>,
6797330f729Sjoerg               ADDS_FM<0x01, 16>, ISA_MIPS1;
6807330f729Sjoerg  defm FSUB :  ADDS_M<"sub.d", II_SUB_D, 0, fsub>, ADDS_FM<0x01, 17>,
6817330f729Sjoerg               ISA_MIPS1;
6827330f729Sjoerg}
6837330f729Sjoerg
6847330f729Sjoerglet AdditionalPredicates = [NotInMicroMips, HasMadd4] in {
6857330f729Sjoerg  def MADD_S : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S, fadd>,
6867330f729Sjoerg               MADDS_FM<4, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6;
6877330f729Sjoerg  def MSUB_S : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S, fsub>,
6887330f729Sjoerg               MADDS_FM<5, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6;
6897330f729Sjoerg
6907330f729Sjoerg  def MADD_D32 : MMRel, MADDS_FT<"madd.d", AFGR64Opnd, II_MADD_D, fadd>,
6917330f729Sjoerg                 MADDS_FM<4, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
6927330f729Sjoerg  def MSUB_D32 : MMRel, MADDS_FT<"msub.d", AFGR64Opnd, II_MSUB_D, fsub>,
6937330f729Sjoerg                 MADDS_FM<5, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
6947330f729Sjoerg
6957330f729Sjoerg  let DecoderNamespace = "MipsFP64" in {
6967330f729Sjoerg    def MADD_D64 : MADDS_FT<"madd.d", FGR64Opnd, II_MADD_D, fadd>,
6977330f729Sjoerg                   MADDS_FM<4, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
6987330f729Sjoerg    def MSUB_D64 : MADDS_FT<"msub.d", FGR64Opnd, II_MSUB_D, fsub>,
6997330f729Sjoerg                   MADDS_FM<5, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
7007330f729Sjoerg  }
7017330f729Sjoerg}
7027330f729Sjoerg
7037330f729Sjoerglet AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips] in {
7047330f729Sjoerg  def NMADD_S : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S, fadd>,
7057330f729Sjoerg                MADDS_FM<6, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6;
7067330f729Sjoerg  def NMSUB_S : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S, fsub>,
7077330f729Sjoerg                MADDS_FM<7, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6;
7087330f729Sjoerg
7097330f729Sjoerg  def NMADD_D32 : MMRel, NMADDS_FT<"nmadd.d", AFGR64Opnd, II_NMADD_D, fadd>,
7107330f729Sjoerg                  MADDS_FM<6, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
7117330f729Sjoerg  def NMSUB_D32 : MMRel, NMADDS_FT<"nmsub.d", AFGR64Opnd, II_NMSUB_D, fsub>,
7127330f729Sjoerg                  MADDS_FM<7, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
7137330f729Sjoerg
7147330f729Sjoerg  let DecoderNamespace = "MipsFP64" in {
7157330f729Sjoerg    def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64Opnd, II_NMADD_D, fadd>,
7167330f729Sjoerg                    MADDS_FM<6, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
7177330f729Sjoerg    def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64Opnd, II_NMSUB_D, fsub>,
7187330f729Sjoerg                    MADDS_FM<7, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
7197330f729Sjoerg  }
7207330f729Sjoerg}
7217330f729Sjoerg//===----------------------------------------------------------------------===//
7227330f729Sjoerg// Floating Point Branch Codes
7237330f729Sjoerg//===----------------------------------------------------------------------===//
7247330f729Sjoerg// Mips branch codes. These correspond to condcode in MipsInstrInfo.h.
7257330f729Sjoerg// They must be kept in synch.
7267330f729Sjoergdef MIPS_BRANCH_F  : PatLeaf<(i32 0)>;
7277330f729Sjoergdef MIPS_BRANCH_T  : PatLeaf<(i32 1)>;
7287330f729Sjoerg
7297330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
7307330f729Sjoerg  def BC1F : MMRel, BC1F_FT<"bc1f", brtarget, II_BC1F, MIPS_BRANCH_F>,
7317330f729Sjoerg             BC1F_FM<0, 0>, ISA_MIPS1_NOT_32R6_64R6;
7327330f729Sjoerg  def BC1FL : MMRel, BC1XL_FT<"bc1fl", brtarget, II_BC1FL>,
7337330f729Sjoerg              BC1F_FM<1, 0>, ISA_MIPS2_NOT_32R6_64R6;
7347330f729Sjoerg  def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, II_BC1T, MIPS_BRANCH_T>,
7357330f729Sjoerg             BC1F_FM<0, 1>, ISA_MIPS1_NOT_32R6_64R6;
7367330f729Sjoerg  def BC1TL : MMRel, BC1XL_FT<"bc1tl", brtarget, II_BC1TL>,
7377330f729Sjoerg              BC1F_FM<1, 1>, ISA_MIPS2_NOT_32R6_64R6;
7387330f729Sjoerg
7397330f729Sjoerg/// Floating Point Compare
7407330f729Sjoerg  def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>,
7417330f729Sjoerg                 ISA_MIPS1_NOT_32R6_64R6 {
7427330f729Sjoerg
7437330f729Sjoerg  // FIXME: This is a required to work around the fact that these instructions
7447330f729Sjoerg  //        only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the
7457330f729Sjoerg  //        fcc register set is used directly.
7467330f729Sjoerg  bits<3> fcc = 0;
7477330f729Sjoerg  }
7487330f729Sjoerg  def FCMP_D32 : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>,
7497330f729Sjoerg                 ISA_MIPS1_NOT_32R6_64R6, FGR_32 {
7507330f729Sjoerg  // FIXME: This is a required to work around the fact that these instructions
7517330f729Sjoerg  //        only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the
7527330f729Sjoerg  //        fcc register set is used directly.
7537330f729Sjoerg  bits<3> fcc = 0;
7547330f729Sjoerg  }
7557330f729Sjoerg}
7567330f729Sjoerglet DecoderNamespace = "MipsFP64" in
7577330f729Sjoergdef FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>,
7587330f729Sjoerg               ISA_MIPS1_NOT_32R6_64R6, FGR_64 {
7597330f729Sjoerg  // FIXME: This is a required to work around the fact that thiese instructions
7607330f729Sjoerg  //        only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the
7617330f729Sjoerg  //        fcc register set is used directly.
7627330f729Sjoerg  bits<3> fcc = 0;
7637330f729Sjoerg}
7647330f729Sjoerg
7657330f729Sjoerg//===----------------------------------------------------------------------===//
7667330f729Sjoerg// Floating Point Pseudo-Instructions
7677330f729Sjoerg//===----------------------------------------------------------------------===//
7687330f729Sjoerg
7697330f729Sjoerg// This pseudo instr gets expanded into 2 mtc1 instrs after register
7707330f729Sjoerg// allocation.
7717330f729Sjoergclass BuildPairF64Base<RegisterOperand RO> :
7727330f729Sjoerg  PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$lo, GPR32Opnd:$hi),
7737330f729Sjoerg           [(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))],
7747330f729Sjoerg           II_MTC1>;
7757330f729Sjoerg
7767330f729Sjoergdef BuildPairF64 : BuildPairF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
7777330f729Sjoergdef BuildPairF64_64 : BuildPairF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
7787330f729Sjoerg
7797330f729Sjoerg// This pseudo instr gets expanded into 2 mfc1 instrs after register
7807330f729Sjoerg// allocation.
7817330f729Sjoerg// if n is 0, lower part of src is extracted.
7827330f729Sjoerg// if n is 1, higher part of src is extracted.
7837330f729Sjoerg// This node has associated scheduling information as the pre RA scheduler
7847330f729Sjoerg// asserts otherwise.
7857330f729Sjoergclass ExtractElementF64Base<RegisterOperand RO> :
7867330f729Sjoerg  PseudoSE<(outs GPR32Opnd:$dst), (ins RO:$src, i32imm:$n),
7877330f729Sjoerg           [(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))],
7887330f729Sjoerg           II_MFC1>;
7897330f729Sjoerg
7907330f729Sjoergdef ExtractElementF64 : ExtractElementF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
7917330f729Sjoergdef ExtractElementF64_64 : ExtractElementF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
7927330f729Sjoerg
7937330f729Sjoergdef PseudoTRUNC_W_S : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
7947330f729Sjoerg                                        (ins FGR32Opnd:$fs, GPR32Opnd:$rs),
7957330f729Sjoerg                                        "trunc.w.s\t$fd, $fs, $rs">;
7967330f729Sjoerg
7977330f729Sjoergdef PseudoTRUNC_W_D32 : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
7987330f729Sjoerg                                          (ins AFGR64Opnd:$fs, GPR32Opnd:$rs),
7997330f729Sjoerg                                          "trunc.w.d\t$fd, $fs, $rs">,
8007330f729Sjoerg                        FGR_32, HARDFLOAT;
8017330f729Sjoerg
8027330f729Sjoergdef PseudoTRUNC_W_D : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
8037330f729Sjoerg                                        (ins FGR64Opnd:$fs, GPR32Opnd:$rs),
8047330f729Sjoerg                                        "trunc.w.d\t$fd, $fs, $rs">,
8057330f729Sjoerg                      FGR_64, HARDFLOAT;
8067330f729Sjoerg
8077330f729Sjoergdef LoadImmSingleGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
8087330f729Sjoerg                                         (ins imm64:$fpimm),
8097330f729Sjoerg                                         "li.s\t$rd, $fpimm">;
8107330f729Sjoerg
8117330f729Sjoergdef LoadImmSingleFGR : MipsAsmPseudoInst<(outs StrictlyFGR32Opnd:$rd),
8127330f729Sjoerg                                         (ins imm64:$fpimm),
8137330f729Sjoerg                                         "li.s\t$rd, $fpimm">,
8147330f729Sjoerg                       HARDFLOAT;
8157330f729Sjoerg
8167330f729Sjoergdef LoadImmDoubleGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
8177330f729Sjoerg                                         (ins imm64:$fpimm),
8187330f729Sjoerg                                         "li.d\t$rd, $fpimm">;
8197330f729Sjoerg
8207330f729Sjoergdef LoadImmDoubleFGR_32 : MipsAsmPseudoInst<(outs StrictlyAFGR64Opnd:$rd),
8217330f729Sjoerg                                            (ins imm64:$fpimm),
8227330f729Sjoerg                                            "li.d\t$rd, $fpimm">,
8237330f729Sjoerg                          FGR_32, HARDFLOAT;
8247330f729Sjoerg
8257330f729Sjoergdef LoadImmDoubleFGR : MipsAsmPseudoInst<(outs StrictlyFGR64Opnd:$rd),
8267330f729Sjoerg                                         (ins imm64:$fpimm),
8277330f729Sjoerg                                         "li.d\t$rd, $fpimm">,
8287330f729Sjoerg                       FGR_64, HARDFLOAT;
8297330f729Sjoerg
8307330f729Sjoergdef SDC1_M1 : MipsAsmPseudoInst<(outs AFGR64Opnd:$fd),
8317330f729Sjoerg                                (ins mem_simm16:$addr),
8327330f729Sjoerg                                "s.d\t$fd, $addr">,
8337330f729Sjoerg              FGR_32, ISA_MIPS1, HARDFLOAT;
8347330f729Sjoerg
8357330f729Sjoerg//===----------------------------------------------------------------------===//
8367330f729Sjoerg// InstAliases.
8377330f729Sjoerg//===----------------------------------------------------------------------===//
8387330f729Sjoergdef : MipsInstAlias
8397330f729Sjoerg        <"s.s $fd, $addr", (SWC1 FGR32Opnd:$fd, mem_simm16:$addr), 0>,
8407330f729Sjoerg      ISA_MIPS2, HARDFLOAT;
8417330f729Sjoergdef : MipsInstAlias
8427330f729Sjoerg        <"s.d $fd, $addr", (SDC1 AFGR64Opnd:$fd, mem_simm16:$addr), 0>,
8437330f729Sjoerg      FGR_32, ISA_MIPS2, HARDFLOAT;
8447330f729Sjoergdef : MipsInstAlias
8457330f729Sjoerg        <"s.d $fd, $addr", (SDC164 FGR64Opnd:$fd, mem_simm16:$addr), 0>,
8467330f729Sjoerg      FGR_64, ISA_MIPS2, HARDFLOAT;
8477330f729Sjoergdef : MipsInstAlias
8487330f729Sjoerg        <"s.d $fd, $addr", (SDC1_M1 AFGR64Opnd:$fd, mem_simm16:$addr), 0>,
8497330f729Sjoerg      FGR_32, ISA_MIPS1, HARDFLOAT;
8507330f729Sjoerg
8517330f729Sjoergdef : MipsInstAlias
8527330f729Sjoerg        <"l.s $fd, $addr", (LWC1 FGR32Opnd:$fd, mem_simm16:$addr), 0>,
8537330f729Sjoerg      ISA_MIPS2, HARDFLOAT;
8547330f729Sjoergdef : MipsInstAlias
8557330f729Sjoerg        <"l.d $fd, $addr", (LDC1 AFGR64Opnd:$fd, mem_simm16:$addr), 0>,
8567330f729Sjoerg      FGR_32, ISA_MIPS2, HARDFLOAT;
8577330f729Sjoergdef : MipsInstAlias
8587330f729Sjoerg        <"l.d $fd, $addr", (LDC164 FGR64Opnd:$fd, mem_simm16:$addr), 0>,
8597330f729Sjoerg      FGR_64, ISA_MIPS2, HARDFLOAT;
8607330f729Sjoerg
8617330f729Sjoergmulticlass C_COND_ALIASES<string TypeStr, RegisterOperand RC> {
8627330f729Sjoerg  def : MipsInstAlias<!strconcat("c.f.", TypeStr, " $fs, $ft"),
8637330f729Sjoerg                      (!cast<Instruction>("C_F_"#NAME) FCC0,
8647330f729Sjoerg                                                       RC:$fs, RC:$ft), 1>;
8657330f729Sjoerg  def : MipsInstAlias<!strconcat("c.un.", TypeStr, " $fs, $ft"),
8667330f729Sjoerg                      (!cast<Instruction>("C_UN_"#NAME) FCC0,
8677330f729Sjoerg                                                        RC:$fs, RC:$ft), 1>;
8687330f729Sjoerg  def : MipsInstAlias<!strconcat("c.eq.", TypeStr, " $fs, $ft"),
8697330f729Sjoerg                      (!cast<Instruction>("C_EQ_"#NAME) FCC0,
8707330f729Sjoerg                                                        RC:$fs, RC:$ft), 1>;
8717330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ueq.", TypeStr, " $fs, $ft"),
8727330f729Sjoerg                      (!cast<Instruction>("C_UEQ_"#NAME) FCC0,
8737330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8747330f729Sjoerg  def : MipsInstAlias<!strconcat("c.olt.", TypeStr, " $fs, $ft"),
8757330f729Sjoerg                      (!cast<Instruction>("C_OLT_"#NAME) FCC0,
8767330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8777330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ult.", TypeStr, " $fs, $ft"),
8787330f729Sjoerg                      (!cast<Instruction>("C_ULT_"#NAME) FCC0,
8797330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8807330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ole.", TypeStr, " $fs, $ft"),
8817330f729Sjoerg                      (!cast<Instruction>("C_OLE_"#NAME) FCC0,
8827330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8837330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ule.", TypeStr, " $fs, $ft"),
8847330f729Sjoerg                      (!cast<Instruction>("C_ULE_"#NAME) FCC0,
8857330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8867330f729Sjoerg  def : MipsInstAlias<!strconcat("c.sf.", TypeStr, " $fs, $ft"),
8877330f729Sjoerg                      (!cast<Instruction>("C_SF_"#NAME) FCC0,
8887330f729Sjoerg                                                        RC:$fs, RC:$ft), 1>;
8897330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ngle.", TypeStr, " $fs, $ft"),
8907330f729Sjoerg                      (!cast<Instruction>("C_NGLE_"#NAME) FCC0,
8917330f729Sjoerg                                                          RC:$fs, RC:$ft), 1>;
8927330f729Sjoerg  def : MipsInstAlias<!strconcat("c.seq.", TypeStr, " $fs, $ft"),
8937330f729Sjoerg                      (!cast<Instruction>("C_SEQ_"#NAME) FCC0,
8947330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8957330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ngl.", TypeStr, " $fs, $ft"),
8967330f729Sjoerg                      (!cast<Instruction>("C_NGL_"#NAME) FCC0,
8977330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
8987330f729Sjoerg  def : MipsInstAlias<!strconcat("c.lt.", TypeStr, " $fs, $ft"),
8997330f729Sjoerg                      (!cast<Instruction>("C_LT_"#NAME) FCC0,
9007330f729Sjoerg                                                        RC:$fs, RC:$ft), 1>;
9017330f729Sjoerg  def : MipsInstAlias<!strconcat("c.nge.", TypeStr, " $fs, $ft"),
9027330f729Sjoerg                      (!cast<Instruction>("C_NGE_"#NAME) FCC0,
9037330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
9047330f729Sjoerg  def : MipsInstAlias<!strconcat("c.le.", TypeStr, " $fs, $ft"),
9057330f729Sjoerg                      (!cast<Instruction>("C_LE_"#NAME) FCC0,
9067330f729Sjoerg                                                        RC:$fs, RC:$ft), 1>;
9077330f729Sjoerg  def : MipsInstAlias<!strconcat("c.ngt.", TypeStr, " $fs, $ft"),
9087330f729Sjoerg                      (!cast<Instruction>("C_NGT_"#NAME) FCC0,
9097330f729Sjoerg                                                         RC:$fs, RC:$ft), 1>;
9107330f729Sjoerg}
9117330f729Sjoerg
9127330f729Sjoergmulticlass BC1_ALIASES<Instruction BCTrue, string BCTrueString,
9137330f729Sjoerg                       Instruction BCFalse, string BCFalseString> {
9147330f729Sjoerg  def : MipsInstAlias<!strconcat(BCTrueString, " $offset"),
9157330f729Sjoerg                                (BCTrue FCC0, brtarget:$offset), 1>;
9167330f729Sjoerg
9177330f729Sjoerg  def : MipsInstAlias<!strconcat(BCFalseString, " $offset"),
9187330f729Sjoerg                                (BCFalse FCC0, brtarget:$offset), 1>;
9197330f729Sjoerg}
9207330f729Sjoerg
9217330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
9227330f729Sjoerg  defm S   : C_COND_ALIASES<"s", FGR32Opnd>, HARDFLOAT,
9237330f729Sjoerg             ISA_MIPS1_NOT_32R6_64R6;
9247330f729Sjoerg  defm D32 : C_COND_ALIASES<"d", AFGR64Opnd>, HARDFLOAT,
9257330f729Sjoerg             ISA_MIPS1_NOT_32R6_64R6, FGR_32;
9267330f729Sjoerg  defm D64 : C_COND_ALIASES<"d", FGR64Opnd>, HARDFLOAT,
9277330f729Sjoerg             ISA_MIPS1_NOT_32R6_64R6, FGR_64;
9287330f729Sjoerg
9297330f729Sjoerg  defm : BC1_ALIASES<BC1T, "bc1t", BC1F, "bc1f">, ISA_MIPS1_NOT_32R6_64R6,
9307330f729Sjoerg         HARDFLOAT;
9317330f729Sjoerg  defm : BC1_ALIASES<BC1TL, "bc1tl", BC1FL, "bc1fl">, ISA_MIPS2_NOT_32R6_64R6,
9327330f729Sjoerg         HARDFLOAT;
9337330f729Sjoerg}
9347330f729Sjoerg//===----------------------------------------------------------------------===//
9357330f729Sjoerg// Floating Point Patterns
9367330f729Sjoerg//===----------------------------------------------------------------------===//
9377330f729Sjoergdef : MipsPat<(f32 fpimm0), (MTC1 ZERO)>, ISA_MIPS1;
9387330f729Sjoergdef : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>, ISA_MIPS1;
9397330f729Sjoerg
9407330f729Sjoergdef : MipsPat<(f32 (sint_to_fp GPR32Opnd:$src)),
9417330f729Sjoerg              (PseudoCVT_S_W GPR32Opnd:$src)>;
9427330f729Sjoergdef : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
9437330f729Sjoerg              (TRUNC_W_S FGR32Opnd:$src)>, ISA_MIPS1;
9447330f729Sjoerg
9457330f729Sjoergdef : MipsPat<(MipsMTC1_D64 GPR32Opnd:$src),
9467330f729Sjoerg              (MTC1_D64 GPR32Opnd:$src)>, ISA_MIPS1, FGR_64;
9477330f729Sjoerg
9487330f729Sjoergdef : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
9497330f729Sjoerg              (PseudoCVT_D32_W GPR32Opnd:$src)>, FGR_32;
9507330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
9517330f729Sjoerg  def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src),
9527330f729Sjoerg                (TRUNC_W_D32 AFGR64Opnd:$src)>, ISA_MIPS2, FGR_32;
9537330f729Sjoerg  def : MipsPat<(f32 (fpround AFGR64Opnd:$src)),
9547330f729Sjoerg                (CVT_S_D32 AFGR64Opnd:$src)>, ISA_MIPS1, FGR_32;
9557330f729Sjoerg  def : MipsPat<(f64 (fpextend FGR32Opnd:$src)),
9567330f729Sjoerg                (CVT_D32_S FGR32Opnd:$src)>, ISA_MIPS1, FGR_32;
9577330f729Sjoerg}
9587330f729Sjoerg
9597330f729Sjoergdef : MipsPat<(f64 fpimm0), (DMTC1 ZERO_64)>, ISA_MIPS3, GPR_64, FGR_64;
9607330f729Sjoergdef : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>, ISA_MIPS3, GPR_64,
9617330f729Sjoerg      FGR_64;
9627330f729Sjoerg
9637330f729Sjoergdef : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
9647330f729Sjoerg              (PseudoCVT_D64_W GPR32Opnd:$src)>, FGR_64;
9657330f729Sjoergdef : MipsPat<(f32 (sint_to_fp GPR64Opnd:$src)),
9667330f729Sjoerg              (EXTRACT_SUBREG (PseudoCVT_S_L GPR64Opnd:$src), sub_lo)>, FGR_64;
9677330f729Sjoergdef : MipsPat<(f64 (sint_to_fp GPR64Opnd:$src)),
9687330f729Sjoerg              (PseudoCVT_D64_L GPR64Opnd:$src)>, FGR_64;
9697330f729Sjoerg
9707330f729Sjoergdef : MipsPat<(MipsTruncIntFP FGR64Opnd:$src),
9717330f729Sjoerg              (TRUNC_W_D64 FGR64Opnd:$src)>, ISA_MIPS2, FGR_64;
9727330f729Sjoergdef : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
9737330f729Sjoerg              (TRUNC_L_S FGR32Opnd:$src)>, ISA_MIPS2, FGR_64;
9747330f729Sjoergdef : MipsPat<(MipsTruncIntFP FGR64Opnd:$src),
9757330f729Sjoerg              (TRUNC_L_D64 FGR64Opnd:$src)>, ISA_MIPS2, FGR_64;
9767330f729Sjoerg
9777330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
9787330f729Sjoerg  def : MipsPat<(f32 (fpround FGR64Opnd:$src)),
9797330f729Sjoerg                (CVT_S_D64 FGR64Opnd:$src)>, ISA_MIPS1, FGR_64;
9807330f729Sjoerg  def : MipsPat<(f64 (fpextend FGR32Opnd:$src)),
9817330f729Sjoerg                (CVT_D64_S FGR32Opnd:$src)>, ISA_MIPS1, FGR_64;
9827330f729Sjoerg}
9837330f729Sjoerg
9847330f729Sjoerg// To generate NMADD and NMSUB instructions when fneg node is present
9857330f729Sjoergmulticlass NMADD_NMSUB<Instruction Nmadd, Instruction Nmsub, RegisterOperand RC> {
9867330f729Sjoerg  def : MipsPat<(fneg (fadd (fmul RC:$fs, RC:$ft), RC:$fr)),
9877330f729Sjoerg                (Nmadd RC:$fr, RC:$fs, RC:$ft)>;
9887330f729Sjoerg  def : MipsPat<(fneg (fsub (fmul RC:$fs, RC:$ft), RC:$fr)),
9897330f729Sjoerg                (Nmsub RC:$fr, RC:$fs, RC:$ft)>;
9907330f729Sjoerg}
9917330f729Sjoerg
9927330f729Sjoerglet AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips] in {
993*82d56013Sjoerg  defm : NMADD_NMSUB<NMADD_S, NMSUB_S, FGR32Opnd>,
994*82d56013Sjoerg         INSN_MIPS4_32R2_NOT_32R6_64R6;
995*82d56013Sjoerg  defm : NMADD_NMSUB<NMADD_D32, NMSUB_D32, AFGR64Opnd>,
996*82d56013Sjoerg         FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6;
997*82d56013Sjoerg  defm : NMADD_NMSUB<NMADD_D64, NMSUB_D64, FGR64Opnd>,
998*82d56013Sjoerg         FGR_64, INSN_MIPS4_32R2_NOT_32R6_64R6;
9997330f729Sjoerg}
10007330f729Sjoerg
10017330f729Sjoerg// Patterns for loads/stores with a reg+imm operand.
10027330f729Sjoerglet AdditionalPredicates = [NotInMicroMips] in {
10037330f729Sjoerg  let AddedComplexity = 40 in {
10047330f729Sjoerg    def : LoadRegImmPat<LWC1, f32, load>, ISA_MIPS1;
10057330f729Sjoerg    def : StoreRegImmPat<SWC1, f32>, ISA_MIPS1;
10067330f729Sjoerg
10077330f729Sjoerg    def : LoadRegImmPat<LDC164, f64, load>, ISA_MIPS1, FGR_64;
10087330f729Sjoerg    def : StoreRegImmPat<SDC164, f64>, ISA_MIPS1, FGR_64;
10097330f729Sjoerg
10107330f729Sjoerg    def : LoadRegImmPat<LDC1, f64, load>, ISA_MIPS1, FGR_32;
10117330f729Sjoerg    def : StoreRegImmPat<SDC1, f64>, ISA_MIPS1, FGR_32;
10127330f729Sjoerg  }
10137330f729Sjoerg}
1014