1//===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Mips implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14
15//===----------------------------------------------------------------------===//
16// Mips profiles and nodes
17//===----------------------------------------------------------------------===//
18
19def SDT_MipsJmpLink      : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
20def SDT_MipsCMov         : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
21                                                SDTCisSameAs<1, 2>,
22                                                SDTCisSameAs<3, 4>,
23                                                SDTCisInt<4>]>;
24def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
25def SDT_MipsCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
26def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
27def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
28                                      SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
29def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
30                                    SDTCisSameAs<1, 2>]>;
31def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
32                                     [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
33                                      SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
34def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
35
36def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
37
38def SDT_Sync             : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
39
40def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
41                                   SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
42def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43                                   SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
44                                   SDTCisSameAs<0, 4>]>;
45
46def SDTMipsLoadLR  : SDTypeProfile<1, 2,
47                                   [SDTCisInt<0>, SDTCisPtrTy<1>,
48                                    SDTCisSameAs<0, 2>]>;
49
50// Call
51def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
52                         [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
53                          SDNPVariadic]>;
54
55// Tail call
56def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
57                          [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
58
59// Hi and Lo nodes are used to handle global addresses. Used on
60// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
61// static model. (nothing to do with Mips Registers Hi and Lo)
62def MipsHi    : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
63def MipsLo    : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
64def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
65
66// TlsGd node is used to handle General Dynamic TLS
67def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
68
69// TprelHi and TprelLo nodes are used to handle Local Exec TLS
70def MipsTprelHi    : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
71def MipsTprelLo    : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
72
73// Thread pointer
74def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
75
76// Return
77def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
78                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
79
80def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
81                      [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
82
83// These are target-independent nodes, but have target-specific formats.
84def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
85                           [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
86def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
87                           [SDNPHasChain, SDNPSideEffect,
88                            SDNPOptInGlue, SDNPOutGlue]>;
89
90// Nodes used to extract LO/HI registers.
91def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
92def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
93
94// Node used to insert 32-bit integers to LOHI register pair.
95def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
96
97// Mult nodes.
98def MipsMult  : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
99def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
100
101// MAdd*/MSub* nodes
102def MipsMAdd  : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
103def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
104def MipsMSub  : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
105def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
106
107// DivRem(u) nodes
108def MipsDivRem    : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
109def MipsDivRemU   : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
110def MipsDivRem16  : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
111                           [SDNPOutGlue]>;
112def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
113                           [SDNPOutGlue]>;
114
115// Target constant nodes that are not part of any isel patterns and remain
116// unchanged can cause instructions with illegal operands to be emitted.
117// Wrapper node patterns give the instruction selector a chance to replace
118// target constant nodes that would otherwise remain unchanged with ADDiu
119// nodes. Without these wrapper node patterns, the following conditional move
120// instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
121// compiled:
122//  movn  %got(d)($gp), %got(c)($gp), $4
123// This instruction is illegal since movn can take only register operands.
124
125def MipsWrapper    : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
126
127def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
128
129def MipsExt :  SDNode<"MipsISD::Ext", SDT_Ext>;
130def MipsIns :  SDNode<"MipsISD::Ins", SDT_Ins>;
131
132def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
133                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
134def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
135                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
136def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
137                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
138def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
139                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
140def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
141                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
143                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
144def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
145                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
147                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
148
149//===----------------------------------------------------------------------===//
150// Mips Instruction Predicate Definitions.
151//===----------------------------------------------------------------------===//
152def HasMips2     :    Predicate<"Subtarget->hasMips2()">,
153                      AssemblerPredicate<"FeatureMips2">;
154def HasMips3_32  :    Predicate<"Subtarget->hasMips3_32()">,
155                      AssemblerPredicate<"FeatureMips3_32">;
156def HasMips3_32r2 :   Predicate<"Subtarget->hasMips3_32r2()">,
157                      AssemblerPredicate<"FeatureMips3_32r2">;
158def HasMips3     :    Predicate<"Subtarget->hasMips3()">,
159                      AssemblerPredicate<"FeatureMips3">;
160def NotMips3     :    Predicate<"!Subtarget->hasMips3()">,
161                      AssemblerPredicate<"!FeatureMips3">;
162def HasMips4_32  :    Predicate<"Subtarget->hasMips4_32()">,
163                      AssemblerPredicate<"FeatureMips4_32">;
164def NotMips4_32  :    Predicate<"!Subtarget->hasMips4_32()">,
165                      AssemblerPredicate<"!FeatureMips4_32">;
166def HasMips4_32r2 :   Predicate<"Subtarget->hasMips4_32r2()">,
167                      AssemblerPredicate<"FeatureMips4_32r2">;
168def HasMips5_32r2 :   Predicate<"Subtarget->hasMips5_32r2()">,
169                      AssemblerPredicate<"FeatureMips5_32r2">;
170def HasMips32    :    Predicate<"Subtarget->hasMips32()">,
171                      AssemblerPredicate<"FeatureMips32">;
172def HasMips32r2  :    Predicate<"Subtarget->hasMips32r2()">,
173                      AssemblerPredicate<"FeatureMips32r2">;
174def HasMips32r5  :    Predicate<"Subtarget->hasMips32r5()">,
175                      AssemblerPredicate<"FeatureMips32r5">;
176def HasMips32r6  :    Predicate<"Subtarget->hasMips32r6()">,
177                      AssemblerPredicate<"FeatureMips32r6">;
178def NotMips32r6  :    Predicate<"!Subtarget->hasMips32r6()">,
179                      AssemblerPredicate<"!FeatureMips32r6">;
180def IsGP64bit    :    Predicate<"Subtarget->isGP64bit()">,
181                      AssemblerPredicate<"FeatureGP64Bit">;
182def IsGP32bit    :    Predicate<"!Subtarget->isGP64bit()">,
183                      AssemblerPredicate<"!FeatureGP64Bit">;
184def IsPTR64bit    :   Predicate<"Subtarget->isABI_N64()">,
185                      AssemblerPredicate<"FeaturePTR64Bit">;
186def IsPTR32bit    :   Predicate<"!Subtarget->isABI_N64()">,
187                      AssemblerPredicate<"!FeaturePTR64Bit">;
188def HasMips64    :    Predicate<"Subtarget->hasMips64()">,
189                      AssemblerPredicate<"FeatureMips64">;
190def NotMips64    :    Predicate<"!Subtarget->hasMips64()">,
191                      AssemblerPredicate<"!FeatureMips64">;
192def HasMips64r2  :    Predicate<"Subtarget->hasMips64r2()">,
193                      AssemblerPredicate<"FeatureMips64r2">;
194def HasMips64r6  :    Predicate<"Subtarget->hasMips64r6()">,
195                      AssemblerPredicate<"FeatureMips64r6">;
196def NotMips64r6  :    Predicate<"!Subtarget->hasMips64r6()">,
197                      AssemblerPredicate<"!FeatureMips64r6">;
198def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
199                       AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
200def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
201                       AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
202def InMips16Mode :    Predicate<"Subtarget->inMips16Mode()">,
203                      AssemblerPredicate<"FeatureMips16">;
204def HasCnMips    :    Predicate<"Subtarget->hasCnMips()">,
205                      AssemblerPredicate<"FeatureCnMips">;
206def NotCnMips    :    Predicate<"!Subtarget->hasCnMips()">,
207                      AssemblerPredicate<"!FeatureCnMips">;
208def RelocNotPIC :     Predicate<"!TM.isPositionIndependent()">;
209def RelocPIC    :     Predicate<"TM.isPositionIndependent()">;
210def NoNaNsFPMath :    Predicate<"TM.Options.NoNaNsFPMath">;
211def HasStdEnc :       Predicate<"Subtarget->hasStandardEncoding()">,
212                      AssemblerPredicate<"!FeatureMips16">;
213def NotDSP :          Predicate<"!Subtarget->hasDSP()">;
214def InMicroMips    :  Predicate<"Subtarget->inMicroMipsMode()">,
215                      AssemblerPredicate<"FeatureMicroMips">;
216def NotInMicroMips :  Predicate<"!Subtarget->inMicroMipsMode()">,
217                      AssemblerPredicate<"!FeatureMicroMips">;
218def IsLE           :  Predicate<"Subtarget->isLittle()">;
219def IsBE           :  Predicate<"!Subtarget->isLittle()">;
220def IsNotNaCl    :    Predicate<"!Subtarget->isTargetNaCl()">;
221def UseTCCInDIV    :  AssemblerPredicate<"FeatureUseTCCInDIV">;
222def HasEVA       :    Predicate<"Subtarget->hasEVA()">,
223                      AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
224def HasMSA : Predicate<"Subtarget->hasMSA()">,
225             AssemblerPredicate<"FeatureMSA">;
226
227
228//===----------------------------------------------------------------------===//
229// Mips GPR size adjectives.
230// They are mutually exclusive.
231//===----------------------------------------------------------------------===//
232
233class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
234class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
235
236class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
237class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
238
239//===----------------------------------------------------------------------===//
240// Mips ISA/ASE membership and instruction group membership adjectives.
241// They are mutually exclusive.
242//===----------------------------------------------------------------------===//
243
244// FIXME: I'd prefer to use additive predicates to build the instruction sets
245//        but we are short on assembler feature bits at the moment. Using a
246//        subtractive predicate will hopefully keep us under the 32 predicate
247//        limit long enough to develop an alternative way to handle P1||P2
248//        predicates.
249class ISA_MIPS1_NOT_MIPS3 {
250  list<Predicate> InsnPredicates = [NotMips3];
251}
252class ISA_MIPS1_NOT_4_32 {
253  list<Predicate> InsnPredicates = [NotMips4_32];
254}
255class ISA_MIPS1_NOT_32R6_64R6 {
256  list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
257}
258class ISA_MIPS2    { list<Predicate> InsnPredicates = [HasMips2]; }
259class ISA_MIPS2_NOT_32R6_64R6 {
260  list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
261}
262class ISA_MIPS3    { list<Predicate> InsnPredicates = [HasMips3]; }
263class ISA_MIPS3_NOT_32R6_64R6 {
264  list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
265}
266class ISA_MIPS32   { list<Predicate> InsnPredicates = [HasMips32]; }
267class ISA_MIPS32_NOT_32R6_64R6 {
268  list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
269}
270class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
271class ISA_MIPS32R2_NOT_32R6_64R6 {
272  list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
273}
274class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
275class ISA_MIPS64   { list<Predicate> InsnPredicates = [HasMips64]; }
276class ISA_MIPS64_NOT_64R6 {
277  list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
278}
279class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
280class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
281class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
282class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
283class ISA_MICROMIPS32R6 {
284  list<Predicate> InsnPredicates = [HasMicroMips32r6];
285}
286class ISA_MICROMIPS64R6 {
287  list<Predicate> InsnPredicates = [HasMicroMips64r6];
288}
289class ISA_MICROMIPS32_NOT_MIPS32R6 {
290  list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
291}
292
293class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
294class INSN_EVA_NOT_32R6_64R6 {
295  list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
296}
297
298// The portions of MIPS-III that were also added to MIPS32
299class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
300
301// The portions of MIPS-III that were also added to MIPS32 but were removed in
302// MIPS32r6 and MIPS64r6.
303class INSN_MIPS3_32_NOT_32R6_64R6 {
304  list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
305}
306
307// The portions of MIPS-III that were also added to MIPS32
308class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
309
310// The portions of MIPS-IV that were also added to MIPS32.
311class INSN_MIPS4_32 { list <Predicate> InsnPredicates = [HasMips4_32]; }
312
313// The portions of MIPS-IV that were also added to MIPS32 but were removed in
314// MIPS32r6 and MIPS64r6.
315class INSN_MIPS4_32_NOT_32R6_64R6 {
316  list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
317}
318
319// The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
320// MIPS32r6 and MIPS64r6.
321class INSN_MIPS4_32R2_NOT_32R6_64R6 {
322  list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
323}
324
325// The portions of MIPS-IV that were also added to MIPS32r2.
326class INSN_MIPS4_32R2 {
327  list<Predicate> InsnPredicates = [HasMips4_32r2];
328}
329
330// The portions of MIPS-V that were also added to MIPS32r2 but were removed in
331// MIPS32r6 and MIPS64r6.
332class INSN_MIPS5_32R2_NOT_32R6_64R6 {
333  list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
334}
335
336class ASE_CNMIPS {
337  list<Predicate> InsnPredicates = [HasCnMips];
338}
339
340class NOT_ASE_CNMIPS {
341  list<Predicate> InsnPredicates = [NotCnMips];
342}
343
344class ASE_MIPS64_CNMIPS {
345  list<Predicate> InsnPredicates = [HasMips64, HasCnMips];
346}
347
348class ASE_MSA {
349  list<Predicate> InsnPredicates = [HasMSA];
350}
351
352class ASE_MSA_NOT_MSA64 {
353  list<Predicate> InsnPredicates = [HasMSA, NotMips64];
354}
355
356class ASE_MSA64 {
357  list<Predicate> InsnPredicates = [HasMSA, HasMips64];
358}
359
360// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
361// It can be used only on instructions that doesn't inherit PredicateControl.
362class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
363  let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
364}
365
366class ASE_NOT_DSP {
367  list<Predicate> InsnPredicates = [NotDSP];
368}
369
370//===----------------------------------------------------------------------===//
371
372class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
373  let EncodingPredicates = [HasStdEnc];
374}
375
376class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
377  InstAlias<Asm, Result, Emit>, PredicateControl;
378
379class IsCommutable {
380  bit isCommutable = 1;
381}
382
383class IsBranch {
384  bit isBranch = 1;
385  bit isCTI = 1;
386}
387
388class IsReturn {
389  bit isReturn = 1;
390  bit isCTI = 1;
391}
392
393class IsCall {
394  bit isCall = 1;
395  bit isCTI = 1;
396}
397
398class IsTailCall {
399  bit isCall = 1;
400  bit isTerminator = 1;
401  bit isReturn = 1;
402  bit isBarrier = 1;
403  bit hasExtraSrcRegAllocReq = 1;
404  bit isCodeGenOnly = 1;
405  bit isCTI = 1;
406}
407
408class IsAsCheapAsAMove {
409  bit isAsCheapAsAMove = 1;
410}
411
412class NeverHasSideEffects {
413  bit hasSideEffects = 0;
414}
415
416//===----------------------------------------------------------------------===//
417// Instruction format superclass
418//===----------------------------------------------------------------------===//
419
420include "MipsInstrFormats.td"
421
422//===----------------------------------------------------------------------===//
423// Mips Operand, Complex Patterns and Transformations Definitions.
424//===----------------------------------------------------------------------===//
425
426class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
427                                  int Offset = 0> : AsmOperandClass {
428  let Name = "ConstantSImm" # Bits # "_" # Offset;
429  let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
430  let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
431  let SuperClasses = Supers;
432  let DiagnosticType = "SImm" # Bits # "_" # Offset;
433}
434
435class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
436                                  int Shift = 0> : AsmOperandClass {
437  let Name = "Simm" # Bits # "_Lsl" # Shift;
438  let RenderMethod = "addImmOperands";
439  let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
440  let SuperClasses = Supers;
441  let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
442}
443
444class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
445                                  int Offset = 0> : AsmOperandClass {
446  let Name = "ConstantUImm" # Bits # "_" # Offset;
447  let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
448  let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
449  let SuperClasses = Supers;
450  let DiagnosticType = "UImm" # Bits # "_" # Offset;
451}
452
453class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
454                                       list<AsmOperandClass> Supers = []>
455    : AsmOperandClass {
456  let Name = "ConstantUImmRange" # Bottom # "_" # Top;
457  let RenderMethod = "addImmOperands";
458  let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
459  let SuperClasses = Supers;
460  let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
461}
462
463class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
464    : AsmOperandClass {
465  let Name = "SImm" # Bits;
466  let RenderMethod = "addSImmOperands<" # Bits # ">";
467  let PredicateMethod = "isSImm<" # Bits # ">";
468  let SuperClasses = Supers;
469  let DiagnosticType = "SImm" # Bits;
470}
471
472class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
473    : AsmOperandClass {
474  let Name = "UImm" # Bits;
475  let RenderMethod = "addUImmOperands<" # Bits # ">";
476  let PredicateMethod = "isUImm<" # Bits # ">";
477  let SuperClasses = Supers;
478  let DiagnosticType = "UImm" # Bits;
479}
480
481// Generic case - only to support certain assembly pseudo instructions.
482class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
483    : AsmOperandClass {
484  let Name = "ImmAny";
485  let RenderMethod = "addConstantUImmOperands<32>";
486  let PredicateMethod = "isSImm<" # Bits # ">";
487  let SuperClasses = Supers;
488  let DiagnosticType = "ImmAny";
489}
490
491// AsmOperandClasses require a strict ordering which is difficult to manage
492// as a hierarchy. Instead, we use a linear ordering and impose an order that
493// is in some places arbitrary.
494//
495// Here the rules that are in use:
496// * Wider immediates are a superset of narrower immediates:
497//     uimm4 < uimm5 < uimm6
498// * For the same bit-width, unsigned immediates are a superset of signed
499//   immediates::
500//     simm4 < uimm4 < simm5 < uimm5
501// * For the same upper-bound, signed immediates are a superset of unsigned
502//   immediates:
503//     uimm3 < simm4 < uimm4 < simm4
504// * Modified immediates are a superset of ordinary immediates:
505//     uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
506//   The term 'superset' starts to break down here since the uimm5_plus* classes
507//   are not true supersets of uimm5 (but they are still subsets of uimm6).
508// * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
509//     uimm16 < uimm16_relaxed
510// * The codeGen pattern type is arbitrarily ordered.
511//     uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
512//   This is entirely arbitrary. We need an ordering and what we pick is
513//   unimportant since only one is possible for a given mnemonic.
514
515def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
516  let Name = "UImm32_Coerced";
517  let DiagnosticType = "UImm32_Coerced";
518}
519def SImm32RelaxedAsmOperandClass
520    : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
521  let Name = "SImm32_Relaxed";
522  let PredicateMethod = "isAnyImm<32>";
523  let DiagnosticType = "SImm32_Relaxed";
524}
525def SImm32AsmOperandClass
526    : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
527def ConstantUImm26AsmOperandClass
528    : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
529def ConstantUImm20AsmOperandClass
530    : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
531def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
532  let Name = "SImm19Lsl2";
533  let RenderMethod = "addImmOperands";
534  let PredicateMethod = "isScaledSImm<19, 2>";
535  let SuperClasses = [ConstantUImm20AsmOperandClass];
536  let DiagnosticType = "SImm19_Lsl2";
537}
538def UImm16RelaxedAsmOperandClass
539    : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
540  let Name = "UImm16_Relaxed";
541  let PredicateMethod = "isAnyImm<16>";
542  let DiagnosticType = "UImm16_Relaxed";
543}
544// Similar to the relaxed classes which take an SImm and render it as
545// an UImm, this takes a UImm and renders it as an SImm.
546def UImm16AltRelaxedAsmOperandClass
547    : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
548  let Name = "UImm16_AltRelaxed";
549  let PredicateMethod = "isUImm<16>";
550  let DiagnosticType = "UImm16_AltRelaxed";
551}
552// FIXME: One of these should probably have UImm16AsmOperandClass as the
553//        superclass instead of UImm16RelaxedasmOPerandClass.
554def UImm16AsmOperandClass
555    : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
556def SImm16RelaxedAsmOperandClass
557    : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
558  let Name = "SImm16_Relaxed";
559  let PredicateMethod = "isAnyImm<16>";
560  let DiagnosticType = "SImm16_Relaxed";
561}
562def SImm16AsmOperandClass
563    : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
564def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
565  let Name = "SImm10Lsl3";
566  let RenderMethod = "addImmOperands";
567  let PredicateMethod = "isScaledSImm<10, 3>";
568  let SuperClasses = [SImm16AsmOperandClass];
569  let DiagnosticType = "SImm10_Lsl3";
570}
571def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
572  let Name = "SImm10Lsl2";
573  let RenderMethod = "addImmOperands";
574  let PredicateMethod = "isScaledSImm<10, 2>";
575  let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
576  let DiagnosticType = "SImm10_Lsl2";
577}
578def ConstantSImm11AsmOperandClass
579    : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
580def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
581  let Name = "SImm10Lsl1";
582  let RenderMethod = "addImmOperands";
583  let PredicateMethod = "isScaledSImm<10, 1>";
584  let SuperClasses = [ConstantSImm11AsmOperandClass];
585  let DiagnosticType = "SImm10_Lsl1";
586}
587def ConstantUImm10AsmOperandClass
588    : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
589def ConstantSImm10AsmOperandClass
590    : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
591def ConstantSImm9AsmOperandClass
592    : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
593def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
594  let Name = "SImm7Lsl2";
595  let RenderMethod = "addImmOperands";
596  let PredicateMethod = "isScaledSImm<7, 2>";
597  let SuperClasses = [ConstantSImm9AsmOperandClass];
598  let DiagnosticType = "SImm7_Lsl2";
599}
600def ConstantUImm8AsmOperandClass
601    : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
602def ConstantUImm7Sub1AsmOperandClass
603    : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
604  // Specify the names since the -1 offset causes invalid identifiers otherwise.
605  let Name = "UImm7_N1";
606  let DiagnosticType = "UImm7_N1";
607}
608def ConstantUImm7AsmOperandClass
609    : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
610def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
611  let Name = "UImm6Lsl2";
612  let RenderMethod = "addImmOperands";
613  let PredicateMethod = "isScaledUImm<6, 2>";
614  let SuperClasses = [ConstantUImm7AsmOperandClass];
615  let DiagnosticType = "UImm6_Lsl2";
616}
617def ConstantUImm6AsmOperandClass
618    : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
619def ConstantSImm6AsmOperandClass
620    : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
621def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
622  let Name = "UImm5Lsl2";
623  let RenderMethod = "addImmOperands";
624  let PredicateMethod = "isScaledUImm<5, 2>";
625  let SuperClasses = [ConstantSImm6AsmOperandClass];
626  let DiagnosticType = "UImm5_Lsl2";
627}
628def ConstantUImm5_Range2_64AsmOperandClass
629    : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
630def ConstantUImm5Plus33AsmOperandClass
631    : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
632                                  33>;
633def ConstantUImm5ReportUImm6AsmOperandClass
634    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
635  let Name = "ConstantUImm5_0_Report_UImm6";
636  let DiagnosticType = "UImm5_0_Report_UImm6";
637}
638def ConstantUImm5Plus32AsmOperandClass
639    : ConstantUImmAsmOperandClass<
640          5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
641def ConstantUImm5Plus32NormalizeAsmOperandClass
642    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
643  let Name = "ConstantUImm5_32_Norm";
644  // We must also subtract 32 when we render the operand.
645  let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
646}
647def ConstantUImm5Plus1AsmOperandClass
648    : ConstantUImmAsmOperandClass<
649          5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
650def ConstantUImm5AsmOperandClass
651    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
652def ConstantSImm5AsmOperandClass
653    : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
654def ConstantUImm4AsmOperandClass
655    : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
656def ConstantSImm4AsmOperandClass
657    : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
658def ConstantUImm3AsmOperandClass
659    : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
660def ConstantUImm2Plus1AsmOperandClass
661    : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
662def ConstantUImm2AsmOperandClass
663    : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
664def ConstantUImm1AsmOperandClass
665    : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
666def ConstantImmzAsmOperandClass : AsmOperandClass {
667  let Name = "ConstantImmz";
668  let RenderMethod = "addConstantUImmOperands<1>";
669  let PredicateMethod = "isConstantImmz";
670  let SuperClasses = [ConstantUImm1AsmOperandClass];
671  let DiagnosticType = "Immz";
672}
673
674def Simm19Lsl2AsmOperand
675    : SimmLslAsmOperandClass<19, [], 2>;
676
677def MipsJumpTargetAsmOperand : AsmOperandClass {
678  let Name = "JumpTarget";
679  let ParserMethod = "parseJumpTarget";
680  let PredicateMethod = "isImm";
681  let RenderMethod = "addImmOperands";
682}
683
684// Instruction operand types
685def jmptarget   : Operand<OtherVT> {
686  let EncoderMethod = "getJumpTargetOpValue";
687  let ParserMatchClass = MipsJumpTargetAsmOperand;
688}
689def brtarget    : Operand<OtherVT> {
690  let EncoderMethod = "getBranchTargetOpValue";
691  let OperandType = "OPERAND_PCREL";
692  let DecoderMethod = "DecodeBranchTarget";
693  let ParserMatchClass = MipsJumpTargetAsmOperand;
694}
695def brtarget1SImm16 : Operand<OtherVT> {
696  let EncoderMethod = "getBranchTargetOpValue1SImm16";
697  let OperandType = "OPERAND_PCREL";
698  let DecoderMethod = "DecodeBranchTarget1SImm16";
699  let ParserMatchClass = MipsJumpTargetAsmOperand;
700}
701def calltarget  : Operand<iPTR> {
702  let EncoderMethod = "getJumpTargetOpValue";
703  let ParserMatchClass = MipsJumpTargetAsmOperand;
704}
705
706def imm64: Operand<i64>;
707
708def simm19_lsl2 : Operand<i32> {
709  let EncoderMethod = "getSimm19Lsl2Encoding";
710  let DecoderMethod = "DecodeSimm19Lsl2";
711  let ParserMatchClass = Simm19Lsl2AsmOperand;
712}
713
714def simm18_lsl3 : Operand<i32> {
715  let EncoderMethod = "getSimm18Lsl3Encoding";
716  let DecoderMethod = "DecodeSimm18Lsl3";
717  let ParserMatchClass = MipsJumpTargetAsmOperand;
718}
719
720// Zero
721def uimmz       : Operand<i32> {
722  let PrintMethod = "printUImm<0>";
723  let ParserMatchClass = ConstantImmzAsmOperandClass;
724}
725
726// size operand of ins instruction
727def uimm_range_2_64 : Operand<i32> {
728  let PrintMethod = "printUImm<6, 2>";
729  let EncoderMethod = "getSizeInsEncoding";
730  let DecoderMethod = "DecodeInsSize";
731  let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
732}
733
734// Unsigned Operands
735foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
736  def uimm # I : Operand<i32> {
737    let PrintMethod = "printUImm<" # I # ">";
738    let ParserMatchClass =
739        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
740  }
741
742def uimm2_plus1 : Operand<i32> {
743  let PrintMethod = "printUImm<2, 1>";
744  let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
745  let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
746  let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
747}
748
749def uimm5_plus1 : Operand<i32> {
750  let PrintMethod = "printUImm<5, 1>";
751  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
752  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
753  let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
754}
755
756def uimm5_plus32 : Operand<i32> {
757  let PrintMethod = "printUImm<5, 32>";
758  let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
759}
760
761def uimm5_plus33 : Operand<i32> {
762  let PrintMethod = "printUImm<5, 33>";
763  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
764  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
765  let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
766}
767
768def uimm5_inssize_plus1 : Operand<i32> {
769  let PrintMethod = "printUImm<6>";
770  let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
771  let EncoderMethod = "getSizeInsEncoding";
772  let DecoderMethod = "DecodeInsSize";
773}
774
775def uimm5_plus32_normalize : Operand<i32> {
776  let PrintMethod = "printUImm<5>";
777  let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
778}
779
780def uimm5_lsl2 : Operand<OtherVT> {
781  let EncoderMethod = "getUImm5Lsl2Encoding";
782  let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
783  let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
784}
785
786def uimm5_plus32_normalize_64 : Operand<i64> {
787  let PrintMethod = "printUImm<5>";
788  let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
789}
790
791def uimm6_lsl2 : Operand<OtherVT> {
792  let EncoderMethod = "getUImm6Lsl2Encoding";
793  let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
794  let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
795}
796
797foreach I = {16} in
798  def uimm # I : Operand<i32> {
799    let PrintMethod = "printUImm<" # I # ">";
800    let ParserMatchClass =
801        !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
802  }
803
804// Like uimm16_64 but coerces simm16 to uimm16.
805def uimm16_relaxed : Operand<i32> {
806  let PrintMethod = "printUImm<16>";
807  let ParserMatchClass =
808      !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
809}
810
811foreach I = {5} in
812  def uimm # I # _64 : Operand<i64> {
813    let PrintMethod = "printUImm<" # I # ">";
814    let ParserMatchClass =
815        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
816  }
817
818foreach I = {16} in
819  def uimm # I # _64 : Operand<i64> {
820    let PrintMethod = "printUImm<" # I # ">";
821    let ParserMatchClass =
822        !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
823  }
824
825// Like uimm16_64 but coerces simm16 to uimm16.
826def uimm16_64_relaxed : Operand<i64> {
827  let PrintMethod = "printUImm<16>";
828  let ParserMatchClass =
829      !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
830}
831
832def uimm16_altrelaxed : Operand<i32> {
833  let PrintMethod = "printUImm<16>";
834  let ParserMatchClass =
835      !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
836}
837// Like uimm5 but reports a less confusing error for 32-63 when
838// an instruction alias permits that.
839def uimm5_report_uimm6 : Operand<i32> {
840  let PrintMethod = "printUImm<5>";
841  let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
842}
843
844// Like uimm5_64 but reports a less confusing error for 32-63 when
845// an instruction alias permits that.
846def uimm5_64_report_uimm6 : Operand<i64> {
847  let PrintMethod = "printUImm<5>";
848  let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
849}
850
851foreach I = {1, 2, 3, 4} in
852  def uimm # I # _ptr : Operand<iPTR> {
853    let PrintMethod = "printUImm<" # I # ">";
854    let ParserMatchClass =
855        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
856  }
857
858foreach I = {1, 2, 3, 4, 5, 6, 8} in
859  def vsplat_uimm # I : Operand<vAny> {
860    let PrintMethod = "printUImm<" # I # ">";
861    let ParserMatchClass =
862        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
863  }
864
865// Signed operands
866foreach I = {4, 5, 6, 9, 10, 11} in
867  def simm # I : Operand<i32> {
868    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
869    let ParserMatchClass =
870        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
871  }
872
873foreach I = {1, 2, 3} in
874  def simm10_lsl # I : Operand<i32> {
875    let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
876    let ParserMatchClass =
877        !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
878  }
879
880foreach I = {10} in
881  def simm # I # _64 : Operand<i64> {
882    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
883    let ParserMatchClass =
884        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
885  }
886
887foreach I = {5, 10} in
888  def vsplat_simm # I : Operand<vAny> {
889    let ParserMatchClass =
890        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
891  }
892
893def simm7_lsl2 : Operand<OtherVT> {
894  let EncoderMethod = "getSImm7Lsl2Encoding";
895  let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
896  let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
897}
898
899foreach I = {16, 32} in
900  def simm # I : Operand<i32> {
901    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
902    let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
903  }
904
905// Like simm16 but coerces uimm16 to simm16.
906def simm16_relaxed : Operand<i32> {
907  let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
908  let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
909}
910
911def simm16_64 : Operand<i64> {
912  let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
913  let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
914}
915
916// like simm32 but coerces simm32 to uimm32.
917def uimm32_coerced : Operand<i32> {
918  let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
919}
920// Like simm32 but coerces uimm32 to simm32.
921def simm32_relaxed : Operand<i32> {
922  let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
923  let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
924}
925
926// This is almost the same as a uimm7 but 0x7f is interpreted as -1.
927def li16_imm : Operand<i32> {
928  let DecoderMethod = "DecodeLi16Imm";
929  let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
930}
931
932def MipsMemAsmOperand : AsmOperandClass {
933  let Name = "Mem";
934  let ParserMethod = "parseMemOperand";
935}
936
937def MipsMemSimm9AsmOperand : AsmOperandClass {
938  let Name = "MemOffsetSimm9";
939  let SuperClasses = [MipsMemAsmOperand];
940  let RenderMethod = "addMemOperands";
941  let ParserMethod = "parseMemOperand";
942  let PredicateMethod = "isMemWithSimmOffset<9>";
943  let DiagnosticType = "MemSImm9";
944}
945
946def MipsMemSimm10AsmOperand : AsmOperandClass {
947  let Name = "MemOffsetSimm10";
948  let SuperClasses = [MipsMemAsmOperand];
949  let RenderMethod = "addMemOperands";
950  let ParserMethod = "parseMemOperand";
951  let PredicateMethod = "isMemWithSimmOffset<10>";
952  let DiagnosticType = "MemSImm10";
953}
954
955def MipsMemSimm12AsmOperand : AsmOperandClass {
956  let Name = "MemOffsetSimm12";
957  let SuperClasses = [MipsMemAsmOperand];
958  let RenderMethod = "addMemOperands";
959  let ParserMethod = "parseMemOperand";
960  let PredicateMethod = "isMemWithSimmOffset<12>";
961  let DiagnosticType = "MemSImm12";
962}
963
964foreach I = {1, 2, 3} in
965  def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
966    let Name = "MemOffsetSimm10_" # I;
967    let SuperClasses = [MipsMemAsmOperand];
968    let RenderMethod = "addMemOperands";
969    let ParserMethod = "parseMemOperand";
970    let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
971    let DiagnosticType = "MemSImm10Lsl" # I;
972  }
973
974def MipsMemSimm11AsmOperand : AsmOperandClass {
975  let Name = "MemOffsetSimm11";
976  let SuperClasses = [MipsMemAsmOperand];
977  let RenderMethod = "addMemOperands";
978  let ParserMethod = "parseMemOperand";
979  let PredicateMethod = "isMemWithSimmOffset<11>";
980  let DiagnosticType = "MemSImm11";
981}
982
983def MipsMemSimm16AsmOperand : AsmOperandClass {
984  let Name = "MemOffsetSimm16";
985  let SuperClasses = [MipsMemAsmOperand];
986  let RenderMethod = "addMemOperands";
987  let ParserMethod = "parseMemOperand";
988  let PredicateMethod = "isMemWithSimmOffset<16>";
989  let DiagnosticType = "MemSImm16";
990}
991
992def MipsInvertedImmoperand : AsmOperandClass {
993  let Name = "InvNum";
994  let RenderMethod = "addImmOperands";
995  let ParserMethod = "parseInvNum";
996}
997
998def InvertedImOperand : Operand<i32> {
999  let ParserMatchClass = MipsInvertedImmoperand;
1000}
1001
1002def InvertedImOperand64 : Operand<i64> {
1003  let ParserMatchClass = MipsInvertedImmoperand;
1004}
1005
1006class mem_generic : Operand<iPTR> {
1007  let PrintMethod = "printMemOperand";
1008  let MIOperandInfo = (ops ptr_rc, simm16);
1009  let EncoderMethod = "getMemEncoding";
1010  let ParserMatchClass = MipsMemAsmOperand;
1011  let OperandType = "OPERAND_MEMORY";
1012}
1013
1014// Address operand
1015def mem : mem_generic;
1016
1017// MSA specific address operand
1018def mem_msa : mem_generic {
1019  let MIOperandInfo = (ops ptr_rc, simm10);
1020  let EncoderMethod = "getMSAMemEncoding";
1021}
1022
1023def simm12 : Operand<i32> {
1024  let DecoderMethod = "DecodeSimm12";
1025}
1026
1027def mem_simm9 : mem_generic {
1028  let MIOperandInfo = (ops ptr_rc, simm9);
1029  let EncoderMethod = "getMemEncoding";
1030  let ParserMatchClass = MipsMemSimm9AsmOperand;
1031}
1032
1033def mem_simm10 : mem_generic {
1034  let MIOperandInfo = (ops ptr_rc, simm10);
1035  let EncoderMethod = "getMemEncoding";
1036  let ParserMatchClass = MipsMemSimm10AsmOperand;
1037}
1038
1039foreach I = {1, 2, 3} in
1040  def mem_simm10_lsl # I : mem_generic {
1041    let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1042    let EncoderMethod = "getMemEncoding<" # I  # ">";
1043    let ParserMatchClass =
1044            !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
1045  }
1046
1047def mem_simm11 : mem_generic {
1048  let MIOperandInfo = (ops ptr_rc, simm11);
1049  let EncoderMethod = "getMemEncoding";
1050  let ParserMatchClass = MipsMemSimm11AsmOperand;
1051}
1052
1053def mem_simm12 : mem_generic {
1054  let MIOperandInfo = (ops ptr_rc, simm12);
1055  let EncoderMethod = "getMemEncoding";
1056  let ParserMatchClass = MipsMemSimm12AsmOperand;
1057}
1058
1059def mem_simm16 : mem_generic {
1060  let MIOperandInfo = (ops ptr_rc, simm16);
1061  let EncoderMethod = "getMemEncoding";
1062  let ParserMatchClass = MipsMemSimm16AsmOperand;
1063}
1064
1065def mem_ea : Operand<iPTR> {
1066  let PrintMethod = "printMemOperandEA";
1067  let MIOperandInfo = (ops ptr_rc, simm16);
1068  let EncoderMethod = "getMemEncoding";
1069  let OperandType = "OPERAND_MEMORY";
1070}
1071
1072def PtrRC : Operand<iPTR> {
1073  let MIOperandInfo = (ops ptr_rc);
1074  let DecoderMethod = "DecodePtrRegisterClass";
1075  let ParserMatchClass = GPR32AsmOperand;
1076}
1077
1078// size operand of ins instruction
1079def size_ins : Operand<i32> {
1080  let EncoderMethod = "getSizeInsEncoding";
1081  let DecoderMethod = "DecodeInsSize";
1082}
1083
1084// Transformation Function - get the lower 16 bits.
1085def LO16 : SDNodeXForm<imm, [{
1086  return getImm(N, N->getZExtValue() & 0xFFFF);
1087}]>;
1088
1089// Transformation Function - get the higher 16 bits.
1090def HI16 : SDNodeXForm<imm, [{
1091  return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1092}]>;
1093
1094// Plus 1.
1095def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1096
1097// Node immediate is zero (e.g. insve.d)
1098def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1099
1100// Node immediate fits as 16-bit sign extended on target immediate.
1101// e.g. addi, andi
1102def immSExt8  : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1103
1104// Node immediate fits as 16-bit sign extended on target immediate.
1105// e.g. addi, andi
1106def immSExt16  : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1107
1108// Node immediate fits as 7-bit zero extended on target immediate.
1109def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1110
1111// Node immediate fits as 16-bit zero extended on target immediate.
1112// The LO16 param means that only the lower 16 bits of the node
1113// immediate are caught.
1114// e.g. addiu, sltiu
1115def immZExt16  : PatLeaf<(imm), [{
1116  if (N->getValueType(0) == MVT::i32)
1117    return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1118  else
1119    return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1120}], LO16>;
1121
1122// Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1123def immSExt32Low16Zero : PatLeaf<(imm), [{
1124  int64_t Val = N->getSExtValue();
1125  return isInt<32>(Val) && !(Val & 0xffff);
1126}]>;
1127
1128// Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1129def immZExt32Low16Zero : PatLeaf<(imm), [{
1130  uint64_t Val = N->getZExtValue();
1131  return isUInt<32>(Val) && !(Val & 0xffff);
1132}]>;
1133
1134// Note immediate fits as a 32 bit signed extended on target immediate.
1135def immSExt32  : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1136
1137// Note immediate fits as a 32 bit zero extended on target immediate.
1138def immZExt32  : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1139
1140// shamt field must fit in 5 bits.
1141def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1142
1143def immZExt5Plus1 : PatLeaf<(imm), [{
1144  return isUInt<5>(N->getZExtValue() - 1);
1145}]>;
1146def immZExt5Plus32 : PatLeaf<(imm), [{
1147  return isUInt<5>(N->getZExtValue() - 32);
1148}]>;
1149def immZExt5Plus33 : PatLeaf<(imm), [{
1150  return isUInt<5>(N->getZExtValue() - 33);
1151}]>;
1152
1153// True if (N + 1) fits in 16-bit field.
1154def immSExt16Plus1 : PatLeaf<(imm), [{
1155  return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1156}]>;
1157
1158// Mips Address Mode! SDNode frameindex could possibily be a match
1159// since load and store instructions from stack used it.
1160def addr :
1161  ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1162
1163def addrRegImm :
1164  ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1165
1166def addrDefault :
1167  ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1168
1169def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1170def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1171                                   [frameindex]>;
1172def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1173                                   [frameindex]>;
1174def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1175                                   [frameindex]>;
1176
1177//===----------------------------------------------------------------------===//
1178// Instructions specific format
1179//===----------------------------------------------------------------------===//
1180
1181// Arithmetic and logical instructions with 3 register operands.
1182class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1183                  InstrItinClass Itin = NoItinerary,
1184                  SDPatternOperator OpNode = null_frag>:
1185  InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1186         !strconcat(opstr, "\t$rd, $rs, $rt"),
1187         [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1188  let isCommutable = isComm;
1189  let isReMaterializable = 1;
1190  let TwoOperandAliasConstraint = "$rd = $rs";
1191}
1192
1193// Arithmetic and logical instructions with 2 register operands.
1194class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1195                  InstrItinClass Itin = NoItinerary,
1196                  SDPatternOperator imm_type = null_frag,
1197                  SDPatternOperator OpNode = null_frag> :
1198  InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1199         !strconcat(opstr, "\t$rt, $rs, $imm16"),
1200         [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1201         Itin, FrmI, opstr> {
1202  let isReMaterializable = 1;
1203  let TwoOperandAliasConstraint = "$rs = $rt";
1204}
1205
1206// Arithmetic Multiply ADD/SUB
1207class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1208  InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1209         !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1210  let Defs = [HI0, LO0];
1211  let Uses = [HI0, LO0];
1212  let isCommutable = isComm;
1213}
1214
1215//  Logical
1216class LogicNOR<string opstr, RegisterOperand RO>:
1217  InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1218         !strconcat(opstr, "\t$rd, $rs, $rt"),
1219         [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1220  let isCommutable = 1;
1221}
1222
1223// Shifts
1224class shift_rotate_imm<string opstr, Operand ImmOpnd,
1225                       RegisterOperand RO, InstrItinClass itin,
1226                       SDPatternOperator OpNode = null_frag,
1227                       SDPatternOperator PF = null_frag> :
1228  InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1229         !strconcat(opstr, "\t$rd, $rt, $shamt"),
1230         [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1231  let TwoOperandAliasConstraint = "$rt = $rd";
1232}
1233
1234class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1235                       SDPatternOperator OpNode = null_frag>:
1236  InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1237         !strconcat(opstr, "\t$rd, $rt, $rs"),
1238         [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1239         opstr>;
1240
1241// Load Upper Immediate
1242class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1243  InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1244         [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1245  let hasSideEffects = 0;
1246  let isReMaterializable = 1;
1247}
1248
1249// Memory Load/Store
1250class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1251                 SDPatternOperator OpNode = null_frag,
1252                 InstrItinClass Itin = NoItinerary,
1253                 ComplexPattern Addr = addr> :
1254  InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1255         [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1256  let DecoderMethod = "DecodeMem";
1257  let canFoldAsLoad = 1;
1258  let mayLoad = 1;
1259}
1260
1261class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1262           InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1263  LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1264
1265class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1266            SDPatternOperator OpNode = null_frag,
1267            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1268  InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1269         [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1270  let DecoderMethod = "DecodeMem";
1271  let mayStore = 1;
1272}
1273
1274class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1275            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1276            DAGOperand MO = mem> :
1277  StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1278
1279// Load/Store Left/Right
1280let canFoldAsLoad = 1 in
1281class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1282                    InstrItinClass Itin> :
1283  InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1284         !strconcat(opstr, "\t$rt, $addr"),
1285         [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1286  let DecoderMethod = "DecodeMem";
1287  string Constraints = "$src = $rt";
1288}
1289
1290class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1291                     InstrItinClass Itin> :
1292  InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1293         [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1294  let DecoderMethod = "DecodeMem";
1295}
1296
1297// COP2 Load/Store
1298class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1299             SDPatternOperator OpNode= null_frag> :
1300  InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1301         !strconcat(opstr, "\t$rt, $addr"),
1302         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1303  let DecoderMethod = "DecodeFMem2";
1304  let mayLoad = 1;
1305}
1306
1307class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1308             SDPatternOperator OpNode= null_frag> :
1309  InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1310         !strconcat(opstr, "\t$rt, $addr"),
1311         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1312  let DecoderMethod = "DecodeFMem2";
1313  let mayStore = 1;
1314}
1315
1316// COP3 Load/Store
1317class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1318             SDPatternOperator OpNode= null_frag> :
1319  InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1320         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1321  let DecoderMethod = "DecodeFMem3";
1322  let mayLoad = 1;
1323}
1324
1325class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1326             SDPatternOperator OpNode= null_frag> :
1327  InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1328         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1329  let DecoderMethod = "DecodeFMem3";
1330  let mayStore = 1;
1331}
1332
1333// Conditional Branch
1334class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1335              RegisterOperand RO, bit DelaySlot = 1> :
1336  InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1337         !strconcat(opstr, "\t$rs, $rt, $offset"),
1338         [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1339         FrmI, opstr> {
1340  let isBranch = 1;
1341  let isTerminator = 1;
1342  let hasDelaySlot = DelaySlot;
1343  let Defs = [AT];
1344  bit isCTI = 1;
1345}
1346
1347class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1348                  RegisterOperand RO, bit DelaySlot = 1> :
1349  InstSE<(outs), (ins RO:$rs, opnd:$offset),
1350         !strconcat(opstr, "\t$rs, $offset"),
1351         [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1352         FrmI, opstr> {
1353  let isBranch = 1;
1354  let isTerminator = 1;
1355  let hasDelaySlot = DelaySlot;
1356  let Defs = [AT];
1357  bit isCTI = 1;
1358}
1359
1360// SetCC
1361class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1362  InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1363         !strconcat(opstr, "\t$rd, $rs, $rt"),
1364         [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1365         II_SLT_SLTU, FrmR, opstr>;
1366
1367class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1368              RegisterOperand RO>:
1369  InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1370         !strconcat(opstr, "\t$rt, $rs, $imm16"),
1371         [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1372         II_SLTI_SLTIU, FrmI, opstr>;
1373
1374// Jump
1375class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1376             SDPatternOperator targetoperator, string bopstr> :
1377  InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1378         [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1379  let isTerminator=1;
1380  let isBarrier=1;
1381  let hasDelaySlot = 1;
1382  let DecoderMethod = "DecodeJumpTarget";
1383  let Defs = [AT];
1384  bit isCTI = 1;
1385}
1386
1387// Unconditional branch
1388class UncondBranch<Instruction BEQInst> :
1389  PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1390  PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
1391  let isBranch = 1;
1392  let isTerminator = 1;
1393  let isBarrier = 1;
1394  let hasDelaySlot = 1;
1395  let AdditionalPredicates = [RelocPIC];
1396  let Defs = [AT];
1397  bit isCTI = 1;
1398}
1399
1400// Base class for indirect branch and return instruction classes.
1401let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1402class JumpFR<string opstr, RegisterOperand RO,
1403             SDPatternOperator operator = null_frag>:
1404  InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1405         FrmR, opstr>;
1406
1407// Indirect branch
1408class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1409  let isBranch = 1;
1410  let isIndirectBranch = 1;
1411}
1412
1413// Jump and Link (Call)
1414let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1415  class JumpLink<string opstr, DAGOperand opnd> :
1416    InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1417           [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1418    let DecoderMethod = "DecodeJumpTarget";
1419  }
1420
1421  class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1422                          Register RetReg, RegisterOperand ResRO = RO>:
1423    PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1424    PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
1425
1426  class JumpLinkReg<string opstr, RegisterOperand RO>:
1427    InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1428           [], II_JALR, FrmR, opstr>;
1429
1430  class BGEZAL_FT<string opstr, DAGOperand opnd,
1431                  RegisterOperand RO, bit DelaySlot = 1> :
1432    InstSE<(outs), (ins RO:$rs, opnd:$offset),
1433           !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1434    let hasDelaySlot = DelaySlot;
1435  }
1436
1437}
1438
1439let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1440    hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1441  class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1442    PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1443    PseudoInstExpansion<(JumpInst Opnd:$target)>;
1444
1445  class TailCallReg<RegisterOperand RO> :
1446    MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
1447}
1448
1449class BAL_BR_Pseudo<Instruction RealInst> :
1450  PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1451  PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1452  let isBranch = 1;
1453  let isTerminator = 1;
1454  let isBarrier = 1;
1455  let hasDelaySlot = 1;
1456  let Defs = [RA];
1457  bit isCTI = 1;
1458}
1459
1460let isCTI = 1 in {
1461// Syscall
1462class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1463  InstSE<(outs), (ins ImmOp:$code_),
1464         !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1465// Break
1466class BRK_FT<string opstr> :
1467  InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1468         !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1469         FrmOther, opstr>;
1470
1471// (D)Eret
1472class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1473  InstSE<(outs), (ins),
1474         opstr, [], itin, FrmOther, opstr>;
1475
1476// Wait
1477class WAIT_FT<string opstr> :
1478  InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1479}
1480
1481// Interrupts
1482class DEI_FT<string opstr, RegisterOperand RO,
1483             InstrItinClass itin = NoItinerary> :
1484  InstSE<(outs RO:$rt), (ins),
1485         !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1486
1487// Sync
1488let hasSideEffects = 1 in
1489class SYNC_FT<string opstr> :
1490  InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1491         [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1492
1493class SYNCI_FT<string opstr> :
1494  InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
1495         II_SYNCI, FrmOther, opstr> {
1496  let hasSideEffects = 1;
1497  let DecoderMethod = "DecodeSyncI";
1498}
1499
1500let hasSideEffects = 1, isCTI = 1 in {
1501class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1502             InstrItinClass itin = NoItinerary> :
1503  InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1504         !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1505
1506class TEQI_FT<string opstr, RegisterOperand RO,
1507              InstrItinClass itin = NoItinerary> :
1508  InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1509         !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1510}
1511
1512// Mul, Div
1513class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1514           list<Register> DefRegs> :
1515  InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1516         itin, FrmR, opstr> {
1517  let isCommutable = 1;
1518  let Defs = DefRegs;
1519  let hasSideEffects = 0;
1520}
1521
1522// Pseudo multiply/divide instruction with explicit accumulator register
1523// operands.
1524class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1525                    SDPatternOperator OpNode, InstrItinClass Itin,
1526                    bit IsComm = 1, bit HasSideEffects = 0,
1527                    bit UsesCustomInserter = 0> :
1528  PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1529           [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1530  PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1531  let isCommutable = IsComm;
1532  let hasSideEffects = HasSideEffects;
1533  let usesCustomInserter = UsesCustomInserter;
1534}
1535
1536// Pseudo multiply add/sub instruction with explicit accumulator register
1537// operands.
1538class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1539                    InstrItinClass itin>
1540  : PseudoSE<(outs ACC64:$ac),
1541             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1542             [(set ACC64:$ac,
1543              (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1544             itin>,
1545    PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1546  string Constraints = "$acin = $ac";
1547}
1548
1549class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1550          list<Register> DefRegs> :
1551  InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1552         [], itin, FrmR, opstr> {
1553  let Defs = DefRegs;
1554}
1555
1556// Move from Hi/Lo
1557class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1558  : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1559             [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1560
1561class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1562  InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1563         FrmR, opstr> {
1564  let Uses = [UseReg];
1565  let hasSideEffects = 0;
1566}
1567
1568class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1569  : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1570             [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1571             II_MTHI_MTLO>;
1572
1573class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1574  InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1575  FrmR, opstr> {
1576  let Defs = DefRegs;
1577  let hasSideEffects = 0;
1578}
1579
1580class EffectiveAddress<string opstr, RegisterOperand RO> :
1581  InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1582         [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1583         !strconcat(opstr, "_lea")> {
1584  let isCodeGenOnly = 1;
1585  let hasNoSchedulingInfo = 1;
1586  let DecoderMethod = "DecodeMem";
1587}
1588
1589// Count Leading Ones/Zeros in Word
1590class CountLeading0<string opstr, RegisterOperand RO,
1591                  InstrItinClass itin = NoItinerary>:
1592  InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1593         [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1594
1595class CountLeading1<string opstr, RegisterOperand RO,
1596                  InstrItinClass itin = NoItinerary>:
1597  InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1598         [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1599
1600// Sign Extend in Register.
1601class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1602                   InstrItinClass itin> :
1603  InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1604         [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1605
1606// Subword Swap
1607class SubwordSwap<string opstr, RegisterOperand RO,
1608                  InstrItinClass itin = NoItinerary>:
1609  InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1610         FrmR, opstr> {
1611  let hasSideEffects = 0;
1612}
1613
1614// Read Hardware
1615class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1616  InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1617         II_RDHWR, FrmR, "rdhwr">;
1618
1619// Ext and Ins
1620class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1621              Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1622              SDPatternOperator Op = null_frag> :
1623  InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1624         !strconcat(opstr, " $rt, $rs, $pos, $size"),
1625         [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1626         FrmR, opstr>, ISA_MIPS32R2;
1627
1628class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1629              Operand SizeOpnd, SDPatternOperator Op = null_frag>:
1630  InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1631         !strconcat(opstr, " $rt, $rs, $pos, $size"),
1632         [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1633         II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1634  let Constraints = "$src = $rt";
1635}
1636
1637// Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1638class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1639  PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1640           [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1641
1642// Atomic Compare & Swap.
1643class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1644  PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1645           [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1646
1647class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1648  InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1649         [], II_LL, FrmI, opstr> {
1650  let DecoderMethod = "DecodeMem";
1651  let mayLoad = 1;
1652}
1653
1654class SCBase<string opstr, RegisterOperand RO> :
1655  InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1656         !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1657  let DecoderMethod = "DecodeMem";
1658  let mayStore = 1;
1659  let Constraints = "$rt = $dst";
1660}
1661
1662class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1663             InstrItinClass itin> :
1664  InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1665         !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1666
1667class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1668             InstrItinClass itin> :
1669  InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1670         !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1671
1672class TrapBase<Instruction RealInst>
1673  : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1674    PseudoInstExpansion<(RealInst 0, 0)> {
1675  let isBarrier = 1;
1676  let isTerminator = 1;
1677  let isCodeGenOnly = 1;
1678  let isCTI = 1;
1679}
1680
1681//===----------------------------------------------------------------------===//
1682// Pseudo instructions
1683//===----------------------------------------------------------------------===//
1684
1685// Return RA.
1686let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1687  let hasDelaySlot=1 in
1688  def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1689
1690  let hasSideEffects=1 in
1691  def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1692}
1693
1694let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1695def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1696                                  [(callseq_start timm:$amt)]>;
1697def ADJCALLSTACKUP   : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1698                                  [(callseq_end timm:$amt1, timm:$amt2)]>;
1699}
1700
1701let usesCustomInserter = 1 in {
1702  def ATOMIC_LOAD_ADD_I8   : Atomic2Ops<atomic_load_add_8, GPR32>;
1703  def ATOMIC_LOAD_ADD_I16  : Atomic2Ops<atomic_load_add_16, GPR32>;
1704  def ATOMIC_LOAD_ADD_I32  : Atomic2Ops<atomic_load_add_32, GPR32>;
1705  def ATOMIC_LOAD_SUB_I8   : Atomic2Ops<atomic_load_sub_8, GPR32>;
1706  def ATOMIC_LOAD_SUB_I16  : Atomic2Ops<atomic_load_sub_16, GPR32>;
1707  def ATOMIC_LOAD_SUB_I32  : Atomic2Ops<atomic_load_sub_32, GPR32>;
1708  def ATOMIC_LOAD_AND_I8   : Atomic2Ops<atomic_load_and_8, GPR32>;
1709  def ATOMIC_LOAD_AND_I16  : Atomic2Ops<atomic_load_and_16, GPR32>;
1710  def ATOMIC_LOAD_AND_I32  : Atomic2Ops<atomic_load_and_32, GPR32>;
1711  def ATOMIC_LOAD_OR_I8    : Atomic2Ops<atomic_load_or_8, GPR32>;
1712  def ATOMIC_LOAD_OR_I16   : Atomic2Ops<atomic_load_or_16, GPR32>;
1713  def ATOMIC_LOAD_OR_I32   : Atomic2Ops<atomic_load_or_32, GPR32>;
1714  def ATOMIC_LOAD_XOR_I8   : Atomic2Ops<atomic_load_xor_8, GPR32>;
1715  def ATOMIC_LOAD_XOR_I16  : Atomic2Ops<atomic_load_xor_16, GPR32>;
1716  def ATOMIC_LOAD_XOR_I32  : Atomic2Ops<atomic_load_xor_32, GPR32>;
1717  def ATOMIC_LOAD_NAND_I8  : Atomic2Ops<atomic_load_nand_8, GPR32>;
1718  def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1719  def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1720
1721  def ATOMIC_SWAP_I8       : Atomic2Ops<atomic_swap_8, GPR32>;
1722  def ATOMIC_SWAP_I16      : Atomic2Ops<atomic_swap_16, GPR32>;
1723  def ATOMIC_SWAP_I32      : Atomic2Ops<atomic_swap_32, GPR32>;
1724
1725  def ATOMIC_CMP_SWAP_I8   : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1726  def ATOMIC_CMP_SWAP_I16  : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1727  def ATOMIC_CMP_SWAP_I32  : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1728}
1729
1730/// Pseudo instructions for loading and storing accumulator registers.
1731let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1732  def LOAD_ACC64  : Load<"", ACC64>;
1733  def STORE_ACC64 : Store<"", ACC64>;
1734}
1735
1736// We need these two pseudo instructions to avoid offset calculation for long
1737// branches.  See the comment in file MipsLongBranch.cpp for detailed
1738// explanation.
1739
1740// Expands to: lui $dst, %hi($tgt - $baltgt)
1741def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1742  (ins brtarget:$tgt, brtarget:$baltgt), []>;
1743
1744// Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1745def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1746  (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1747
1748//===----------------------------------------------------------------------===//
1749// Instruction definition
1750//===----------------------------------------------------------------------===//
1751//===----------------------------------------------------------------------===//
1752// MipsI Instructions
1753//===----------------------------------------------------------------------===//
1754
1755/// Arithmetic Instructions (ALU Immediate)
1756let AdditionalPredicates = [NotInMicroMips] in {
1757  def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
1758                                             II_ADDIU, immSExt16, add>,
1759              ADDI_FM<0x9>, IsAsCheapAsAMove;
1760
1761  def ANDi : MMRel, StdMMR6Rel,
1762             ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1763             ADDI_FM<0xc>;
1764  def ORi  : MMRel, StdMMR6Rel,
1765             ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1766             ADDI_FM<0xd>;
1767  def XORi : MMRel, StdMMR6Rel,
1768             ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1769             ADDI_FM<0xe>;
1770}
1771def ADDi  : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>, ADDI_FM<0x8>,
1772            ISA_MIPS1_NOT_32R6_64R6;
1773let AdditionalPredicates = [NotInMicroMips] in {
1774  def SLTi  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1775              SLTI_FM<0xa>;
1776  def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1777              SLTI_FM<0xb>;
1778}
1779def LUi   : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM;
1780let AdditionalPredicates = [NotInMicroMips] in {
1781  /// Arithmetic Instructions (3-Operand, R-Type)
1782  def ADDu  : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1783              ADD_FM<0, 0x21>;
1784  def SUBu  : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1785              ADD_FM<0, 0x23>;
1786}
1787let Defs = [HI0, LO0] in
1788def MUL   : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1789            ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1790def ADD   : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>, ADD_FM<0, 0x20>;
1791def SUB   : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>, ADD_FM<0, 0x22>;
1792let AdditionalPredicates = [NotInMicroMips] in {
1793  def SLT   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1794  def SLTu  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1795  def AND   : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1796              ADD_FM<0, 0x24>;
1797  def OR    : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1798              ADD_FM<0, 0x25>;
1799  def XOR   : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1800              ADD_FM<0, 0x26>;
1801  def NOR   : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1802}
1803
1804/// Shift Instructions
1805let AdditionalPredicates = [NotInMicroMips] in {
1806def SLL  : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1807                                   immZExt5>, SRA_FM<0, 0>;
1808def SRL  : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1809                                   immZExt5>, SRA_FM<2, 0>;
1810def SRA  : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1811                                   immZExt5>, SRA_FM<3, 0>;
1812def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1813           SRLV_FM<4, 0>;
1814def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1815           SRLV_FM<6, 0>;
1816def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1817           SRLV_FM<7, 0>;
1818}
1819
1820// Rotate Instructions
1821let AdditionalPredicates = [NotInMicroMips] in {
1822  def ROTR  : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1823                                      immZExt5>,
1824              SRA_FM<2, 1>, ISA_MIPS32R2;
1825  def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1826              SRLV_FM<6, 1>, ISA_MIPS32R2;
1827}
1828
1829/// Load and Store Instructions
1830///  aligned
1831def LB  : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel,
1832          LW_FM<0x20>;
1833def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU,
1834                     addrDefault>, MMRel, LW_FM<0x24>;
1835let AdditionalPredicates = [NotInMicroMips] in {
1836  def LH  : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH,
1837                       addrDefault>, MMRel, LW_FM<0x21>;
1838  def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>,
1839            MMRel, LW_FM<0x25>;
1840  def LW  : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1841            LW_FM<0x23>;
1842}
1843def SB  : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1844          LW_FM<0x28>;
1845def SH  : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1846let AdditionalPredicates = [NotInMicroMips] in {
1847def SW  : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1848}
1849
1850/// load/store left/right
1851let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1852    AdditionalPredicates = [NotInMicroMips] in {
1853def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1854          ISA_MIPS1_NOT_32R6_64R6;
1855def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1856          ISA_MIPS1_NOT_32R6_64R6;
1857def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1858          ISA_MIPS1_NOT_32R6_64R6;
1859def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1860          ISA_MIPS1_NOT_32R6_64R6;
1861}
1862
1863let AdditionalPredicates = [NotInMicroMips] in {
1864// COP2 Memory Instructions
1865def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
1866           ISA_MIPS1_NOT_32R6_64R6;
1867def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
1868           LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
1869def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
1870           ISA_MIPS2_NOT_32R6_64R6;
1871def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
1872           LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
1873
1874// COP3 Memory Instructions
1875let DecoderNamespace = "COP3_" in {
1876  def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>;
1877  def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>;
1878  def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
1879             ISA_MIPS2;
1880  def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
1881             ISA_MIPS2;
1882}
1883
1884  def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
1885  def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1886}
1887
1888let AdditionalPredicates = [NotInMicroMips] in {
1889  def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>, ISA_MIPS2;
1890  def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>, ISA_MIPS2;
1891  def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>, ISA_MIPS2;
1892  def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>, ISA_MIPS2;
1893  def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>, ISA_MIPS2;
1894  def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>, ISA_MIPS2;
1895}
1896
1897def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
1898           ISA_MIPS2_NOT_32R6_64R6;
1899def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
1900           ISA_MIPS2_NOT_32R6_64R6;
1901def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
1902           ISA_MIPS2_NOT_32R6_64R6;
1903def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
1904           ISA_MIPS2_NOT_32R6_64R6;
1905def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
1906           ISA_MIPS2_NOT_32R6_64R6;
1907def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
1908           ISA_MIPS2_NOT_32R6_64R6;
1909
1910let AdditionalPredicates = [NotInMicroMips] in {
1911def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1912def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>;
1913}
1914def TRAP : TrapBase<BREAK>;
1915let AdditionalPredicates = [NotInMicroMips] in {
1916def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1917}
1918
1919let AdditionalPredicates = [NotInMicroMips] in {
1920  def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1921  def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1922  def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1923}
1924
1925let AdditionalPredicates = [NotInMicroMips] in {
1926  def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>, ISA_MIPS32R2;
1927  def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>, ISA_MIPS32R2;
1928}
1929
1930let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1931    AdditionalPredicates = [NotInMicroMips] in {
1932def WAIT : WAIT_FT<"wait">, WAIT_FM;
1933}
1934
1935let AdditionalPredicates = [NotInMicroMips] in {
1936/// Load-linked, Store-conditional
1937def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1938def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1939}
1940
1941/// Jump and Branch Instructions
1942def J       : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1943              AdditionalRequires<[RelocNotPIC]>, IsBranch;
1944def JR      : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
1945def BEQ     : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1946def BEQL    : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1947              BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1948def BNE     : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1949def BNEL    : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1950              BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1951def BGEZ    : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1952              BGEZ_FM<1, 1>;
1953def BGEZL   : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1954              BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1955def BGTZ    : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1956              BGEZ_FM<7, 0>;
1957def BGTZL   : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1958              BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1959def BLEZ    : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1960              BGEZ_FM<6, 0>;
1961def BLEZL   : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1962              BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1963def BLTZ    : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1964              BGEZ_FM<1, 0>;
1965def BLTZL   : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1966              BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1967def B       : UncondBranch<BEQ>;
1968
1969def JAL  : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1970let AdditionalPredicates = [NotInMicroMips] in {
1971  def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1972  def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1973}
1974
1975def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1976           ISA_MIPS32_NOT_32R6_64R6;
1977def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1978             ISA_MIPS1_NOT_32R6_64R6;
1979def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1980              BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1981def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1982             ISA_MIPS1_NOT_32R6_64R6;
1983def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1984              BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1985def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1986
1987let Predicates = [NotInMicroMips] in {
1988  def TAILCALL : TailCall<J, jmptarget>;
1989}
1990
1991def TAILCALLREG : TailCallReg<GPR32Opnd>;
1992
1993// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1994// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1995class PseudoIndirectBranchBase<RegisterOperand RO> :
1996    MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1997               II_IndirectBranchPseudo> {
1998  let isTerminator=1;
1999  let isBarrier=1;
2000  let hasDelaySlot = 1;
2001  let isBranch = 1;
2002  let isIndirectBranch = 1;
2003  bit isCTI = 1;
2004}
2005
2006def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
2007
2008// Return instructions are matched as a RetRA instruction, then are expanded
2009// into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2010// MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2011// ISA.
2012class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2013                                                        [], II_ReturnPseudo> {
2014  let isTerminator = 1;
2015  let isBarrier = 1;
2016  let hasDelaySlot = 1;
2017  let isReturn = 1;
2018  let isCodeGenOnly = 1;
2019  let hasCtrlDep = 1;
2020  let hasExtraSrcRegAllocReq = 1;
2021  bit isCTI = 1;
2022}
2023
2024def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2025
2026// Exception handling related node and instructions.
2027// The conversion sequence is:
2028// ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2029// MIPSeh_return -> (stack change + indirect branch)
2030//
2031// MIPSeh_return takes the place of regular return instruction
2032// but takes two arguments (V1, V0) which are used for storing
2033// the offset and return address respectively.
2034def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2035
2036def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2037                      [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2038
2039let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in {
2040  def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2041                                [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2042  def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
2043                                                GPR64:$dst),
2044                                [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2045}
2046
2047/// Multiply and Divide Instructions.
2048def MULT  : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2049            MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2050def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2051            MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2052let AdditionalPredicates = [NotInMicroMips] in {
2053  def SDIV  : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2054              MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2055  def UDIV  : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2056              MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2057}
2058def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2059           ISA_MIPS1_NOT_32R6_64R6;
2060def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2061           ISA_MIPS1_NOT_32R6_64R6;
2062let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
2063    AdditionalPredicates = [NotInMicroMips] in {
2064def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2065           ISA_MIPS1_NOT_32R6_64R6;
2066def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2067           ISA_MIPS1_NOT_32R6_64R6;
2068}
2069
2070/// Sign Ext In Register Instructions.
2071def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2072          SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2073def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2074          SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2075
2076/// Count Leading
2077def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2078          ISA_MIPS32_NOT_32R6_64R6;
2079def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2080          ISA_MIPS32_NOT_32R6_64R6;
2081
2082let AdditionalPredicates = [NotInMicroMips] in {
2083  /// Word Swap Bytes Within Halfwords
2084  def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2085             ISA_MIPS32R2;
2086}
2087
2088/// No operation.
2089def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
2090
2091// FrameIndexes are legalized when they are operands from load/store
2092// instructions. The same not happens for stack address copies, so an
2093// add op with mem ComplexPattern is used and the stack address copy
2094// can be matched. It's similar to Sparc LEA_ADDRi
2095def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
2096
2097// MADD*/MSUB*
2098def MADD  : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2099            ISA_MIPS32_NOT_32R6_64R6;
2100def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2101            ISA_MIPS32_NOT_32R6_64R6;
2102def MSUB  : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2103            ISA_MIPS32_NOT_32R6_64R6;
2104def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2105            ISA_MIPS32_NOT_32R6_64R6;
2106
2107let AdditionalPredicates = [NotDSP] in {
2108def PseudoMULT  : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2109                  ISA_MIPS1_NOT_32R6_64R6;
2110def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2111                  ISA_MIPS1_NOT_32R6_64R6;
2112def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2113def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2114def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2115def PseudoMADD  : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2116                  ISA_MIPS32_NOT_32R6_64R6;
2117def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2118                  ISA_MIPS32_NOT_32R6_64R6;
2119def PseudoMSUB  : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2120                  ISA_MIPS32_NOT_32R6_64R6;
2121def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2122                  ISA_MIPS32_NOT_32R6_64R6;
2123}
2124
2125let AdditionalPredicates = [NotInMicroMips] in {
2126  def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2127                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2128  def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2129                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2130  def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
2131  // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2132  def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2133                                       immZExt5, immZExt5Plus1, MipsExt>,
2134            EXT_FM<0>;
2135  def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2136                                       uimm5_inssize_plus1, MipsIns>,
2137            EXT_FM<4>;
2138}
2139/// Move Control Registers From/To CPU Registers
2140let AdditionalPredicates = [NotInMicroMips] in {
2141  def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>,
2142             ISA_MIPS32;
2143  def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>,
2144             ISA_MIPS32;
2145}
2146def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>;
2147def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>;
2148
2149class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2150  InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2151
2152def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>;
2153def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>;
2154
2155let isCTI = 1 in
2156def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2157            ISA_MIPS32R2;
2158
2159// JR_HB and JALR_HB are defined here using the new style naming
2160// scheme because some of this code is shared with Mips32r6InstrInfo.td
2161// and because of that it doesn't follow the naming convention of the
2162// rest of the file. To avoid a mixture of old vs new style, the new
2163// style was chosen.
2164class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2165  dag OutOperandList = (outs);
2166  dag InOperandList = (ins GPROpnd:$rs);
2167  string AsmString = !strconcat(instr_asm, "\t$rs");
2168  list<dag> Pattern = [];
2169}
2170
2171class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2172  dag OutOperandList = (outs GPROpnd:$rd);
2173  dag InOperandList = (ins GPROpnd:$rs);
2174  string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2175  list<dag> Pattern = [];
2176}
2177
2178class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>,
2179                   JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
2180  let isBranch=1;
2181  let isIndirectBranch=1;
2182  let hasDelaySlot=1;
2183  let isTerminator=1;
2184  let isBarrier=1;
2185  bit isCTI = 1;
2186}
2187
2188class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>,
2189                     JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
2190  let isIndirectBranch=1;
2191  let hasDelaySlot=1;
2192  bit isCTI = 1;
2193}
2194
2195class JR_HB_ENC : JR_HB_FM<8>;
2196class JALR_HB_ENC : JALR_HB_FM<9>;
2197
2198def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
2199def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2200
2201class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2202  InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2203let AdditionalPredicates = [NotInMicroMips] in {
2204def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>;
2205def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>;
2206def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>;
2207def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>;
2208}
2209class CacheOp<string instr_asm, Operand MemOpnd,
2210              InstrItinClass itin = NoItinerary> :
2211    InstSE<(outs), (ins  MemOpnd:$addr, uimm5:$hint),
2212           !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2213           instr_asm> {
2214  let DecoderMethod = "DecodeCacheOp";
2215}
2216
2217def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2218            INSN_MIPS3_32_NOT_32R6_64R6;
2219def PREF :  MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2220            INSN_MIPS3_32_NOT_32R6_64R6;
2221
2222def ROL : MipsAsmPseudoInst<(outs),
2223                            (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2224                            "rol\t$rs, $rt, $rd">;
2225def ROLImm : MipsAsmPseudoInst<(outs),
2226                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2227                               "rol\t$rs, $rt, $imm">;
2228def : MipsInstAlias<"rol $rd, $rs",
2229                    (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2230def : MipsInstAlias<"rol $rd, $imm",
2231                    (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2232
2233def ROR : MipsAsmPseudoInst<(outs),
2234                            (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2235                            "ror\t$rs, $rt, $rd">;
2236def RORImm : MipsAsmPseudoInst<(outs),
2237                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2238                               "ror\t$rs, $rt, $imm">;
2239def : MipsInstAlias<"ror $rd, $rs",
2240                    (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2241def : MipsInstAlias<"ror $rd, $imm",
2242                    (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2243
2244def DROL : MipsAsmPseudoInst<(outs),
2245                             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2246                             "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2247def DROLImm : MipsAsmPseudoInst<(outs),
2248                                (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2249                                "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2250def : MipsInstAlias<"drol $rd, $rs",
2251                    (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2252def : MipsInstAlias<"drol $rd, $imm",
2253                    (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2254
2255def DROR : MipsAsmPseudoInst<(outs),
2256                             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2257                             "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2258def DRORImm : MipsAsmPseudoInst<(outs),
2259                                (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2260                                "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2261def : MipsInstAlias<"dror $rd, $rs",
2262                    (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2263def : MipsInstAlias<"dror $rd, $imm",
2264                    (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2265
2266def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2267                                 "abs\t$rd, $rs">;
2268
2269def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2270                                 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2271                                 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2272
2273def : MipsInstAlias<"seq $rd, $rs",
2274                    (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2275                    NOT_ASE_CNMIPS;
2276
2277def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2278                                  (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2279                                  "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2280
2281def : MipsInstAlias<"seq $rd, $imm",
2282                    (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2283                    NOT_ASE_CNMIPS;
2284//===----------------------------------------------------------------------===//
2285// Instruction aliases
2286//===----------------------------------------------------------------------===//
2287def : MipsInstAlias<"move $dst, $src",
2288                    (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2289      GPR_32 {
2290  let AdditionalPredicates = [NotInMicroMips];
2291}
2292def : MipsInstAlias<"move $dst, $src",
2293                    (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2294      GPR_32 {
2295  let AdditionalPredicates = [NotInMicroMips];
2296}
2297def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
2298      ISA_MIPS1_NOT_32R6_64R6;
2299def : MipsInstAlias<
2300          "addu $rs, $rt, $imm",
2301          (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2302def : MipsInstAlias<
2303          "addu $rs, $imm",
2304          (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2305def : MipsInstAlias<
2306          "add $rs, $rt, $imm",
2307          (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>,
2308          ISA_MIPS1_NOT_32R6_64R6;
2309def : MipsInstAlias<
2310          "add $rs, $imm",
2311          (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>,
2312          ISA_MIPS1_NOT_32R6_64R6;
2313def : MipsInstAlias<
2314          "and $rs, $rt, $imm",
2315          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2316def : MipsInstAlias<
2317          "and $rs, $imm",
2318          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2319def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
2320let Predicates = [NotInMicroMips] in {
2321def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2322}
2323def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
2324def : MipsInstAlias<"neg $rt, $rs",
2325                    (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2326def : MipsInstAlias<"neg $rt",
2327                    (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>;
2328def : MipsInstAlias<"negu $rt, $rs",
2329                    (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2330def : MipsInstAlias<"negu $rt",
2331                    (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>;
2332let AdditionalPredicates = [NotInMicroMips] in {
2333  def : MipsInstAlias<
2334          "sgt $rd, $rs, $rt",
2335          (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2336  def : MipsInstAlias<
2337          "sgt $rs, $rt",
2338          (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2339  def : MipsInstAlias<
2340          "sgtu $rd, $rs, $rt",
2341          (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2342  def : MipsInstAlias<
2343          "sgtu $$rs, $rt",
2344          (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2345  def : MipsInstAlias<
2346          "slt $rs, $rt, $imm",
2347          (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2348  def : MipsInstAlias<
2349          "sltu $rt, $rs, $imm",
2350          (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2351  def : MipsInstAlias<
2352          "and $rs, $rt, $imm",
2353          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2354  def : MipsInstAlias<
2355          "and $rs, $imm",
2356          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2357  def : MipsInstAlias<
2358          "xor $rs, $rt, $imm",
2359          (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2360  def : MipsInstAlias<
2361          "xor $rs, $imm",
2362          (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2363  def : MipsInstAlias<
2364          "or $rs, $rt, $imm",
2365          (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2366  def : MipsInstAlias<
2367          "or $rs, $imm",
2368          (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2369  def : MipsInstAlias<
2370          "not $rt, $rs",
2371          (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
2372  def : MipsInstAlias<
2373          "not $rt",
2374          (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>;
2375  def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
2376}
2377def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
2378def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2379def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
2380def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2381let AdditionalPredicates = [NotInMicroMips] in {
2382def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
2383}
2384def : MipsInstAlias<"bnez $rs,$offset",
2385                    (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2386def : MipsInstAlias<"bnezl $rs,$offset",
2387                    (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2388def : MipsInstAlias<"beqz $rs,$offset",
2389                    (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2390def : MipsInstAlias<"beqzl $rs,$offset",
2391                    (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2392let AdditionalPredicates = [NotInMicroMips] in {
2393  def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
2394}
2395
2396def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
2397def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
2398let AdditionalPredicates = [NotInMicroMips] in {
2399  def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2400  def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2401}
2402let AdditionalPredicates = [NotInMicroMips] in {
2403  def : MipsInstAlias<"teq $rs, $rt",
2404                      (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2405  def : MipsInstAlias<"tge $rs, $rt",
2406                      (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2407  def : MipsInstAlias<"tgeu $rs, $rt",
2408                      (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2409  def : MipsInstAlias<"tlt $rs, $rt",
2410                      (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2411  def : MipsInstAlias<"tltu $rs, $rt",
2412                      (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2413  def : MipsInstAlias<"tne $rs, $rt",
2414                      (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2415}
2416def : MipsInstAlias<"sub, $rd, $rs, $imm",
2417                    (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2418                          InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2419def : MipsInstAlias<"sub $rs, $imm",
2420                    (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2421                    0>, ISA_MIPS1_NOT_32R6_64R6;
2422def : MipsInstAlias<"subu, $rd, $rs, $imm",
2423                    (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2424                           InvertedImOperand:$imm), 0>;
2425def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2426                                             InvertedImOperand:$imm), 0>;
2427let AdditionalPredicates = [NotInMicroMips] in {
2428  def : MipsInstAlias<"sll $rd, $rt, $rs",
2429                      (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2430  def : MipsInstAlias<"sra $rd, $rt, $rs",
2431                      (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2432  def : MipsInstAlias<"srl $rd, $rt, $rs",
2433                      (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2434  def : MipsInstAlias<"sll $rd, $rt",
2435                      (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2436  def : MipsInstAlias<"sra $rd, $rt",
2437                      (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2438  def : MipsInstAlias<"srl $rd, $rt",
2439                      (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2440  def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2441                     ISA_MIPS32R2;
2442  def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2443                     ISA_MIPS32R2;
2444}
2445def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2446def : MipsInstAlias<"sync",
2447                    (SYNC 0), 1>, ISA_MIPS2;
2448//===----------------------------------------------------------------------===//
2449// Assembler Pseudo Instructions
2450//===----------------------------------------------------------------------===//
2451
2452// We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2453// a 32 bit number.
2454class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2455  MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2456                     !strconcat(instr_asm, "\t$rt, $imm32")> ;
2457def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2458
2459class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2460                           RegisterOperand RO> :
2461  MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2462                     !strconcat(instr_asm, "\t$rt, $addr")> ;
2463def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2464
2465class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2466  MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2467                     !strconcat(instr_asm, "\t$rt, $imm32")> ;
2468def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2469
2470def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2471                      "jal\t$rd, $rs"> ;
2472def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2473                      "jal\t$rs"> ;
2474
2475def NORImm : MipsAsmPseudoInst<
2476                 (outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm),
2477                 "nor\t$rs, $rt, $imm"> ;
2478
2479let hasDelaySlot = 1, isCTI = 1 in {
2480def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2481                               (ins imm64:$imm64, brtarget:$offset),
2482                               "bne\t$rt, $imm64, $offset">;
2483def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2484                               (ins imm64:$imm64, brtarget:$offset),
2485                               "beq\t$rt, $imm64, $offset">;
2486
2487class CondBranchPseudo<string instr_asm> :
2488  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2489                                 brtarget:$offset),
2490                    !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2491}
2492
2493def BLT : CondBranchPseudo<"blt">;
2494def BLE : CondBranchPseudo<"ble">;
2495def BGE : CondBranchPseudo<"bge">;
2496def BGT : CondBranchPseudo<"bgt">;
2497def BLTU : CondBranchPseudo<"bltu">;
2498def BLEU : CondBranchPseudo<"bleu">;
2499def BGEU : CondBranchPseudo<"bgeu">;
2500def BGTU : CondBranchPseudo<"bgtu">;
2501def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2502def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2503def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2504def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2505def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2506def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2507def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2508def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2509
2510let isCTI = 1 in
2511class CondBranchImmPseudo<string instr_asm> :
2512  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2513                    !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2514
2515def BLTImmMacro  : CondBranchImmPseudo<"blt">;
2516def BLEImmMacro  : CondBranchImmPseudo<"ble">;
2517def BGEImmMacro  : CondBranchImmPseudo<"bge">;
2518def BGTImmMacro  : CondBranchImmPseudo<"bgt">;
2519def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2520def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2521def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2522def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2523def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2524def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2525def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2526def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2527def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2528def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2529def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2530def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2531
2532// FIXME: Predicates are removed because instructions are matched regardless of
2533// predicates, because PredicateControl was not in the hierarchy. This was
2534// done to emit more precise error message from expansion function.
2535// Once the tablegen-erated errors are made better, this needs to be fixed and
2536// predicates needs to be restored.
2537
2538def SDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2539                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2540                                  "div\t$rd, $rs, $rt">,
2541                ISA_MIPS1_NOT_32R6_64R6;
2542def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2543                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2544                                  "divu\t$rd, $rs, $rt">,
2545                ISA_MIPS1_NOT_32R6_64R6;
2546def : MipsInstAlias<"div $rt, $rs", (SDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2547                                               GPR32Opnd:$rs), 0>,
2548      ISA_MIPS1_NOT_32R6_64R6;
2549def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2550                                                GPR32Opnd:$rs), 0>,
2551      ISA_MIPS1_NOT_32R6_64R6;
2552def DSDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2553                                   (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2554                                   "ddiv\t$rd, $rs, $rt">,
2555                 ISA_MIPS64_NOT_64R6;
2556def DUDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2557                                   (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2558                                   "ddivu\t$rd, $rs, $rt">,
2559                 ISA_MIPS64_NOT_64R6;
2560def : MipsInstAlias<"ddiv $rt, $rs", (DSDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2561                                                 GPR32Opnd:$rs), 0>,
2562      ISA_MIPS64_NOT_64R6;
2563def : MipsInstAlias<"ddivu $rt, $rs", (DUDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2564                                                  GPR32Opnd:$rs), 0>,
2565      ISA_MIPS64_NOT_64R6;
2566
2567def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2568                            "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2569
2570def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2571                             "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2572
2573def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2574                            "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2575
2576def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2577                            "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2578
2579def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2580                            "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2581
2582def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2583                                (ins mem_simm16:$addr), "ld $rt, $addr">,
2584                                ISA_MIPS1_NOT_MIPS3;
2585def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2586                                (ins mem_simm16:$addr), "sd $rt, $addr">,
2587                                ISA_MIPS1_NOT_MIPS3;
2588//===----------------------------------------------------------------------===//
2589//  Arbitrary patterns that map to one or more instructions
2590//===----------------------------------------------------------------------===//
2591
2592// Load/store pattern templates.
2593class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2594  MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2595
2596class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2597  MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2598
2599// Materialize constants.
2600multiclass MaterializeImms<ValueType VT, Register ZEROReg,
2601                           Instruction ADDiuOp, Instruction LUiOp,
2602                           Instruction ORiOp> {
2603
2604// Small immediates
2605def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
2606def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>;
2607
2608// Bits 32-16 set, sign/zero extended.
2609def : MipsPat<(VT immSExt32Low16Zero:$imm), (LUiOp (HI16 imm:$imm))>;
2610
2611// Arbitrary immediates
2612def : MipsPat<(VT immSExt32:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
2613}
2614
2615let AdditionalPredicates = [NotInMicroMips] in
2616  defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>;
2617
2618// Carry MipsPatterns
2619let AdditionalPredicates = [NotInMicroMips] in {
2620  def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2621                (SUBu GPR32:$lhs, GPR32:$rhs)>;
2622}
2623def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2624              (ADDu GPR32:$lhs, GPR32:$rhs)>, ASE_NOT_DSP;
2625def : MipsPat<(addc  GPR32:$src, immSExt16:$imm),
2626              (ADDiu GPR32:$src, imm:$imm)>, ASE_NOT_DSP;
2627
2628// Support multiplication for pre-Mips32 targets that don't have
2629// the MUL instruction.
2630def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2631              (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2632      ISA_MIPS1_NOT_32R6_64R6;
2633
2634// SYNC
2635def : MipsPat<(MipsSync (i32 immz)),
2636              (SYNC 0)>, ISA_MIPS2;
2637
2638// Call
2639def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2640              (JAL texternalsym:$dst)>;
2641//def : MipsPat<(MipsJmpLink GPR32:$dst),
2642//              (JALR GPR32:$dst)>;
2643
2644// Tail call
2645def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2646              (TAILCALL tglobaladdr:$dst)>;
2647def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2648              (TAILCALL texternalsym:$dst)>;
2649// hi/lo relocs
2650def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2651def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
2652def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
2653def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
2654def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
2655def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
2656
2657def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
2658def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
2659def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
2660def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
2661def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
2662def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
2663
2664def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
2665              (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
2666def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
2667              (ADDiu GPR32:$hi, tblockaddress:$lo)>;
2668def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
2669              (ADDiu GPR32:$hi, tjumptable:$lo)>;
2670def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
2671              (ADDiu GPR32:$hi, tconstpool:$lo)>;
2672def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
2673              (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
2674
2675// gp_rel relocs
2676def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2677              (ADDiu GPR32:$gp, tglobaladdr:$in)>;
2678def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2679              (ADDiu GPR32:$gp, tconstpool:$in)>;
2680
2681// wrapper_pic
2682class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2683      MipsPat<(MipsWrapper RC:$gp, node:$in),
2684              (ADDiuOp RC:$gp, node:$in)>;
2685
2686def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2687def : WrapperPat<tconstpool, ADDiu, GPR32>;
2688def : WrapperPat<texternalsym, ADDiu, GPR32>;
2689def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2690def : WrapperPat<tjumptable, ADDiu, GPR32>;
2691def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2692
2693let AdditionalPredicates = [NotInMicroMips] in {
2694// Mips does not have "not", so we expand our way
2695def : MipsPat<(not GPR32:$in),
2696              (NOR GPR32Opnd:$in, ZERO)>;
2697}
2698
2699// extended loads
2700def : MipsPat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>;
2701def : MipsPat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>;
2702let AdditionalPredicates = [NotInMicroMips] in {
2703  def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2704}
2705
2706// peepholes
2707def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2708
2709// brcond patterns
2710multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
2711                      Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
2712                      Instruction SLTiOp, Instruction SLTiuOp,
2713                      Register ZEROReg> {
2714def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2715              (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2716def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2717              (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2718
2719def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2720              (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2721def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2722              (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2723def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2724              (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2725def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2726              (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2727def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2728              (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2729def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2730              (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2731
2732def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2733              (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2734def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2735              (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2736
2737def : MipsPat<(brcond RC:$cond, bb:$dst),
2738              (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2739}
2740let AdditionalPredicates = [NotInMicroMips] in {
2741  defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2742}
2743def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2744              (BLEZ i32:$lhs, bb:$dst)>;
2745def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2746              (BGEZ i32:$lhs, bb:$dst)>;
2747
2748// setcc patterns
2749multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2750                     Instruction SLTuOp, Register ZEROReg> {
2751  def : MipsPat<(seteq RC:$lhs, 0),
2752                (SLTiuOp RC:$lhs, 1)>;
2753  def : MipsPat<(setne RC:$lhs, 0),
2754                (SLTuOp ZEROReg, RC:$lhs)>;
2755  def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2756                (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2757  def : MipsPat<(setne RC:$lhs, RC:$rhs),
2758                (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2759}
2760
2761multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
2762                     Instruction SLTuOp> {
2763  def : MipsPat<(setle RC:$lhs, RC:$rhs),
2764                (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
2765  def : MipsPat<(setule RC:$lhs, RC:$rhs),
2766                (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2767}
2768
2769multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2770  def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2771                (SLTOp RC:$rhs, RC:$lhs)>;
2772  def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2773                (SLTuOp RC:$rhs, RC:$lhs)>;
2774}
2775
2776multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
2777                     Instruction SLTuOp> {
2778  def : MipsPat<(setge RC:$lhs, RC:$rhs),
2779                (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
2780  def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2781                (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2782}
2783
2784multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
2785                        Instruction SLTiOp, Instruction SLTiuOp> {
2786  def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2787                (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2788  def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2789                (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2790}
2791
2792let AdditionalPredicates = [NotInMicroMips] in {
2793  defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2794  defm : SetlePats<GPR32, XORi, SLT, SLTu>;
2795  defm : SetgtPats<GPR32, SLT, SLTu>;
2796  defm : SetgePats<GPR32, XORi, SLT, SLTu>;
2797  defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>;
2798}
2799
2800// bswap pattern
2801def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2802
2803// Load halfword/word patterns.
2804let AddedComplexity = 40 in {
2805  def : LoadRegImmPat<LBu, i32, zextloadi8>;
2806  let AdditionalPredicates = [NotInMicroMips] in {
2807    def : LoadRegImmPat<LH, i32, sextloadi16>;
2808    def : LoadRegImmPat<LW, i32, load>;
2809  }
2810}
2811
2812// Atomic load patterns.
2813def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2814let AdditionalPredicates = [NotInMicroMips] in {
2815  def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2816}
2817def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2818
2819// Atomic store patterns.
2820def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2821def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2822def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2823
2824//===----------------------------------------------------------------------===//
2825// Floating Point Support
2826//===----------------------------------------------------------------------===//
2827
2828include "MipsInstrFPU.td"
2829include "Mips64InstrInfo.td"
2830include "MipsCondMov.td"
2831
2832include "Mips32r6InstrInfo.td"
2833include "Mips64r6InstrInfo.td"
2834
2835//
2836// Mips16
2837
2838include "Mips16InstrFormats.td"
2839include "Mips16InstrInfo.td"
2840
2841// DSP
2842include "MipsDSPInstrFormats.td"
2843include "MipsDSPInstrInfo.td"
2844
2845// MSA
2846include "MipsMSAInstrFormats.td"
2847include "MipsMSAInstrInfo.td"
2848
2849// EVA
2850include "MipsEVAInstrFormats.td"
2851include "MipsEVAInstrInfo.td"
2852
2853// Micromips
2854include "MicroMipsInstrFormats.td"
2855include "MicroMipsInstrInfo.td"
2856include "MicroMipsInstrFPU.td"
2857
2858// Micromips r6
2859include "MicroMips32r6InstrFormats.td"
2860include "MicroMips32r6InstrInfo.td"
2861
2862// Micromips64 r6
2863include "MicroMips64r6InstrFormats.td"
2864include "MicroMips64r6InstrInfo.td"
2865
2866// Micromips DSP
2867include "MicroMipsDSPInstrFormats.td"
2868include "MicroMipsDSPInstrInfo.td"
2869