10b57cec5SDimitry Andric//===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This file contains the Mips implementation of the TargetInstrInfo class.
100b57cec5SDimitry Andric//
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric// Mips profiles and nodes
160b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17647cbc5dSDimitry Andricinclude "MipsInstrCompiler.td"
180b57cec5SDimitry Andric
190b57cec5SDimitry Andricdef SDT_MipsJmpLink      : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
200b57cec5SDimitry Andricdef SDT_MipsCMov         : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
210b57cec5SDimitry Andric                                                SDTCisSameAs<1, 2>,
220b57cec5SDimitry Andric                                                SDTCisSameAs<3, 4>,
230b57cec5SDimitry Andric                                                SDTCisInt<4>]>;
240b57cec5SDimitry Andricdef SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
250b57cec5SDimitry Andricdef SDT_MipsCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
260b57cec5SDimitry Andricdef SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
270b57cec5SDimitry Andricdef SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
280b57cec5SDimitry Andric                                      SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
290b57cec5SDimitry Andricdef SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
300b57cec5SDimitry Andric                                    SDTCisSameAs<1, 2>]>;
310b57cec5SDimitry Andricdef SDT_MipsMAddMSub : SDTypeProfile<1, 3,
320b57cec5SDimitry Andric                                     [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
330b57cec5SDimitry Andric                                      SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
340b57cec5SDimitry Andricdef SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
350b57cec5SDimitry Andric
360b57cec5SDimitry Andricdef SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andricdef SDT_Sync             : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
390b57cec5SDimitry Andric
400b57cec5SDimitry Andricdef SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
410b57cec5SDimitry Andric                                   SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
420b57cec5SDimitry Andricdef SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
430b57cec5SDimitry Andric                                   SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
440b57cec5SDimitry Andric                                   SDTCisSameAs<0, 4>]>;
450b57cec5SDimitry Andric
460b57cec5SDimitry Andricdef SDTMipsLoadLR  : SDTypeProfile<1, 2,
470b57cec5SDimitry Andric                                   [SDTCisInt<0>, SDTCisPtrTy<1>,
480b57cec5SDimitry Andric                                    SDTCisSameAs<0, 2>]>;
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric// Call
510b57cec5SDimitry Andricdef MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
520b57cec5SDimitry Andric                         [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
530b57cec5SDimitry Andric                          SDNPVariadic]>;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric// Tail call
560b57cec5SDimitry Andricdef MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
570b57cec5SDimitry Andric                          [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric// Hi and Lo nodes are used to handle global addresses. Used on
600b57cec5SDimitry Andric// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
610b57cec5SDimitry Andric// static model. (nothing to do with Mips Registers Hi and Lo)
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric// Hi is the odd node out, on MIPS64 it can expand to either daddiu when
640b57cec5SDimitry Andric// using static relocations with 64 bit symbols, or lui when using 32 bit
650b57cec5SDimitry Andric// symbols.
660b57cec5SDimitry Andricdef MipsHigher : SDNode<"MipsISD::Higher", SDTIntUnaryOp>;
670b57cec5SDimitry Andricdef MipsHighest : SDNode<"MipsISD::Highest", SDTIntUnaryOp>;
680b57cec5SDimitry Andricdef MipsHi    : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
690b57cec5SDimitry Andricdef MipsLo    : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
700b57cec5SDimitry Andric
710b57cec5SDimitry Andricdef MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric// Hi node for accessing the GOT.
740b57cec5SDimitry Andricdef MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>;
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric// Hi node for handling TLS offsets
770b57cec5SDimitry Andricdef MipsTlsHi   : SDNode<"MipsISD::TlsHi", SDTIntUnaryOp>;
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric// Thread pointer
800b57cec5SDimitry Andricdef MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric// Return
830b57cec5SDimitry Andricdef MipsRet : SDNode<"MipsISD::Ret", SDTNone,
840b57cec5SDimitry Andric                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
850b57cec5SDimitry Andric
860b57cec5SDimitry Andricdef MipsERet : SDNode<"MipsISD::ERet", SDTNone,
870b57cec5SDimitry Andric                      [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric// These are target-independent nodes, but have target-specific formats.
900b57cec5SDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
910b57cec5SDimitry Andric                           [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
920b57cec5SDimitry Andricdef callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
930b57cec5SDimitry Andric                           [SDNPHasChain, SDNPSideEffect,
940b57cec5SDimitry Andric                            SDNPOptInGlue, SDNPOutGlue]>;
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric// Nodes used to extract LO/HI registers.
970b57cec5SDimitry Andricdef MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
980b57cec5SDimitry Andricdef MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric// Node used to insert 32-bit integers to LOHI register pair.
1010b57cec5SDimitry Andricdef MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric// Mult nodes.
1040b57cec5SDimitry Andricdef MipsMult  : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
1050b57cec5SDimitry Andricdef MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric// MAdd*/MSub* nodes
1080b57cec5SDimitry Andricdef MipsMAdd  : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
1090b57cec5SDimitry Andricdef MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
1100b57cec5SDimitry Andricdef MipsMSub  : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
1110b57cec5SDimitry Andricdef MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric// DivRem(u) nodes
1140b57cec5SDimitry Andricdef MipsDivRem    : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
1150b57cec5SDimitry Andricdef MipsDivRemU   : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
1160b57cec5SDimitry Andricdef MipsDivRem16  : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
1170b57cec5SDimitry Andric                           [SDNPOutGlue]>;
1180b57cec5SDimitry Andricdef MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
1190b57cec5SDimitry Andric                           [SDNPOutGlue]>;
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric// Target constant nodes that are not part of any isel patterns and remain
1220b57cec5SDimitry Andric// unchanged can cause instructions with illegal operands to be emitted.
1230b57cec5SDimitry Andric// Wrapper node patterns give the instruction selector a chance to replace
1240b57cec5SDimitry Andric// target constant nodes that would otherwise remain unchanged with ADDiu
1250b57cec5SDimitry Andric// nodes. Without these wrapper node patterns, the following conditional move
1260b57cec5SDimitry Andric// instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
1270b57cec5SDimitry Andric// compiled:
1280b57cec5SDimitry Andric//  movn  %got(d)($gp), %got(c)($gp), $4
1290b57cec5SDimitry Andric// This instruction is illegal since movn can take only register operands.
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andricdef MipsWrapper    : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andricdef MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
1340b57cec5SDimitry Andric
1350b57cec5SDimitry Andricdef MipsExt :  SDNode<"MipsISD::Ext", SDT_Ext>;
1360b57cec5SDimitry Andricdef MipsIns :  SDNode<"MipsISD::Ins", SDT_Ins>;
1370b57cec5SDimitry Andricdef MipsCIns : SDNode<"MipsISD::CIns", SDT_Ext>;
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andricdef MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
1400b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1410b57cec5SDimitry Andricdef MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
1420b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1430b57cec5SDimitry Andricdef MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
1440b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
1450b57cec5SDimitry Andricdef MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
1460b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
1470b57cec5SDimitry Andricdef MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
1480b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1490b57cec5SDimitry Andricdef MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
1500b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1510b57cec5SDimitry Andricdef MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
1520b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
1530b57cec5SDimitry Andricdef MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
1540b57cec5SDimitry Andric                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1570b57cec5SDimitry Andric// Mips Instruction Predicate Definitions.
1580b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1590b57cec5SDimitry Andricdef HasMips2     :    Predicate<"Subtarget->hasMips2()">,
1605ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips2)>;
1610b57cec5SDimitry Andricdef HasMips3_32  :    Predicate<"Subtarget->hasMips3_32()">,
1625ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips3_32)>;
1630b57cec5SDimitry Andricdef HasMips3_32r2 :   Predicate<"Subtarget->hasMips3_32r2()">,
1645ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips3_32r2)>;
1650b57cec5SDimitry Andricdef HasMips3     :    Predicate<"Subtarget->hasMips3()">,
1665ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips3)>;
1670b57cec5SDimitry Andricdef NotMips3     :    Predicate<"!Subtarget->hasMips3()">,
1685ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips3))>;
1690b57cec5SDimitry Andricdef HasMips4_32  :    Predicate<"Subtarget->hasMips4_32()">,
1705ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips4_32)>;
1710b57cec5SDimitry Andricdef NotMips4_32  :    Predicate<"!Subtarget->hasMips4_32()">,
1725ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips4_32))>;
1730b57cec5SDimitry Andricdef HasMips4_32r2 :   Predicate<"Subtarget->hasMips4_32r2()">,
1745ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips4_32r2)>;
1750b57cec5SDimitry Andricdef HasMips5_32r2 :   Predicate<"Subtarget->hasMips5_32r2()">,
1765ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips5_32r2)>;
1770b57cec5SDimitry Andricdef HasMips32    :    Predicate<"Subtarget->hasMips32()">,
1785ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips32)>;
1790b57cec5SDimitry Andricdef HasMips32r2  :    Predicate<"Subtarget->hasMips32r2()">,
1805ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips32r2)>;
1810b57cec5SDimitry Andricdef HasMips32r5  :    Predicate<"Subtarget->hasMips32r5()">,
1825ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips32r5)>;
1830b57cec5SDimitry Andricdef HasMips32r6  :    Predicate<"Subtarget->hasMips32r6()">,
1845ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips32r6)>;
1850b57cec5SDimitry Andricdef NotMips32r6  :    Predicate<"!Subtarget->hasMips32r6()">,
1865ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips32r6))>;
1870b57cec5SDimitry Andricdef IsGP64bit    :    Predicate<"Subtarget->isGP64bit()">,
1885ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureGP64Bit)>;
1890b57cec5SDimitry Andricdef IsGP32bit    :    Predicate<"!Subtarget->isGP64bit()">,
1905ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureGP64Bit))>;
1910b57cec5SDimitry Andricdef IsPTR64bit    :   Predicate<"Subtarget->isABI_N64()">,
1925ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeaturePTR64Bit)>;
1930b57cec5SDimitry Andricdef IsPTR32bit    :   Predicate<"!Subtarget->isABI_N64()">,
1945ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeaturePTR64Bit))>;
1950b57cec5SDimitry Andricdef HasMips64    :    Predicate<"Subtarget->hasMips64()">,
1965ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips64)>;
1970b57cec5SDimitry Andricdef NotMips64    :    Predicate<"!Subtarget->hasMips64()">,
1985ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips64))>;
1990b57cec5SDimitry Andricdef HasMips64r2  :    Predicate<"Subtarget->hasMips64r2()">,
2005ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips64r2)>;
2010b57cec5SDimitry Andricdef HasMips64r5  :    Predicate<"Subtarget->hasMips64r5()">,
2025ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips64r5)>;
2030b57cec5SDimitry Andricdef HasMips64r6  :    Predicate<"Subtarget->hasMips64r6()">,
2045ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips64r6)>;
2050b57cec5SDimitry Andricdef NotMips64r6  :    Predicate<"!Subtarget->hasMips64r6()">,
2065ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips64r6))>;
2070b57cec5SDimitry Andricdef InMips16Mode :    Predicate<"Subtarget->inMips16Mode()">,
2085ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMips16)>;
2090b57cec5SDimitry Andricdef NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
2105ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips16))>;
2110b57cec5SDimitry Andricdef HasCnMips    :    Predicate<"Subtarget->hasCnMips()">,
2125ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureCnMips)>;
2130b57cec5SDimitry Andricdef NotCnMips    :    Predicate<"!Subtarget->hasCnMips()">,
2145ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureCnMips))>;
2150b57cec5SDimitry Andricdef HasCnMipsP   :    Predicate<"Subtarget->hasCnMipsP()">,
2165ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureCnMipsP)>;
2170b57cec5SDimitry Andricdef NotCnMipsP   :    Predicate<"!Subtarget->hasCnMipsP()">,
2185ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureCnMipsP))>;
219f10421e9SDimitry Andricdef IsSym32     :     Predicate<"Subtarget->hasSym32()">,
2205ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureSym32)>;
221f10421e9SDimitry Andricdef IsSym64     :     Predicate<"!Subtarget->hasSym32()">,
2225ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureSym32))>;
2230b57cec5SDimitry Andricdef IsN64       :     Predicate<"Subtarget->isABI_N64()">;
2240b57cec5SDimitry Andricdef IsNotN64    :     Predicate<"!Subtarget->isABI_N64()">;
2250b57cec5SDimitry Andricdef RelocNotPIC :     Predicate<"!TM.isPositionIndependent()">;
2260b57cec5SDimitry Andricdef RelocPIC    :     Predicate<"TM.isPositionIndependent()">;
2270b57cec5SDimitry Andricdef NoNaNsFPMath :    Predicate<"TM.Options.NoNaNsFPMath">;
2280b57cec5SDimitry Andricdef UseAbs :          Predicate<"Subtarget->inAbs2008Mode() ||"
2290b57cec5SDimitry Andric                                "TM.Options.NoNaNsFPMath">;
2300b57cec5SDimitry Andricdef HasStdEnc :       Predicate<"Subtarget->hasStandardEncoding()">,
2315ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMips16))>;
2320b57cec5SDimitry Andricdef NotDSP :          Predicate<"!Subtarget->hasDSP()">;
2330b57cec5SDimitry Andricdef InMicroMips    :  Predicate<"Subtarget->inMicroMipsMode()">,
2345ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureMicroMips)>;
2350b57cec5SDimitry Andricdef NotInMicroMips :  Predicate<"!Subtarget->inMicroMipsMode()">,
2365ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of (not FeatureMicroMips))>;
2370b57cec5SDimitry Andricdef IsLE           :  Predicate<"Subtarget->isLittle()">;
2380b57cec5SDimitry Andricdef IsBE           :  Predicate<"!Subtarget->isLittle()">;
2390b57cec5SDimitry Andricdef IsNotNaCl    :    Predicate<"!Subtarget->isTargetNaCl()">;
2405ffd83dbSDimitry Andricdef UseTCCInDIV    :  AssemblerPredicate<(all_of FeatureUseTCCInDIV)>;
2410b57cec5SDimitry Andricdef HasEVA       :    Predicate<"Subtarget->hasEVA()">,
2425ffd83dbSDimitry Andric                      AssemblerPredicate<(all_of FeatureEVA)>;
2430b57cec5SDimitry Andricdef HasMSA : Predicate<"Subtarget->hasMSA()">,
2445ffd83dbSDimitry Andric             AssemblerPredicate<(all_of FeatureMSA)>;
2450b57cec5SDimitry Andricdef HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
246e8d8bef9SDimitry Andric               AssemblerPredicate<(all_of (not FeatureNoMadd4))>;
2470b57cec5SDimitry Andricdef HasMT  : Predicate<"Subtarget->hasMT()">,
2485ffd83dbSDimitry Andric             AssemblerPredicate<(all_of FeatureMT)>;
2490b57cec5SDimitry Andricdef UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
2505ffd83dbSDimitry Andric                            AssemblerPredicate<(all_of FeatureUseIndirectJumpsHazard)>;
2510b57cec5SDimitry Andricdef NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
2525ffd83dbSDimitry Andric                           AssemblerPredicate<(all_of (not FeatureUseIndirectJumpsHazard))>;
2530b57cec5SDimitry Andricdef HasCRC   : Predicate<"Subtarget->hasCRC()">,
2545ffd83dbSDimitry Andric               AssemblerPredicate<(all_of FeatureCRC)>;
2550b57cec5SDimitry Andricdef HasVirt  : Predicate<"Subtarget->hasVirt()">,
2565ffd83dbSDimitry Andric               AssemblerPredicate<(all_of FeatureVirt)>;
2570b57cec5SDimitry Andricdef HasGINV  : Predicate<"Subtarget->hasGINV()">,
2585ffd83dbSDimitry Andric               AssemblerPredicate<(all_of FeatureGINV)>;
2590b57cec5SDimitry Andric// TODO: Add support for FPOpFusion::Standard
2600b57cec5SDimitry Andricdef AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
2610b57cec5SDimitry Andric                                " FPOpFusion::Fast">;
2620b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2630b57cec5SDimitry Andric// Mips GPR size adjectives.
2640b57cec5SDimitry Andric// They are mutually exclusive.
2650b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andricclass GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
2680b57cec5SDimitry Andricclass GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andricclass PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
2710b57cec5SDimitry Andricclass PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2740b57cec5SDimitry Andric// Mips Symbol size adjectives.
2750b57cec5SDimitry Andric// They are mutally exculsive.
2760b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andricclass SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
2790b57cec5SDimitry Andricclass SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2820b57cec5SDimitry Andric// Mips ISA/ASE membership and instruction group membership adjectives.
2830b57cec5SDimitry Andric// They are mutually exclusive.
2840b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric// FIXME: I'd prefer to use additive predicates to build the instruction sets
2870b57cec5SDimitry Andric//        but we are short on assembler feature bits at the moment. Using a
2880b57cec5SDimitry Andric//        subtractive predicate will hopefully keep us under the 32 predicate
2890b57cec5SDimitry Andric//        limit long enough to develop an alternative way to handle P1||P2
2900b57cec5SDimitry Andric//        predicates.
2910b57cec5SDimitry Andricclass ISA_MIPS1 {
2920b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
2930b57cec5SDimitry Andric}
2940b57cec5SDimitry Andricclass ISA_MIPS1_NOT_MIPS3 {
2950b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [NotMips3];
2960b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
2970b57cec5SDimitry Andric}
2980b57cec5SDimitry Andricclass ISA_MIPS1_NOT_4_32 {
2990b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [NotMips4_32];
3000b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3010b57cec5SDimitry Andric}
3020b57cec5SDimitry Andricclass ISA_MIPS1_NOT_32R6_64R6 {
3030b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
3040b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3050b57cec5SDimitry Andric}
3060b57cec5SDimitry Andricclass ISA_MIPS2 {
3070b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips2];
3080b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3090b57cec5SDimitry Andric}
3100b57cec5SDimitry Andricclass ISA_MIPS2_NOT_32R6_64R6 {
3110b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
3120b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3130b57cec5SDimitry Andric}
3140b57cec5SDimitry Andricclass ISA_MIPS3 {
3150b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips3];
3160b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3170b57cec5SDimitry Andric}
3180b57cec5SDimitry Andricclass ISA_MIPS3_NOT_32R6_64R6 {
3190b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
3200b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3210b57cec5SDimitry Andric}
3220b57cec5SDimitry Andricclass ISA_MIPS32 {
3230b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32];
3240b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3250b57cec5SDimitry Andric}
3260b57cec5SDimitry Andricclass ISA_MIPS32_NOT_32R6_64R6 {
3270b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
3280b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3290b57cec5SDimitry Andric}
3300b57cec5SDimitry Andricclass ISA_MIPS32R2 {
3310b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32r2];
3320b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3330b57cec5SDimitry Andric}
3340b57cec5SDimitry Andricclass ISA_MIPS32R2_NOT_32R6_64R6 {
3350b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
3360b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3370b57cec5SDimitry Andric}
3380b57cec5SDimitry Andricclass ISA_MIPS32R5 {
3390b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32r5];
3400b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3410b57cec5SDimitry Andric}
3420b57cec5SDimitry Andricclass ISA_MIPS64 {
3430b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips64];
3440b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3450b57cec5SDimitry Andric}
3460b57cec5SDimitry Andricclass ISA_MIPS64_NOT_64R6 {
3470b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
3480b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3490b57cec5SDimitry Andric}
3500b57cec5SDimitry Andricclass ISA_MIPS64R2 {
3510b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips64r2];
3520b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3530b57cec5SDimitry Andric}
3540b57cec5SDimitry Andricclass ISA_MIPS64R5 {
3550b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips64r5];
3560b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3570b57cec5SDimitry Andric}
3580b57cec5SDimitry Andricclass ISA_MIPS32R6 {
3590b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32r6];
3600b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3610b57cec5SDimitry Andric}
3620b57cec5SDimitry Andricclass ISA_MIPS64R6 {
3630b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips64r6];
3640b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3650b57cec5SDimitry Andric}
3660b57cec5SDimitry Andricclass ISA_MICROMIPS {
3670b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [InMicroMips];
3680b57cec5SDimitry Andric}
3690b57cec5SDimitry Andricclass ISA_MICROMIPS32R5 {
3700b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32r5];
3710b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [InMicroMips];
3720b57cec5SDimitry Andric}
3730b57cec5SDimitry Andricclass ISA_MICROMIPS32R6 {
3740b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips32r6];
3750b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [InMicroMips];
3760b57cec5SDimitry Andric}
3770b57cec5SDimitry Andricclass ISA_MICROMIPS64R6 {
3780b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips64r6];
3790b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [InMicroMips];
3800b57cec5SDimitry Andric}
3810b57cec5SDimitry Andricclass ISA_MICROMIPS32_NOT_MIPS32R6 {
3820b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [NotMips32r6];
3830b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [InMicroMips];
3840b57cec5SDimitry Andric}
3850b57cec5SDimitry Andricclass ASE_EVA { list<Predicate> ASEPredicate = [HasEVA]; }
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric// The portions of MIPS-III that were also added to MIPS32
3880b57cec5SDimitry Andricclass INSN_MIPS3_32 {
3890b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips3_32];
3900b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3910b57cec5SDimitry Andric}
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric// The portions of MIPS-III that were also added to MIPS32 but were removed in
3940b57cec5SDimitry Andric// MIPS32r6 and MIPS64r6.
3950b57cec5SDimitry Andricclass INSN_MIPS3_32_NOT_32R6_64R6 {
3960b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
3970b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
3980b57cec5SDimitry Andric}
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric// The portions of MIPS-III that were also added to MIPS32
4010b57cec5SDimitry Andricclass INSN_MIPS3_32R2 {
4020b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips3_32r2];
4030b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
4040b57cec5SDimitry Andric}
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric// The portions of MIPS-IV that were also added to MIPS32.
4070b57cec5SDimitry Andricclass INSN_MIPS4_32 {
4080b57cec5SDimitry Andric  list <Predicate> InsnPredicates = [HasMips4_32];
4090b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
4100b57cec5SDimitry Andric}
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andric// The portions of MIPS-IV that were also added to MIPS32 but were removed in
4130b57cec5SDimitry Andric// MIPS32r6 and MIPS64r6.
4140b57cec5SDimitry Andricclass INSN_MIPS4_32_NOT_32R6_64R6 {
4150b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
4160b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
4170b57cec5SDimitry Andric}
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andric// The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
4200b57cec5SDimitry Andric// MIPS32r6 and MIPS64r6.
4210b57cec5SDimitry Andricclass INSN_MIPS4_32R2_NOT_32R6_64R6 {
4220b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
4230b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
4240b57cec5SDimitry Andric}
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric// The portions of MIPS-IV that were also added to MIPS32r2.
4270b57cec5SDimitry Andricclass INSN_MIPS4_32R2 {
4280b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips4_32r2];
4290b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
4300b57cec5SDimitry Andric}
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric// The portions of MIPS-V that were also added to MIPS32r2 but were removed in
4330b57cec5SDimitry Andric// MIPS32r6 and MIPS64r6.
4340b57cec5SDimitry Andricclass INSN_MIPS5_32R2_NOT_32R6_64R6 {
4350b57cec5SDimitry Andric  list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
4360b57cec5SDimitry Andric  list<Predicate> EncodingPredicates = [HasStdEnc];
4370b57cec5SDimitry Andric}
4380b57cec5SDimitry Andric
4390b57cec5SDimitry Andricclass ASE_CNMIPS {
4400b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [HasCnMips];
4410b57cec5SDimitry Andric}
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andricclass NOT_ASE_CNMIPS {
4440b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [NotCnMips];
4450b57cec5SDimitry Andric}
4460b57cec5SDimitry Andric
4470b57cec5SDimitry Andricclass ASE_CNMIPSP {
4480b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [HasCnMipsP];
4490b57cec5SDimitry Andric}
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andricclass NOT_ASE_CNMIPSP {
4520b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [NotCnMipsP];
4530b57cec5SDimitry Andric}
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andricclass ASE_MIPS64_CNMIPS {
4560b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [HasMips64, HasCnMips];
4570b57cec5SDimitry Andric}
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andricclass ASE_MSA {
4600b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [HasMSA];
4610b57cec5SDimitry Andric}
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andricclass ASE_MSA_NOT_MSA64 {
4640b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [HasMSA, NotMips64];
4650b57cec5SDimitry Andric}
4660b57cec5SDimitry Andric
4670b57cec5SDimitry Andricclass ASE_MSA64 {
4680b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [HasMSA, HasMips64];
4690b57cec5SDimitry Andric}
4700b57cec5SDimitry Andric
4710b57cec5SDimitry Andricclass ASE_MT {
4720b57cec5SDimitry Andric  list <Predicate> ASEPredicate = [HasMT];
4730b57cec5SDimitry Andric}
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andricclass ASE_CRC {
4760b57cec5SDimitry Andric  list <Predicate> ASEPredicate = [HasCRC];
4770b57cec5SDimitry Andric}
4780b57cec5SDimitry Andric
4790b57cec5SDimitry Andricclass ASE_VIRT {
4800b57cec5SDimitry Andric  list <Predicate> ASEPredicate = [HasVirt];
4810b57cec5SDimitry Andric}
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andricclass ASE_GINV {
4840b57cec5SDimitry Andric  list <Predicate> ASEPredicate = [HasGINV];
4850b57cec5SDimitry Andric}
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
4880b57cec5SDimitry Andric// It can be used only on instructions that doesn't inherit PredicateControl.
4890b57cec5SDimitry Andricclass ISA_MICROMIPS_NOT_32R6 : PredicateControl {
4900b57cec5SDimitry Andric  let InsnPredicates = [NotMips32r6];
4910b57cec5SDimitry Andric  let EncodingPredicates = [InMicroMips];
4920b57cec5SDimitry Andric}
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andricclass ASE_NOT_DSP {
4950b57cec5SDimitry Andric  list<Predicate> ASEPredicate = [NotDSP];
4960b57cec5SDimitry Andric}
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andricclass MADD4 {
4990b57cec5SDimitry Andric  list<Predicate> AdditionalPredicates = [HasMadd4];
5000b57cec5SDimitry Andric}
5010b57cec5SDimitry Andric
5025ffd83dbSDimitry Andric// Classes used for separating expansions that differ based on the ABI in
5030b57cec5SDimitry Andric// use.
5040b57cec5SDimitry Andricclass ABI_N64 {
5050b57cec5SDimitry Andric  list<Predicate> AdditionalPredicates = [IsN64];
5060b57cec5SDimitry Andric}
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andricclass ABI_NOT_N64 {
5090b57cec5SDimitry Andric  list<Predicate> AdditionalPredicates = [IsNotN64];
5100b57cec5SDimitry Andric}
5110b57cec5SDimitry Andric
5120b57cec5SDimitry Andricclass FPOP_FUSION_FAST {
5130b57cec5SDimitry Andric  list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
5140b57cec5SDimitry Andric}
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andricclass MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl;
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andricclass MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
5210b57cec5SDimitry Andric  InstAlias<Asm, Result, Emit>, PredicateControl;
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andricclass IsCommutable {
5240b57cec5SDimitry Andric  bit isCommutable = 1;
5250b57cec5SDimitry Andric}
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andricclass IsBranch {
5280b57cec5SDimitry Andric  bit isBranch = 1;
5290b57cec5SDimitry Andric  bit isCTI = 1;
5300b57cec5SDimitry Andric}
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andricclass IsReturn {
5330b57cec5SDimitry Andric  bit isReturn = 1;
5340b57cec5SDimitry Andric  bit isCTI = 1;
5350b57cec5SDimitry Andric}
5360b57cec5SDimitry Andric
5370b57cec5SDimitry Andricclass IsCall {
5380b57cec5SDimitry Andric  bit isCall = 1;
5390b57cec5SDimitry Andric  bit isCTI = 1;
5400b57cec5SDimitry Andric}
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andricclass IsTailCall {
5430b57cec5SDimitry Andric  bit isCall = 1;
5440b57cec5SDimitry Andric  bit isTerminator = 1;
5450b57cec5SDimitry Andric  bit isReturn = 1;
5460b57cec5SDimitry Andric  bit isBarrier = 1;
5470b57cec5SDimitry Andric  bit hasExtraSrcRegAllocReq = 1;
5480b57cec5SDimitry Andric  bit isCodeGenOnly = 1;
5490b57cec5SDimitry Andric  bit isCTI = 1;
5500b57cec5SDimitry Andric}
5510b57cec5SDimitry Andric
5520b57cec5SDimitry Andricclass IsAsCheapAsAMove {
5530b57cec5SDimitry Andric  bit isAsCheapAsAMove = 1;
5540b57cec5SDimitry Andric}
5550b57cec5SDimitry Andric
5560b57cec5SDimitry Andricclass NeverHasSideEffects {
5570b57cec5SDimitry Andric  bit hasSideEffects = 0;
5580b57cec5SDimitry Andric}
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5610b57cec5SDimitry Andric// Instruction format superclass
5620b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5630b57cec5SDimitry Andric
5640b57cec5SDimitry Andricinclude "MipsInstrFormats.td"
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5670b57cec5SDimitry Andric// Mips Operand, Complex Patterns and Transformations Definitions.
5680b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andricclass ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
5710b57cec5SDimitry Andric                                  int Offset = 0> : AsmOperandClass {
5720b57cec5SDimitry Andric  let Name = "ConstantSImm" # Bits # "_" # Offset;
5730b57cec5SDimitry Andric  let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
5740b57cec5SDimitry Andric  let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
5750b57cec5SDimitry Andric  let SuperClasses = Supers;
5760b57cec5SDimitry Andric  let DiagnosticType = "SImm" # Bits # "_" # Offset;
5770b57cec5SDimitry Andric}
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andricclass SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
5800b57cec5SDimitry Andric                                  int Shift = 0> : AsmOperandClass {
5810b57cec5SDimitry Andric  let Name = "Simm" # Bits # "_Lsl" # Shift;
5820b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
5830b57cec5SDimitry Andric  let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
5840b57cec5SDimitry Andric  let SuperClasses = Supers;
5850b57cec5SDimitry Andric  let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
5860b57cec5SDimitry Andric}
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andricclass ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
5890b57cec5SDimitry Andric                                  int Offset = 0> : AsmOperandClass {
5900b57cec5SDimitry Andric  let Name = "ConstantUImm" # Bits # "_" # Offset;
5910b57cec5SDimitry Andric  let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
5920b57cec5SDimitry Andric  let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
5930b57cec5SDimitry Andric  let SuperClasses = Supers;
5940b57cec5SDimitry Andric  let DiagnosticType = "UImm" # Bits # "_" # Offset;
5950b57cec5SDimitry Andric}
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andricclass ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
5980b57cec5SDimitry Andric                                       list<AsmOperandClass> Supers = []>
5990b57cec5SDimitry Andric    : AsmOperandClass {
6000b57cec5SDimitry Andric  let Name = "ConstantUImmRange" # Bottom # "_" # Top;
6010b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
6020b57cec5SDimitry Andric  let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
6030b57cec5SDimitry Andric  let SuperClasses = Supers;
6040b57cec5SDimitry Andric  let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
6050b57cec5SDimitry Andric}
6060b57cec5SDimitry Andric
6070b57cec5SDimitry Andricclass SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
6080b57cec5SDimitry Andric    : AsmOperandClass {
6090b57cec5SDimitry Andric  let Name = "SImm" # Bits;
6100b57cec5SDimitry Andric  let RenderMethod = "addSImmOperands<" # Bits # ">";
6110b57cec5SDimitry Andric  let PredicateMethod = "isSImm<" # Bits # ">";
6120b57cec5SDimitry Andric  let SuperClasses = Supers;
6130b57cec5SDimitry Andric  let DiagnosticType = "SImm" # Bits;
6140b57cec5SDimitry Andric}
6150b57cec5SDimitry Andric
6160b57cec5SDimitry Andricclass UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
6170b57cec5SDimitry Andric    : AsmOperandClass {
6180b57cec5SDimitry Andric  let Name = "UImm" # Bits;
6190b57cec5SDimitry Andric  let RenderMethod = "addUImmOperands<" # Bits # ">";
6200b57cec5SDimitry Andric  let PredicateMethod = "isUImm<" # Bits # ">";
6210b57cec5SDimitry Andric  let SuperClasses = Supers;
6220b57cec5SDimitry Andric  let DiagnosticType = "UImm" # Bits;
6230b57cec5SDimitry Andric}
6240b57cec5SDimitry Andric
6250b57cec5SDimitry Andric// Generic case - only to support certain assembly pseudo instructions.
6260b57cec5SDimitry Andricclass UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
6270b57cec5SDimitry Andric    : AsmOperandClass {
6280b57cec5SDimitry Andric  let Name = "ImmAny";
6290b57cec5SDimitry Andric  let RenderMethod = "addConstantUImmOperands<32>";
6300b57cec5SDimitry Andric  let PredicateMethod = "isSImm<" # Bits # ">";
6310b57cec5SDimitry Andric  let SuperClasses = Supers;
6320b57cec5SDimitry Andric  let DiagnosticType = "ImmAny";
6330b57cec5SDimitry Andric}
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andric// AsmOperandClasses require a strict ordering which is difficult to manage
6360b57cec5SDimitry Andric// as a hierarchy. Instead, we use a linear ordering and impose an order that
6370b57cec5SDimitry Andric// is in some places arbitrary.
6380b57cec5SDimitry Andric//
6390b57cec5SDimitry Andric// Here the rules that are in use:
6400b57cec5SDimitry Andric// * Wider immediates are a superset of narrower immediates:
6410b57cec5SDimitry Andric//     uimm4 < uimm5 < uimm6
6420b57cec5SDimitry Andric// * For the same bit-width, unsigned immediates are a superset of signed
6430b57cec5SDimitry Andric//   immediates::
6440b57cec5SDimitry Andric//     simm4 < uimm4 < simm5 < uimm5
6450b57cec5SDimitry Andric// * For the same upper-bound, signed immediates are a superset of unsigned
6460b57cec5SDimitry Andric//   immediates:
6470b57cec5SDimitry Andric//     uimm3 < simm4 < uimm4 < simm4
6480b57cec5SDimitry Andric// * Modified immediates are a superset of ordinary immediates:
6490b57cec5SDimitry Andric//     uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
6500b57cec5SDimitry Andric//   The term 'superset' starts to break down here since the uimm5_plus* classes
6510b57cec5SDimitry Andric//   are not true supersets of uimm5 (but they are still subsets of uimm6).
6520b57cec5SDimitry Andric// * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
6530b57cec5SDimitry Andric//     uimm16 < uimm16_relaxed
6540b57cec5SDimitry Andric// * The codeGen pattern type is arbitrarily ordered.
6550b57cec5SDimitry Andric//     uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
6560b57cec5SDimitry Andric//   This is entirely arbitrary. We need an ordering and what we pick is
6570b57cec5SDimitry Andric//   unimportant since only one is possible for a given mnemonic.
6580b57cec5SDimitry Andric
6590b57cec5SDimitry Andricdef UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
6600b57cec5SDimitry Andric  let Name = "UImm32_Coerced";
6610b57cec5SDimitry Andric  let DiagnosticType = "UImm32_Coerced";
6620b57cec5SDimitry Andric}
6630b57cec5SDimitry Andricdef SImm32RelaxedAsmOperandClass
6640b57cec5SDimitry Andric    : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
6650b57cec5SDimitry Andric  let Name = "SImm32_Relaxed";
6660b57cec5SDimitry Andric  let PredicateMethod = "isAnyImm<33>";
6670b57cec5SDimitry Andric  let DiagnosticType = "SImm32_Relaxed";
6680b57cec5SDimitry Andric}
6690b57cec5SDimitry Andricdef SImm32AsmOperandClass
6700b57cec5SDimitry Andric    : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
6710b57cec5SDimitry Andricdef ConstantUImm26AsmOperandClass
6720b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
6730b57cec5SDimitry Andricdef ConstantUImm20AsmOperandClass
6740b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
6750b57cec5SDimitry Andricdef ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
6760b57cec5SDimitry Andric  let Name = "SImm19Lsl2";
6770b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
6780b57cec5SDimitry Andric  let PredicateMethod = "isScaledSImm<19, 2>";
6790b57cec5SDimitry Andric  let SuperClasses = [ConstantUImm20AsmOperandClass];
6800b57cec5SDimitry Andric  let DiagnosticType = "SImm19_Lsl2";
6810b57cec5SDimitry Andric}
6820b57cec5SDimitry Andricdef UImm16RelaxedAsmOperandClass
6830b57cec5SDimitry Andric    : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
6840b57cec5SDimitry Andric  let Name = "UImm16_Relaxed";
6850b57cec5SDimitry Andric  let PredicateMethod = "isAnyImm<16>";
6860b57cec5SDimitry Andric  let DiagnosticType = "UImm16_Relaxed";
6870b57cec5SDimitry Andric}
6880b57cec5SDimitry Andric// Similar to the relaxed classes which take an SImm and render it as
6890b57cec5SDimitry Andric// an UImm, this takes a UImm and renders it as an SImm.
6900b57cec5SDimitry Andricdef UImm16AltRelaxedAsmOperandClass
6910b57cec5SDimitry Andric    : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
6920b57cec5SDimitry Andric  let Name = "UImm16_AltRelaxed";
6930b57cec5SDimitry Andric  let PredicateMethod = "isUImm<16>";
6940b57cec5SDimitry Andric  let DiagnosticType = "UImm16_AltRelaxed";
6950b57cec5SDimitry Andric}
6960b57cec5SDimitry Andric// FIXME: One of these should probably have UImm16AsmOperandClass as the
6970b57cec5SDimitry Andric//        superclass instead of UImm16RelaxedasmOPerandClass.
6980b57cec5SDimitry Andricdef UImm16AsmOperandClass
6990b57cec5SDimitry Andric    : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
7000b57cec5SDimitry Andricdef SImm16RelaxedAsmOperandClass
7010b57cec5SDimitry Andric    : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
7020b57cec5SDimitry Andric  let Name = "SImm16_Relaxed";
7030b57cec5SDimitry Andric  let PredicateMethod = "isAnyImm<16>";
7040b57cec5SDimitry Andric  let DiagnosticType = "SImm16_Relaxed";
7050b57cec5SDimitry Andric}
7060b57cec5SDimitry Andricdef SImm16AsmOperandClass
7070b57cec5SDimitry Andric    : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
7080b57cec5SDimitry Andricdef ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
7090b57cec5SDimitry Andric  let Name = "SImm10Lsl3";
7100b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
7110b57cec5SDimitry Andric  let PredicateMethod = "isScaledSImm<10, 3>";
7120b57cec5SDimitry Andric  let SuperClasses = [SImm16AsmOperandClass];
7130b57cec5SDimitry Andric  let DiagnosticType = "SImm10_Lsl3";
7140b57cec5SDimitry Andric}
7150b57cec5SDimitry Andricdef ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
7160b57cec5SDimitry Andric  let Name = "SImm10Lsl2";
7170b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
7180b57cec5SDimitry Andric  let PredicateMethod = "isScaledSImm<10, 2>";
7190b57cec5SDimitry Andric  let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
7200b57cec5SDimitry Andric  let DiagnosticType = "SImm10_Lsl2";
7210b57cec5SDimitry Andric}
7220b57cec5SDimitry Andricdef ConstantSImm11AsmOperandClass
7230b57cec5SDimitry Andric    : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
7240b57cec5SDimitry Andricdef ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
7250b57cec5SDimitry Andric  let Name = "SImm10Lsl1";
7260b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
7270b57cec5SDimitry Andric  let PredicateMethod = "isScaledSImm<10, 1>";
7280b57cec5SDimitry Andric  let SuperClasses = [ConstantSImm11AsmOperandClass];
7290b57cec5SDimitry Andric  let DiagnosticType = "SImm10_Lsl1";
7300b57cec5SDimitry Andric}
7310b57cec5SDimitry Andricdef ConstantUImm10AsmOperandClass
7320b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
7330b57cec5SDimitry Andricdef ConstantSImm10AsmOperandClass
7340b57cec5SDimitry Andric    : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
7350b57cec5SDimitry Andricdef ConstantSImm9AsmOperandClass
7360b57cec5SDimitry Andric    : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
7370b57cec5SDimitry Andricdef ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
7380b57cec5SDimitry Andric  let Name = "SImm7Lsl2";
7390b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
7400b57cec5SDimitry Andric  let PredicateMethod = "isScaledSImm<7, 2>";
7410b57cec5SDimitry Andric  let SuperClasses = [ConstantSImm9AsmOperandClass];
7420b57cec5SDimitry Andric  let DiagnosticType = "SImm7_Lsl2";
7430b57cec5SDimitry Andric}
7440b57cec5SDimitry Andricdef ConstantUImm8AsmOperandClass
7450b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
7460b57cec5SDimitry Andricdef ConstantUImm7Sub1AsmOperandClass
7470b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
7480b57cec5SDimitry Andric  // Specify the names since the -1 offset causes invalid identifiers otherwise.
7490b57cec5SDimitry Andric  let Name = "UImm7_N1";
7500b57cec5SDimitry Andric  let DiagnosticType = "UImm7_N1";
7510b57cec5SDimitry Andric}
7520b57cec5SDimitry Andricdef ConstantUImm7AsmOperandClass
7530b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
7540b57cec5SDimitry Andricdef ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
7550b57cec5SDimitry Andric  let Name = "UImm6Lsl2";
7560b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
7570b57cec5SDimitry Andric  let PredicateMethod = "isScaledUImm<6, 2>";
7580b57cec5SDimitry Andric  let SuperClasses = [ConstantUImm7AsmOperandClass];
7590b57cec5SDimitry Andric  let DiagnosticType = "UImm6_Lsl2";
7600b57cec5SDimitry Andric}
7610b57cec5SDimitry Andricdef ConstantUImm6AsmOperandClass
7620b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
7630b57cec5SDimitry Andricdef ConstantSImm6AsmOperandClass
7640b57cec5SDimitry Andric    : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
7650b57cec5SDimitry Andricdef ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
7660b57cec5SDimitry Andric  let Name = "UImm5Lsl2";
7670b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
7680b57cec5SDimitry Andric  let PredicateMethod = "isScaledUImm<5, 2>";
7690b57cec5SDimitry Andric  let SuperClasses = [ConstantSImm6AsmOperandClass];
7700b57cec5SDimitry Andric  let DiagnosticType = "UImm5_Lsl2";
7710b57cec5SDimitry Andric}
7720b57cec5SDimitry Andricdef ConstantUImm5_Range2_64AsmOperandClass
7730b57cec5SDimitry Andric    : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
7740b57cec5SDimitry Andricdef ConstantUImm5Plus33AsmOperandClass
7750b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
7760b57cec5SDimitry Andric                                  33>;
7770b57cec5SDimitry Andricdef ConstantUImm5ReportUImm6AsmOperandClass
7780b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
7790b57cec5SDimitry Andric  let Name = "ConstantUImm5_0_Report_UImm6";
7800b57cec5SDimitry Andric  let DiagnosticType = "UImm5_0_Report_UImm6";
7810b57cec5SDimitry Andric}
7820b57cec5SDimitry Andricdef ConstantUImm5Plus32AsmOperandClass
7830b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<
7840b57cec5SDimitry Andric          5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
7850b57cec5SDimitry Andricdef ConstantUImm5Plus32NormalizeAsmOperandClass
7860b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
7870b57cec5SDimitry Andric  let Name = "ConstantUImm5_32_Norm";
7880b57cec5SDimitry Andric  // We must also subtract 32 when we render the operand.
7890b57cec5SDimitry Andric  let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
7900b57cec5SDimitry Andric}
7910b57cec5SDimitry Andricdef ConstantUImm5Plus1ReportUImm6AsmOperandClass
7920b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<
7930b57cec5SDimitry Andric          5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
7940b57cec5SDimitry Andric  let Name = "ConstantUImm5_Plus1_Report_UImm6";
7950b57cec5SDimitry Andric}
7960b57cec5SDimitry Andricdef ConstantUImm5Plus1AsmOperandClass
7970b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<
7980b57cec5SDimitry Andric          5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
7990b57cec5SDimitry Andricdef ConstantUImm5AsmOperandClass
8000b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
8010b57cec5SDimitry Andricdef ConstantSImm5AsmOperandClass
8020b57cec5SDimitry Andric    : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
8030b57cec5SDimitry Andricdef ConstantUImm4AsmOperandClass
8040b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
8050b57cec5SDimitry Andricdef ConstantSImm4AsmOperandClass
8060b57cec5SDimitry Andric    : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
8070b57cec5SDimitry Andricdef ConstantUImm3AsmOperandClass
8080b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
8090b57cec5SDimitry Andricdef ConstantUImm2Plus1AsmOperandClass
8100b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
8110b57cec5SDimitry Andricdef ConstantUImm2AsmOperandClass
8120b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
8130b57cec5SDimitry Andricdef ConstantUImm1AsmOperandClass
8140b57cec5SDimitry Andric    : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
8150b57cec5SDimitry Andricdef ConstantImmzAsmOperandClass : AsmOperandClass {
8160b57cec5SDimitry Andric  let Name = "ConstantImmz";
8170b57cec5SDimitry Andric  let RenderMethod = "addConstantUImmOperands<1>";
8180b57cec5SDimitry Andric  let PredicateMethod = "isConstantImmz";
8190b57cec5SDimitry Andric  let SuperClasses = [ConstantUImm1AsmOperandClass];
8200b57cec5SDimitry Andric  let DiagnosticType = "Immz";
8210b57cec5SDimitry Andric}
8220b57cec5SDimitry Andric
8230b57cec5SDimitry Andricdef Simm19Lsl2AsmOperand
8240b57cec5SDimitry Andric    : SimmLslAsmOperandClass<19, [], 2>;
8250b57cec5SDimitry Andric
8260b57cec5SDimitry Andricdef MipsJumpTargetAsmOperand : AsmOperandClass {
8270b57cec5SDimitry Andric  let Name = "JumpTarget";
8280b57cec5SDimitry Andric  let ParserMethod = "parseJumpTarget";
8290b57cec5SDimitry Andric  let PredicateMethod = "isImm";
8300b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
8310b57cec5SDimitry Andric}
8320b57cec5SDimitry Andric
8330b57cec5SDimitry Andric// Instruction operand types
8340b57cec5SDimitry Andricdef jmptarget   : Operand<OtherVT> {
8350b57cec5SDimitry Andric  let EncoderMethod = "getJumpTargetOpValue";
8360b57cec5SDimitry Andric  let ParserMatchClass = MipsJumpTargetAsmOperand;
83781ad6265SDimitry Andric  let PrintMethod = "printJumpOperand";
8380b57cec5SDimitry Andric}
8390b57cec5SDimitry Andricdef brtarget    : Operand<OtherVT> {
8400b57cec5SDimitry Andric  let EncoderMethod = "getBranchTargetOpValue";
8410b57cec5SDimitry Andric  let OperandType = "OPERAND_PCREL";
8420b57cec5SDimitry Andric  let DecoderMethod = "DecodeBranchTarget";
8430b57cec5SDimitry Andric  let ParserMatchClass = MipsJumpTargetAsmOperand;
84481ad6265SDimitry Andric  let PrintMethod = "printBranchOperand";
8450b57cec5SDimitry Andric}
8460b57cec5SDimitry Andricdef brtarget1SImm16 : Operand<OtherVT> {
8470b57cec5SDimitry Andric  let EncoderMethod = "getBranchTargetOpValue1SImm16";
8480b57cec5SDimitry Andric  let OperandType = "OPERAND_PCREL";
8490b57cec5SDimitry Andric  let DecoderMethod = "DecodeBranchTarget1SImm16";
8500b57cec5SDimitry Andric  let ParserMatchClass = MipsJumpTargetAsmOperand;
85181ad6265SDimitry Andric  let PrintMethod = "printBranchOperand";
8520b57cec5SDimitry Andric}
8530b57cec5SDimitry Andricdef calltarget  : Operand<iPTR> {
8540b57cec5SDimitry Andric  let EncoderMethod = "getJumpTargetOpValue";
8550b57cec5SDimitry Andric  let ParserMatchClass = MipsJumpTargetAsmOperand;
85681ad6265SDimitry Andric  let PrintMethod = "printJumpOperand";
8570b57cec5SDimitry Andric}
8580b57cec5SDimitry Andric
8590b57cec5SDimitry Andricdef imm64: Operand<i64>;
8600b57cec5SDimitry Andric
8610b57cec5SDimitry Andricdef simm19_lsl2 : Operand<i32> {
8620b57cec5SDimitry Andric  let EncoderMethod = "getSimm19Lsl2Encoding";
8630b57cec5SDimitry Andric  let DecoderMethod = "DecodeSimm19Lsl2";
8640b57cec5SDimitry Andric  let ParserMatchClass = Simm19Lsl2AsmOperand;
8650b57cec5SDimitry Andric}
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andricdef simm18_lsl3 : Operand<i32> {
8680b57cec5SDimitry Andric  let EncoderMethod = "getSimm18Lsl3Encoding";
8690b57cec5SDimitry Andric  let DecoderMethod = "DecodeSimm18Lsl3";
8700b57cec5SDimitry Andric  let ParserMatchClass = MipsJumpTargetAsmOperand;
8710b57cec5SDimitry Andric}
8720b57cec5SDimitry Andric
8730b57cec5SDimitry Andric// Zero
8740b57cec5SDimitry Andricdef uimmz       : Operand<i32> {
8750b57cec5SDimitry Andric  let PrintMethod = "printUImm<0>";
8760b57cec5SDimitry Andric  let ParserMatchClass = ConstantImmzAsmOperandClass;
8770b57cec5SDimitry Andric}
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andric// size operand of ins instruction
8800b57cec5SDimitry Andricdef uimm_range_2_64 : Operand<i32> {
8810b57cec5SDimitry Andric  let PrintMethod = "printUImm<6, 2>";
8820b57cec5SDimitry Andric  let EncoderMethod = "getSizeInsEncoding";
8830b57cec5SDimitry Andric  let DecoderMethod = "DecodeInsSize";
8840b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
8850b57cec5SDimitry Andric}
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric// Unsigned Operands
8880b57cec5SDimitry Andricforeach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
8890b57cec5SDimitry Andric  def uimm # I : Operand<i32> {
8900b57cec5SDimitry Andric    let PrintMethod = "printUImm<" # I # ">";
8910b57cec5SDimitry Andric    let ParserMatchClass =
8920b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
8930b57cec5SDimitry Andric  }
8940b57cec5SDimitry Andric
8950b57cec5SDimitry Andricdef uimm2_plus1 : Operand<i32> {
8960b57cec5SDimitry Andric  let PrintMethod = "printUImm<2, 1>";
8970b57cec5SDimitry Andric  let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
8980b57cec5SDimitry Andric  let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
8990b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
9000b57cec5SDimitry Andric}
9010b57cec5SDimitry Andric
9020b57cec5SDimitry Andricdef uimm5_plus1 : Operand<i32> {
9030b57cec5SDimitry Andric  let PrintMethod = "printUImm<5, 1>";
9040b57cec5SDimitry Andric  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
9050b57cec5SDimitry Andric  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
9060b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
9070b57cec5SDimitry Andric}
9080b57cec5SDimitry Andric
9090b57cec5SDimitry Andricdef uimm5_plus1_report_uimm6 : Operand<i32> {
9100b57cec5SDimitry Andric  let PrintMethod = "printUImm<6, 1>";
9110b57cec5SDimitry Andric  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
9120b57cec5SDimitry Andric  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
9130b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
9140b57cec5SDimitry Andric}
9150b57cec5SDimitry Andric
9160b57cec5SDimitry Andricdef uimm5_plus32 : Operand<i32> {
9170b57cec5SDimitry Andric  let PrintMethod = "printUImm<5, 32>";
9180b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
9190b57cec5SDimitry Andric}
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andricdef uimm5_plus33 : Operand<i32> {
9220b57cec5SDimitry Andric  let PrintMethod = "printUImm<5, 33>";
9230b57cec5SDimitry Andric  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
9240b57cec5SDimitry Andric  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
9250b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
9260b57cec5SDimitry Andric}
9270b57cec5SDimitry Andric
9280b57cec5SDimitry Andricdef uimm5_inssize_plus1 : Operand<i32> {
9290b57cec5SDimitry Andric  let PrintMethod = "printUImm<6>";
9300b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
9310b57cec5SDimitry Andric  let EncoderMethod = "getSizeInsEncoding";
9320b57cec5SDimitry Andric  let DecoderMethod = "DecodeInsSize";
9330b57cec5SDimitry Andric}
9340b57cec5SDimitry Andric
9350b57cec5SDimitry Andricdef uimm5_plus32_normalize : Operand<i32> {
9360b57cec5SDimitry Andric  let PrintMethod = "printUImm<5>";
9370b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
9380b57cec5SDimitry Andric}
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andricdef uimm5_lsl2 : Operand<OtherVT> {
9410b57cec5SDimitry Andric  let EncoderMethod = "getUImm5Lsl2Encoding";
9420b57cec5SDimitry Andric  let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
9430b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
9440b57cec5SDimitry Andric}
9450b57cec5SDimitry Andric
9460b57cec5SDimitry Andricdef uimm5_plus32_normalize_64 : Operand<i64> {
9470b57cec5SDimitry Andric  let PrintMethod = "printUImm<5>";
9480b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
9490b57cec5SDimitry Andric}
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andricdef uimm6_lsl2 : Operand<OtherVT> {
9520b57cec5SDimitry Andric  let EncoderMethod = "getUImm6Lsl2Encoding";
9530b57cec5SDimitry Andric  let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
9540b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
9550b57cec5SDimitry Andric}
9560b57cec5SDimitry Andric
9570b57cec5SDimitry Andricforeach I = {16} in
9580b57cec5SDimitry Andric  def uimm # I : Operand<i32> {
9590b57cec5SDimitry Andric    let PrintMethod = "printUImm<" # I # ">";
9600b57cec5SDimitry Andric    let ParserMatchClass =
9610b57cec5SDimitry Andric        !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
9620b57cec5SDimitry Andric  }
9630b57cec5SDimitry Andric
9640b57cec5SDimitry Andric// Like uimm16_64 but coerces simm16 to uimm16.
9650b57cec5SDimitry Andricdef uimm16_relaxed : Operand<i32> {
9660b57cec5SDimitry Andric  let PrintMethod = "printUImm<16>";
967480093f4SDimitry Andric  let ParserMatchClass = UImm16RelaxedAsmOperandClass;
9680b57cec5SDimitry Andric}
9690b57cec5SDimitry Andric
9700b57cec5SDimitry Andricforeach I = {5} in
9710b57cec5SDimitry Andric  def uimm # I # _64 : Operand<i64> {
9720b57cec5SDimitry Andric    let PrintMethod = "printUImm<" # I # ">";
9730b57cec5SDimitry Andric    let ParserMatchClass =
9740b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
9750b57cec5SDimitry Andric  }
9760b57cec5SDimitry Andric
9770b57cec5SDimitry Andricforeach I = {16} in
9780b57cec5SDimitry Andric  def uimm # I # _64 : Operand<i64> {
9790b57cec5SDimitry Andric    let PrintMethod = "printUImm<" # I # ">";
9800b57cec5SDimitry Andric    let ParserMatchClass =
9810b57cec5SDimitry Andric        !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
9820b57cec5SDimitry Andric  }
9830b57cec5SDimitry Andric
9840b57cec5SDimitry Andric// Like uimm16_64 but coerces simm16 to uimm16.
9850b57cec5SDimitry Andricdef uimm16_64_relaxed : Operand<i64> {
9860b57cec5SDimitry Andric  let PrintMethod = "printUImm<16>";
987480093f4SDimitry Andric  let ParserMatchClass = UImm16RelaxedAsmOperandClass;
9880b57cec5SDimitry Andric}
9890b57cec5SDimitry Andric
9900b57cec5SDimitry Andricdef uimm16_altrelaxed : Operand<i32> {
9910b57cec5SDimitry Andric  let PrintMethod = "printUImm<16>";
992480093f4SDimitry Andric  let ParserMatchClass = UImm16AltRelaxedAsmOperandClass;
9930b57cec5SDimitry Andric}
9940b57cec5SDimitry Andric// Like uimm5 but reports a less confusing error for 32-63 when
9950b57cec5SDimitry Andric// an instruction alias permits that.
9960b57cec5SDimitry Andricdef uimm5_report_uimm6 : Operand<i32> {
9970b57cec5SDimitry Andric  let PrintMethod = "printUImm<6>";
9980b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
9990b57cec5SDimitry Andric}
10000b57cec5SDimitry Andric
10010b57cec5SDimitry Andric// Like uimm5_64 but reports a less confusing error for 32-63 when
10020b57cec5SDimitry Andric// an instruction alias permits that.
10030b57cec5SDimitry Andricdef uimm5_64_report_uimm6 : Operand<i64> {
10040b57cec5SDimitry Andric  let PrintMethod = "printUImm<5>";
10050b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
10060b57cec5SDimitry Andric}
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andricforeach I = {1, 2, 3, 4} in
10090b57cec5SDimitry Andric  def uimm # I # _ptr : Operand<iPTR> {
10100b57cec5SDimitry Andric    let PrintMethod = "printUImm<" # I # ">";
10110b57cec5SDimitry Andric    let ParserMatchClass =
10120b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
10130b57cec5SDimitry Andric  }
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andricforeach I = {1, 2, 3, 4, 5, 6, 8} in
10160b57cec5SDimitry Andric  def vsplat_uimm # I : Operand<vAny> {
10170b57cec5SDimitry Andric    let PrintMethod = "printUImm<" # I # ">";
10180b57cec5SDimitry Andric    let ParserMatchClass =
10190b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
10200b57cec5SDimitry Andric  }
10210b57cec5SDimitry Andric
10220b57cec5SDimitry Andric// Signed operands
10230b57cec5SDimitry Andricforeach I = {4, 5, 6, 9, 10, 11} in
10240b57cec5SDimitry Andric  def simm # I : Operand<i32> {
10250b57cec5SDimitry Andric    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
10260b57cec5SDimitry Andric    let ParserMatchClass =
10270b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
10280b57cec5SDimitry Andric  }
10290b57cec5SDimitry Andric
10300b57cec5SDimitry Andricforeach I = {1, 2, 3} in
10310b57cec5SDimitry Andric  def simm10_lsl # I : Operand<i32> {
10320b57cec5SDimitry Andric    let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
10330b57cec5SDimitry Andric    let ParserMatchClass =
10340b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
10350b57cec5SDimitry Andric  }
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andricforeach I = {10} in
10380b57cec5SDimitry Andric  def simm # I # _64 : Operand<i64> {
10390b57cec5SDimitry Andric    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
10400b57cec5SDimitry Andric    let ParserMatchClass =
10410b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
10420b57cec5SDimitry Andric  }
10430b57cec5SDimitry Andric
10440b57cec5SDimitry Andricforeach I = {5, 10} in
10450b57cec5SDimitry Andric  def vsplat_simm # I : Operand<vAny> {
10460b57cec5SDimitry Andric    let ParserMatchClass =
10470b57cec5SDimitry Andric        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
10480b57cec5SDimitry Andric  }
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andricdef simm7_lsl2 : Operand<OtherVT> {
10510b57cec5SDimitry Andric  let EncoderMethod = "getSImm7Lsl2Encoding";
10520b57cec5SDimitry Andric  let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
10530b57cec5SDimitry Andric  let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
10540b57cec5SDimitry Andric}
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andricforeach I = {16, 32} in
10570b57cec5SDimitry Andric  def simm # I : Operand<i32> {
10580b57cec5SDimitry Andric    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
10590b57cec5SDimitry Andric    let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
10600b57cec5SDimitry Andric  }
10610b57cec5SDimitry Andric
10620b57cec5SDimitry Andric// Like simm16 but coerces uimm16 to simm16.
10630b57cec5SDimitry Andricdef simm16_relaxed : Operand<i32> {
10640b57cec5SDimitry Andric  let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1065480093f4SDimitry Andric  let ParserMatchClass = SImm16RelaxedAsmOperandClass;
10660b57cec5SDimitry Andric}
10670b57cec5SDimitry Andric
10680b57cec5SDimitry Andricdef simm16_64 : Operand<i64> {
10690b57cec5SDimitry Andric  let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1070480093f4SDimitry Andric  let ParserMatchClass = SImm16AsmOperandClass;
10710b57cec5SDimitry Andric}
10720b57cec5SDimitry Andric
10730b57cec5SDimitry Andric// like simm32 but coerces simm32 to uimm32.
10740b57cec5SDimitry Andricdef uimm32_coerced : Operand<i32> {
1075480093f4SDimitry Andric  let ParserMatchClass = UImm32CoercedAsmOperandClass;
10760b57cec5SDimitry Andric}
10770b57cec5SDimitry Andric// Like simm32 but coerces uimm32 to simm32.
10780b57cec5SDimitry Andricdef simm32_relaxed : Operand<i32> {
10790b57cec5SDimitry Andric  let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1080480093f4SDimitry Andric  let ParserMatchClass = SImm32RelaxedAsmOperandClass;
10810b57cec5SDimitry Andric}
10820b57cec5SDimitry Andric
10830b57cec5SDimitry Andric// This is almost the same as a uimm7 but 0x7f is interpreted as -1.
10840b57cec5SDimitry Andricdef li16_imm : Operand<i32> {
10850b57cec5SDimitry Andric  let DecoderMethod = "DecodeLi16Imm";
10860b57cec5SDimitry Andric  let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
10870b57cec5SDimitry Andric}
10880b57cec5SDimitry Andric
10890b57cec5SDimitry Andricdef MipsMemAsmOperand : AsmOperandClass {
10900b57cec5SDimitry Andric  let Name = "Mem";
10910b57cec5SDimitry Andric  let ParserMethod = "parseMemOperand";
10920b57cec5SDimitry Andric}
10930b57cec5SDimitry Andric
1094480093f4SDimitry Andricclass MipsMemSimmAsmOperand<int Width, int Shift = 0> : AsmOperandClass {
1095480093f4SDimitry Andric  let Name = "MemOffsetSimm" # Width # "_" # Shift;
10960b57cec5SDimitry Andric  let SuperClasses = [MipsMemAsmOperand];
10970b57cec5SDimitry Andric  let RenderMethod = "addMemOperands";
10980b57cec5SDimitry Andric  let ParserMethod = "parseMemOperand";
1099480093f4SDimitry Andric  let PredicateMethod = "isMemWithSimmOffset<" # Width # ", " # Shift # ">";
1100480093f4SDimitry Andric  let DiagnosticType = !if(!eq(Shift, 0), "MemSImm" # Width,
1101480093f4SDimitry Andric                                          "MemSImm" # Width # "Lsl" # Shift);
11020b57cec5SDimitry Andric}
11030b57cec5SDimitry Andric
11040b57cec5SDimitry Andricdef MipsMemSimmPtrAsmOperand : AsmOperandClass {
11050b57cec5SDimitry Andric  let Name = "MemOffsetSimmPtr";
11060b57cec5SDimitry Andric  let SuperClasses = [MipsMemAsmOperand];
11070b57cec5SDimitry Andric  let RenderMethod = "addMemOperands";
11080b57cec5SDimitry Andric  let ParserMethod = "parseMemOperand";
11090b57cec5SDimitry Andric  let PredicateMethod = "isMemWithPtrSizeOffset";
11100b57cec5SDimitry Andric  let DiagnosticType = "MemSImmPtr";
11110b57cec5SDimitry Andric}
11120b57cec5SDimitry Andric
11130b57cec5SDimitry Andricdef MipsInvertedImmoperand : AsmOperandClass {
11140b57cec5SDimitry Andric  let Name = "InvNum";
11150b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
11160b57cec5SDimitry Andric  let ParserMethod = "parseInvNum";
11170b57cec5SDimitry Andric}
11180b57cec5SDimitry Andric
11190b57cec5SDimitry Andricdef InvertedImOperand : Operand<i32> {
11200b57cec5SDimitry Andric  let ParserMatchClass = MipsInvertedImmoperand;
11210b57cec5SDimitry Andric}
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andricdef InvertedImOperand64 : Operand<i64> {
11240b57cec5SDimitry Andric  let ParserMatchClass = MipsInvertedImmoperand;
11250b57cec5SDimitry Andric}
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andricclass mem_generic : Operand<iPTR> {
11280b57cec5SDimitry Andric  let PrintMethod = "printMemOperand";
11290b57cec5SDimitry Andric  let MIOperandInfo = (ops ptr_rc, simm16);
11300b57cec5SDimitry Andric  let EncoderMethod = "getMemEncoding";
11310b57cec5SDimitry Andric  let ParserMatchClass = MipsMemAsmOperand;
11320b57cec5SDimitry Andric  let OperandType = "OPERAND_MEMORY";
11330b57cec5SDimitry Andric}
11340b57cec5SDimitry Andric
11350b57cec5SDimitry Andric// Address operand
11360b57cec5SDimitry Andricdef mem : mem_generic;
11370b57cec5SDimitry Andric
11380b57cec5SDimitry Andric// MSA specific address operand
11390b57cec5SDimitry Andricdef mem_msa : mem_generic {
11400b57cec5SDimitry Andric  let MIOperandInfo = (ops ptr_rc, simm10);
11410b57cec5SDimitry Andric  let EncoderMethod = "getMSAMemEncoding";
11420b57cec5SDimitry Andric}
11430b57cec5SDimitry Andric
11440b57cec5SDimitry Andricdef simm12 : Operand<i32> {
11450b57cec5SDimitry Andric  let DecoderMethod = "DecodeSimm12";
11460b57cec5SDimitry Andric}
11470b57cec5SDimitry Andric
1148480093f4SDimitry Andricdef mem_simm9_exp : mem_generic {
11490b57cec5SDimitry Andric  let MIOperandInfo = (ops ptr_rc, simm9);
1150480093f4SDimitry Andric  let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1151480093f4SDimitry Andric  let OperandNamespace = "MipsII";
1152480093f4SDimitry Andric  let OperandType = "OPERAND_MEM_SIMM9";
11530b57cec5SDimitry Andric}
11540b57cec5SDimitry Andric
1155480093f4SDimitry Andricforeach I = {9, 10, 11, 12, 16} in
1156480093f4SDimitry Andric  def mem_simm # I : mem_generic {
1157480093f4SDimitry Andric    let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm" # I));
1158480093f4SDimitry Andric    let ParserMatchClass = MipsMemSimmAsmOperand<I>;
11590b57cec5SDimitry Andric  }
11600b57cec5SDimitry Andric
11610b57cec5SDimitry Andricforeach I = {1, 2, 3} in
11620b57cec5SDimitry Andric  def mem_simm10_lsl # I : mem_generic {
11630b57cec5SDimitry Andric    let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
11640b57cec5SDimitry Andric    let EncoderMethod = "getMemEncoding<" # I  # ">";
1165480093f4SDimitry Andric    let ParserMatchClass = MipsMemSimmAsmOperand<10, I>;
11660b57cec5SDimitry Andric  }
11670b57cec5SDimitry Andric
11680b57cec5SDimitry Andricdef mem_simmptr : mem_generic {
11690b57cec5SDimitry Andric  let ParserMatchClass = MipsMemSimmPtrAsmOperand;
11700b57cec5SDimitry Andric}
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andricdef mem_ea : Operand<iPTR> {
11730b57cec5SDimitry Andric  let PrintMethod = "printMemOperandEA";
11740b57cec5SDimitry Andric  let MIOperandInfo = (ops ptr_rc, simm16);
11750b57cec5SDimitry Andric  let EncoderMethod = "getMemEncoding";
11760b57cec5SDimitry Andric  let OperandType = "OPERAND_MEMORY";
11770b57cec5SDimitry Andric}
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andricdef PtrRC : Operand<iPTR> {
11800b57cec5SDimitry Andric  let MIOperandInfo = (ops ptr_rc);
11810b57cec5SDimitry Andric  let DecoderMethod = "DecodePtrRegisterClass";
11820b57cec5SDimitry Andric  let ParserMatchClass = GPR32AsmOperand;
11830b57cec5SDimitry Andric}
11840b57cec5SDimitry Andric
11850b57cec5SDimitry Andric// size operand of ins instruction
11860b57cec5SDimitry Andricdef size_ins : Operand<i32> {
11870b57cec5SDimitry Andric  let EncoderMethod = "getSizeInsEncoding";
11880b57cec5SDimitry Andric  let DecoderMethod = "DecodeInsSize";
11890b57cec5SDimitry Andric}
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric// Transformation Function - get the lower 16 bits.
11920b57cec5SDimitry Andricdef LO16 : SDNodeXForm<imm, [{
11930b57cec5SDimitry Andric  return getImm(N, N->getZExtValue() & 0xFFFF);
11940b57cec5SDimitry Andric}]>;
11950b57cec5SDimitry Andric
11960b57cec5SDimitry Andric// Transformation Function - get the higher 16 bits.
11970b57cec5SDimitry Andricdef HI16 : SDNodeXForm<imm, [{
11980b57cec5SDimitry Andric  return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
11990b57cec5SDimitry Andric}]>;
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andric// Plus 1.
12020b57cec5SDimitry Andricdef Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
12030b57cec5SDimitry Andric
12040b57cec5SDimitry Andric// Node immediate is zero (e.g. insve.d)
12050b57cec5SDimitry Andricdef immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
12060b57cec5SDimitry Andric
12070b57cec5SDimitry Andric// Node immediate fits as 16-bit sign extended on target immediate.
12080b57cec5SDimitry Andric// e.g. addi, andi
12090b57cec5SDimitry Andricdef immSExt8  : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
12100b57cec5SDimitry Andric
12110b57cec5SDimitry Andric// Node immediate fits as 16-bit sign extended on target immediate.
12120b57cec5SDimitry Andric// e.g. addi, andi
12130b57cec5SDimitry Andricdef immSExt16  : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1214480093f4SDimitry Andricdef imm32SExt16  : IntImmLeaf<i32, [{ return isInt<16>(Imm.getSExtValue()); }]>;
12150b57cec5SDimitry Andric
12160b57cec5SDimitry Andric// Node immediate fits as 7-bit zero extended on target immediate.
12170b57cec5SDimitry Andricdef immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
12188bcb0991SDimitry Andricdef timmZExt7 : PatLeaf<(timm), [{ return isUInt<7>(N->getZExtValue()); }]>;
12190b57cec5SDimitry Andric
12200b57cec5SDimitry Andric// Node immediate fits as 16-bit zero extended on target immediate.
12210b57cec5SDimitry Andric// The LO16 param means that only the lower 16 bits of the node
12220b57cec5SDimitry Andric// immediate are caught.
12230b57cec5SDimitry Andric// e.g. addiu, sltiu
12240b57cec5SDimitry Andricdef immZExt16  : PatLeaf<(imm), [{
12250b57cec5SDimitry Andric  if (N->getValueType(0) == MVT::i32)
12260b57cec5SDimitry Andric    return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
12270b57cec5SDimitry Andric  else
12280b57cec5SDimitry Andric    return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
12290b57cec5SDimitry Andric}], LO16>;
1230480093f4SDimitry Andricdef imm32ZExt16  : IntImmLeaf<i32, [{
1231480093f4SDimitry Andric  return (uint32_t)Imm.getZExtValue() == (unsigned short)Imm.getZExtValue();
1232480093f4SDimitry Andric}]>;
12330b57cec5SDimitry Andric
12340b57cec5SDimitry Andric// Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
12350b57cec5SDimitry Andricdef immSExt32Low16Zero : PatLeaf<(imm), [{
12360b57cec5SDimitry Andric  int64_t Val = N->getSExtValue();
12370b57cec5SDimitry Andric  return isInt<32>(Val) && !(Val & 0xffff);
12380b57cec5SDimitry Andric}]>;
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andric// Zero-extended 32-bit unsigned int with lower 16-bit cleared.
12410b57cec5SDimitry Andricdef immZExt32Low16Zero : PatLeaf<(imm), [{
12420b57cec5SDimitry Andric  uint64_t Val = N->getZExtValue();
12430b57cec5SDimitry Andric  return isUInt<32>(Val) && !(Val & 0xffff);
12440b57cec5SDimitry Andric}]>;
12450b57cec5SDimitry Andric
12460b57cec5SDimitry Andric// Note immediate fits as a 32 bit signed extended on target immediate.
12470b57cec5SDimitry Andricdef immSExt32  : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
12480b57cec5SDimitry Andric
12490b57cec5SDimitry Andric// Note immediate fits as a 32 bit zero extended on target immediate.
12500b57cec5SDimitry Andricdef immZExt32  : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric// shamt field must fit in 5 bits.
12530b57cec5SDimitry Andricdef immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
12548bcb0991SDimitry Andricdef timmZExt5 : TImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
12550b57cec5SDimitry Andric
12560b57cec5SDimitry Andricdef immZExt5Plus1 : PatLeaf<(imm), [{
12570b57cec5SDimitry Andric  return isUInt<5>(N->getZExtValue() - 1);
12580b57cec5SDimitry Andric}]>;
12590b57cec5SDimitry Andricdef immZExt5Plus32 : PatLeaf<(imm), [{
12600b57cec5SDimitry Andric  return isUInt<5>(N->getZExtValue() - 32);
12610b57cec5SDimitry Andric}]>;
12620b57cec5SDimitry Andricdef immZExt5Plus33 : PatLeaf<(imm), [{
12630b57cec5SDimitry Andric  return isUInt<5>(N->getZExtValue() - 33);
12640b57cec5SDimitry Andric}]>;
12650b57cec5SDimitry Andric
12660b57cec5SDimitry Andricdef immZExt5To31 : SDNodeXForm<imm, [{
12670b57cec5SDimitry Andric  return getImm(N, 31 - N->getZExtValue());
12680b57cec5SDimitry Andric}]>;
12690b57cec5SDimitry Andric
12700b57cec5SDimitry Andric// True if (N + 1) fits in 16-bit field.
12710b57cec5SDimitry Andricdef immSExt16Plus1 : PatLeaf<(imm), [{
12720b57cec5SDimitry Andric  return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
12730b57cec5SDimitry Andric}]>;
12740b57cec5SDimitry Andric
12750b57cec5SDimitry Andricdef immZExtRange2To64 : PatLeaf<(imm), [{
12760b57cec5SDimitry Andric  return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
12770b57cec5SDimitry Andric         (N->getZExtValue() <= 64);
12780b57cec5SDimitry Andric}]>;
12790b57cec5SDimitry Andric
12800b57cec5SDimitry Andricdef ORiPred  : PatLeaf<(imm), [{
12810b57cec5SDimitry Andric  return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
12820b57cec5SDimitry Andric}], LO16>;
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andricdef LUiPred : PatLeaf<(imm), [{
12850b57cec5SDimitry Andric  int64_t Val = N->getSExtValue();
12860b57cec5SDimitry Andric  return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
12870b57cec5SDimitry Andric}]>;
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andricdef LUiORiPred  : PatLeaf<(imm), [{
12900b57cec5SDimitry Andric  int64_t SVal = N->getSExtValue();
12910b57cec5SDimitry Andric  return isInt<32>(SVal) && (SVal & 0xffff);
12920b57cec5SDimitry Andric}]>;
12930b57cec5SDimitry Andric
12945ffd83dbSDimitry Andric// Mips Address Mode! SDNode frameindex could possibly be a match
12950b57cec5SDimitry Andric// since load and store instructions from stack used it.
12960b57cec5SDimitry Andricdef addr :
12970b57cec5SDimitry Andric  ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
12980b57cec5SDimitry Andric
12990b57cec5SDimitry Andricdef addrRegImm :
13000b57cec5SDimitry Andric  ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
13010b57cec5SDimitry Andric
13020b57cec5SDimitry Andricdef addrDefault :
13030b57cec5SDimitry Andric  ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
13040b57cec5SDimitry Andric
13050b57cec5SDimitry Andricdef addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
13060b57cec5SDimitry Andricdef addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
13070b57cec5SDimitry Andric                                   [frameindex]>;
13080b57cec5SDimitry Andricdef addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
13090b57cec5SDimitry Andric                                   [frameindex]>;
13100b57cec5SDimitry Andricdef addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
13110b57cec5SDimitry Andric                                   [frameindex]>;
13120b57cec5SDimitry Andric
13130b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
13140b57cec5SDimitry Andric// Instructions specific format
13150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric// Arithmetic and logical instructions with 3 register operands.
13180b57cec5SDimitry Andricclass ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
13190b57cec5SDimitry Andric                  InstrItinClass Itin = NoItinerary,
13200b57cec5SDimitry Andric                  SDPatternOperator OpNode = null_frag>:
13210b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
13220b57cec5SDimitry Andric         !strconcat(opstr, "\t$rd, $rs, $rt"),
13230b57cec5SDimitry Andric         [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
13240b57cec5SDimitry Andric  let isCommutable = isComm;
13250b57cec5SDimitry Andric  let isReMaterializable = 1;
13260b57cec5SDimitry Andric  let TwoOperandAliasConstraint = "$rd = $rs";
13270b57cec5SDimitry Andric}
13280b57cec5SDimitry Andric
13290b57cec5SDimitry Andric// Arithmetic and logical instructions with 2 register operands.
13300b57cec5SDimitry Andricclass ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
13310b57cec5SDimitry Andric                  InstrItinClass Itin = NoItinerary,
13320b57cec5SDimitry Andric                  SDPatternOperator imm_type = null_frag,
13330b57cec5SDimitry Andric                  SDPatternOperator OpNode = null_frag> :
13340b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
13350b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $rs, $imm16"),
13360b57cec5SDimitry Andric         [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
13370b57cec5SDimitry Andric         Itin, FrmI, opstr> {
13380b57cec5SDimitry Andric  let isReMaterializable = 1;
13390b57cec5SDimitry Andric  let TwoOperandAliasConstraint = "$rs = $rt";
13400b57cec5SDimitry Andric}
13410b57cec5SDimitry Andric
13420b57cec5SDimitry Andric// Arithmetic Multiply ADD/SUB
13430b57cec5SDimitry Andricclass MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
13440b57cec5SDimitry Andric  InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
13450b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
13460b57cec5SDimitry Andric  let Defs = [HI0, LO0];
13470b57cec5SDimitry Andric  let Uses = [HI0, LO0];
13480b57cec5SDimitry Andric  let isCommutable = isComm;
13490b57cec5SDimitry Andric}
13500b57cec5SDimitry Andric
13510b57cec5SDimitry Andric//  Logical
13520b57cec5SDimitry Andricclass LogicNOR<string opstr, RegisterOperand RO>:
13530b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
13540b57cec5SDimitry Andric         !strconcat(opstr, "\t$rd, $rs, $rt"),
13550b57cec5SDimitry Andric         [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
13560b57cec5SDimitry Andric  let isCommutable = 1;
13570b57cec5SDimitry Andric}
13580b57cec5SDimitry Andric
13590b57cec5SDimitry Andric// Shifts
13600b57cec5SDimitry Andricclass shift_rotate_imm<string opstr, Operand ImmOpnd,
13610b57cec5SDimitry Andric                       RegisterOperand RO, InstrItinClass itin,
13620b57cec5SDimitry Andric                       SDPatternOperator OpNode = null_frag,
13630b57cec5SDimitry Andric                       SDPatternOperator PF = null_frag> :
13640b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
13650b57cec5SDimitry Andric         !strconcat(opstr, "\t$rd, $rt, $shamt"),
13660b57cec5SDimitry Andric         [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
13670b57cec5SDimitry Andric  let TwoOperandAliasConstraint = "$rt = $rd";
13680b57cec5SDimitry Andric}
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andricclass shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
13710b57cec5SDimitry Andric                       SDPatternOperator OpNode = null_frag>:
13720b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
13730b57cec5SDimitry Andric         !strconcat(opstr, "\t$rd, $rt, $rs"),
13740b57cec5SDimitry Andric         [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
13750b57cec5SDimitry Andric         opstr>;
13760b57cec5SDimitry Andric
13770b57cec5SDimitry Andric// Load Upper Immediate
13780b57cec5SDimitry Andricclass LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
13790b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
13800b57cec5SDimitry Andric         [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
13810b57cec5SDimitry Andric  let hasSideEffects = 0;
13820b57cec5SDimitry Andric  let isReMaterializable = 1;
13830b57cec5SDimitry Andric}
13840b57cec5SDimitry Andric
13850b57cec5SDimitry Andric// Memory Load/Store
13860b57cec5SDimitry Andricclass LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
13870b57cec5SDimitry Andric                 SDPatternOperator OpNode = null_frag,
13880b57cec5SDimitry Andric                 InstrItinClass Itin = NoItinerary,
13890b57cec5SDimitry Andric                 ComplexPattern Addr = addr> :
13900b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
13910b57cec5SDimitry Andric         [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
13920b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
13930b57cec5SDimitry Andric  let canFoldAsLoad = 1;
13940b57cec5SDimitry Andric  string BaseOpcode = opstr;
13950b57cec5SDimitry Andric  let mayLoad = 1;
13960b57cec5SDimitry Andric}
13970b57cec5SDimitry Andric
13980b57cec5SDimitry Andricclass Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
13990b57cec5SDimitry Andric           InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
14000b57cec5SDimitry Andric  LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
14010b57cec5SDimitry Andric
14020b57cec5SDimitry Andricclass StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
14030b57cec5SDimitry Andric            SDPatternOperator OpNode = null_frag,
14040b57cec5SDimitry Andric            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
14050b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
14060b57cec5SDimitry Andric         [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
14070b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
14080b57cec5SDimitry Andric  string BaseOpcode = opstr;
14090b57cec5SDimitry Andric  let mayStore = 1;
14100b57cec5SDimitry Andric}
14110b57cec5SDimitry Andric
14120b57cec5SDimitry Andricclass Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
14130b57cec5SDimitry Andric            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
14140b57cec5SDimitry Andric            DAGOperand MO = mem> :
14150b57cec5SDimitry Andric  StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
14160b57cec5SDimitry Andric
14170b57cec5SDimitry Andric// Load/Store Left/Right
14180b57cec5SDimitry Andriclet canFoldAsLoad = 1 in
14190b57cec5SDimitry Andricclass LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
14200b57cec5SDimitry Andric                    InstrItinClass Itin> :
14210b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
14220b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $addr"),
14230b57cec5SDimitry Andric         [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
14240b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
14250b57cec5SDimitry Andric  string Constraints = "$src = $rt";
14260b57cec5SDimitry Andric  let BaseOpcode = opstr;
14270b57cec5SDimitry Andric}
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andricclass StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
14300b57cec5SDimitry Andric                     InstrItinClass Itin> :
14310b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
14320b57cec5SDimitry Andric         [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
14330b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
14340b57cec5SDimitry Andric  let BaseOpcode = opstr;
14350b57cec5SDimitry Andric}
14360b57cec5SDimitry Andric
14370b57cec5SDimitry Andric// COP2 Load/Store
14380b57cec5SDimitry Andricclass LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
14390b57cec5SDimitry Andric             SDPatternOperator OpNode= null_frag> :
14400b57cec5SDimitry Andric  InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
14410b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $addr"),
14420b57cec5SDimitry Andric         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
14430b57cec5SDimitry Andric  let DecoderMethod = "DecodeFMem2";
14440b57cec5SDimitry Andric  let mayLoad = 1;
14450b57cec5SDimitry Andric}
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andricclass SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
14480b57cec5SDimitry Andric             SDPatternOperator OpNode= null_frag> :
14490b57cec5SDimitry Andric  InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
14500b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $addr"),
14510b57cec5SDimitry Andric         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
14520b57cec5SDimitry Andric  let DecoderMethod = "DecodeFMem2";
14530b57cec5SDimitry Andric  let mayStore = 1;
14540b57cec5SDimitry Andric}
14550b57cec5SDimitry Andric
14560b57cec5SDimitry Andric// COP3 Load/Store
14570b57cec5SDimitry Andricclass LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
14580b57cec5SDimitry Andric             SDPatternOperator OpNode= null_frag> :
14590b57cec5SDimitry Andric  InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
14600b57cec5SDimitry Andric         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
14610b57cec5SDimitry Andric  let DecoderMethod = "DecodeFMem3";
14620b57cec5SDimitry Andric  let mayLoad = 1;
14630b57cec5SDimitry Andric}
14640b57cec5SDimitry Andric
14650b57cec5SDimitry Andricclass SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
14660b57cec5SDimitry Andric             SDPatternOperator OpNode= null_frag> :
14670b57cec5SDimitry Andric  InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
14680b57cec5SDimitry Andric         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
14690b57cec5SDimitry Andric  let DecoderMethod = "DecodeFMem3";
14700b57cec5SDimitry Andric  let mayStore = 1;
14710b57cec5SDimitry Andric}
14720b57cec5SDimitry Andric
14730b57cec5SDimitry Andric// Conditional Branch
14740b57cec5SDimitry Andricclass CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
14750b57cec5SDimitry Andric              RegisterOperand RO> :
14760b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
14770b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $rt, $offset"),
14780b57cec5SDimitry Andric         [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
14790b57cec5SDimitry Andric         FrmI, opstr> {
14800b57cec5SDimitry Andric  let isBranch = 1;
14810b57cec5SDimitry Andric  let isTerminator = 1;
14820b57cec5SDimitry Andric  let hasDelaySlot = 1;
14830b57cec5SDimitry Andric  let Defs = [AT];
14840b57cec5SDimitry Andric  bit isCTI = 1;
14850b57cec5SDimitry Andric}
14860b57cec5SDimitry Andric
14870b57cec5SDimitry Andricclass CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
14880b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
14890b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
14900b57cec5SDimitry Andric  let isBranch = 1;
14910b57cec5SDimitry Andric  let isTerminator = 1;
14920b57cec5SDimitry Andric  let hasDelaySlot = 1;
14930b57cec5SDimitry Andric  let Defs = [AT];
14940b57cec5SDimitry Andric  bit isCTI = 1;
14950b57cec5SDimitry Andric}
14960b57cec5SDimitry Andric
14970b57cec5SDimitry Andricclass CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
14980b57cec5SDimitry Andric                  RegisterOperand RO> :
14990b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, opnd:$offset),
15000b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $offset"),
15010b57cec5SDimitry Andric         [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
15020b57cec5SDimitry Andric         FrmI, opstr> {
15030b57cec5SDimitry Andric  let isBranch = 1;
15040b57cec5SDimitry Andric  let isTerminator = 1;
15050b57cec5SDimitry Andric  let hasDelaySlot = 1;
15060b57cec5SDimitry Andric  let Defs = [AT];
15070b57cec5SDimitry Andric  bit isCTI = 1;
15080b57cec5SDimitry Andric}
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andricclass CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
15110b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, opnd:$offset),
15120b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
15130b57cec5SDimitry Andric  let isBranch = 1;
15140b57cec5SDimitry Andric  let isTerminator = 1;
15150b57cec5SDimitry Andric  let hasDelaySlot = 1;
15160b57cec5SDimitry Andric  let Defs = [AT];
15170b57cec5SDimitry Andric  bit isCTI = 1;
15180b57cec5SDimitry Andric}
15190b57cec5SDimitry Andric
15200b57cec5SDimitry Andric// SetCC
15210b57cec5SDimitry Andricclass SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
15220b57cec5SDimitry Andric  InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
15230b57cec5SDimitry Andric         !strconcat(opstr, "\t$rd, $rs, $rt"),
15240b57cec5SDimitry Andric         [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
15250b57cec5SDimitry Andric         II_SLT_SLTU, FrmR, opstr>;
15260b57cec5SDimitry Andric
15270b57cec5SDimitry Andricclass SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
15280b57cec5SDimitry Andric              RegisterOperand RO>:
15290b57cec5SDimitry Andric  InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
15300b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $rs, $imm16"),
15310b57cec5SDimitry Andric         [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
15320b57cec5SDimitry Andric         II_SLTI_SLTIU, FrmI, opstr>;
15330b57cec5SDimitry Andric
15340b57cec5SDimitry Andric// Jump
15350b57cec5SDimitry Andricclass JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
15360b57cec5SDimitry Andric             SDPatternOperator targetoperator, string bopstr> :
15370b57cec5SDimitry Andric  InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
15380b57cec5SDimitry Andric         [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
15390b57cec5SDimitry Andric  let isTerminator=1;
15400b57cec5SDimitry Andric  let isBarrier=1;
15410b57cec5SDimitry Andric  let hasDelaySlot = 1;
15420b57cec5SDimitry Andric  let DecoderMethod = "DecodeJumpTarget";
15430b57cec5SDimitry Andric  let Defs = [AT];
15440b57cec5SDimitry Andric  bit isCTI = 1;
15450b57cec5SDimitry Andric}
15460b57cec5SDimitry Andric
15470b57cec5SDimitry Andric// Unconditional branch
15480b57cec5SDimitry Andricclass UncondBranch<Instruction BEQInst, DAGOperand opnd> :
15490b57cec5SDimitry Andric  PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
15500b57cec5SDimitry Andric  PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
15510b57cec5SDimitry Andric  let isBranch = 1;
15520b57cec5SDimitry Andric  let isTerminator = 1;
15530b57cec5SDimitry Andric  let isBarrier = 1;
15540b57cec5SDimitry Andric  let hasDelaySlot = 1;
15550b57cec5SDimitry Andric  let AdditionalPredicates = [RelocPIC];
15560b57cec5SDimitry Andric  let Defs = [AT];
15570b57cec5SDimitry Andric  bit isCTI = 1;
15580b57cec5SDimitry Andric}
15590b57cec5SDimitry Andric
15600b57cec5SDimitry Andric// Base class for indirect branch and return instruction classes.
15610b57cec5SDimitry Andriclet isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
15620b57cec5SDimitry Andricclass JumpFR<string opstr, RegisterOperand RO,
15630b57cec5SDimitry Andric             SDPatternOperator operator = null_frag>:
15640b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
15650b57cec5SDimitry Andric         FrmR, opstr>;
15660b57cec5SDimitry Andric
15670b57cec5SDimitry Andric// Indirect branch
15680b57cec5SDimitry Andricclass IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
15690b57cec5SDimitry Andric  let isBranch = 1;
15700b57cec5SDimitry Andric  let isIndirectBranch = 1;
15710b57cec5SDimitry Andric}
15720b57cec5SDimitry Andric
15730b57cec5SDimitry Andric// Jump and Link (Call)
15740b57cec5SDimitry Andriclet isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
15750b57cec5SDimitry Andric  class JumpLink<string opstr, DAGOperand opnd> :
15760b57cec5SDimitry Andric    InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
15770b57cec5SDimitry Andric           [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
15780b57cec5SDimitry Andric    let DecoderMethod = "DecodeJumpTarget";
15790b57cec5SDimitry Andric  }
15800b57cec5SDimitry Andric
15810b57cec5SDimitry Andric  class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
15820b57cec5SDimitry Andric                          Register RetReg, RegisterOperand ResRO = RO>:
15830b57cec5SDimitry Andric    PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
15840b57cec5SDimitry Andric    PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
15850b57cec5SDimitry Andric    let hasPostISelHook = 1;
15860b57cec5SDimitry Andric  }
15870b57cec5SDimitry Andric
15880b57cec5SDimitry Andric  class JumpLinkReg<string opstr, RegisterOperand RO>:
15890b57cec5SDimitry Andric    InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
15900b57cec5SDimitry Andric           [], II_JALR, FrmR, opstr> {
15910b57cec5SDimitry Andric    let hasPostISelHook = 1;
15920b57cec5SDimitry Andric  }
15930b57cec5SDimitry Andric
15940b57cec5SDimitry Andric  class BGEZAL_FT<string opstr, DAGOperand opnd,
15950b57cec5SDimitry Andric                  RegisterOperand RO> :
15960b57cec5SDimitry Andric    InstSE<(outs), (ins RO:$rs, opnd:$offset),
15970b57cec5SDimitry Andric           !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
15980b57cec5SDimitry Andric    let hasDelaySlot = 1;
15990b57cec5SDimitry Andric  }
16000b57cec5SDimitry Andric
16010b57cec5SDimitry Andric}
16020b57cec5SDimitry Andric
16030b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
16040b57cec5SDimitry Andric    hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
16050b57cec5SDimitry Andric  class TailCall<Instruction JumpInst, DAGOperand Opnd> :
16060b57cec5SDimitry Andric    PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
16070b57cec5SDimitry Andric    PseudoInstExpansion<(JumpInst Opnd:$target)>;
16080b57cec5SDimitry Andric
16090b57cec5SDimitry Andric  class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
16100b57cec5SDimitry Andric    PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
16110b57cec5SDimitry Andric    PseudoInstExpansion<(JumpInst RO:$rs)> {
16120b57cec5SDimitry Andric    let hasPostISelHook = 1;
16130b57cec5SDimitry Andric  }
16140b57cec5SDimitry Andric}
16150b57cec5SDimitry Andric
16160b57cec5SDimitry Andricclass BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
16170b57cec5SDimitry Andric  PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
16180b57cec5SDimitry Andric  PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
16190b57cec5SDimitry Andric  let isBranch = 1;
16200b57cec5SDimitry Andric  let isTerminator = 1;
16210b57cec5SDimitry Andric  let isBarrier = 1;
16220b57cec5SDimitry Andric  let hasDelaySlot = 1;
16230b57cec5SDimitry Andric  let Defs = [RA];
16240b57cec5SDimitry Andric  bit isCTI = 1;
16250b57cec5SDimitry Andric}
16260b57cec5SDimitry Andric
16270b57cec5SDimitry Andriclet isCTI = 1 in {
16280b57cec5SDimitry Andric// Syscall
16290b57cec5SDimitry Andricclass SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
16300b57cec5SDimitry Andric  InstSE<(outs), (ins ImmOp:$code_),
16310b57cec5SDimitry Andric         !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
16320b57cec5SDimitry Andric// Break
16330b57cec5SDimitry Andricclass BRK_FT<string opstr> :
16340b57cec5SDimitry Andric  InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
16350b57cec5SDimitry Andric         !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
16360b57cec5SDimitry Andric         FrmOther, opstr>;
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andric// (D)Eret
16390b57cec5SDimitry Andricclass ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
16400b57cec5SDimitry Andric  InstSE<(outs), (ins),
16410b57cec5SDimitry Andric         opstr, [], itin, FrmOther, opstr>;
16420b57cec5SDimitry Andric
16430b57cec5SDimitry Andric// Wait
16440b57cec5SDimitry Andricclass WAIT_FT<string opstr> :
16450b57cec5SDimitry Andric  InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
16460b57cec5SDimitry Andric}
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andric// Interrupts
16490b57cec5SDimitry Andricclass DEI_FT<string opstr, RegisterOperand RO,
16500b57cec5SDimitry Andric             InstrItinClass itin = NoItinerary> :
16510b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins),
16520b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andric// Sync
16550b57cec5SDimitry Andriclet hasSideEffects = 1 in
16560b57cec5SDimitry Andricclass SYNC_FT<string opstr> :
16570b57cec5SDimitry Andric  InstSE<(outs), (ins uimm5:$stype), "sync $stype",
16580b57cec5SDimitry Andric         [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andricclass SYNCI_FT<string opstr, DAGOperand MO> :
16610b57cec5SDimitry Andric  InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
16620b57cec5SDimitry Andric         II_SYNCI, FrmOther, opstr> {
16630b57cec5SDimitry Andric  let hasSideEffects = 1;
16640b57cec5SDimitry Andric  let DecoderMethod = "DecodeSyncI";
16650b57cec5SDimitry Andric}
16660b57cec5SDimitry Andric
16670b57cec5SDimitry Andriclet hasSideEffects = 1, isCTI = 1 in {
16680b57cec5SDimitry Andricclass TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
16690b57cec5SDimitry Andric             InstrItinClass itin = NoItinerary> :
16700b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
16710b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
16720b57cec5SDimitry Andric
16730b57cec5SDimitry Andricclass TEQI_FT<string opstr, RegisterOperand RO,
16740b57cec5SDimitry Andric              InstrItinClass itin = NoItinerary> :
16750b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, simm16:$imm16),
16760b57cec5SDimitry Andric         !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
16770b57cec5SDimitry Andric}
16780b57cec5SDimitry Andric
16790b57cec5SDimitry Andric// Mul, Div
16800b57cec5SDimitry Andricclass Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
16810b57cec5SDimitry Andric           list<Register> DefRegs> :
16820b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
16830b57cec5SDimitry Andric         itin, FrmR, opstr> {
16840b57cec5SDimitry Andric  let isCommutable = 1;
16850b57cec5SDimitry Andric  let Defs = DefRegs;
16860b57cec5SDimitry Andric  let hasSideEffects = 0;
16870b57cec5SDimitry Andric}
16880b57cec5SDimitry Andric
16890b57cec5SDimitry Andric// Pseudo multiply/divide instruction with explicit accumulator register
16900b57cec5SDimitry Andric// operands.
16910b57cec5SDimitry Andricclass MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
16920b57cec5SDimitry Andric                    SDPatternOperator OpNode, InstrItinClass Itin,
16930b57cec5SDimitry Andric                    bit IsComm = 1, bit HasSideEffects = 0,
16940b57cec5SDimitry Andric                    bit UsesCustomInserter = 0> :
16950b57cec5SDimitry Andric  PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
16960b57cec5SDimitry Andric           [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
16970b57cec5SDimitry Andric  PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
16980b57cec5SDimitry Andric  let isCommutable = IsComm;
16990b57cec5SDimitry Andric  let hasSideEffects = HasSideEffects;
17000b57cec5SDimitry Andric  let usesCustomInserter = UsesCustomInserter;
17010b57cec5SDimitry Andric}
17020b57cec5SDimitry Andric
17030b57cec5SDimitry Andric// Pseudo multiply add/sub instruction with explicit accumulator register
17040b57cec5SDimitry Andric// operands.
17050b57cec5SDimitry Andricclass MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
17060b57cec5SDimitry Andric                    InstrItinClass itin>
17070b57cec5SDimitry Andric  : PseudoSE<(outs ACC64:$ac),
17080b57cec5SDimitry Andric             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
17090b57cec5SDimitry Andric             [(set ACC64:$ac,
17100b57cec5SDimitry Andric              (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
17110b57cec5SDimitry Andric             itin>,
17120b57cec5SDimitry Andric    PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
17130b57cec5SDimitry Andric  string Constraints = "$acin = $ac";
17140b57cec5SDimitry Andric}
17150b57cec5SDimitry Andric
17160b57cec5SDimitry Andricclass Div<string opstr, InstrItinClass itin, RegisterOperand RO,
17170b57cec5SDimitry Andric          list<Register> DefRegs> :
17180b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
17190b57cec5SDimitry Andric         [], itin, FrmR, opstr> {
17200b57cec5SDimitry Andric  let Defs = DefRegs;
17210b57cec5SDimitry Andric}
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andric// Move from Hi/Lo
17240b57cec5SDimitry Andricclass PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
17250b57cec5SDimitry Andric  : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
17260b57cec5SDimitry Andric             [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
17270b57cec5SDimitry Andric
17280b57cec5SDimitry Andricclass MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
17290b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
17300b57cec5SDimitry Andric         FrmR, opstr> {
17310b57cec5SDimitry Andric  let Uses = [UseReg];
17320b57cec5SDimitry Andric  let hasSideEffects = 0;
17330b57cec5SDimitry Andric  let isMoveReg = 1;
17340b57cec5SDimitry Andric}
17350b57cec5SDimitry Andric
17360b57cec5SDimitry Andricclass PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
17370b57cec5SDimitry Andric  : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
17380b57cec5SDimitry Andric             [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
17390b57cec5SDimitry Andric             II_MTHI_MTLO>;
17400b57cec5SDimitry Andric
17410b57cec5SDimitry Andricclass MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
17420b57cec5SDimitry Andric  InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
17430b57cec5SDimitry Andric  FrmR, opstr> {
17440b57cec5SDimitry Andric  let Defs = DefRegs;
17450b57cec5SDimitry Andric  let hasSideEffects = 0;
17460b57cec5SDimitry Andric  let isMoveReg = 1;
17470b57cec5SDimitry Andric}
17480b57cec5SDimitry Andric
17490b57cec5SDimitry Andricclass EffectiveAddress<string opstr, RegisterOperand RO> :
17500b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
17510b57cec5SDimitry Andric         [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
17520b57cec5SDimitry Andric         !strconcat(opstr, "_lea")> {
17530b57cec5SDimitry Andric  let isCodeGenOnly = 1;
17540b57cec5SDimitry Andric  let hasNoSchedulingInfo = 1;
17550b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
17560b57cec5SDimitry Andric}
17570b57cec5SDimitry Andric
17580b57cec5SDimitry Andric// Count Leading Ones/Zeros in Word
17590b57cec5SDimitry Andricclass CountLeading0<string opstr, RegisterOperand RO,
17600b57cec5SDimitry Andric                  InstrItinClass itin = NoItinerary>:
17610b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
17620b57cec5SDimitry Andric         [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
17630b57cec5SDimitry Andric
17640b57cec5SDimitry Andricclass CountLeading1<string opstr, RegisterOperand RO,
17650b57cec5SDimitry Andric                  InstrItinClass itin = NoItinerary>:
17660b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
17670b57cec5SDimitry Andric         [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
17680b57cec5SDimitry Andric
17690b57cec5SDimitry Andric// Sign Extend in Register.
17700b57cec5SDimitry Andricclass SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
17710b57cec5SDimitry Andric                   InstrItinClass itin> :
17720b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
17730b57cec5SDimitry Andric         [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
17740b57cec5SDimitry Andric
17750b57cec5SDimitry Andric// Subword Swap
17760b57cec5SDimitry Andricclass SubwordSwap<string opstr, RegisterOperand RO,
17770b57cec5SDimitry Andric                  InstrItinClass itin = NoItinerary>:
17780b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
17790b57cec5SDimitry Andric         FrmR, opstr> {
17800b57cec5SDimitry Andric  let hasSideEffects = 0;
17810b57cec5SDimitry Andric}
17820b57cec5SDimitry Andric
17830b57cec5SDimitry Andric// Read Hardware
17840b57cec5SDimitry Andricclass ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
17850b57cec5SDimitry Andric  InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
17860b57cec5SDimitry Andric         "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
17870b57cec5SDimitry Andric
17880b57cec5SDimitry Andric// Ext and Ins
17890b57cec5SDimitry Andricclass ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
17900b57cec5SDimitry Andric              Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
17910b57cec5SDimitry Andric              SDPatternOperator Op = null_frag> :
17920b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
17930b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
17940b57cec5SDimitry Andric         [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
17950b57cec5SDimitry Andric         FrmR, opstr>;
17960b57cec5SDimitry Andric
17970b57cec5SDimitry Andric// 'ins' and its' 64 bit variants are matched by C++ code.
17980b57cec5SDimitry Andricclass InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
17990b57cec5SDimitry Andric              Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
18000b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
18010b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
18020b57cec5SDimitry Andric         [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
18030b57cec5SDimitry Andric                                  RO:$src))],
18040b57cec5SDimitry Andric         II_INS, FrmR, opstr> {
18050b57cec5SDimitry Andric  let Constraints = "$src = $rt";
18060b57cec5SDimitry Andric}
18070b57cec5SDimitry Andric
18080b57cec5SDimitry Andric// Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
18090b57cec5SDimitry Andricclass Atomic2Ops<PatFrag Op, RegisterClass DRC> :
18100b57cec5SDimitry Andric  PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
18110b57cec5SDimitry Andric           [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
18120b57cec5SDimitry Andric  let hasNoSchedulingInfo = 1;
18130b57cec5SDimitry Andric}
18140b57cec5SDimitry Andric
18150b57cec5SDimitry Andricclass Atomic2OpsPostRA<RegisterClass RC> :
18160b57cec5SDimitry Andric  PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
18170b57cec5SDimitry Andric  let mayLoad = 1;
18180b57cec5SDimitry Andric  let mayStore = 1;
18190b57cec5SDimitry Andric}
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andricclass Atomic2OpsSubwordPostRA<RegisterClass RC> :
18220b57cec5SDimitry Andric  PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
18230b57cec5SDimitry Andric                                RC:$shiftamnt), []>;
18240b57cec5SDimitry Andric
18250b57cec5SDimitry Andric// Atomic Compare & Swap.
18260b57cec5SDimitry Andric// Atomic compare and swap is lowered into two stages. The first stage happens
18270b57cec5SDimitry Andric// during ISelLowering, which produces the PostRA version of this instruction.
18280b57cec5SDimitry Andricclass AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
18290b57cec5SDimitry Andric  PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
18300b57cec5SDimitry Andric           [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
18310b57cec5SDimitry Andric  let hasNoSchedulingInfo = 1;
18320b57cec5SDimitry Andric}
18330b57cec5SDimitry Andric
18340b57cec5SDimitry Andricclass AtomicCmpSwapPostRA<RegisterClass RC> :
18350b57cec5SDimitry Andric  PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
18360b57cec5SDimitry Andric  let mayLoad = 1;
18370b57cec5SDimitry Andric  let mayStore = 1;
18380b57cec5SDimitry Andric}
18390b57cec5SDimitry Andric
18400b57cec5SDimitry Andricclass AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
18410b57cec5SDimitry Andric  PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
18420b57cec5SDimitry Andric                                RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
18430b57cec5SDimitry Andric  let mayLoad = 1;
18440b57cec5SDimitry Andric  let mayStore = 1;
18450b57cec5SDimitry Andric}
18460b57cec5SDimitry Andric
18470b57cec5SDimitry Andricclass LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
18480b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
18490b57cec5SDimitry Andric         [], II_LL, FrmI, opstr> {
18500b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
18510b57cec5SDimitry Andric  let mayLoad = 1;
18520b57cec5SDimitry Andric}
18530b57cec5SDimitry Andric
18540b57cec5SDimitry Andricclass SCBase<string opstr, RegisterOperand RO> :
18550b57cec5SDimitry Andric  InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
18560b57cec5SDimitry Andric         !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
18570b57cec5SDimitry Andric  let DecoderMethod = "DecodeMem";
18580b57cec5SDimitry Andric  let mayStore = 1;
18590b57cec5SDimitry Andric  let Constraints = "$rt = $dst";
18600b57cec5SDimitry Andric}
18610b57cec5SDimitry Andric
18620b57cec5SDimitry Andricclass MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
18630b57cec5SDimitry Andric             InstrItinClass itin> :
18640b57cec5SDimitry Andric  InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
18650b57cec5SDimitry Andric         !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
18660b57cec5SDimitry Andric  let BaseOpcode = asmstr;
18670b57cec5SDimitry Andric}
18680b57cec5SDimitry Andric
18690b57cec5SDimitry Andricclass MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
18700b57cec5SDimitry Andric             InstrItinClass itin> :
18710b57cec5SDimitry Andric  InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
18720b57cec5SDimitry Andric         !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
18730b57cec5SDimitry Andric  let BaseOpcode = asmstr;
18740b57cec5SDimitry Andric}
18750b57cec5SDimitry Andric
18760b57cec5SDimitry Andricclass TrapBase<Instruction RealInst>
18770b57cec5SDimitry Andric  : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
18780b57cec5SDimitry Andric    PseudoInstExpansion<(RealInst 0, 0)> {
18795ffd83dbSDimitry Andric  let mayStore = 0;
18805ffd83dbSDimitry Andric  let mayLoad = 0;
18815ffd83dbSDimitry Andric  let hasSideEffects = 1;
18825ffd83dbSDimitry Andric  let isTrap = 1;
18830b57cec5SDimitry Andric  let isCodeGenOnly = 1;
18840b57cec5SDimitry Andric}
18850b57cec5SDimitry Andric
18860b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
18870b57cec5SDimitry Andric// Pseudo instructions
18880b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
18890b57cec5SDimitry Andric
18900b57cec5SDimitry Andric// Return RA.
18910b57cec5SDimitry Andriclet isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
18920b57cec5SDimitry Andric  let hasDelaySlot=1 in
18930b57cec5SDimitry Andric  def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
18940b57cec5SDimitry Andric
18950b57cec5SDimitry Andric  let hasSideEffects=1 in
18960b57cec5SDimitry Andric  def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
18970b57cec5SDimitry Andric}
18980b57cec5SDimitry Andric
18990b57cec5SDimitry Andriclet Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
19000b57cec5SDimitry Andricdef ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
19010b57cec5SDimitry Andric                                  [(callseq_start timm:$amt1, timm:$amt2)]>;
19020b57cec5SDimitry Andricdef ADJCALLSTACKUP   : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
19030b57cec5SDimitry Andric                                  [(callseq_end timm:$amt1, timm:$amt2)]>;
19040b57cec5SDimitry Andric}
19050b57cec5SDimitry Andric
19060b57cec5SDimitry Andriclet usesCustomInserter = 1 in {
19070b57cec5SDimitry Andric  def ATOMIC_LOAD_ADD_I8   : Atomic2Ops<atomic_load_add_8, GPR32>;
19080b57cec5SDimitry Andric  def ATOMIC_LOAD_ADD_I16  : Atomic2Ops<atomic_load_add_16, GPR32>;
19090b57cec5SDimitry Andric  def ATOMIC_LOAD_ADD_I32  : Atomic2Ops<atomic_load_add_32, GPR32>;
19100b57cec5SDimitry Andric  def ATOMIC_LOAD_SUB_I8   : Atomic2Ops<atomic_load_sub_8, GPR32>;
19110b57cec5SDimitry Andric  def ATOMIC_LOAD_SUB_I16  : Atomic2Ops<atomic_load_sub_16, GPR32>;
19120b57cec5SDimitry Andric  def ATOMIC_LOAD_SUB_I32  : Atomic2Ops<atomic_load_sub_32, GPR32>;
19130b57cec5SDimitry Andric  def ATOMIC_LOAD_AND_I8   : Atomic2Ops<atomic_load_and_8, GPR32>;
19140b57cec5SDimitry Andric  def ATOMIC_LOAD_AND_I16  : Atomic2Ops<atomic_load_and_16, GPR32>;
19150b57cec5SDimitry Andric  def ATOMIC_LOAD_AND_I32  : Atomic2Ops<atomic_load_and_32, GPR32>;
19160b57cec5SDimitry Andric  def ATOMIC_LOAD_OR_I8    : Atomic2Ops<atomic_load_or_8, GPR32>;
19170b57cec5SDimitry Andric  def ATOMIC_LOAD_OR_I16   : Atomic2Ops<atomic_load_or_16, GPR32>;
19180b57cec5SDimitry Andric  def ATOMIC_LOAD_OR_I32   : Atomic2Ops<atomic_load_or_32, GPR32>;
19190b57cec5SDimitry Andric  def ATOMIC_LOAD_XOR_I8   : Atomic2Ops<atomic_load_xor_8, GPR32>;
19200b57cec5SDimitry Andric  def ATOMIC_LOAD_XOR_I16  : Atomic2Ops<atomic_load_xor_16, GPR32>;
19210b57cec5SDimitry Andric  def ATOMIC_LOAD_XOR_I32  : Atomic2Ops<atomic_load_xor_32, GPR32>;
19220b57cec5SDimitry Andric  def ATOMIC_LOAD_NAND_I8  : Atomic2Ops<atomic_load_nand_8, GPR32>;
19230b57cec5SDimitry Andric  def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
19240b57cec5SDimitry Andric  def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andric  def ATOMIC_SWAP_I8       : Atomic2Ops<atomic_swap_8, GPR32>;
19270b57cec5SDimitry Andric  def ATOMIC_SWAP_I16      : Atomic2Ops<atomic_swap_16, GPR32>;
19280b57cec5SDimitry Andric  def ATOMIC_SWAP_I32      : Atomic2Ops<atomic_swap_32, GPR32>;
19290b57cec5SDimitry Andric
19300b57cec5SDimitry Andric  def ATOMIC_CMP_SWAP_I8   : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
19310b57cec5SDimitry Andric  def ATOMIC_CMP_SWAP_I16  : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
19320b57cec5SDimitry Andric  def ATOMIC_CMP_SWAP_I32  : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
19330b57cec5SDimitry Andric
1934480093f4SDimitry Andric  def ATOMIC_LOAD_MIN_I8   : Atomic2Ops<atomic_load_min_8, GPR32>;
1935480093f4SDimitry Andric  def ATOMIC_LOAD_MIN_I16  : Atomic2Ops<atomic_load_min_16, GPR32>;
1936480093f4SDimitry Andric  def ATOMIC_LOAD_MIN_I32  : Atomic2Ops<atomic_load_min_32, GPR32>;
1937480093f4SDimitry Andric  def ATOMIC_LOAD_MAX_I8   : Atomic2Ops<atomic_load_max_8, GPR32>;
1938480093f4SDimitry Andric  def ATOMIC_LOAD_MAX_I16  : Atomic2Ops<atomic_load_max_16, GPR32>;
1939480093f4SDimitry Andric  def ATOMIC_LOAD_MAX_I32  : Atomic2Ops<atomic_load_max_32, GPR32>;
1940480093f4SDimitry Andric  def ATOMIC_LOAD_UMIN_I8  : Atomic2Ops<atomic_load_umin_8, GPR32>;
1941480093f4SDimitry Andric  def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops<atomic_load_umin_16, GPR32>;
1942480093f4SDimitry Andric  def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops<atomic_load_umin_32, GPR32>;
1943480093f4SDimitry Andric  def ATOMIC_LOAD_UMAX_I8  : Atomic2Ops<atomic_load_umax_8, GPR32>;
1944480093f4SDimitry Andric  def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops<atomic_load_umax_16, GPR32>;
1945480093f4SDimitry Andric  def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops<atomic_load_umax_32, GPR32>;
19460b57cec5SDimitry Andric}
19470b57cec5SDimitry Andric
19480b57cec5SDimitry Andricdef ATOMIC_LOAD_ADD_I8_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
19490b57cec5SDimitry Andricdef ATOMIC_LOAD_ADD_I16_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
19500b57cec5SDimitry Andricdef ATOMIC_LOAD_ADD_I32_POSTRA  : Atomic2OpsPostRA<GPR32>;
19510b57cec5SDimitry Andricdef ATOMIC_LOAD_SUB_I8_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
19520b57cec5SDimitry Andricdef ATOMIC_LOAD_SUB_I16_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
19530b57cec5SDimitry Andricdef ATOMIC_LOAD_SUB_I32_POSTRA  : Atomic2OpsPostRA<GPR32>;
19540b57cec5SDimitry Andricdef ATOMIC_LOAD_AND_I8_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
19550b57cec5SDimitry Andricdef ATOMIC_LOAD_AND_I16_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
19560b57cec5SDimitry Andricdef ATOMIC_LOAD_AND_I32_POSTRA  : Atomic2OpsPostRA<GPR32>;
19570b57cec5SDimitry Andricdef ATOMIC_LOAD_OR_I8_POSTRA    : Atomic2OpsSubwordPostRA<GPR32>;
19580b57cec5SDimitry Andricdef ATOMIC_LOAD_OR_I16_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
19590b57cec5SDimitry Andricdef ATOMIC_LOAD_OR_I32_POSTRA   : Atomic2OpsPostRA<GPR32>;
19600b57cec5SDimitry Andricdef ATOMIC_LOAD_XOR_I8_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
19610b57cec5SDimitry Andricdef ATOMIC_LOAD_XOR_I16_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
19620b57cec5SDimitry Andricdef ATOMIC_LOAD_XOR_I32_POSTRA  : Atomic2OpsPostRA<GPR32>;
19630b57cec5SDimitry Andricdef ATOMIC_LOAD_NAND_I8_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
19640b57cec5SDimitry Andricdef ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
19650b57cec5SDimitry Andricdef ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
19660b57cec5SDimitry Andric
19670b57cec5SDimitry Andricdef ATOMIC_SWAP_I8_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
19680b57cec5SDimitry Andricdef ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
19690b57cec5SDimitry Andricdef ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
19700b57cec5SDimitry Andric
19710b57cec5SDimitry Andricdef ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
19720b57cec5SDimitry Andricdef ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
19730b57cec5SDimitry Andricdef ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
19740b57cec5SDimitry Andric
1975480093f4SDimitry Andricdef ATOMIC_LOAD_MIN_I8_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
1976480093f4SDimitry Andricdef ATOMIC_LOAD_MIN_I16_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
1977480093f4SDimitry Andricdef ATOMIC_LOAD_MIN_I32_POSTRA  : Atomic2OpsPostRA<GPR32>;
1978480093f4SDimitry Andricdef ATOMIC_LOAD_MAX_I8_POSTRA   : Atomic2OpsSubwordPostRA<GPR32>;
1979480093f4SDimitry Andricdef ATOMIC_LOAD_MAX_I16_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
1980480093f4SDimitry Andricdef ATOMIC_LOAD_MAX_I32_POSTRA  : Atomic2OpsPostRA<GPR32>;
1981480093f4SDimitry Andricdef ATOMIC_LOAD_UMIN_I8_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
1982480093f4SDimitry Andricdef ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1983480093f4SDimitry Andricdef ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1984480093f4SDimitry Andricdef ATOMIC_LOAD_UMAX_I8_POSTRA  : Atomic2OpsSubwordPostRA<GPR32>;
1985480093f4SDimitry Andricdef ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1986480093f4SDimitry Andricdef ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1987480093f4SDimitry Andric
19880b57cec5SDimitry Andric/// Pseudo instructions for loading and storing accumulator registers.
19890b57cec5SDimitry Andriclet isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
19900b57cec5SDimitry Andric  def LOAD_ACC64  : Load<"", ACC64>;
19910b57cec5SDimitry Andric  def STORE_ACC64 : Store<"", ACC64>;
19920b57cec5SDimitry Andric}
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andric// We need these two pseudo instructions to avoid offset calculation for long
19950b57cec5SDimitry Andric// branches.  See the comment in file MipsLongBranch.cpp for detailed
19960b57cec5SDimitry Andric// explanation.
19970b57cec5SDimitry Andric
19980b57cec5SDimitry Andric// Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
19990b57cec5SDimitry Andricdef LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
20000b57cec5SDimitry Andric  (ins brtarget:$tgt, brtarget:$baltgt), []> {
20010b57cec5SDimitry Andric  bit hasNoSchedulingInfo = 1;
20020b57cec5SDimitry Andric}
20030b57cec5SDimitry Andric// Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
20040b57cec5SDimitry Andricdef LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
20050b57cec5SDimitry Andric  (ins brtarget:$tgt), []> {
20060b57cec5SDimitry Andric  bit hasNoSchedulingInfo = 1;
20070b57cec5SDimitry Andric}
20080b57cec5SDimitry Andric
20090b57cec5SDimitry Andric// Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
20100b57cec5SDimitry Andricdef LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
20110b57cec5SDimitry Andric  (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
20120b57cec5SDimitry Andric  bit hasNoSchedulingInfo = 1;
20130b57cec5SDimitry Andric}
20140b57cec5SDimitry Andric// Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
20150b57cec5SDimitry Andricdef LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
20160b57cec5SDimitry Andric  (ins GPR32Opnd:$src, brtarget:$tgt), []> {
20170b57cec5SDimitry Andric  bit hasNoSchedulingInfo = 1;
20180b57cec5SDimitry Andric}
20190b57cec5SDimitry Andric
20200b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
20210b57cec5SDimitry Andric// Instruction definition
20220b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
20230b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
20240b57cec5SDimitry Andric// MipsI Instructions
20250b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
20260b57cec5SDimitry Andric
20270b57cec5SDimitry Andric/// Arithmetic Instructions (ALU Immediate)
20280b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
20290b57cec5SDimitry Andric  def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2030480093f4SDimitry Andric                                             II_ADDIU, imm32SExt16, add>,
20310b57cec5SDimitry Andric              ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
20320b57cec5SDimitry Andric
20330b57cec5SDimitry Andric  def ANDi : MMRel, StdMMR6Rel,
2034480093f4SDimitry Andric             ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, imm32ZExt16, and>,
20350b57cec5SDimitry Andric             ADDI_FM<0xc>, ISA_MIPS1;
20360b57cec5SDimitry Andric  def ORi  : MMRel, StdMMR6Rel,
2037480093f4SDimitry Andric             ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, imm32ZExt16, or>,
20380b57cec5SDimitry Andric             ADDI_FM<0xd>, ISA_MIPS1;
20390b57cec5SDimitry Andric  def XORi : MMRel, StdMMR6Rel,
2040480093f4SDimitry Andric             ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, imm32ZExt16, xor>,
20410b57cec5SDimitry Andric             ADDI_FM<0xe>, ISA_MIPS1;
20420b57cec5SDimitry Andric  def ADDi  : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
20430b57cec5SDimitry Andric              ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
20440b57cec5SDimitry Andric  def SLTi  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
20450b57cec5SDimitry Andric              SLTI_FM<0xa>, ISA_MIPS1;
20460b57cec5SDimitry Andric  def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
20470b57cec5SDimitry Andric              SLTI_FM<0xb>, ISA_MIPS1;
20480b57cec5SDimitry Andric
20490b57cec5SDimitry Andric  def LUi   : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
20500b57cec5SDimitry Andric              ISA_MIPS1;
20510b57cec5SDimitry Andric
20520b57cec5SDimitry Andric  /// Arithmetic Instructions (3-Operand, R-Type)
20530b57cec5SDimitry Andric  def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
20540b57cec5SDimitry Andric             ADD_FM<0, 0x21>, ISA_MIPS1;
20550b57cec5SDimitry Andric  def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
20560b57cec5SDimitry Andric             ADD_FM<0, 0x23>, ISA_MIPS1;
20570b57cec5SDimitry Andric
20580b57cec5SDimitry Andric  let Defs = [HI0, LO0] in
20590b57cec5SDimitry Andric    def MUL   : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
20600b57cec5SDimitry Andric                ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
20610b57cec5SDimitry Andric
20620b57cec5SDimitry Andric  def ADD   : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
20630b57cec5SDimitry Andric              ADD_FM<0, 0x20>, ISA_MIPS1;
20640b57cec5SDimitry Andric  def SUB   : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
20650b57cec5SDimitry Andric              ADD_FM<0, 0x22>, ISA_MIPS1;
20660b57cec5SDimitry Andric
20670b57cec5SDimitry Andric  def SLT   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
20680b57cec5SDimitry Andric              ISA_MIPS1;
20690b57cec5SDimitry Andric  def SLTu  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
20700b57cec5SDimitry Andric              ISA_MIPS1;
20710b57cec5SDimitry Andric  def AND   : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
20720b57cec5SDimitry Andric              ADD_FM<0, 0x24>, ISA_MIPS1;
20730b57cec5SDimitry Andric  def OR    : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
20740b57cec5SDimitry Andric              ADD_FM<0, 0x25>, ISA_MIPS1;
20750b57cec5SDimitry Andric  def XOR   : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
20760b57cec5SDimitry Andric              ADD_FM<0, 0x26>, ISA_MIPS1;
20770b57cec5SDimitry Andric  def NOR   : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
20780b57cec5SDimitry Andric              ISA_MIPS1;
20790b57cec5SDimitry Andric}
20800b57cec5SDimitry Andric
20810b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
20820b57cec5SDimitry Andric  /// Shift Instructions
2083647cbc5dSDimitry Andric  def SLL  : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, mshl_32,
20840b57cec5SDimitry Andric                                     immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2085647cbc5dSDimitry Andric  def SRL  : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, msrl_32,
20860b57cec5SDimitry Andric                                     immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2087647cbc5dSDimitry Andric  def SRA  : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, msra_32,
20880b57cec5SDimitry Andric                                     immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2089647cbc5dSDimitry Andric  def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, mshl_32>,
20900b57cec5SDimitry Andric             SRLV_FM<4, 0>, ISA_MIPS1;
2091647cbc5dSDimitry Andric  def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, msrl_32>,
20920b57cec5SDimitry Andric             SRLV_FM<6, 0>, ISA_MIPS1;
2093647cbc5dSDimitry Andric  def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, msra_32>,
20940b57cec5SDimitry Andric             SRLV_FM<7, 0>, ISA_MIPS1;
20950b57cec5SDimitry Andric
20960b57cec5SDimitry Andric  // Rotate Instructions
20970b57cec5SDimitry Andric  def ROTR  : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
20980b57cec5SDimitry Andric                                      immZExt5>,
20990b57cec5SDimitry Andric              SRA_FM<2, 1>, ISA_MIPS32R2;
21000b57cec5SDimitry Andric  def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
21010b57cec5SDimitry Andric              SRLV_FM<6, 1>, ISA_MIPS32R2;
21020b57cec5SDimitry Andric}
21030b57cec5SDimitry Andric
21040b57cec5SDimitry Andric/// Load and Store Instructions
21050b57cec5SDimitry Andric///  aligned
21060b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
21070b57cec5SDimitry Andric  def LB  : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
21080b57cec5SDimitry Andric            LW_FM<0x20>, ISA_MIPS1;
21090b57cec5SDimitry Andric  def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
21100b57cec5SDimitry Andric                       addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
21110b57cec5SDimitry Andric  def LH  : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
21120b57cec5SDimitry Andric                       addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
21130b57cec5SDimitry Andric  def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
21140b57cec5SDimitry Andric            MMRel, LW_FM<0x25>, ISA_MIPS1;
21150b57cec5SDimitry Andric  def LW  : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
21160b57cec5SDimitry Andric            LW_FM<0x23>, ISA_MIPS1;
21170b57cec5SDimitry Andric  def SB  : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
21180b57cec5SDimitry Andric            LW_FM<0x28>, ISA_MIPS1;
21190b57cec5SDimitry Andric  def SH  : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
21200b57cec5SDimitry Andric            ISA_MIPS1;
2121480093f4SDimitry Andric  def SW  : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>,
2122480093f4SDimitry Andric            MMRel, LW_FM<0x2b>, ISA_MIPS1;
21230b57cec5SDimitry Andric}
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andric/// load/store left/right
21260b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
21270b57cec5SDimitry Andricdef LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
21280b57cec5SDimitry Andric          ISA_MIPS1_NOT_32R6_64R6;
21290b57cec5SDimitry Andricdef LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
21300b57cec5SDimitry Andric          ISA_MIPS1_NOT_32R6_64R6;
21310b57cec5SDimitry Andricdef SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
21320b57cec5SDimitry Andric          ISA_MIPS1_NOT_32R6_64R6;
21330b57cec5SDimitry Andricdef SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
21340b57cec5SDimitry Andric          ISA_MIPS1_NOT_32R6_64R6;
21350b57cec5SDimitry Andric
21360b57cec5SDimitry Andric// COP2 Memory Instructions
21370b57cec5SDimitry Andricdef LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
21380b57cec5SDimitry Andric           ISA_MIPS1_NOT_32R6_64R6;
21390b57cec5SDimitry Andricdef SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
21400b57cec5SDimitry Andric           LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
21410b57cec5SDimitry Andricdef LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
21420b57cec5SDimitry Andric           ISA_MIPS2_NOT_32R6_64R6;
21430b57cec5SDimitry Andricdef SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
21440b57cec5SDimitry Andric           LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
21450b57cec5SDimitry Andric
21460b57cec5SDimitry Andric// COP3 Memory Instructions
21470b57cec5SDimitry Andriclet DecoderNamespace = "COP3_" in {
21480b57cec5SDimitry Andric  def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
21490b57cec5SDimitry Andric             ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
21500b57cec5SDimitry Andric  def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
21510b57cec5SDimitry Andric             ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
21520b57cec5SDimitry Andric  def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
21530b57cec5SDimitry Andric             ISA_MIPS2, NOT_ASE_CNMIPS;
21540b57cec5SDimitry Andric  def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
21550b57cec5SDimitry Andric             ISA_MIPS2, NOT_ASE_CNMIPS;
21560b57cec5SDimitry Andric}
21570b57cec5SDimitry Andric
21580b57cec5SDimitry Andric  def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
21590b57cec5SDimitry Andric  def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
21600b57cec5SDimitry Andric              ISA_MIPS32R2;
21610b57cec5SDimitry Andric}
21620b57cec5SDimitry Andric
21630b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
21640b57cec5SDimitry Andric  def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
21650b57cec5SDimitry Andric            ISA_MIPS2;
21660b57cec5SDimitry Andric  def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
21670b57cec5SDimitry Andric            ISA_MIPS2;
21680b57cec5SDimitry Andric  def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
21690b57cec5SDimitry Andric             ISA_MIPS2;
21700b57cec5SDimitry Andric  def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
21710b57cec5SDimitry Andric            ISA_MIPS2;
21720b57cec5SDimitry Andric  def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
21730b57cec5SDimitry Andric            ISA_MIPS2;
21740b57cec5SDimitry Andric  def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
21750b57cec5SDimitry Andric            ISA_MIPS2;
21760b57cec5SDimitry Andric
21770b57cec5SDimitry Andric  def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
21780b57cec5SDimitry Andric             ISA_MIPS2_NOT_32R6_64R6;
21790b57cec5SDimitry Andric  def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
21800b57cec5SDimitry Andric             ISA_MIPS2_NOT_32R6_64R6;
21810b57cec5SDimitry Andric  def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
21820b57cec5SDimitry Andric              ISA_MIPS2_NOT_32R6_64R6;
21830b57cec5SDimitry Andric  def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
21840b57cec5SDimitry Andric             ISA_MIPS2_NOT_32R6_64R6;
21850b57cec5SDimitry Andric  def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
21860b57cec5SDimitry Andric               ISA_MIPS2_NOT_32R6_64R6;
21870b57cec5SDimitry Andric  def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
21880b57cec5SDimitry Andric             ISA_MIPS2_NOT_32R6_64R6;
21890b57cec5SDimitry Andric}
21900b57cec5SDimitry Andric
21910b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
21920b57cec5SDimitry Andric  def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
21930b57cec5SDimitry Andric  def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
21940b57cec5SDimitry Andric                ISA_MIPS1;
21950b57cec5SDimitry Andric  def TRAP : TrapBase<BREAK>, ISA_MIPS1;
21960b57cec5SDimitry Andric  def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
21970b57cec5SDimitry Andric              ISA_MIPS32_NOT_32R6_64R6;
21980b57cec5SDimitry Andric
21990b57cec5SDimitry Andric  def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
22000b57cec5SDimitry Andric  def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
22010b57cec5SDimitry Andric               ISA_MIPS32R5;
22020b57cec5SDimitry Andric  def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
22030b57cec5SDimitry Andric
22040b57cec5SDimitry Andric  def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
22050b57cec5SDimitry Andric           ISA_MIPS32R2;
22060b57cec5SDimitry Andric  def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
22070b57cec5SDimitry Andric           ISA_MIPS32R2;
22080b57cec5SDimitry Andric
22090b57cec5SDimitry Andric  def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
22100b57cec5SDimitry Andric}
22110b57cec5SDimitry Andric
22120b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
22130b57cec5SDimitry Andric/// Load-linked, Store-conditional
22140b57cec5SDimitry Andricdef LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
22150b57cec5SDimitry Andricdef SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
22160b57cec5SDimitry Andric}
22170b57cec5SDimitry Andric/// Jump and Branch Instructions
22180b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
22190b57cec5SDimitry Andricdef J       : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
22200b57cec5SDimitry Andric              IsBranch, ISA_MIPS1;
22210b57cec5SDimitry Andric
22220b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
2223480093f4SDimitry Andricdef JR      : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>,
2224480093f4SDimitry Andric              ISA_MIPS1_NOT_32R6_64R6;
22250b57cec5SDimitry Andricdef BEQ     : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
22260b57cec5SDimitry Andric              ISA_MIPS1;
22270b57cec5SDimitry Andricdef BEQL    : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
22280b57cec5SDimitry Andric              BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
22290b57cec5SDimitry Andricdef BNE     : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
22300b57cec5SDimitry Andric              ISA_MIPS1;
22310b57cec5SDimitry Andricdef BNEL    : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
22320b57cec5SDimitry Andric              BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
22330b57cec5SDimitry Andricdef BGEZ    : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
22340b57cec5SDimitry Andric              BGEZ_FM<1, 1>, ISA_MIPS1;
22350b57cec5SDimitry Andricdef BGEZL   : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
22360b57cec5SDimitry Andric              BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
22370b57cec5SDimitry Andricdef BGTZ    : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
22380b57cec5SDimitry Andric              BGEZ_FM<7, 0>, ISA_MIPS1;
22390b57cec5SDimitry Andricdef BGTZL   : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
22400b57cec5SDimitry Andric              BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
22410b57cec5SDimitry Andricdef BLEZ    : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
22420b57cec5SDimitry Andric              BGEZ_FM<6, 0>, ISA_MIPS1;
22430b57cec5SDimitry Andricdef BLEZL   : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
22440b57cec5SDimitry Andric              BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
22450b57cec5SDimitry Andricdef BLTZ    : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
22460b57cec5SDimitry Andric              BGEZ_FM<1, 0>, ISA_MIPS1;
22470b57cec5SDimitry Andricdef BLTZL   : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
22480b57cec5SDimitry Andric              BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
22490b57cec5SDimitry Andricdef B       : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
22500b57cec5SDimitry Andric
22510b57cec5SDimitry Andricdef JAL  : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
22520b57cec5SDimitry Andric
22530b57cec5SDimitry Andric}
22540b57cec5SDimitry Andric
22550b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
22560b57cec5SDimitry Andric  def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
22570b57cec5SDimitry Andric  def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
22580b57cec5SDimitry Andric}
22590b57cec5SDimitry Andric
22600b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
22610b57cec5SDimitry Andric  def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
22620b57cec5SDimitry Andric             ISA_MIPS32_NOT_32R6_64R6;
22630b57cec5SDimitry Andric  def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
22640b57cec5SDimitry Andric               ISA_MIPS1_NOT_32R6_64R6;
22650b57cec5SDimitry Andric  def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
22660b57cec5SDimitry Andric                BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
22670b57cec5SDimitry Andric  def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
22680b57cec5SDimitry Andric               ISA_MIPS1_NOT_32R6_64R6;
22690b57cec5SDimitry Andric  def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
22700b57cec5SDimitry Andric                BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
22710b57cec5SDimitry Andric  def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
22720b57cec5SDimitry Andric}
22730b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
22740b57cec5SDimitry Andric  def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
22750b57cec5SDimitry Andric}
22760b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
22770b57cec5SDimitry Andric                            NoIndirectJumpGuards] in
22780b57cec5SDimitry Andric  def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
22790b57cec5SDimitry Andric
22800b57cec5SDimitry Andric// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
22810b57cec5SDimitry Andric// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
22820b57cec5SDimitry Andricclass PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
22830b57cec5SDimitry Andric    MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
22840b57cec5SDimitry Andric               II_IndirectBranchPseudo>,
22850b57cec5SDimitry Andric    PseudoInstExpansion<(JumpInst RO:$rs)> {
22860b57cec5SDimitry Andric  let isTerminator=1;
22870b57cec5SDimitry Andric  let isBarrier=1;
22880b57cec5SDimitry Andric  let hasDelaySlot = 1;
22890b57cec5SDimitry Andric  let isBranch = 1;
22900b57cec5SDimitry Andric  let isIndirectBranch = 1;
22910b57cec5SDimitry Andric  bit isCTI = 1;
22920b57cec5SDimitry Andric}
22930b57cec5SDimitry Andric
22940b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
22950b57cec5SDimitry Andric                            NoIndirectJumpGuards] in
22960b57cec5SDimitry Andric  def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
22970b57cec5SDimitry Andric                             ISA_MIPS1_NOT_32R6_64R6;
22980b57cec5SDimitry Andric
22990b57cec5SDimitry Andric// Return instructions are matched as a RetRA instruction, then are expanded
23000b57cec5SDimitry Andric// into PseudoReturn/PseudoReturn64 after register allocation. Finally,
23010b57cec5SDimitry Andric// MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
23020b57cec5SDimitry Andric// ISA.
23030b57cec5SDimitry Andricclass PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
23040b57cec5SDimitry Andric                                                        [], II_ReturnPseudo> {
23050b57cec5SDimitry Andric  let isTerminator = 1;
23060b57cec5SDimitry Andric  let isBarrier = 1;
23070b57cec5SDimitry Andric  let hasDelaySlot = 1;
23080b57cec5SDimitry Andric  let isReturn = 1;
23090b57cec5SDimitry Andric  let isCodeGenOnly = 1;
23100b57cec5SDimitry Andric  let hasCtrlDep = 1;
23110b57cec5SDimitry Andric  let hasExtraSrcRegAllocReq = 1;
23120b57cec5SDimitry Andric  bit isCTI = 1;
23130b57cec5SDimitry Andric}
23140b57cec5SDimitry Andric
23150b57cec5SDimitry Andricdef PseudoReturn : PseudoReturnBase<GPR32Opnd>;
23160b57cec5SDimitry Andric
23170b57cec5SDimitry Andric// Exception handling related node and instructions.
23180b57cec5SDimitry Andric// The conversion sequence is:
23190b57cec5SDimitry Andric// ISD::EH_RETURN -> MipsISD::EH_RETURN ->
23200b57cec5SDimitry Andric// MIPSeh_return -> (stack change + indirect branch)
23210b57cec5SDimitry Andric//
23220b57cec5SDimitry Andric// MIPSeh_return takes the place of regular return instruction
23230b57cec5SDimitry Andric// but takes two arguments (V1, V0) which are used for storing
23240b57cec5SDimitry Andric// the offset and return address respectively.
23250b57cec5SDimitry Andricdef SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
23260b57cec5SDimitry Andric
23270b57cec5SDimitry Andricdef MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
23280b57cec5SDimitry Andric                      [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
23290b57cec5SDimitry Andric
23300b57cec5SDimitry Andriclet Uses = [V0, V1], isTerminator = 1, isReturn = 1,
23310b57cec5SDimitry Andric           isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
23320b57cec5SDimitry Andric  def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
23330b57cec5SDimitry Andric                                   [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
23340b57cec5SDimitry Andric  def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
23350b57cec5SDimitry Andric                                   [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
23360b57cec5SDimitry Andric}
23370b57cec5SDimitry Andric
23380b57cec5SDimitry Andric/// Multiply and Divide Instructions.
23390b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
23400b57cec5SDimitry Andric  def MULT  : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
23410b57cec5SDimitry Andric              MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
23420b57cec5SDimitry Andric  def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
23430b57cec5SDimitry Andric              MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
23440b57cec5SDimitry Andric  def SDIV  : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
23450b57cec5SDimitry Andric              MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
23460b57cec5SDimitry Andric  def UDIV  : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
23470b57cec5SDimitry Andric              MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
23480b57cec5SDimitry Andric  def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
23490b57cec5SDimitry Andric             ISA_MIPS1_NOT_32R6_64R6;
23500b57cec5SDimitry Andric  def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
23510b57cec5SDimitry Andric             ISA_MIPS1_NOT_32R6_64R6;
23520b57cec5SDimitry Andric  def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
23530b57cec5SDimitry Andric             ISA_MIPS1_NOT_32R6_64R6;
23540b57cec5SDimitry Andric  def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
23550b57cec5SDimitry Andric             ISA_MIPS1_NOT_32R6_64R6;
23560b57cec5SDimitry Andric
23570b57cec5SDimitry Andric  /// Sign Ext In Register Instructions.
23580b57cec5SDimitry Andric  def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
23590b57cec5SDimitry Andric            SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
23600b57cec5SDimitry Andric  def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
23610b57cec5SDimitry Andric            SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
23620b57cec5SDimitry Andric
23630b57cec5SDimitry Andric  /// Count Leading
23640b57cec5SDimitry Andric  def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
23650b57cec5SDimitry Andric            ISA_MIPS32_NOT_32R6_64R6;
23660b57cec5SDimitry Andric  def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
23670b57cec5SDimitry Andric            ISA_MIPS32_NOT_32R6_64R6;
23680b57cec5SDimitry Andric
23690b57cec5SDimitry Andric  /// Word Swap Bytes Within Halfwords
23700b57cec5SDimitry Andric  def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
23710b57cec5SDimitry Andric             ISA_MIPS32R2;
23720b57cec5SDimitry Andric
23730b57cec5SDimitry Andric  /// No operation.
23740b57cec5SDimitry Andric  def NOP : PseudoSE<(outs), (ins), []>,
23750b57cec5SDimitry Andric                     PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
23760b57cec5SDimitry Andric
23770b57cec5SDimitry Andric  // FrameIndexes are legalized when they are operands from load/store
23780b57cec5SDimitry Andric  // instructions. The same not happens for stack address copies, so an
23790b57cec5SDimitry Andric  // add op with mem ComplexPattern is used and the stack address copy
23800b57cec5SDimitry Andric  // can be matched. It's similar to Sparc LEA_ADDRi
23810b57cec5SDimitry Andric  let AdditionalPredicates = [NotInMicroMips] in
2382480093f4SDimitry Andric    def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>,
2383480093f4SDimitry Andric                    ISA_MIPS1;
23840b57cec5SDimitry Andric
23850b57cec5SDimitry Andric  // MADD*/MSUB*
23860b57cec5SDimitry Andric  def MADD  : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
23870b57cec5SDimitry Andric              ISA_MIPS32_NOT_32R6_64R6;
23880b57cec5SDimitry Andric  def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
23890b57cec5SDimitry Andric              ISA_MIPS32_NOT_32R6_64R6;
23900b57cec5SDimitry Andric  def MSUB  : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
23910b57cec5SDimitry Andric              ISA_MIPS32_NOT_32R6_64R6;
23920b57cec5SDimitry Andric  def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
23930b57cec5SDimitry Andric              ISA_MIPS32_NOT_32R6_64R6;
23940b57cec5SDimitry Andric}
23950b57cec5SDimitry Andric
23960b57cec5SDimitry Andriclet AdditionalPredicates = [NotDSP] in {
23970b57cec5SDimitry Andricdef PseudoMULT  : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
23980b57cec5SDimitry Andric                  ISA_MIPS1_NOT_32R6_64R6;
23990b57cec5SDimitry Andricdef PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
24000b57cec5SDimitry Andric                  ISA_MIPS1_NOT_32R6_64R6;
24010b57cec5SDimitry Andricdef PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
24020b57cec5SDimitry Andricdef PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
24030b57cec5SDimitry Andricdef PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
24040b57cec5SDimitry Andricdef PseudoMADD  : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
24050b57cec5SDimitry Andric                  ISA_MIPS32_NOT_32R6_64R6;
24060b57cec5SDimitry Andricdef PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
24070b57cec5SDimitry Andric                  ISA_MIPS32_NOT_32R6_64R6;
24080b57cec5SDimitry Andricdef PseudoMSUB  : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
24090b57cec5SDimitry Andric                  ISA_MIPS32_NOT_32R6_64R6;
24100b57cec5SDimitry Andricdef PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
24110b57cec5SDimitry Andric                  ISA_MIPS32_NOT_32R6_64R6;
24120b57cec5SDimitry Andric}
24130b57cec5SDimitry Andric
24140b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
24150b57cec5SDimitry Andric  def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
24160b57cec5SDimitry Andric                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
24170b57cec5SDimitry Andric  def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
24180b57cec5SDimitry Andric                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
24190b57cec5SDimitry Andric  def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
24200b57cec5SDimitry Andric  // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
24210b57cec5SDimitry Andric  def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
24220b57cec5SDimitry Andric                                       immZExt5, immZExt5Plus1, MipsExt>,
24230b57cec5SDimitry Andric            EXT_FM<0>, ISA_MIPS32R2;
24240b57cec5SDimitry Andric  def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
24250b57cec5SDimitry Andric                                       uimm5_inssize_plus1, immZExt5,
24260b57cec5SDimitry Andric                                       immZExt5Plus1>,
24270b57cec5SDimitry Andric            EXT_FM<4>, ISA_MIPS32R2;
24280b57cec5SDimitry Andric}
24290b57cec5SDimitry Andric/// Move Control Registers From/To CPU Registers
24300b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
24310b57cec5SDimitry Andric  def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
24320b57cec5SDimitry Andric             MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
24330b57cec5SDimitry Andric  def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
24340b57cec5SDimitry Andric             MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
24350b57cec5SDimitry Andric  def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
24360b57cec5SDimitry Andric             MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
24370b57cec5SDimitry Andric  def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
24380b57cec5SDimitry Andric             MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
24390b57cec5SDimitry Andric}
24400b57cec5SDimitry Andric
24410b57cec5SDimitry Andricclass Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
24420b57cec5SDimitry Andric  InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
24430b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
24440b57cec5SDimitry Andric  def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
24450b57cec5SDimitry Andric              ISA_MIPS1;
24460b57cec5SDimitry Andric  def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
24470b57cec5SDimitry Andric
24480b57cec5SDimitry Andric  let isCTI = 1 in
24490b57cec5SDimitry Andric  def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
24500b57cec5SDimitry Andric              ISA_MIPS32R2;
24510b57cec5SDimitry Andric}
24520b57cec5SDimitry Andric
24530b57cec5SDimitry Andric// JR_HB and JALR_HB are defined here using the new style naming
24540b57cec5SDimitry Andric// scheme because some of this code is shared with Mips32r6InstrInfo.td
24550b57cec5SDimitry Andric// and because of that it doesn't follow the naming convention of the
24560b57cec5SDimitry Andric// rest of the file. To avoid a mixture of old vs new style, the new
24570b57cec5SDimitry Andric// style was chosen.
24580b57cec5SDimitry Andricclass JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
24590b57cec5SDimitry Andric  dag OutOperandList = (outs);
24600b57cec5SDimitry Andric  dag InOperandList = (ins GPROpnd:$rs);
24610b57cec5SDimitry Andric  string AsmString = !strconcat(instr_asm, "\t$rs");
24620b57cec5SDimitry Andric  list<dag> Pattern = [];
24630b57cec5SDimitry Andric}
24640b57cec5SDimitry Andric
24650b57cec5SDimitry Andricclass JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
24660b57cec5SDimitry Andric  dag OutOperandList = (outs GPROpnd:$rd);
24670b57cec5SDimitry Andric  dag InOperandList = (ins GPROpnd:$rs);
24680b57cec5SDimitry Andric  string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
24690b57cec5SDimitry Andric  list<dag> Pattern = [];
24700b57cec5SDimitry Andric}
24710b57cec5SDimitry Andric
24720b57cec5SDimitry Andricclass JR_HB_DESC<RegisterOperand RO> :
24730b57cec5SDimitry Andric  InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
24740b57cec5SDimitry Andric  let isBranch=1;
24750b57cec5SDimitry Andric  let isIndirectBranch=1;
24760b57cec5SDimitry Andric  let hasDelaySlot=1;
24770b57cec5SDimitry Andric  let isTerminator=1;
24780b57cec5SDimitry Andric  let isBarrier=1;
24790b57cec5SDimitry Andric  bit isCTI = 1;
24800b57cec5SDimitry Andric}
24810b57cec5SDimitry Andric
24820b57cec5SDimitry Andricclass JALR_HB_DESC<RegisterOperand RO> :
24830b57cec5SDimitry Andric  InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
24840b57cec5SDimitry Andric                                                                     RO> {
24850b57cec5SDimitry Andric  let isIndirectBranch=1;
24860b57cec5SDimitry Andric  let hasDelaySlot=1;
24870b57cec5SDimitry Andric  bit isCTI = 1;
24880b57cec5SDimitry Andric}
24890b57cec5SDimitry Andric
24900b57cec5SDimitry Andricclass JR_HB_ENC : JR_HB_FM<8>;
24910b57cec5SDimitry Andricclass JALR_HB_ENC : JALR_HB_FM<9>;
24920b57cec5SDimitry Andric
24930b57cec5SDimitry Andricdef JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
24940b57cec5SDimitry Andricdef JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
24950b57cec5SDimitry Andric
24960b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
24970b57cec5SDimitry Andric  def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
24980b57cec5SDimitry Andric
24990b57cec5SDimitry Andric
25000b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
25010b57cec5SDimitry Andric                            UseIndirectJumpsHazard] in {
25020b57cec5SDimitry Andric  def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
25030b57cec5SDimitry Andric  def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
25040b57cec5SDimitry Andric                                   ISA_MIPS32R2_NOT_32R6_64R6;
25050b57cec5SDimitry Andric}
25060b57cec5SDimitry Andric
25070b57cec5SDimitry Andricclass TLB<string asmstr, InstrItinClass itin = NoItinerary> :
25080b57cec5SDimitry Andric  InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
25090b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
25100b57cec5SDimitry Andric  def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
25110b57cec5SDimitry Andric  def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
25120b57cec5SDimitry Andric  def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
25130b57cec5SDimitry Andric  def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
25140b57cec5SDimitry Andric}
25150b57cec5SDimitry Andricclass CacheOp<string instr_asm, Operand MemOpnd,
25160b57cec5SDimitry Andric              InstrItinClass itin = NoItinerary> :
25170b57cec5SDimitry Andric    InstSE<(outs), (ins  MemOpnd:$addr, uimm5:$hint),
25180b57cec5SDimitry Andric           !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
25190b57cec5SDimitry Andric           instr_asm> {
25200b57cec5SDimitry Andric  let DecoderMethod = "DecodeCacheOp";
25210b57cec5SDimitry Andric}
25220b57cec5SDimitry Andric
25230b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
25240b57cec5SDimitry Andric  def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
25250b57cec5SDimitry Andric              INSN_MIPS3_32_NOT_32R6_64R6;
25260b57cec5SDimitry Andric  def PREF :  MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
25270b57cec5SDimitry Andric              INSN_MIPS3_32_NOT_32R6_64R6;
25280b57cec5SDimitry Andric}
25290b57cec5SDimitry Andric// FIXME: We are missing the prefx instruction.
25300b57cec5SDimitry Andricdef ROL : MipsAsmPseudoInst<(outs),
25310b57cec5SDimitry Andric                            (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
25320b57cec5SDimitry Andric                            "rol\t$rs, $rt, $rd">;
25330b57cec5SDimitry Andricdef ROLImm : MipsAsmPseudoInst<(outs),
25340b57cec5SDimitry Andric                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
25350b57cec5SDimitry Andric                               "rol\t$rs, $rt, $imm">;
25360b57cec5SDimitry Andricdef : MipsInstAlias<"rol $rd, $rs",
25370b57cec5SDimitry Andric                    (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
25380b57cec5SDimitry Andricdef : MipsInstAlias<"rol $rd, $imm",
25390b57cec5SDimitry Andric                    (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
25400b57cec5SDimitry Andric
25410b57cec5SDimitry Andricdef ROR : MipsAsmPseudoInst<(outs),
25420b57cec5SDimitry Andric                            (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
25430b57cec5SDimitry Andric                            "ror\t$rs, $rt, $rd">;
25440b57cec5SDimitry Andricdef RORImm : MipsAsmPseudoInst<(outs),
25450b57cec5SDimitry Andric                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
25460b57cec5SDimitry Andric                               "ror\t$rs, $rt, $imm">;
25470b57cec5SDimitry Andricdef : MipsInstAlias<"ror $rd, $rs",
25480b57cec5SDimitry Andric                    (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
25490b57cec5SDimitry Andricdef : MipsInstAlias<"ror $rd, $imm",
25500b57cec5SDimitry Andric                    (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
25510b57cec5SDimitry Andric
25520b57cec5SDimitry Andricdef DROL : MipsAsmPseudoInst<(outs),
25530b57cec5SDimitry Andric                             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
25540b57cec5SDimitry Andric                             "drol\t$rs, $rt, $rd">, ISA_MIPS64;
25550b57cec5SDimitry Andricdef DROLImm : MipsAsmPseudoInst<(outs),
25560b57cec5SDimitry Andric                                (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
25570b57cec5SDimitry Andric                                "drol\t$rs, $rt, $imm">, ISA_MIPS64;
25580b57cec5SDimitry Andricdef : MipsInstAlias<"drol $rd, $rs",
2559480093f4SDimitry Andric                    (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2560480093f4SDimitry Andric      ISA_MIPS64;
25610b57cec5SDimitry Andricdef : MipsInstAlias<"drol $rd, $imm",
2562480093f4SDimitry Andric                    (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2563480093f4SDimitry Andric      ISA_MIPS64;
25640b57cec5SDimitry Andric
25650b57cec5SDimitry Andricdef DROR : MipsAsmPseudoInst<(outs),
25660b57cec5SDimitry Andric                             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
25670b57cec5SDimitry Andric                             "dror\t$rs, $rt, $rd">, ISA_MIPS64;
25680b57cec5SDimitry Andricdef DRORImm : MipsAsmPseudoInst<(outs),
25690b57cec5SDimitry Andric                                (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
25700b57cec5SDimitry Andric                                "dror\t$rs, $rt, $imm">, ISA_MIPS64;
25710b57cec5SDimitry Andricdef : MipsInstAlias<"dror $rd, $rs",
2572480093f4SDimitry Andric                    (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2573480093f4SDimitry Andric      ISA_MIPS64;
25740b57cec5SDimitry Andricdef : MipsInstAlias<"dror $rd, $imm",
2575480093f4SDimitry Andric                    (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2576480093f4SDimitry Andric      ISA_MIPS64;
25770b57cec5SDimitry Andric
25780b57cec5SDimitry Andricdef ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
25790b57cec5SDimitry Andric                                 "abs\t$rd, $rs">;
25800b57cec5SDimitry Andric
25810b57cec5SDimitry Andricdef SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
25820b57cec5SDimitry Andric                                 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
25830b57cec5SDimitry Andric                                 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
25840b57cec5SDimitry Andric
25850b57cec5SDimitry Andricdef : MipsInstAlias<"seq $rd, $rs",
25860b57cec5SDimitry Andric                    (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
25870b57cec5SDimitry Andric                    NOT_ASE_CNMIPS;
25880b57cec5SDimitry Andric
25890b57cec5SDimitry Andricdef SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
25900b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
25910b57cec5SDimitry Andric                                  "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
25920b57cec5SDimitry Andric
25930b57cec5SDimitry Andricdef : MipsInstAlias<"seq $rd, $imm",
25940b57cec5SDimitry Andric                    (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
25950b57cec5SDimitry Andric                    NOT_ASE_CNMIPS;
25960b57cec5SDimitry Andric
25975ffd83dbSDimitry Andricdef SNEMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
25985ffd83dbSDimitry Andric                                 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
25995ffd83dbSDimitry Andric                                 "sne $rd, $rs, $rt">, NOT_ASE_CNMIPS;
26005ffd83dbSDimitry Andric
26015ffd83dbSDimitry Andricdef : MipsInstAlias<"sne $rd, $rs",
26025ffd83dbSDimitry Andric                    (SNEMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
26035ffd83dbSDimitry Andric                    NOT_ASE_CNMIPS;
26045ffd83dbSDimitry Andric
26055ffd83dbSDimitry Andricdef SNEIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
26065ffd83dbSDimitry Andric                                  (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
26075ffd83dbSDimitry Andric                                  "sne $rd, $rs, $imm">, NOT_ASE_CNMIPS;
26085ffd83dbSDimitry Andric
26095ffd83dbSDimitry Andricdef : MipsInstAlias<"sne $rd, $imm",
26105ffd83dbSDimitry Andric                    (SNEIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
26115ffd83dbSDimitry Andric                    NOT_ASE_CNMIPS;
26125ffd83dbSDimitry Andric
26130b57cec5SDimitry Andricdef MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
26140b57cec5SDimitry Andric                                                 simm32_relaxed:$imm),
26150b57cec5SDimitry Andric                                    "mul\t$rd, $rs, $imm">,
26160b57cec5SDimitry Andric                  ISA_MIPS1_NOT_32R6_64R6;
26170b57cec5SDimitry Andricdef MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
26180b57cec5SDimitry Andric                                               GPR32Opnd:$rt),
26190b57cec5SDimitry Andric                                  "mulo\t$rd, $rs, $rt">,
26200b57cec5SDimitry Andric                ISA_MIPS1_NOT_32R6_64R6;
26210b57cec5SDimitry Andricdef MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
26220b57cec5SDimitry Andric                                                GPR32Opnd:$rt),
26230b57cec5SDimitry Andric                                   "mulou\t$rd, $rs, $rt">,
26240b57cec5SDimitry Andric                 ISA_MIPS1_NOT_32R6_64R6;
26250b57cec5SDimitry Andric
26260b57cec5SDimitry Andric// Virtualization ASE
26270b57cec5SDimitry Andricclass HYPCALL_FT<string opstr> :
26280b57cec5SDimitry Andric  InstSE<(outs), (ins uimm10:$code_),
26290b57cec5SDimitry Andric         !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
26300b57cec5SDimitry Andric  let BaseOpcode = opstr;
26310b57cec5SDimitry Andric}
26320b57cec5SDimitry Andric
26330b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
26340b57cec5SDimitry Andric  def MFGC0    : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
26350b57cec5SDimitry Andric                 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
26360b57cec5SDimitry Andric  def MTGC0    : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
26370b57cec5SDimitry Andric                 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
26380b57cec5SDimitry Andric  def MFHGC0   : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
26390b57cec5SDimitry Andric                 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
26400b57cec5SDimitry Andric  def MTHGC0   : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
26410b57cec5SDimitry Andric                 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
26420b57cec5SDimitry Andric  def TLBGINV  : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
26430b57cec5SDimitry Andric                 ISA_MIPS32R5, ASE_VIRT;
26440b57cec5SDimitry Andric  def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
26450b57cec5SDimitry Andric                 ISA_MIPS32R5, ASE_VIRT;
26460b57cec5SDimitry Andric  def TLBGP    : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
26470b57cec5SDimitry Andric                 ISA_MIPS32R5, ASE_VIRT;
26480b57cec5SDimitry Andric  def TLBGR    : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
26490b57cec5SDimitry Andric                 ISA_MIPS32R5, ASE_VIRT;
26500b57cec5SDimitry Andric  def TLBGWI   : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
26510b57cec5SDimitry Andric                 ISA_MIPS32R5, ASE_VIRT;
26520b57cec5SDimitry Andric  def TLBGWR   : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
26530b57cec5SDimitry Andric                 ISA_MIPS32R5, ASE_VIRT;
26540b57cec5SDimitry Andric  def HYPCALL  : MMRel, HYPCALL_FT<"hypcall">,
26550b57cec5SDimitry Andric                 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
26560b57cec5SDimitry Andric}
26570b57cec5SDimitry Andric
26580b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
26590b57cec5SDimitry Andric// Instruction aliases
26600b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
26610b57cec5SDimitry Andric
26620b57cec5SDimitry Andricmulticlass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
26630b57cec5SDimitry Andric                                              Instruction Opcode,
26640b57cec5SDimitry Andric                                              RegisterOperand RO = GPR32Opnd,
26650b57cec5SDimitry Andric                                              Operand Imm = simm32_relaxed> {
26660b57cec5SDimitry Andric  def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
26670b57cec5SDimitry Andric                                (Opcode RO:$rs,
26680b57cec5SDimitry Andric                                        RO:$rt,
26690b57cec5SDimitry Andric                                        Imm:$imm), 0>;
26700b57cec5SDimitry Andric  def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
26710b57cec5SDimitry Andric                                (Opcode RO:$rs,
26720b57cec5SDimitry Andric                                        RO:$rs,
26730b57cec5SDimitry Andric                                        Imm:$imm), 0>;
26740b57cec5SDimitry Andric}
26750b57cec5SDimitry Andric
26760b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
26770b57cec5SDimitry Andric  def : MipsInstAlias<"move $dst, $src",
26780b57cec5SDimitry Andric                      (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
26790b57cec5SDimitry Andric        GPR_32, ISA_MIPS1;
26800b57cec5SDimitry Andric  def : MipsInstAlias<"move $dst, $src",
26810b57cec5SDimitry Andric                      (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
26820b57cec5SDimitry Andric        GPR_32, ISA_MIPS1;
26830b57cec5SDimitry Andric
26840b57cec5SDimitry Andric  def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
26850b57cec5SDimitry Andric        ISA_MIPS1_NOT_32R6_64R6;
26860b57cec5SDimitry Andric
26870b57cec5SDimitry Andric  def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
26880b57cec5SDimitry Andric
26890b57cec5SDimitry Andric  def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
26900b57cec5SDimitry Andric
26910b57cec5SDimitry Andric  def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
26920b57cec5SDimitry Andric        ISA_MIPS32;
26930b57cec5SDimitry Andric
26940b57cec5SDimitry Andric  def : MipsInstAlias<"neg $rt, $rs",
26950b57cec5SDimitry Andric                      (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
26960b57cec5SDimitry Andric  def : MipsInstAlias<"neg $rt",
26970b57cec5SDimitry Andric                      (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
26980b57cec5SDimitry Andric  def : MipsInstAlias<"negu $rt, $rs",
26990b57cec5SDimitry Andric                      (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
27000b57cec5SDimitry Andric  def : MipsInstAlias<"negu $rt",
27010b57cec5SDimitry Andric                      (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
27020b57cec5SDimitry Andric
27030b57cec5SDimitry Andric  def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27040b57cec5SDimitry Andric                              (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
27050b57cec5SDimitry Andric                              "sge\t$rd, $rs, $rt">, ISA_MIPS1;
27060b57cec5SDimitry Andric  def : MipsInstAlias<"sge $rs, $rt",
27070b57cec5SDimitry Andric                      (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
27080b57cec5SDimitry Andric        ISA_MIPS1;
27090b57cec5SDimitry Andric  def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27100b57cec5SDimitry Andric                                 (ins GPR32Opnd:$rs, simm32:$imm),
27110b57cec5SDimitry Andric                                 "sge\t$rd, $rs, $imm">, GPR_32;
27120b57cec5SDimitry Andric  def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
27130b57cec5SDimitry Andric                                               GPR32Opnd:$rs,
27140b57cec5SDimitry Andric                                               simm32:$imm), 0>,
27150b57cec5SDimitry Andric        GPR_32;
27160b57cec5SDimitry Andric
27170b57cec5SDimitry Andric  def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27180b57cec5SDimitry Andric                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
27190b57cec5SDimitry Andric                               "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
27200b57cec5SDimitry Andric  def : MipsInstAlias<"sgeu $rs, $rt",
27210b57cec5SDimitry Andric                      (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
27220b57cec5SDimitry Andric        ISA_MIPS1;
27230b57cec5SDimitry Andric  def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27240b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
27250b57cec5SDimitry Andric                                  "sgeu\t$rd, $rs, $imm">, GPR_32;
27260b57cec5SDimitry Andric  def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
27270b57cec5SDimitry Andric                                                 GPR32Opnd:$rs,
27280b57cec5SDimitry Andric                                                 uimm32_coerced:$imm), 0>,
27290b57cec5SDimitry Andric        GPR_32;
27300b57cec5SDimitry Andric
27310b57cec5SDimitry Andric  def : MipsInstAlias<
27320b57cec5SDimitry Andric          "sgt $rd, $rs, $rt",
27330b57cec5SDimitry Andric          (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
27340b57cec5SDimitry Andric  def : MipsInstAlias<
27350b57cec5SDimitry Andric          "sgt $rs, $rt",
27360b57cec5SDimitry Andric          (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
27370b57cec5SDimitry Andric
27380b57cec5SDimitry Andric  def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27390b57cec5SDimitry Andric                                 (ins GPR32Opnd:$rs, simm32:$imm),
27400b57cec5SDimitry Andric                                 "sgt\t$rd, $rs, $imm">, GPR_32;
27410b57cec5SDimitry Andric  def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
27420b57cec5SDimitry Andric                                               GPR32Opnd:$rs,
27430b57cec5SDimitry Andric                                               simm32:$imm), 0>,
27440b57cec5SDimitry Andric        GPR_32;
27450b57cec5SDimitry Andric  def : MipsInstAlias<
27460b57cec5SDimitry Andric          "sgtu $rd, $rs, $rt",
27470b57cec5SDimitry Andric          (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
27480b57cec5SDimitry Andric  def : MipsInstAlias<
27490b57cec5SDimitry Andric          "sgtu $$rs, $rt",
27500b57cec5SDimitry Andric          (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
27510b57cec5SDimitry Andric
27520b57cec5SDimitry Andric  def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27530b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
27540b57cec5SDimitry Andric                                  "sgtu\t$rd, $rs, $imm">, GPR_32;
27550b57cec5SDimitry Andric  def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
27560b57cec5SDimitry Andric                                                 GPR32Opnd:$rs,
27570b57cec5SDimitry Andric                                                 uimm32_coerced:$imm), 0>,
27580b57cec5SDimitry Andric        GPR_32;
27590b57cec5SDimitry Andric
27605ffd83dbSDimitry Andric  def SLE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27615ffd83dbSDimitry Andric                              (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
27625ffd83dbSDimitry Andric                              "sle\t$rd, $rs, $rt">, ISA_MIPS1;
27635ffd83dbSDimitry Andric  def : MipsInstAlias<"sle $rs, $rt",
27645ffd83dbSDimitry Andric                      (SLE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
27655ffd83dbSDimitry Andric        ISA_MIPS1;
27665ffd83dbSDimitry Andric  def SLEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27675ffd83dbSDimitry Andric                                 (ins GPR32Opnd:$rs, simm32:$imm),
27685ffd83dbSDimitry Andric                                 "sle\t$rd, $rs, $imm">, GPR_32;
27695ffd83dbSDimitry Andric  def : MipsInstAlias<"sle $rs, $imm", (SLEImm GPR32Opnd:$rs,
27705ffd83dbSDimitry Andric                                               GPR32Opnd:$rs,
27715ffd83dbSDimitry Andric                                               simm32:$imm), 0>,
27725ffd83dbSDimitry Andric        GPR_32;
27735ffd83dbSDimitry Andric
27745ffd83dbSDimitry Andric  def SLEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27755ffd83dbSDimitry Andric                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
27765ffd83dbSDimitry Andric                               "sleu\t$rd, $rs, $rt">, ISA_MIPS1;
27775ffd83dbSDimitry Andric  def : MipsInstAlias<"sleu $rs, $rt",
27785ffd83dbSDimitry Andric                      (SLEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
27795ffd83dbSDimitry Andric        ISA_MIPS1;
27805ffd83dbSDimitry Andric  def SLEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
27815ffd83dbSDimitry Andric                                  (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
27825ffd83dbSDimitry Andric                                  "sleu\t$rd, $rs, $imm">, GPR_32;
27835ffd83dbSDimitry Andric  def : MipsInstAlias<"sleu $rs, $imm", (SLEUImm GPR32Opnd:$rs,
27845ffd83dbSDimitry Andric                                                 GPR32Opnd:$rs,
27855ffd83dbSDimitry Andric                                                 uimm32_coerced:$imm), 0>,
27865ffd83dbSDimitry Andric        GPR_32;
27875ffd83dbSDimitry Andric
27880b57cec5SDimitry Andric  def : MipsInstAlias<
27890b57cec5SDimitry Andric          "not $rt, $rs",
27900b57cec5SDimitry Andric          (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
27910b57cec5SDimitry Andric  def : MipsInstAlias<
27920b57cec5SDimitry Andric          "not $rt",
27930b57cec5SDimitry Andric          (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
27940b57cec5SDimitry Andric
27950b57cec5SDimitry Andric  def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
27960b57cec5SDimitry Andric
2797480093f4SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>,
2798480093f4SDimitry Andric         ISA_MIPS1_NOT_32R6_64R6;
27990b57cec5SDimitry Andric
28000b57cec5SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
28010b57cec5SDimitry Andric
28020b57cec5SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
28030b57cec5SDimitry Andric
28040b57cec5SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
28050b57cec5SDimitry Andric
28060b57cec5SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
28070b57cec5SDimitry Andric
28080b57cec5SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
28090b57cec5SDimitry Andric
28100b57cec5SDimitry Andric  defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
28110b57cec5SDimitry Andric
28120b57cec5SDimitry Andric  def : MipsInstAlias<"mfgc0 $rt, $rd",
28130b57cec5SDimitry Andric                      (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
28140b57cec5SDimitry Andric                      ISA_MIPS32R5, ASE_VIRT;
28150b57cec5SDimitry Andric  def : MipsInstAlias<"mtgc0 $rt, $rd",
28160b57cec5SDimitry Andric                      (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
28170b57cec5SDimitry Andric                      ISA_MIPS32R5, ASE_VIRT;
28180b57cec5SDimitry Andric  def : MipsInstAlias<"mfhgc0 $rt, $rd",
28190b57cec5SDimitry Andric                      (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
28200b57cec5SDimitry Andric                      ISA_MIPS32R5, ASE_VIRT;
28210b57cec5SDimitry Andric  def : MipsInstAlias<"mthgc0 $rt, $rd",
28220b57cec5SDimitry Andric                      (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
28230b57cec5SDimitry Andric                      ISA_MIPS32R5, ASE_VIRT;
28240b57cec5SDimitry Andric  def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
28250b57cec5SDimitry Andric        ISA_MIPS1;
28260b57cec5SDimitry Andric  def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
28270b57cec5SDimitry Andric        ISA_MIPS1;
28280b57cec5SDimitry Andric  def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
28290b57cec5SDimitry Andric        ISA_MIPS1;
28300b57cec5SDimitry Andric  def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
28310b57cec5SDimitry Andric        ISA_MIPS1;
28320b57cec5SDimitry Andric
28330b57cec5SDimitry Andric  def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
28340b57cec5SDimitry Andric        ISA_MIPS1;
28350b57cec5SDimitry Andric
28360b57cec5SDimitry Andric  def : MipsInstAlias<"bnez $rs,$offset",
28370b57cec5SDimitry Andric                      (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
28380b57cec5SDimitry Andric        ISA_MIPS1;
28390b57cec5SDimitry Andric  def : MipsInstAlias<"bnezl $rs, $offset",
28400b57cec5SDimitry Andric                      (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
28410b57cec5SDimitry Andric        ISA_MIPS2;
28420b57cec5SDimitry Andric  def : MipsInstAlias<"beqz $rs,$offset",
28430b57cec5SDimitry Andric                      (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
28440b57cec5SDimitry Andric        ISA_MIPS1;
28450b57cec5SDimitry Andric  def : MipsInstAlias<"beqzl $rs, $offset",
28460b57cec5SDimitry Andric                      (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
28470b57cec5SDimitry Andric        ISA_MIPS2;
28480b57cec5SDimitry Andric
28490b57cec5SDimitry Andric  def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
28500b57cec5SDimitry Andric
28510b57cec5SDimitry Andric  def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
28520b57cec5SDimitry Andric  def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
28530b57cec5SDimitry Andric  def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
28540b57cec5SDimitry Andric  def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
28550b57cec5SDimitry Andric
28560b57cec5SDimitry Andric  def : MipsInstAlias<"teq $rs, $rt",
28570b57cec5SDimitry Andric                      (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
28580b57cec5SDimitry Andric  def : MipsInstAlias<"tge $rs, $rt",
28590b57cec5SDimitry Andric                      (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
28600b57cec5SDimitry Andric  def : MipsInstAlias<"tgeu $rs, $rt",
28610b57cec5SDimitry Andric                      (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
28620b57cec5SDimitry Andric  def : MipsInstAlias<"tlt $rs, $rt",
28630b57cec5SDimitry Andric                      (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
28640b57cec5SDimitry Andric  def : MipsInstAlias<"tltu $rs, $rt",
28650b57cec5SDimitry Andric                      (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
28660b57cec5SDimitry Andric  def : MipsInstAlias<"tne $rs, $rt",
28670b57cec5SDimitry Andric                      (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
28680b57cec5SDimitry Andric  def : MipsInstAlias<"rdhwr $rt, $rs",
28690b57cec5SDimitry Andric                      (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
28700b57cec5SDimitry Andric
28710b57cec5SDimitry Andric}
28720b57cec5SDimitry Andricdef : MipsInstAlias<"sub, $rd, $rs, $imm",
28730b57cec5SDimitry Andric                    (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
28740b57cec5SDimitry Andric                          InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
28750b57cec5SDimitry Andricdef : MipsInstAlias<"sub $rs, $imm",
28760b57cec5SDimitry Andric                    (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
28770b57cec5SDimitry Andric                    0>, ISA_MIPS1_NOT_32R6_64R6;
28780b57cec5SDimitry Andricdef : MipsInstAlias<"subu, $rd, $rs, $imm",
28790b57cec5SDimitry Andric                    (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
28800b57cec5SDimitry Andric                           InvertedImOperand:$imm), 0>;
28810b57cec5SDimitry Andricdef : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
28820b57cec5SDimitry Andric                                             InvertedImOperand:$imm), 0>;
28830b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
28840b57cec5SDimitry Andric  def : MipsInstAlias<"sll $rd, $rt, $rs",
28850b57cec5SDimitry Andric                      (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
28860b57cec5SDimitry Andric  def : MipsInstAlias<"sra $rd, $rt, $rs",
28870b57cec5SDimitry Andric                      (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
28880b57cec5SDimitry Andric  def : MipsInstAlias<"srl $rd, $rt, $rs",
28890b57cec5SDimitry Andric                      (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
28900b57cec5SDimitry Andric  def : MipsInstAlias<"sll $rd, $rt",
28910b57cec5SDimitry Andric                      (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
28920b57cec5SDimitry Andric  def : MipsInstAlias<"sra $rd, $rt",
28930b57cec5SDimitry Andric                      (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
28940b57cec5SDimitry Andric  def : MipsInstAlias<"srl $rd, $rt",
28950b57cec5SDimitry Andric                      (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
28960b57cec5SDimitry Andric  def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
28970b57cec5SDimitry Andric                     ISA_MIPS32R2;
28980b57cec5SDimitry Andric  def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
28990b57cec5SDimitry Andric                     ISA_MIPS32R2;
29000b57cec5SDimitry Andric}
29010b57cec5SDimitry Andricdef : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
29020b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in
29030b57cec5SDimitry Andric  def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
29040b57cec5SDimitry Andric
29050b57cec5SDimitry Andricdef : MipsInstAlias<"mulo $rs, $rt",
29060b57cec5SDimitry Andric                    (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
29070b57cec5SDimitry Andric                    ISA_MIPS1_NOT_32R6_64R6;
29080b57cec5SDimitry Andricdef : MipsInstAlias<"mulou $rs, $rt",
29090b57cec5SDimitry Andric                    (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
29100b57cec5SDimitry Andric                    ISA_MIPS1_NOT_32R6_64R6;
29110b57cec5SDimitry Andric
29120b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in
29130b57cec5SDimitry Andric  def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
29140b57cec5SDimitry Andric
29150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
29160b57cec5SDimitry Andric// Assembler Pseudo Instructions
29170b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
29180b57cec5SDimitry Andric
29190b57cec5SDimitry Andric// We use uimm32_coerced to accept a 33 bit signed number that is rendered into
29200b57cec5SDimitry Andric// a 32 bit number.
29210b57cec5SDimitry Andricclass LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
29220b57cec5SDimitry Andric  MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
29230b57cec5SDimitry Andric                     !strconcat(instr_asm, "\t$rt, $imm32")> ;
29240b57cec5SDimitry Andricdef LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
29250b57cec5SDimitry Andric
29260b57cec5SDimitry Andricclass LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
29270b57cec5SDimitry Andric                           RegisterOperand RO> :
29280b57cec5SDimitry Andric  MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
29290b57cec5SDimitry Andric                     !strconcat(instr_asm, "\t$rt, $addr")> ;
29300b57cec5SDimitry Andricdef LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
29310b57cec5SDimitry Andric
29320b57cec5SDimitry Andricclass LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
29330b57cec5SDimitry Andric  MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
29340b57cec5SDimitry Andric                     !strconcat(instr_asm, "\t$rt, $imm32")> ;
29350b57cec5SDimitry Andricdef LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
29360b57cec5SDimitry Andric
29370b57cec5SDimitry Andricdef JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
29380b57cec5SDimitry Andric                      "jal\t$rd, $rs"> ;
29390b57cec5SDimitry Andricdef JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
29400b57cec5SDimitry Andric                      "jal\t$rs"> ;
29410b57cec5SDimitry Andric
29420b57cec5SDimitry Andricclass NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
29430b57cec5SDimitry Andric   MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
29440b57cec5SDimitry Andric                      "nor\t$rs, $rt, $imm">;
29450b57cec5SDimitry Andricdef NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
29460b57cec5SDimitry Andricdef : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
29470b57cec5SDimitry Andric                                              simm32_relaxed:$imm)>, GPR_32;
29480b57cec5SDimitry Andric
29490b57cec5SDimitry Andriclet hasDelaySlot = 1, isCTI = 1 in {
29500b57cec5SDimitry Andricdef BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
29510b57cec5SDimitry Andric                               (ins imm64:$imm64, brtarget:$offset),
29520b57cec5SDimitry Andric                               "bne\t$rt, $imm64, $offset">;
29530b57cec5SDimitry Andricdef BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
29540b57cec5SDimitry Andric                               (ins imm64:$imm64, brtarget:$offset),
29550b57cec5SDimitry Andric                               "beq\t$rt, $imm64, $offset">;
29560b57cec5SDimitry Andric
29570b57cec5SDimitry Andricclass CondBranchPseudo<string instr_asm> :
29580b57cec5SDimitry Andric  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
29590b57cec5SDimitry Andric                                 brtarget:$offset),
29600b57cec5SDimitry Andric                    !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
29610b57cec5SDimitry Andric}
29620b57cec5SDimitry Andric
29630b57cec5SDimitry Andricdef BLT : CondBranchPseudo<"blt">;
29640b57cec5SDimitry Andricdef BLE : CondBranchPseudo<"ble">;
29650b57cec5SDimitry Andricdef BGE : CondBranchPseudo<"bge">;
29660b57cec5SDimitry Andricdef BGT : CondBranchPseudo<"bgt">;
29670b57cec5SDimitry Andricdef BLTU : CondBranchPseudo<"bltu">;
29680b57cec5SDimitry Andricdef BLEU : CondBranchPseudo<"bleu">;
29690b57cec5SDimitry Andricdef BGEU : CondBranchPseudo<"bgeu">;
29700b57cec5SDimitry Andricdef BGTU : CondBranchPseudo<"bgtu">;
29710b57cec5SDimitry Andricdef BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
29720b57cec5SDimitry Andricdef BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
29730b57cec5SDimitry Andricdef BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
29740b57cec5SDimitry Andricdef BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
29750b57cec5SDimitry Andricdef BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
29760b57cec5SDimitry Andricdef BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
29770b57cec5SDimitry Andricdef BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
29780b57cec5SDimitry Andricdef BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
29790b57cec5SDimitry Andric
29800b57cec5SDimitry Andriclet isCTI = 1 in
29810b57cec5SDimitry Andricclass CondBranchImmPseudo<string instr_asm> :
29820b57cec5SDimitry Andric  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
29830b57cec5SDimitry Andric                    !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
29840b57cec5SDimitry Andric
29850b57cec5SDimitry Andricdef BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
29860b57cec5SDimitry Andricdef BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
29870b57cec5SDimitry Andric
29880b57cec5SDimitry Andricdef BLTImmMacro  : CondBranchImmPseudo<"blt">;
29890b57cec5SDimitry Andricdef BLEImmMacro  : CondBranchImmPseudo<"ble">;
29900b57cec5SDimitry Andricdef BGEImmMacro  : CondBranchImmPseudo<"bge">;
29910b57cec5SDimitry Andricdef BGTImmMacro  : CondBranchImmPseudo<"bgt">;
29920b57cec5SDimitry Andricdef BLTUImmMacro : CondBranchImmPseudo<"bltu">;
29930b57cec5SDimitry Andricdef BLEUImmMacro : CondBranchImmPseudo<"bleu">;
29940b57cec5SDimitry Andricdef BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
29950b57cec5SDimitry Andricdef BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
29960b57cec5SDimitry Andricdef BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
29970b57cec5SDimitry Andricdef BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
29980b57cec5SDimitry Andricdef BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
29990b57cec5SDimitry Andricdef BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
30000b57cec5SDimitry Andricdef BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
30010b57cec5SDimitry Andricdef BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
30020b57cec5SDimitry Andricdef BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
30030b57cec5SDimitry Andricdef BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
30040b57cec5SDimitry Andric
30050b57cec5SDimitry Andric// FIXME: Predicates are removed because instructions are matched regardless of
30060b57cec5SDimitry Andric// predicates, because PredicateControl was not in the hierarchy. This was
30070b57cec5SDimitry Andric// done to emit more precise error message from expansion function.
30080b57cec5SDimitry Andric// Once the tablegen-erated errors are made better, this needs to be fixed and
30090b57cec5SDimitry Andric// predicates needs to be restored.
30100b57cec5SDimitry Andric
30110b57cec5SDimitry Andricdef SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
30120b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
30130b57cec5SDimitry Andric                                  "div\t$rd, $rs, $rt">,
30140b57cec5SDimitry Andric                ISA_MIPS1_NOT_32R6_64R6;
30150b57cec5SDimitry Andricdef SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30160b57cec5SDimitry Andric                                   (ins GPR32Opnd:$rs, simm32:$imm),
30170b57cec5SDimitry Andric                                   "div\t$rd, $rs, $imm">,
30180b57cec5SDimitry Andric                 ISA_MIPS1_NOT_32R6_64R6;
30190b57cec5SDimitry Andricdef UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30200b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
30210b57cec5SDimitry Andric                                  "divu\t$rd, $rs, $rt">,
30220b57cec5SDimitry Andric                ISA_MIPS1_NOT_32R6_64R6;
30230b57cec5SDimitry Andricdef UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30240b57cec5SDimitry Andric                                   (ins GPR32Opnd:$rs, simm32:$imm),
30250b57cec5SDimitry Andric                                   "divu\t$rd, $rs, $imm">,
30260b57cec5SDimitry Andric                 ISA_MIPS1_NOT_32R6_64R6;
30270b57cec5SDimitry Andric
30280b57cec5SDimitry Andric
30290b57cec5SDimitry Andricdef : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
30300b57cec5SDimitry Andric                                          GPR32Opnd:$rt), 0>,
30310b57cec5SDimitry Andric     ISA_MIPS1_NOT_32R6_64R6;
30320b57cec5SDimitry Andricdef : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
30330b57cec5SDimitry Andric                                               GPR32NonZeroOpnd:$rs,
30340b57cec5SDimitry Andric                                               GPR32Opnd:$rt), 0>,
30350b57cec5SDimitry Andric     ISA_MIPS1_NOT_32R6_64R6;
30360b57cec5SDimitry Andricdef : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
30370b57cec5SDimitry Andric                                                 simm32:$imm), 0>,
30380b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30390b57cec5SDimitry Andric
30400b57cec5SDimitry Andricdef : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
30410b57cec5SDimitry Andric                                           GPR32Opnd:$rs), 0>,
30420b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30430b57cec5SDimitry Andricdef : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
30440b57cec5SDimitry Andric                                                GPR32NonZeroOpnd:$rt,
30450b57cec5SDimitry Andric                                                GPR32Opnd:$rs), 0>,
30460b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30470b57cec5SDimitry Andric
30480b57cec5SDimitry Andricdef : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
30490b57cec5SDimitry Andric                                                  simm32:$imm), 0>,
30500b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30510b57cec5SDimitry Andric
30520b57cec5SDimitry Andricdef SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30530b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
30540b57cec5SDimitry Andric                                  "rem\t$rd, $rs, $rt">,
30550b57cec5SDimitry Andric                ISA_MIPS1_NOT_32R6_64R6;
30560b57cec5SDimitry Andricdef SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30570b57cec5SDimitry Andric                                   (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
30580b57cec5SDimitry Andric                                   "rem\t$rd, $rs, $imm">,
30590b57cec5SDimitry Andric                 ISA_MIPS1_NOT_32R6_64R6;
30600b57cec5SDimitry Andricdef URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30610b57cec5SDimitry Andric                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
30620b57cec5SDimitry Andric                                  "remu\t$rd, $rs, $rt">,
30630b57cec5SDimitry Andric                ISA_MIPS1_NOT_32R6_64R6;
30640b57cec5SDimitry Andricdef URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
30650b57cec5SDimitry Andric                                   (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
30660b57cec5SDimitry Andric                                   "remu\t$rd, $rs, $imm">,
30670b57cec5SDimitry Andric                 ISA_MIPS1_NOT_32R6_64R6;
30680b57cec5SDimitry Andric
30690b57cec5SDimitry Andricdef : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
30700b57cec5SDimitry Andric                                               GPR32Opnd:$rs), 0>,
30710b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30720b57cec5SDimitry Andricdef : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
30730b57cec5SDimitry Andric                                      simm32_relaxed:$imm), 0>,
30740b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30750b57cec5SDimitry Andricdef : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
30760b57cec5SDimitry Andric                                                GPR32Opnd:$rs), 0>,
30770b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30780b57cec5SDimitry Andricdef : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
30790b57cec5SDimitry Andric                                       simm32_relaxed:$imm), 0>,
30800b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
30810b57cec5SDimitry Andric
30820b57cec5SDimitry Andricdef Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
30830b57cec5SDimitry Andric                            "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
30840b57cec5SDimitry Andric
30850b57cec5SDimitry Andricdef Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
30860b57cec5SDimitry Andric                             "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
30870b57cec5SDimitry Andric
30880b57cec5SDimitry Andricdef Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
30890b57cec5SDimitry Andric                            "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
30900b57cec5SDimitry Andric
30910b57cec5SDimitry Andricdef Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
30920b57cec5SDimitry Andric                            "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
30930b57cec5SDimitry Andric
30940b57cec5SDimitry Andricdef Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
30950b57cec5SDimitry Andric                            "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
30960b57cec5SDimitry Andric
30970b57cec5SDimitry Andricdef LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
30980b57cec5SDimitry Andric                                (ins mem_simm16:$addr), "ld $rt, $addr">,
30990b57cec5SDimitry Andric                                ISA_MIPS1_NOT_MIPS3;
31000b57cec5SDimitry Andricdef SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
31010b57cec5SDimitry Andric                                (ins mem_simm16:$addr), "sd $rt, $addr">,
31020b57cec5SDimitry Andric                                ISA_MIPS1_NOT_MIPS3;
31030b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
31040b57cec5SDimitry Andric//  Arbitrary patterns that map to one or more instructions
31050b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
31060b57cec5SDimitry Andric
31070b57cec5SDimitry Andric// Load/store pattern templates.
31080b57cec5SDimitry Andricclass LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
31090b57cec5SDimitry Andric  MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
31100b57cec5SDimitry Andric
31110b57cec5SDimitry Andricclass StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
31120b57cec5SDimitry Andric  MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
31130b57cec5SDimitry Andric
31140b57cec5SDimitry Andric// Materialize constants.
31150b57cec5SDimitry Andricmulticlass MaterializeImms<ValueType VT, Register ZEROReg,
31160b57cec5SDimitry Andric                           Instruction ADDiuOp, Instruction LUiOp,
31170b57cec5SDimitry Andric                           Instruction ORiOp> {
31180b57cec5SDimitry Andric
31190b57cec5SDimitry Andric// Constant synthesis previously relied on the ordering of the patterns below.
31200b57cec5SDimitry Andric// By making the predicates they use non-overlapping, the patterns were
31210b57cec5SDimitry Andric// reordered so that the effect of the newly introduced predicates can be
31220b57cec5SDimitry Andric// observed.
31230b57cec5SDimitry Andric
31240b57cec5SDimitry Andric// Arbitrary immediates
3125480093f4SDimitry Andricdef : MipsPat<(VT LUiORiPred:$imm),
3126480093f4SDimitry Andric              (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
31270b57cec5SDimitry Andric
31280b57cec5SDimitry Andric// Bits 32-16 set, sign/zero extended.
31290b57cec5SDimitry Andricdef : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
31300b57cec5SDimitry Andric
31310b57cec5SDimitry Andric// Small immediates
31320b57cec5SDimitry Andricdef : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
31330b57cec5SDimitry Andricdef : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
31340b57cec5SDimitry Andric}
31350b57cec5SDimitry Andric
31360b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in
31370b57cec5SDimitry Andric  defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
31380b57cec5SDimitry Andric
31390b57cec5SDimitry Andric// Carry MipsPatterns
31400b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
31410b57cec5SDimitry Andric  def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
31420b57cec5SDimitry Andric                (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
31430b57cec5SDimitry Andric}
31440b57cec5SDimitry Andricdef : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
31450b57cec5SDimitry Andric              (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
31460b57cec5SDimitry Andricdef : MipsPat<(addc  GPR32:$src, immSExt16:$imm),
31470b57cec5SDimitry Andric              (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
31480b57cec5SDimitry Andric
31490b57cec5SDimitry Andric// Support multiplication for pre-Mips32 targets that don't have
31500b57cec5SDimitry Andric// the MUL instruction.
31510b57cec5SDimitry Andricdef : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
31520b57cec5SDimitry Andric              (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
31530b57cec5SDimitry Andric      ISA_MIPS1_NOT_32R6_64R6;
31540b57cec5SDimitry Andric
31550b57cec5SDimitry Andric// SYNC
31560b57cec5SDimitry Andricdef : MipsPat<(MipsSync (i32 immz)),
31570b57cec5SDimitry Andric              (SYNC 0)>, ISA_MIPS2;
31580b57cec5SDimitry Andric
31590b57cec5SDimitry Andric// Call
31600b57cec5SDimitry Andricdef : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
31610b57cec5SDimitry Andric              (JAL texternalsym:$dst)>, ISA_MIPS1;
31620b57cec5SDimitry Andric//def : MipsPat<(MipsJmpLink GPR32:$dst),
31630b57cec5SDimitry Andric//              (JALR GPR32:$dst)>;
31640b57cec5SDimitry Andric
31650b57cec5SDimitry Andric// Tail call
31660b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
31670b57cec5SDimitry Andric  def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
31680b57cec5SDimitry Andric                (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
31690b57cec5SDimitry Andric  def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
31700b57cec5SDimitry Andric                (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
31710b57cec5SDimitry Andric}
31720b57cec5SDimitry Andric// hi/lo relocs
31730b57cec5SDimitry Andricmulticlass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
31740b57cec5SDimitry Andric                          Register ZeroReg, RegisterOperand GPROpnd> {
31750b57cec5SDimitry Andric  def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
31760b57cec5SDimitry Andric  def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
31770b57cec5SDimitry Andric  def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
31780b57cec5SDimitry Andric  def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
31790b57cec5SDimitry Andric  def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
31800b57cec5SDimitry Andric
31818bcb0991SDimitry Andric  def : MipsPat<(MipsLo tglobaladdr:$in),
31828bcb0991SDimitry Andric                (Addiu ZeroReg, tglobaladdr:$in)>;
31830b57cec5SDimitry Andric  def : MipsPat<(MipsLo tblockaddress:$in),
31840b57cec5SDimitry Andric                (Addiu ZeroReg, tblockaddress:$in)>;
31858bcb0991SDimitry Andric  def : MipsPat<(MipsLo tjumptable:$in),
31868bcb0991SDimitry Andric                (Addiu ZeroReg, tjumptable:$in)>;
31878bcb0991SDimitry Andric  def : MipsPat<(MipsLo tconstpool:$in),
31888bcb0991SDimitry Andric                (Addiu ZeroReg, tconstpool:$in)>;
31890b57cec5SDimitry Andric  def : MipsPat<(MipsLo tglobaltlsaddr:$in),
31900b57cec5SDimitry Andric                (Addiu ZeroReg, tglobaltlsaddr:$in)>;
31918bcb0991SDimitry Andric  def : MipsPat<(MipsLo texternalsym:$in),
31928bcb0991SDimitry Andric                (Addiu ZeroReg, texternalsym:$in)>;
31930b57cec5SDimitry Andric
31940b57cec5SDimitry Andric  def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
31950b57cec5SDimitry Andric                (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
31960b57cec5SDimitry Andric  def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
31970b57cec5SDimitry Andric                (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
31980b57cec5SDimitry Andric  def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
31990b57cec5SDimitry Andric                (Addiu GPROpnd:$hi, tjumptable:$lo)>;
32000b57cec5SDimitry Andric  def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
32010b57cec5SDimitry Andric                (Addiu GPROpnd:$hi, tconstpool:$lo)>;
32020b57cec5SDimitry Andric  def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
32030b57cec5SDimitry Andric                (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3204f10421e9SDimitry Andric  def : MipsPat<(add GPROpnd:$hi, (MipsLo texternalsym:$lo)),
3205f10421e9SDimitry Andric                (Addiu GPROpnd:$hi, texternalsym:$lo)>;
32060b57cec5SDimitry Andric}
32070b57cec5SDimitry Andric
32080b57cec5SDimitry Andric// wrapper_pic
32090b57cec5SDimitry Andricclass WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
32100b57cec5SDimitry Andric      MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
32110b57cec5SDimitry Andric
32120b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
32130b57cec5SDimitry Andric  defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
32140b57cec5SDimitry Andric
32150b57cec5SDimitry Andric  def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
32160b57cec5SDimitry Andric  def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
32170b57cec5SDimitry Andric        ISA_MIPS1;
32180b57cec5SDimitry Andric
32190b57cec5SDimitry Andric  def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
32200b57cec5SDimitry Andric        ISA_MIPS1;
32210b57cec5SDimitry Andric
32220b57cec5SDimitry Andric  // gp_rel relocs
32230b57cec5SDimitry Andric  def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
32240b57cec5SDimitry Andric                (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
32250b57cec5SDimitry Andric  def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
32260b57cec5SDimitry Andric                (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
32270b57cec5SDimitry Andric
32280b57cec5SDimitry Andric  def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
32290b57cec5SDimitry Andric  def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
32300b57cec5SDimitry Andric  def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
32310b57cec5SDimitry Andric  def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
32320b57cec5SDimitry Andric  def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
32330b57cec5SDimitry Andric  def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
32340b57cec5SDimitry Andric
32350b57cec5SDimitry Andric  // Mips does not have "not", so we expand our way
32360b57cec5SDimitry Andric  def : MipsPat<(not GPR32:$in),
32370b57cec5SDimitry Andric                (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
32380b57cec5SDimitry Andric}
32390b57cec5SDimitry Andric
32400b57cec5SDimitry Andric// extended loads
32410b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
32420b57cec5SDimitry Andric  def : MipsPat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
32430b57cec5SDimitry Andric  def : MipsPat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
32440b57cec5SDimitry Andric  def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
32450b57cec5SDimitry Andric
32460b57cec5SDimitry Andric  // peepholes
32470b57cec5SDimitry Andric  def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
32480b57cec5SDimitry Andric}
32490b57cec5SDimitry Andric
32500b57cec5SDimitry Andric// brcond patterns
32510b57cec5SDimitry Andricmulticlass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
32520b57cec5SDimitry Andric                      Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
32530b57cec5SDimitry Andric                      Instruction SLTiOp, Instruction SLTiuOp,
32540b57cec5SDimitry Andric                      Register ZEROReg> {
32550b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
32560b57cec5SDimitry Andric              (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
32570b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
32580b57cec5SDimitry Andric              (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
32590b57cec5SDimitry Andric
32600b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
32610b57cec5SDimitry Andric              (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
32620b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
32630b57cec5SDimitry Andric              (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
32640b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
32650b57cec5SDimitry Andric              (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
32660b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
32670b57cec5SDimitry Andric              (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
32680b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
32690b57cec5SDimitry Andric              (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
32700b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
32710b57cec5SDimitry Andric              (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
32720b57cec5SDimitry Andric
32730b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
32740b57cec5SDimitry Andric              (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
32750b57cec5SDimitry Andricdef : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
32760b57cec5SDimitry Andric              (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
32770b57cec5SDimitry Andric
32780b57cec5SDimitry Andricdef : MipsPat<(brcond RC:$cond, bb:$dst),
32790b57cec5SDimitry Andric              (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
32800b57cec5SDimitry Andric}
32810b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
32820b57cec5SDimitry Andric  defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
32830b57cec5SDimitry Andric         ISA_MIPS1;
32840b57cec5SDimitry Andric  def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
32850b57cec5SDimitry Andric                (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
32860b57cec5SDimitry Andric  def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
32870b57cec5SDimitry Andric                (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
32880b57cec5SDimitry Andric}
32890b57cec5SDimitry Andric
32900b57cec5SDimitry Andric// setcc patterns
32910b57cec5SDimitry Andricmulticlass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
32920b57cec5SDimitry Andric                     Instruction SLTuOp, Register ZEROReg> {
32930b57cec5SDimitry Andric  def : MipsPat<(seteq RC:$lhs, 0),
32940b57cec5SDimitry Andric                (SLTiuOp RC:$lhs, 1)>;
32950b57cec5SDimitry Andric  def : MipsPat<(setne RC:$lhs, 0),
32960b57cec5SDimitry Andric                (SLTuOp ZEROReg, RC:$lhs)>;
32970b57cec5SDimitry Andric  def : MipsPat<(seteq RC:$lhs, RC:$rhs),
32980b57cec5SDimitry Andric                (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
32990b57cec5SDimitry Andric  def : MipsPat<(setne RC:$lhs, RC:$rhs),
33000b57cec5SDimitry Andric                (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
33010b57cec5SDimitry Andric}
33020b57cec5SDimitry Andric
33030b57cec5SDimitry Andricmulticlass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
33040b57cec5SDimitry Andric                     Instruction SLTuOp> {
33050b57cec5SDimitry Andric  def : MipsPat<(setle RC:$lhs, RC:$rhs),
33060b57cec5SDimitry Andric                (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
33070b57cec5SDimitry Andric  def : MipsPat<(setule RC:$lhs, RC:$rhs),
33080b57cec5SDimitry Andric                (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
33090b57cec5SDimitry Andric}
33100b57cec5SDimitry Andric
33110b57cec5SDimitry Andricmulticlass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
33120b57cec5SDimitry Andric  def : MipsPat<(setgt RC:$lhs, RC:$rhs),
33130b57cec5SDimitry Andric                (SLTOp RC:$rhs, RC:$lhs)>;
33140b57cec5SDimitry Andric  def : MipsPat<(setugt RC:$lhs, RC:$rhs),
33150b57cec5SDimitry Andric                (SLTuOp RC:$rhs, RC:$lhs)>;
33160b57cec5SDimitry Andric}
33170b57cec5SDimitry Andric
33180b57cec5SDimitry Andricmulticlass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
33190b57cec5SDimitry Andric                     Instruction SLTuOp> {
33200b57cec5SDimitry Andric  def : MipsPat<(setge RC:$lhs, RC:$rhs),
33210b57cec5SDimitry Andric                (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
33220b57cec5SDimitry Andric  def : MipsPat<(setuge RC:$lhs, RC:$rhs),
33230b57cec5SDimitry Andric                (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
33240b57cec5SDimitry Andric}
33250b57cec5SDimitry Andric
33260b57cec5SDimitry Andricmulticlass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
33270b57cec5SDimitry Andric                        Instruction SLTiOp, Instruction SLTiuOp> {
33280b57cec5SDimitry Andric  def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
33290b57cec5SDimitry Andric                (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
33300b57cec5SDimitry Andric  def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
33310b57cec5SDimitry Andric                (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
33320b57cec5SDimitry Andric}
33330b57cec5SDimitry Andric
33340b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
33350b57cec5SDimitry Andric  defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
33360b57cec5SDimitry Andric  defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
33370b57cec5SDimitry Andric  defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
33380b57cec5SDimitry Andric  defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
33390b57cec5SDimitry Andric  defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
33400b57cec5SDimitry Andric
33410b57cec5SDimitry Andric  // bswap pattern
33420b57cec5SDimitry Andric  def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
33430b57cec5SDimitry Andric}
33440b57cec5SDimitry Andric
33450b57cec5SDimitry Andric// Load halfword/word patterns.
33460b57cec5SDimitry Andriclet AdditionalPredicates = [NotInMicroMips] in {
33470b57cec5SDimitry Andric  let AddedComplexity = 40 in {
33480b57cec5SDimitry Andric    def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
33490b57cec5SDimitry Andric    def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
33500b57cec5SDimitry Andric    def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
33510b57cec5SDimitry Andric    def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
33520b57cec5SDimitry Andric    def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
33530b57cec5SDimitry Andric  }
33540b57cec5SDimitry Andric
33550b57cec5SDimitry Andric  // Atomic load patterns.
33560b57cec5SDimitry Andric  def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
33570b57cec5SDimitry Andric  def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
33580b57cec5SDimitry Andric  def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
33590b57cec5SDimitry Andric
33600b57cec5SDimitry Andric  // Atomic store patterns.
33615f757f3fSDimitry Andric  def : MipsPat<(atomic_store_8 GPR32:$v, addr:$a), (SB GPR32:$v, addr:$a)>,
33620b57cec5SDimitry Andric        ISA_MIPS1;
33635f757f3fSDimitry Andric  def : MipsPat<(atomic_store_16 GPR32:$v, addr:$a), (SH GPR32:$v, addr:$a)>,
33640b57cec5SDimitry Andric        ISA_MIPS1;
33655f757f3fSDimitry Andric  def : MipsPat<(atomic_store_32 GPR32:$v, addr:$a), (SW GPR32:$v, addr:$a)>,
33660b57cec5SDimitry Andric        ISA_MIPS1;
33670b57cec5SDimitry Andric}
33680b57cec5SDimitry Andric
33690b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
33700b57cec5SDimitry Andric// Floating Point Support
33710b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
33720b57cec5SDimitry Andric
33730b57cec5SDimitry Andricinclude "MipsInstrFPU.td"
33740b57cec5SDimitry Andricinclude "Mips64InstrInfo.td"
33750b57cec5SDimitry Andricinclude "MipsCondMov.td"
33760b57cec5SDimitry Andric
33770b57cec5SDimitry Andricinclude "Mips32r6InstrInfo.td"
33780b57cec5SDimitry Andricinclude "Mips64r6InstrInfo.td"
33790b57cec5SDimitry Andric
33800b57cec5SDimitry Andric//
33810b57cec5SDimitry Andric// Mips16
33820b57cec5SDimitry Andric
33830b57cec5SDimitry Andricinclude "Mips16InstrFormats.td"
33840b57cec5SDimitry Andricinclude "Mips16InstrInfo.td"
33850b57cec5SDimitry Andric
33860b57cec5SDimitry Andric// DSP
33870b57cec5SDimitry Andricinclude "MipsDSPInstrFormats.td"
33880b57cec5SDimitry Andricinclude "MipsDSPInstrInfo.td"
33890b57cec5SDimitry Andric
33900b57cec5SDimitry Andric// MSA
33910b57cec5SDimitry Andricinclude "MipsMSAInstrFormats.td"
33920b57cec5SDimitry Andricinclude "MipsMSAInstrInfo.td"
33930b57cec5SDimitry Andric
33940b57cec5SDimitry Andric// EVA
33950b57cec5SDimitry Andricinclude "MipsEVAInstrFormats.td"
33960b57cec5SDimitry Andricinclude "MipsEVAInstrInfo.td"
33970b57cec5SDimitry Andric
33980b57cec5SDimitry Andric// MT
33990b57cec5SDimitry Andricinclude "MipsMTInstrFormats.td"
34000b57cec5SDimitry Andricinclude "MipsMTInstrInfo.td"
34010b57cec5SDimitry Andric
34020b57cec5SDimitry Andric// Micromips
34030b57cec5SDimitry Andricinclude "MicroMipsInstrFormats.td"
34040b57cec5SDimitry Andricinclude "MicroMipsInstrInfo.td"
34050b57cec5SDimitry Andricinclude "MicroMipsInstrFPU.td"
34060b57cec5SDimitry Andric
34070b57cec5SDimitry Andric// Micromips r6
34080b57cec5SDimitry Andricinclude "MicroMips32r6InstrFormats.td"
34090b57cec5SDimitry Andricinclude "MicroMips32r6InstrInfo.td"
34100b57cec5SDimitry Andric
34110b57cec5SDimitry Andric// Micromips DSP
34120b57cec5SDimitry Andricinclude "MicroMipsDSPInstrFormats.td"
34130b57cec5SDimitry Andricinclude "MicroMipsDSPInstrInfo.td"
3414