1 //===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Mips implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // Mips profiles and nodes
17 //===----------------------------------------------------------------------===//
19 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
20 def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
24 def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
25 def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
26 def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
27 def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
28 SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
29 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
31 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
32 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
33 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
34 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
36 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
38 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
40 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
41 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
42 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
46 def SDTMipsLoadLR : SDTypeProfile<1, 2,
47 [SDTCisInt<0>, SDTCisPtrTy<1>,
51 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
52 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
56 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
57 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
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)
63 // Hi is the odd node out, on MIPS64 it can expand to either daddiu when
64 // using static relocations with 64 bit symbols, or lui when using 32 bit
66 def MipsHigher : SDNode<"MipsISD::Higher", SDTIntUnaryOp>;
67 def MipsHighest : SDNode<"MipsISD::Highest", SDTIntUnaryOp>;
68 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
69 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
71 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
73 // Hi node for accessing the GOT.
74 def MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>;
76 // Hi node for handling TLS offsets
77 def MipsTlsHi : SDNode<"MipsISD::TlsHi", SDTIntUnaryOp>;
80 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
83 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
84 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
86 def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
87 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
89 // These are target-independent nodes, but have target-specific formats.
90 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
91 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
92 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
93 [SDNPHasChain, SDNPSideEffect,
94 SDNPOptInGlue, SDNPOutGlue]>;
96 // Nodes used to extract LO/HI registers.
97 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
98 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
100 // Node used to insert 32-bit integers to LOHI register pair.
101 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
104 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
105 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
108 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
109 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
110 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
111 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
114 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
115 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
116 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
118 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
121 // Target constant nodes that are not part of any isel patterns and remain
122 // unchanged can cause instructions with illegal operands to be emitted.
123 // Wrapper node patterns give the instruction selector a chance to replace
124 // target constant nodes that would otherwise remain unchanged with ADDiu
125 // nodes. Without these wrapper node patterns, the following conditional move
126 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
128 // movn %got(d)($gp), %got(c)($gp), $4
129 // This instruction is illegal since movn can take only register operands.
131 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
133 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
135 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
136 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
137 def MipsCIns : SDNode<"MipsISD::CIns", SDT_Ext>;
139 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
140 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
141 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
142 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
143 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
144 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
145 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
146 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
147 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
148 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
149 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
150 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
151 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
152 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
153 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
154 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
156 //===----------------------------------------------------------------------===//
157 // Mips Instruction Predicate Definitions.
158 //===----------------------------------------------------------------------===//
159 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
160 AssemblerPredicate<"FeatureMips2">;
161 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
162 AssemblerPredicate<"FeatureMips3_32">;
163 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
164 AssemblerPredicate<"FeatureMips3_32r2">;
165 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
166 AssemblerPredicate<"FeatureMips3">;
167 def NotMips3 : Predicate<"!Subtarget->hasMips3()">,
168 AssemblerPredicate<"!FeatureMips3">;
169 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
170 AssemblerPredicate<"FeatureMips4_32">;
171 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
172 AssemblerPredicate<"!FeatureMips4_32">;
173 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
174 AssemblerPredicate<"FeatureMips4_32r2">;
175 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
176 AssemblerPredicate<"FeatureMips5_32r2">;
177 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
178 AssemblerPredicate<"FeatureMips32">;
179 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
180 AssemblerPredicate<"FeatureMips32r2">;
181 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
182 AssemblerPredicate<"FeatureMips32r5">;
183 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
184 AssemblerPredicate<"FeatureMips32r6">;
185 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
186 AssemblerPredicate<"!FeatureMips32r6">;
187 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
188 AssemblerPredicate<"FeatureGP64Bit">;
189 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
190 AssemblerPredicate<"!FeatureGP64Bit">;
191 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
192 AssemblerPredicate<"FeaturePTR64Bit">;
193 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
194 AssemblerPredicate<"!FeaturePTR64Bit">;
195 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
196 AssemblerPredicate<"FeatureMips64">;
197 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
198 AssemblerPredicate<"!FeatureMips64">;
199 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
200 AssemblerPredicate<"FeatureMips64r2">;
201 def HasMips64r5 : Predicate<"Subtarget->hasMips64r5()">,
202 AssemblerPredicate<"FeatureMips64r5">;
203 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
204 AssemblerPredicate<"FeatureMips64r6">;
205 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
206 AssemblerPredicate<"!FeatureMips64r6">;
207 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
208 AssemblerPredicate<"FeatureMips16">;
209 def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
210 AssemblerPredicate<"!FeatureMips16">;
211 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
212 AssemblerPredicate<"FeatureCnMips">;
213 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
214 AssemblerPredicate<"!FeatureCnMips">;
215 def IsSym32 : Predicate<"Subtarget->HasSym32()">,
216 AssemblerPredicate<"FeatureSym32">;
217 def IsSym64 : Predicate<"!Subtarget->HasSym32()">,
218 AssemblerPredicate<"!FeatureSym32">;
219 def IsN64 : Predicate<"Subtarget->isABI_N64()">;
220 def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">;
221 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
222 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
223 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
224 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
225 AssemblerPredicate<"!FeatureMips16">;
226 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
227 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
228 AssemblerPredicate<"FeatureMicroMips">;
229 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
230 AssemblerPredicate<"!FeatureMicroMips">;
231 def IsLE : Predicate<"Subtarget->isLittle()">;
232 def IsBE : Predicate<"!Subtarget->isLittle()">;
233 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
234 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
235 def HasEVA : Predicate<"Subtarget->hasEVA()">,
236 AssemblerPredicate<"FeatureEVA">;
237 def HasMSA : Predicate<"Subtarget->hasMSA()">,
238 AssemblerPredicate<"FeatureMSA">;
239 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
240 AssemblerPredicate<"!FeatureMadd4">;
241 def HasMT : Predicate<"Subtarget->hasMT()">,
242 AssemblerPredicate<"FeatureMT">;
243 def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
244 AssemblerPredicate<"FeatureUseIndirectJumpsHazard">;
245 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
246 AssemblerPredicate<"!FeatureUseIndirectJumpsHazard">;
247 def HasCRC : Predicate<"Subtarget->hasCRC()">,
248 AssemblerPredicate<"FeatureCRC">;
249 def HasVirt : Predicate<"Subtarget->hasVirt()">,
250 AssemblerPredicate<"FeatureVirt">;
251 def HasGINV : Predicate<"Subtarget->hasGINV()">,
252 AssemblerPredicate<"FeatureGINV">;
253 // TODO: Add support for FPOpFusion::Standard
254 def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
255 " FPOpFusion::Fast">;
256 //===----------------------------------------------------------------------===//
257 // Mips GPR size adjectives.
258 // They are mutually exclusive.
259 //===----------------------------------------------------------------------===//
261 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
262 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
264 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
265 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
267 //===----------------------------------------------------------------------===//
268 // Mips Symbol size adjectives.
269 // They are mutally exculsive.
270 //===----------------------------------------------------------------------===//
272 class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
273 class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
275 //===----------------------------------------------------------------------===//
276 // Mips ISA/ASE membership and instruction group membership adjectives.
277 // They are mutually exclusive.
278 //===----------------------------------------------------------------------===//
280 // FIXME: I'd prefer to use additive predicates to build the instruction sets
281 // but we are short on assembler feature bits at the moment. Using a
282 // subtractive predicate will hopefully keep us under the 32 predicate
283 // limit long enough to develop an alternative way to handle P1||P2
286 list<Predicate> EncodingPredicates = [HasStdEnc];
288 class ISA_MIPS1_NOT_MIPS3 {
289 list<Predicate> InsnPredicates = [NotMips3];
290 list<Predicate> EncodingPredicates = [HasStdEnc];
292 class ISA_MIPS1_NOT_4_32 {
293 list<Predicate> InsnPredicates = [NotMips4_32];
294 list<Predicate> EncodingPredicates = [HasStdEnc];
296 class ISA_MIPS1_NOT_32R6_64R6 {
297 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
298 list<Predicate> EncodingPredicates = [HasStdEnc];
301 list<Predicate> InsnPredicates = [HasMips2];
302 list<Predicate> EncodingPredicates = [HasStdEnc];
304 class ISA_MIPS2_NOT_32R6_64R6 {
305 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
306 list<Predicate> EncodingPredicates = [HasStdEnc];
309 list<Predicate> InsnPredicates = [HasMips3];
310 list<Predicate> EncodingPredicates = [HasStdEnc];
312 class ISA_MIPS3_NOT_32R6_64R6 {
313 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
314 list<Predicate> EncodingPredicates = [HasStdEnc];
317 list<Predicate> InsnPredicates = [HasMips32];
318 list<Predicate> EncodingPredicates = [HasStdEnc];
320 class ISA_MIPS32_NOT_32R6_64R6 {
321 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
322 list<Predicate> EncodingPredicates = [HasStdEnc];
325 list<Predicate> InsnPredicates = [HasMips32r2];
326 list<Predicate> EncodingPredicates = [HasStdEnc];
328 class ISA_MIPS32R2_NOT_32R6_64R6 {
329 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
330 list<Predicate> EncodingPredicates = [HasStdEnc];
333 list<Predicate> InsnPredicates = [HasMips32r5];
334 list<Predicate> EncodingPredicates = [HasStdEnc];
337 list<Predicate> InsnPredicates = [HasMips64];
338 list<Predicate> EncodingPredicates = [HasStdEnc];
340 class ISA_MIPS64_NOT_64R6 {
341 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
342 list<Predicate> EncodingPredicates = [HasStdEnc];
345 list<Predicate> InsnPredicates = [HasMips64r2];
346 list<Predicate> EncodingPredicates = [HasStdEnc];
349 list<Predicate> InsnPredicates = [HasMips64r5];
350 list<Predicate> EncodingPredicates = [HasStdEnc];
353 list<Predicate> InsnPredicates = [HasMips32r6];
354 list<Predicate> EncodingPredicates = [HasStdEnc];
357 list<Predicate> InsnPredicates = [HasMips64r6];
358 list<Predicate> EncodingPredicates = [HasStdEnc];
360 class ISA_MICROMIPS {
361 list<Predicate> EncodingPredicates = [InMicroMips];
363 class ISA_MICROMIPS32R5 {
364 list<Predicate> InsnPredicates = [HasMips32r5];
365 list<Predicate> EncodingPredicates = [InMicroMips];
367 class ISA_MICROMIPS32R6 {
368 list<Predicate> InsnPredicates = [HasMips32r6];
369 list<Predicate> EncodingPredicates = [InMicroMips];
371 class ISA_MICROMIPS64R6 {
372 list<Predicate> InsnPredicates = [HasMips64r6];
373 list<Predicate> EncodingPredicates = [InMicroMips];
375 class ISA_MICROMIPS32_NOT_MIPS32R6 {
376 list<Predicate> InsnPredicates = [NotMips32r6];
377 list<Predicate> EncodingPredicates = [InMicroMips];
379 class ASE_EVA { list<Predicate> ASEPredicate = [HasEVA]; }
381 // The portions of MIPS-III that were also added to MIPS32
382 class INSN_MIPS3_32 {
383 list<Predicate> InsnPredicates = [HasMips3_32];
384 list<Predicate> EncodingPredicates = [HasStdEnc];
387 // The portions of MIPS-III that were also added to MIPS32 but were removed in
388 // MIPS32r6 and MIPS64r6.
389 class INSN_MIPS3_32_NOT_32R6_64R6 {
390 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
391 list<Predicate> EncodingPredicates = [HasStdEnc];
394 // The portions of MIPS-III that were also added to MIPS32
395 class INSN_MIPS3_32R2 {
396 list<Predicate> InsnPredicates = [HasMips3_32r2];
397 list<Predicate> EncodingPredicates = [HasStdEnc];
400 // The portions of MIPS-IV that were also added to MIPS32.
401 class INSN_MIPS4_32 {
402 list <Predicate> InsnPredicates = [HasMips4_32];
403 list<Predicate> EncodingPredicates = [HasStdEnc];
406 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
407 // MIPS32r6 and MIPS64r6.
408 class INSN_MIPS4_32_NOT_32R6_64R6 {
409 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
410 list<Predicate> EncodingPredicates = [HasStdEnc];
413 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
414 // MIPS32r6 and MIPS64r6.
415 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
416 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
417 list<Predicate> EncodingPredicates = [HasStdEnc];
420 // The portions of MIPS-IV that were also added to MIPS32r2.
421 class INSN_MIPS4_32R2 {
422 list<Predicate> InsnPredicates = [HasMips4_32r2];
423 list<Predicate> EncodingPredicates = [HasStdEnc];
426 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
427 // MIPS32r6 and MIPS64r6.
428 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
429 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
430 list<Predicate> EncodingPredicates = [HasStdEnc];
434 list<Predicate> ASEPredicate = [HasCnMips];
437 class NOT_ASE_CNMIPS {
438 list<Predicate> ASEPredicate = [NotCnMips];
441 class ASE_MIPS64_CNMIPS {
442 list<Predicate> ASEPredicate = [HasMips64, HasCnMips];
446 list<Predicate> ASEPredicate = [HasMSA];
449 class ASE_MSA_NOT_MSA64 {
450 list<Predicate> ASEPredicate = [HasMSA, NotMips64];
454 list<Predicate> ASEPredicate = [HasMSA, HasMips64];
458 list <Predicate> ASEPredicate = [HasMT];
462 list <Predicate> ASEPredicate = [HasCRC];
466 list <Predicate> ASEPredicate = [HasVirt];
470 list <Predicate> ASEPredicate = [HasGINV];
473 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
474 // It can be used only on instructions that doesn't inherit PredicateControl.
475 class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
476 let InsnPredicates = [NotMips32r6];
477 let EncodingPredicates = [InMicroMips];
481 list<Predicate> ASEPredicate = [NotDSP];
485 list<Predicate> AdditionalPredicates = [HasMadd4];
488 // Classses used for separating expansions that differ based on the ABI in
491 list<Predicate> AdditionalPredicates = [IsN64];
495 list<Predicate> AdditionalPredicates = [IsNotN64];
498 class FPOP_FUSION_FAST {
499 list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
502 //===----------------------------------------------------------------------===//
504 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl;
506 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
507 InstAlias<Asm, Result, Emit>, PredicateControl;
510 bit isCommutable = 1;
530 bit isTerminator = 1;
533 bit hasExtraSrcRegAllocReq = 1;
534 bit isCodeGenOnly = 1;
538 class IsAsCheapAsAMove {
539 bit isAsCheapAsAMove = 1;
542 class NeverHasSideEffects {
543 bit hasSideEffects = 0;
546 //===----------------------------------------------------------------------===//
547 // Instruction format superclass
548 //===----------------------------------------------------------------------===//
550 include "MipsInstrFormats.td"
552 //===----------------------------------------------------------------------===//
553 // Mips Operand, Complex Patterns and Transformations Definitions.
554 //===----------------------------------------------------------------------===//
556 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
557 int Offset = 0> : AsmOperandClass {
558 let Name = "ConstantSImm" # Bits # "_" # Offset;
559 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
560 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
561 let SuperClasses = Supers;
562 let DiagnosticType = "SImm" # Bits # "_" # Offset;
565 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
566 int Shift = 0> : AsmOperandClass {
567 let Name = "Simm" # Bits # "_Lsl" # Shift;
568 let RenderMethod = "addImmOperands";
569 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
570 let SuperClasses = Supers;
571 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
574 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
575 int Offset = 0> : AsmOperandClass {
576 let Name = "ConstantUImm" # Bits # "_" # Offset;
577 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
578 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
579 let SuperClasses = Supers;
580 let DiagnosticType = "UImm" # Bits # "_" # Offset;
583 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
584 list<AsmOperandClass> Supers = []>
586 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
587 let RenderMethod = "addImmOperands";
588 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
589 let SuperClasses = Supers;
590 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
593 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
595 let Name = "SImm" # Bits;
596 let RenderMethod = "addSImmOperands<" # Bits # ">";
597 let PredicateMethod = "isSImm<" # Bits # ">";
598 let SuperClasses = Supers;
599 let DiagnosticType = "SImm" # Bits;
602 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
604 let Name = "UImm" # Bits;
605 let RenderMethod = "addUImmOperands<" # Bits # ">";
606 let PredicateMethod = "isUImm<" # Bits # ">";
607 let SuperClasses = Supers;
608 let DiagnosticType = "UImm" # Bits;
611 // Generic case - only to support certain assembly pseudo instructions.
612 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
615 let RenderMethod = "addConstantUImmOperands<32>";
616 let PredicateMethod = "isSImm<" # Bits # ">";
617 let SuperClasses = Supers;
618 let DiagnosticType = "ImmAny";
621 // AsmOperandClasses require a strict ordering which is difficult to manage
622 // as a hierarchy. Instead, we use a linear ordering and impose an order that
623 // is in some places arbitrary.
625 // Here the rules that are in use:
626 // * Wider immediates are a superset of narrower immediates:
627 // uimm4 < uimm5 < uimm6
628 // * For the same bit-width, unsigned immediates are a superset of signed
630 // simm4 < uimm4 < simm5 < uimm5
631 // * For the same upper-bound, signed immediates are a superset of unsigned
633 // uimm3 < simm4 < uimm4 < simm4
634 // * Modified immediates are a superset of ordinary immediates:
635 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
636 // The term 'superset' starts to break down here since the uimm5_plus* classes
637 // are not true supersets of uimm5 (but they are still subsets of uimm6).
638 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
639 // uimm16 < uimm16_relaxed
640 // * The codeGen pattern type is arbitrarily ordered.
641 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
642 // This is entirely arbitrary. We need an ordering and what we pick is
643 // unimportant since only one is possible for a given mnemonic.
645 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
646 let Name = "UImm32_Coerced";
647 let DiagnosticType = "UImm32_Coerced";
649 def SImm32RelaxedAsmOperandClass
650 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
651 let Name = "SImm32_Relaxed";
652 let PredicateMethod = "isAnyImm<33>";
653 let DiagnosticType = "SImm32_Relaxed";
655 def SImm32AsmOperandClass
656 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
657 def ConstantUImm26AsmOperandClass
658 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
659 def ConstantUImm20AsmOperandClass
660 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
661 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
662 let Name = "SImm19Lsl2";
663 let RenderMethod = "addImmOperands";
664 let PredicateMethod = "isScaledSImm<19, 2>";
665 let SuperClasses = [ConstantUImm20AsmOperandClass];
666 let DiagnosticType = "SImm19_Lsl2";
668 def UImm16RelaxedAsmOperandClass
669 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
670 let Name = "UImm16_Relaxed";
671 let PredicateMethod = "isAnyImm<16>";
672 let DiagnosticType = "UImm16_Relaxed";
674 // Similar to the relaxed classes which take an SImm and render it as
675 // an UImm, this takes a UImm and renders it as an SImm.
676 def UImm16AltRelaxedAsmOperandClass
677 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
678 let Name = "UImm16_AltRelaxed";
679 let PredicateMethod = "isUImm<16>";
680 let DiagnosticType = "UImm16_AltRelaxed";
682 // FIXME: One of these should probably have UImm16AsmOperandClass as the
683 // superclass instead of UImm16RelaxedasmOPerandClass.
684 def UImm16AsmOperandClass
685 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
686 def SImm16RelaxedAsmOperandClass
687 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
688 let Name = "SImm16_Relaxed";
689 let PredicateMethod = "isAnyImm<16>";
690 let DiagnosticType = "SImm16_Relaxed";
692 def SImm16AsmOperandClass
693 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
694 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
695 let Name = "SImm10Lsl3";
696 let RenderMethod = "addImmOperands";
697 let PredicateMethod = "isScaledSImm<10, 3>";
698 let SuperClasses = [SImm16AsmOperandClass];
699 let DiagnosticType = "SImm10_Lsl3";
701 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
702 let Name = "SImm10Lsl2";
703 let RenderMethod = "addImmOperands";
704 let PredicateMethod = "isScaledSImm<10, 2>";
705 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
706 let DiagnosticType = "SImm10_Lsl2";
708 def ConstantSImm11AsmOperandClass
709 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
710 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
711 let Name = "SImm10Lsl1";
712 let RenderMethod = "addImmOperands";
713 let PredicateMethod = "isScaledSImm<10, 1>";
714 let SuperClasses = [ConstantSImm11AsmOperandClass];
715 let DiagnosticType = "SImm10_Lsl1";
717 def ConstantUImm10AsmOperandClass
718 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
719 def ConstantSImm10AsmOperandClass
720 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
721 def ConstantSImm9AsmOperandClass
722 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
723 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
724 let Name = "SImm7Lsl2";
725 let RenderMethod = "addImmOperands";
726 let PredicateMethod = "isScaledSImm<7, 2>";
727 let SuperClasses = [ConstantSImm9AsmOperandClass];
728 let DiagnosticType = "SImm7_Lsl2";
730 def ConstantUImm8AsmOperandClass
731 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
732 def ConstantUImm7Sub1AsmOperandClass
733 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
734 // Specify the names since the -1 offset causes invalid identifiers otherwise.
735 let Name = "UImm7_N1";
736 let DiagnosticType = "UImm7_N1";
738 def ConstantUImm7AsmOperandClass
739 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
740 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
741 let Name = "UImm6Lsl2";
742 let RenderMethod = "addImmOperands";
743 let PredicateMethod = "isScaledUImm<6, 2>";
744 let SuperClasses = [ConstantUImm7AsmOperandClass];
745 let DiagnosticType = "UImm6_Lsl2";
747 def ConstantUImm6AsmOperandClass
748 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
749 def ConstantSImm6AsmOperandClass
750 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
751 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
752 let Name = "UImm5Lsl2";
753 let RenderMethod = "addImmOperands";
754 let PredicateMethod = "isScaledUImm<5, 2>";
755 let SuperClasses = [ConstantSImm6AsmOperandClass];
756 let DiagnosticType = "UImm5_Lsl2";
758 def ConstantUImm5_Range2_64AsmOperandClass
759 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
760 def ConstantUImm5Plus33AsmOperandClass
761 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
763 def ConstantUImm5ReportUImm6AsmOperandClass
764 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
765 let Name = "ConstantUImm5_0_Report_UImm6";
766 let DiagnosticType = "UImm5_0_Report_UImm6";
768 def ConstantUImm5Plus32AsmOperandClass
769 : ConstantUImmAsmOperandClass<
770 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
771 def ConstantUImm5Plus32NormalizeAsmOperandClass
772 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
773 let Name = "ConstantUImm5_32_Norm";
774 // We must also subtract 32 when we render the operand.
775 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
777 def ConstantUImm5Plus1ReportUImm6AsmOperandClass
778 : ConstantUImmAsmOperandClass<
779 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
780 let Name = "ConstantUImm5_Plus1_Report_UImm6";
782 def ConstantUImm5Plus1AsmOperandClass
783 : ConstantUImmAsmOperandClass<
784 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
785 def ConstantUImm5AsmOperandClass
786 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
787 def ConstantSImm5AsmOperandClass
788 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
789 def ConstantUImm4AsmOperandClass
790 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
791 def ConstantSImm4AsmOperandClass
792 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
793 def ConstantUImm3AsmOperandClass
794 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
795 def ConstantUImm2Plus1AsmOperandClass
796 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
797 def ConstantUImm2AsmOperandClass
798 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
799 def ConstantUImm1AsmOperandClass
800 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
801 def ConstantImmzAsmOperandClass : AsmOperandClass {
802 let Name = "ConstantImmz";
803 let RenderMethod = "addConstantUImmOperands<1>";
804 let PredicateMethod = "isConstantImmz";
805 let SuperClasses = [ConstantUImm1AsmOperandClass];
806 let DiagnosticType = "Immz";
809 def Simm19Lsl2AsmOperand
810 : SimmLslAsmOperandClass<19, [], 2>;
812 def MipsJumpTargetAsmOperand : AsmOperandClass {
813 let Name = "JumpTarget";
814 let ParserMethod = "parseJumpTarget";
815 let PredicateMethod = "isImm";
816 let RenderMethod = "addImmOperands";
819 // Instruction operand types
820 def jmptarget : Operand<OtherVT> {
821 let EncoderMethod = "getJumpTargetOpValue";
822 let ParserMatchClass = MipsJumpTargetAsmOperand;
824 def brtarget : Operand<OtherVT> {
825 let EncoderMethod = "getBranchTargetOpValue";
826 let OperandType = "OPERAND_PCREL";
827 let DecoderMethod = "DecodeBranchTarget";
828 let ParserMatchClass = MipsJumpTargetAsmOperand;
830 def brtarget1SImm16 : Operand<OtherVT> {
831 let EncoderMethod = "getBranchTargetOpValue1SImm16";
832 let OperandType = "OPERAND_PCREL";
833 let DecoderMethod = "DecodeBranchTarget1SImm16";
834 let ParserMatchClass = MipsJumpTargetAsmOperand;
836 def calltarget : Operand<iPTR> {
837 let EncoderMethod = "getJumpTargetOpValue";
838 let ParserMatchClass = MipsJumpTargetAsmOperand;
841 def imm64: Operand<i64>;
843 def simm19_lsl2 : Operand<i32> {
844 let EncoderMethod = "getSimm19Lsl2Encoding";
845 let DecoderMethod = "DecodeSimm19Lsl2";
846 let ParserMatchClass = Simm19Lsl2AsmOperand;
849 def simm18_lsl3 : Operand<i32> {
850 let EncoderMethod = "getSimm18Lsl3Encoding";
851 let DecoderMethod = "DecodeSimm18Lsl3";
852 let ParserMatchClass = MipsJumpTargetAsmOperand;
856 def uimmz : Operand<i32> {
857 let PrintMethod = "printUImm<0>";
858 let ParserMatchClass = ConstantImmzAsmOperandClass;
861 // size operand of ins instruction
862 def uimm_range_2_64 : Operand<i32> {
863 let PrintMethod = "printUImm<6, 2>";
864 let EncoderMethod = "getSizeInsEncoding";
865 let DecoderMethod = "DecodeInsSize";
866 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
870 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
871 def uimm # I : Operand<i32> {
872 let PrintMethod = "printUImm<" # I # ">";
873 let ParserMatchClass =
874 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
877 def uimm2_plus1 : Operand<i32> {
878 let PrintMethod = "printUImm<2, 1>";
879 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
880 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
881 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
884 def uimm5_plus1 : Operand<i32> {
885 let PrintMethod = "printUImm<5, 1>";
886 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
887 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
888 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
891 def uimm5_plus1_report_uimm6 : Operand<i32> {
892 let PrintMethod = "printUImm<6, 1>";
893 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
894 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
895 let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
898 def uimm5_plus32 : Operand<i32> {
899 let PrintMethod = "printUImm<5, 32>";
900 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
903 def uimm5_plus33 : Operand<i32> {
904 let PrintMethod = "printUImm<5, 33>";
905 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
906 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
907 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
910 def uimm5_inssize_plus1 : Operand<i32> {
911 let PrintMethod = "printUImm<6>";
912 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
913 let EncoderMethod = "getSizeInsEncoding";
914 let DecoderMethod = "DecodeInsSize";
917 def uimm5_plus32_normalize : Operand<i32> {
918 let PrintMethod = "printUImm<5>";
919 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
922 def uimm5_lsl2 : Operand<OtherVT> {
923 let EncoderMethod = "getUImm5Lsl2Encoding";
924 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
925 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
928 def uimm5_plus32_normalize_64 : Operand<i64> {
929 let PrintMethod = "printUImm<5>";
930 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
933 def uimm6_lsl2 : Operand<OtherVT> {
934 let EncoderMethod = "getUImm6Lsl2Encoding";
935 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
936 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
940 def uimm # I : Operand<i32> {
941 let PrintMethod = "printUImm<" # I # ">";
942 let ParserMatchClass =
943 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
946 // Like uimm16_64 but coerces simm16 to uimm16.
947 def uimm16_relaxed : Operand<i32> {
948 let PrintMethod = "printUImm<16>";
949 let ParserMatchClass =
950 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
954 def uimm # I # _64 : Operand<i64> {
955 let PrintMethod = "printUImm<" # I # ">";
956 let ParserMatchClass =
957 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
961 def uimm # I # _64 : Operand<i64> {
962 let PrintMethod = "printUImm<" # I # ">";
963 let ParserMatchClass =
964 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
967 // Like uimm16_64 but coerces simm16 to uimm16.
968 def uimm16_64_relaxed : Operand<i64> {
969 let PrintMethod = "printUImm<16>";
970 let ParserMatchClass =
971 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
974 def uimm16_altrelaxed : Operand<i32> {
975 let PrintMethod = "printUImm<16>";
976 let ParserMatchClass =
977 !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
979 // Like uimm5 but reports a less confusing error for 32-63 when
980 // an instruction alias permits that.
981 def uimm5_report_uimm6 : Operand<i32> {
982 let PrintMethod = "printUImm<6>";
983 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
986 // Like uimm5_64 but reports a less confusing error for 32-63 when
987 // an instruction alias permits that.
988 def uimm5_64_report_uimm6 : Operand<i64> {
989 let PrintMethod = "printUImm<5>";
990 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
993 foreach I = {1, 2, 3, 4} in
994 def uimm # I # _ptr : Operand<iPTR> {
995 let PrintMethod = "printUImm<" # I # ">";
996 let ParserMatchClass =
997 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1000 foreach I = {1, 2, 3, 4, 5, 6, 8} in
1001 def vsplat_uimm # I : Operand<vAny> {
1002 let PrintMethod = "printUImm<" # I # ">";
1003 let ParserMatchClass =
1004 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1008 foreach I = {4, 5, 6, 9, 10, 11} in
1009 def simm # I : Operand<i32> {
1010 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1011 let ParserMatchClass =
1012 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1015 foreach I = {1, 2, 3} in
1016 def simm10_lsl # I : Operand<i32> {
1017 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
1018 let ParserMatchClass =
1019 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
1023 def simm # I # _64 : Operand<i64> {
1024 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1025 let ParserMatchClass =
1026 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1029 foreach I = {5, 10} in
1030 def vsplat_simm # I : Operand<vAny> {
1031 let ParserMatchClass =
1032 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1035 def simm7_lsl2 : Operand<OtherVT> {
1036 let EncoderMethod = "getSImm7Lsl2Encoding";
1037 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
1038 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
1041 foreach I = {16, 32} in
1042 def simm # I : Operand<i32> {
1043 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1044 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
1047 // Like simm16 but coerces uimm16 to simm16.
1048 def simm16_relaxed : Operand<i32> {
1049 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1050 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
1053 def simm16_64 : Operand<i64> {
1054 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1055 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
1058 // like simm32 but coerces simm32 to uimm32.
1059 def uimm32_coerced : Operand<i32> {
1060 let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
1062 // Like simm32 but coerces uimm32 to simm32.
1063 def simm32_relaxed : Operand<i32> {
1064 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1065 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
1068 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
1069 def li16_imm : Operand<i32> {
1070 let DecoderMethod = "DecodeLi16Imm";
1071 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
1074 def MipsMemAsmOperand : AsmOperandClass {
1076 let ParserMethod = "parseMemOperand";
1079 def MipsMemSimm9AsmOperand : AsmOperandClass {
1080 let Name = "MemOffsetSimm9";
1081 let SuperClasses = [MipsMemAsmOperand];
1082 let RenderMethod = "addMemOperands";
1083 let ParserMethod = "parseMemOperand";
1084 let PredicateMethod = "isMemWithSimmOffset<9>";
1085 let DiagnosticType = "MemSImm9";
1088 def MipsMemSimm10AsmOperand : AsmOperandClass {
1089 let Name = "MemOffsetSimm10";
1090 let SuperClasses = [MipsMemAsmOperand];
1091 let RenderMethod = "addMemOperands";
1092 let ParserMethod = "parseMemOperand";
1093 let PredicateMethod = "isMemWithSimmOffset<10>";
1094 let DiagnosticType = "MemSImm10";
1097 def MipsMemSimm12AsmOperand : AsmOperandClass {
1098 let Name = "MemOffsetSimm12";
1099 let SuperClasses = [MipsMemAsmOperand];
1100 let RenderMethod = "addMemOperands";
1101 let ParserMethod = "parseMemOperand";
1102 let PredicateMethod = "isMemWithSimmOffset<12>";
1103 let DiagnosticType = "MemSImm12";
1106 foreach I = {1, 2, 3} in
1107 def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
1108 let Name = "MemOffsetSimm10_" # I;
1109 let SuperClasses = [MipsMemAsmOperand];
1110 let RenderMethod = "addMemOperands";
1111 let ParserMethod = "parseMemOperand";
1112 let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
1113 let DiagnosticType = "MemSImm10Lsl" # I;
1116 def MipsMemSimm11AsmOperand : AsmOperandClass {
1117 let Name = "MemOffsetSimm11";
1118 let SuperClasses = [MipsMemAsmOperand];
1119 let RenderMethod = "addMemOperands";
1120 let ParserMethod = "parseMemOperand";
1121 let PredicateMethod = "isMemWithSimmOffset<11>";
1122 let DiagnosticType = "MemSImm11";
1125 def MipsMemSimm16AsmOperand : AsmOperandClass {
1126 let Name = "MemOffsetSimm16";
1127 let SuperClasses = [MipsMemAsmOperand];
1128 let RenderMethod = "addMemOperands";
1129 let ParserMethod = "parseMemOperand";
1130 let PredicateMethod = "isMemWithSimmOffset<16>";
1131 let DiagnosticType = "MemSImm16";
1134 def MipsMemSimmPtrAsmOperand : AsmOperandClass {
1135 let Name = "MemOffsetSimmPtr";
1136 let SuperClasses = [MipsMemAsmOperand];
1137 let RenderMethod = "addMemOperands";
1138 let ParserMethod = "parseMemOperand";
1139 let PredicateMethod = "isMemWithPtrSizeOffset";
1140 let DiagnosticType = "MemSImmPtr";
1143 def MipsInvertedImmoperand : AsmOperandClass {
1144 let Name = "InvNum";
1145 let RenderMethod = "addImmOperands";
1146 let ParserMethod = "parseInvNum";
1149 def InvertedImOperand : Operand<i32> {
1150 let ParserMatchClass = MipsInvertedImmoperand;
1153 def InvertedImOperand64 : Operand<i64> {
1154 let ParserMatchClass = MipsInvertedImmoperand;
1157 class mem_generic : Operand<iPTR> {
1158 let PrintMethod = "printMemOperand";
1159 let MIOperandInfo = (ops ptr_rc, simm16);
1160 let EncoderMethod = "getMemEncoding";
1161 let ParserMatchClass = MipsMemAsmOperand;
1162 let OperandType = "OPERAND_MEMORY";
1166 def mem : mem_generic;
1168 // MSA specific address operand
1169 def mem_msa : mem_generic {
1170 let MIOperandInfo = (ops ptr_rc, simm10);
1171 let EncoderMethod = "getMSAMemEncoding";
1174 def simm12 : Operand<i32> {
1175 let DecoderMethod = "DecodeSimm12";
1178 def mem_simm9 : mem_generic {
1179 let MIOperandInfo = (ops ptr_rc, simm9);
1180 let EncoderMethod = "getMemEncoding";
1181 let ParserMatchClass = MipsMemSimm9AsmOperand;
1184 def mem_simm10 : mem_generic {
1185 let MIOperandInfo = (ops ptr_rc, simm10);
1186 let EncoderMethod = "getMemEncoding";
1187 let ParserMatchClass = MipsMemSimm10AsmOperand;
1190 foreach I = {1, 2, 3} in
1191 def mem_simm10_lsl # I : mem_generic {
1192 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1193 let EncoderMethod = "getMemEncoding<" # I # ">";
1194 let ParserMatchClass =
1195 !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
1198 def mem_simm11 : mem_generic {
1199 let MIOperandInfo = (ops ptr_rc, simm11);
1200 let EncoderMethod = "getMemEncoding";
1201 let ParserMatchClass = MipsMemSimm11AsmOperand;
1204 def mem_simm12 : mem_generic {
1205 let MIOperandInfo = (ops ptr_rc, simm12);
1206 let EncoderMethod = "getMemEncoding";
1207 let ParserMatchClass = MipsMemSimm12AsmOperand;
1210 def mem_simm16 : mem_generic {
1211 let MIOperandInfo = (ops ptr_rc, simm16);
1212 let EncoderMethod = "getMemEncoding";
1213 let ParserMatchClass = MipsMemSimm16AsmOperand;
1216 def mem_simmptr : mem_generic {
1217 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1220 def mem_ea : Operand<iPTR> {
1221 let PrintMethod = "printMemOperandEA";
1222 let MIOperandInfo = (ops ptr_rc, simm16);
1223 let EncoderMethod = "getMemEncoding";
1224 let OperandType = "OPERAND_MEMORY";
1227 def PtrRC : Operand<iPTR> {
1228 let MIOperandInfo = (ops ptr_rc);
1229 let DecoderMethod = "DecodePtrRegisterClass";
1230 let ParserMatchClass = GPR32AsmOperand;
1233 // size operand of ins instruction
1234 def size_ins : Operand<i32> {
1235 let EncoderMethod = "getSizeInsEncoding";
1236 let DecoderMethod = "DecodeInsSize";
1239 // Transformation Function - get the lower 16 bits.
1240 def LO16 : SDNodeXForm<imm, [{
1241 return getImm(N, N->getZExtValue() & 0xFFFF);
1244 // Transformation Function - get the higher 16 bits.
1245 def HI16 : SDNodeXForm<imm, [{
1246 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1250 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1252 // Node immediate is zero (e.g. insve.d)
1253 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1255 // Node immediate fits as 16-bit sign extended on target immediate.
1257 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1259 // Node immediate fits as 16-bit sign extended on target immediate.
1261 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1263 // Node immediate fits as 7-bit zero extended on target immediate.
1264 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1266 // Node immediate fits as 16-bit zero extended on target immediate.
1267 // The LO16 param means that only the lower 16 bits of the node
1268 // immediate are caught.
1269 // e.g. addiu, sltiu
1270 def immZExt16 : PatLeaf<(imm), [{
1271 if (N->getValueType(0) == MVT::i32)
1272 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1274 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1277 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1278 def immSExt32Low16Zero : PatLeaf<(imm), [{
1279 int64_t Val = N->getSExtValue();
1280 return isInt<32>(Val) && !(Val & 0xffff);
1283 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1284 def immZExt32Low16Zero : PatLeaf<(imm), [{
1285 uint64_t Val = N->getZExtValue();
1286 return isUInt<32>(Val) && !(Val & 0xffff);
1289 // Note immediate fits as a 32 bit signed extended on target immediate.
1290 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1292 // Note immediate fits as a 32 bit zero extended on target immediate.
1293 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1295 // shamt field must fit in 5 bits.
1296 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1298 def immZExt5Plus1 : PatLeaf<(imm), [{
1299 return isUInt<5>(N->getZExtValue() - 1);
1301 def immZExt5Plus32 : PatLeaf<(imm), [{
1302 return isUInt<5>(N->getZExtValue() - 32);
1304 def immZExt5Plus33 : PatLeaf<(imm), [{
1305 return isUInt<5>(N->getZExtValue() - 33);
1308 def immZExt5To31 : SDNodeXForm<imm, [{
1309 return getImm(N, 31 - N->getZExtValue());
1312 // True if (N + 1) fits in 16-bit field.
1313 def immSExt16Plus1 : PatLeaf<(imm), [{
1314 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1317 def immZExtRange2To64 : PatLeaf<(imm), [{
1318 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1319 (N->getZExtValue() <= 64);
1322 def ORiPred : PatLeaf<(imm), [{
1323 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1326 def LUiPred : PatLeaf<(imm), [{
1327 int64_t Val = N->getSExtValue();
1328 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1331 def LUiORiPred : PatLeaf<(imm), [{
1332 int64_t SVal = N->getSExtValue();
1333 return isInt<32>(SVal) && (SVal & 0xffff);
1336 // Mips Address Mode! SDNode frameindex could possibily be a match
1337 // since load and store instructions from stack used it.
1339 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1342 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1345 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1347 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1348 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1350 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1352 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1355 //===----------------------------------------------------------------------===//
1356 // Instructions specific format
1357 //===----------------------------------------------------------------------===//
1359 // Arithmetic and logical instructions with 3 register operands.
1360 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1361 InstrItinClass Itin = NoItinerary,
1362 SDPatternOperator OpNode = null_frag>:
1363 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1364 !strconcat(opstr, "\t$rd, $rs, $rt"),
1365 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1366 let isCommutable = isComm;
1367 let isReMaterializable = 1;
1368 let TwoOperandAliasConstraint = "$rd = $rs";
1371 // Arithmetic and logical instructions with 2 register operands.
1372 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1373 InstrItinClass Itin = NoItinerary,
1374 SDPatternOperator imm_type = null_frag,
1375 SDPatternOperator OpNode = null_frag> :
1376 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1377 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1378 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1379 Itin, FrmI, opstr> {
1380 let isReMaterializable = 1;
1381 let TwoOperandAliasConstraint = "$rs = $rt";
1384 // Arithmetic Multiply ADD/SUB
1385 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1386 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1387 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1388 let Defs = [HI0, LO0];
1389 let Uses = [HI0, LO0];
1390 let isCommutable = isComm;
1394 class LogicNOR<string opstr, RegisterOperand RO>:
1395 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1396 !strconcat(opstr, "\t$rd, $rs, $rt"),
1397 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1398 let isCommutable = 1;
1402 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1403 RegisterOperand RO, InstrItinClass itin,
1404 SDPatternOperator OpNode = null_frag,
1405 SDPatternOperator PF = null_frag> :
1406 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1407 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1408 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1409 let TwoOperandAliasConstraint = "$rt = $rd";
1412 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1413 SDPatternOperator OpNode = null_frag>:
1414 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1415 !strconcat(opstr, "\t$rd, $rt, $rs"),
1416 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1419 // Load Upper Immediate
1420 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1421 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1422 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1423 let hasSideEffects = 0;
1424 let isReMaterializable = 1;
1427 // Memory Load/Store
1428 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1429 SDPatternOperator OpNode = null_frag,
1430 InstrItinClass Itin = NoItinerary,
1431 ComplexPattern Addr = addr> :
1432 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1433 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1434 let DecoderMethod = "DecodeMem";
1435 let canFoldAsLoad = 1;
1436 string BaseOpcode = opstr;
1440 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1441 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1442 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1444 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1445 SDPatternOperator OpNode = null_frag,
1446 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1447 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1448 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1449 let DecoderMethod = "DecodeMem";
1450 string BaseOpcode = opstr;
1454 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1455 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1456 DAGOperand MO = mem> :
1457 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1459 // Load/Store Left/Right
1460 let canFoldAsLoad = 1 in
1461 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1462 InstrItinClass Itin> :
1463 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1464 !strconcat(opstr, "\t$rt, $addr"),
1465 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1466 let DecoderMethod = "DecodeMem";
1467 string Constraints = "$src = $rt";
1468 let BaseOpcode = opstr;
1471 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1472 InstrItinClass Itin> :
1473 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1474 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1475 let DecoderMethod = "DecodeMem";
1476 let BaseOpcode = opstr;
1480 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1481 SDPatternOperator OpNode= null_frag> :
1482 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1483 !strconcat(opstr, "\t$rt, $addr"),
1484 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1485 let DecoderMethod = "DecodeFMem2";
1489 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1490 SDPatternOperator OpNode= null_frag> :
1491 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1492 !strconcat(opstr, "\t$rt, $addr"),
1493 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1494 let DecoderMethod = "DecodeFMem2";
1499 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1500 SDPatternOperator OpNode= null_frag> :
1501 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1502 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1503 let DecoderMethod = "DecodeFMem3";
1507 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1508 SDPatternOperator OpNode= null_frag> :
1509 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1510 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1511 let DecoderMethod = "DecodeFMem3";
1515 // Conditional Branch
1516 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1517 RegisterOperand RO> :
1518 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1519 !strconcat(opstr, "\t$rs, $rt, $offset"),
1520 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1523 let isTerminator = 1;
1524 let hasDelaySlot = 1;
1529 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1530 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1531 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1533 let isTerminator = 1;
1534 let hasDelaySlot = 1;
1539 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1540 RegisterOperand RO> :
1541 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1542 !strconcat(opstr, "\t$rs, $offset"),
1543 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1546 let isTerminator = 1;
1547 let hasDelaySlot = 1;
1552 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1553 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1554 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1556 let isTerminator = 1;
1557 let hasDelaySlot = 1;
1563 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1564 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1565 !strconcat(opstr, "\t$rd, $rs, $rt"),
1566 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1567 II_SLT_SLTU, FrmR, opstr>;
1569 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1570 RegisterOperand RO>:
1571 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1572 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1573 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1574 II_SLTI_SLTIU, FrmI, opstr>;
1577 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1578 SDPatternOperator targetoperator, string bopstr> :
1579 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1580 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1583 let hasDelaySlot = 1;
1584 let DecoderMethod = "DecodeJumpTarget";
1589 // Unconditional branch
1590 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1591 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1592 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1594 let isTerminator = 1;
1596 let hasDelaySlot = 1;
1597 let AdditionalPredicates = [RelocPIC];
1602 // Base class for indirect branch and return instruction classes.
1603 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1604 class JumpFR<string opstr, RegisterOperand RO,
1605 SDPatternOperator operator = null_frag>:
1606 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1610 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1612 let isIndirectBranch = 1;
1615 // Jump and Link (Call)
1616 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1617 class JumpLink<string opstr, DAGOperand opnd> :
1618 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1619 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1620 let DecoderMethod = "DecodeJumpTarget";
1623 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1624 Register RetReg, RegisterOperand ResRO = RO>:
1625 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1626 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1627 let hasPostISelHook = 1;
1630 class JumpLinkReg<string opstr, RegisterOperand RO>:
1631 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1632 [], II_JALR, FrmR, opstr> {
1633 let hasPostISelHook = 1;
1636 class BGEZAL_FT<string opstr, DAGOperand opnd,
1637 RegisterOperand RO> :
1638 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1639 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1640 let hasDelaySlot = 1;
1645 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1646 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1647 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1648 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1649 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1651 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1652 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1653 PseudoInstExpansion<(JumpInst RO:$rs)> {
1654 let hasPostISelHook = 1;
1658 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1659 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1660 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1662 let isTerminator = 1;
1664 let hasDelaySlot = 1;
1671 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1672 InstSE<(outs), (ins ImmOp:$code_),
1673 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1675 class BRK_FT<string opstr> :
1676 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1677 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1681 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1682 InstSE<(outs), (ins),
1683 opstr, [], itin, FrmOther, opstr>;
1686 class WAIT_FT<string opstr> :
1687 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1691 class DEI_FT<string opstr, RegisterOperand RO,
1692 InstrItinClass itin = NoItinerary> :
1693 InstSE<(outs RO:$rt), (ins),
1694 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1697 let hasSideEffects = 1 in
1698 class SYNC_FT<string opstr> :
1699 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1700 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1702 class SYNCI_FT<string opstr, DAGOperand MO> :
1703 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1704 II_SYNCI, FrmOther, opstr> {
1705 let hasSideEffects = 1;
1706 let DecoderMethod = "DecodeSyncI";
1709 let hasSideEffects = 1, isCTI = 1 in {
1710 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1711 InstrItinClass itin = NoItinerary> :
1712 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1713 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1715 class TEQI_FT<string opstr, RegisterOperand RO,
1716 InstrItinClass itin = NoItinerary> :
1717 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1718 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1722 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1723 list<Register> DefRegs> :
1724 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1725 itin, FrmR, opstr> {
1726 let isCommutable = 1;
1728 let hasSideEffects = 0;
1731 // Pseudo multiply/divide instruction with explicit accumulator register
1733 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1734 SDPatternOperator OpNode, InstrItinClass Itin,
1735 bit IsComm = 1, bit HasSideEffects = 0,
1736 bit UsesCustomInserter = 0> :
1737 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1738 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1739 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1740 let isCommutable = IsComm;
1741 let hasSideEffects = HasSideEffects;
1742 let usesCustomInserter = UsesCustomInserter;
1745 // Pseudo multiply add/sub instruction with explicit accumulator register
1747 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1748 InstrItinClass itin>
1749 : PseudoSE<(outs ACC64:$ac),
1750 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1752 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1754 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1755 string Constraints = "$acin = $ac";
1758 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1759 list<Register> DefRegs> :
1760 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1761 [], itin, FrmR, opstr> {
1766 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1767 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1768 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1770 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1771 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1773 let Uses = [UseReg];
1774 let hasSideEffects = 0;
1778 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1779 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1780 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1783 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1784 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1787 let hasSideEffects = 0;
1791 class EffectiveAddress<string opstr, RegisterOperand RO> :
1792 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1793 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1794 !strconcat(opstr, "_lea")> {
1795 let isCodeGenOnly = 1;
1796 let hasNoSchedulingInfo = 1;
1797 let DecoderMethod = "DecodeMem";
1800 // Count Leading Ones/Zeros in Word
1801 class CountLeading0<string opstr, RegisterOperand RO,
1802 InstrItinClass itin = NoItinerary>:
1803 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1804 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1806 class CountLeading1<string opstr, RegisterOperand RO,
1807 InstrItinClass itin = NoItinerary>:
1808 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1809 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1811 // Sign Extend in Register.
1812 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1813 InstrItinClass itin> :
1814 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1815 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1818 class SubwordSwap<string opstr, RegisterOperand RO,
1819 InstrItinClass itin = NoItinerary>:
1820 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1822 let hasSideEffects = 0;
1826 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1827 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1828 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1831 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1832 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1833 SDPatternOperator Op = null_frag> :
1834 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1835 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1836 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1839 // 'ins' and its' 64 bit variants are matched by C++ code.
1840 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1841 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1842 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1843 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1844 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1846 II_INS, FrmR, opstr> {
1847 let Constraints = "$src = $rt";
1850 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1851 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1852 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1853 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1855 class Atomic2OpsPostRA<RegisterClass RC> :
1856 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1861 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1862 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1863 RC:$shiftamnt), []>;
1865 // Atomic Compare & Swap.
1866 // Atomic compare and swap is lowered into two stages. The first stage happens
1867 // during ISelLowering, which produces the PostRA version of this instruction.
1868 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1869 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1870 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1872 class AtomicCmpSwapPostRA<RegisterClass RC> :
1873 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1878 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1879 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1880 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1886 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1887 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1888 [], II_LL, FrmI, opstr> {
1889 let DecoderMethod = "DecodeMem";
1893 class SCBase<string opstr, RegisterOperand RO> :
1894 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1895 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1896 let DecoderMethod = "DecodeMem";
1898 let Constraints = "$rt = $dst";
1901 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1902 InstrItinClass itin> :
1903 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1904 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1905 let BaseOpcode = asmstr;
1908 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1909 InstrItinClass itin> :
1910 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1911 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1912 let BaseOpcode = asmstr;
1915 class TrapBase<Instruction RealInst>
1916 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1917 PseudoInstExpansion<(RealInst 0, 0)> {
1919 let isTerminator = 1;
1920 let isCodeGenOnly = 1;
1924 //===----------------------------------------------------------------------===//
1925 // Pseudo instructions
1926 //===----------------------------------------------------------------------===//
1929 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1930 let hasDelaySlot=1 in
1931 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1933 let hasSideEffects=1 in
1934 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1937 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1938 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1939 [(callseq_start timm:$amt1, timm:$amt2)]>;
1940 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1941 [(callseq_end timm:$amt1, timm:$amt2)]>;
1944 let usesCustomInserter = 1 in {
1945 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1946 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1947 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1948 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1949 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1950 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1951 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1952 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1953 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1954 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1955 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1956 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1957 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1958 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1959 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1960 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1961 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1962 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1964 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1965 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1966 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1968 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1969 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1970 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1974 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1975 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1976 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1977 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1978 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1979 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1980 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1981 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1982 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1983 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1984 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1985 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1986 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1987 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1988 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1989 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1990 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1991 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1993 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1994 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1995 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1997 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1998 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1999 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
2001 /// Pseudo instructions for loading and storing accumulator registers.
2002 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
2003 def LOAD_ACC64 : Load<"", ACC64>;
2004 def STORE_ACC64 : Store<"", ACC64>;
2007 // We need these two pseudo instructions to avoid offset calculation for long
2008 // branches. See the comment in file MipsLongBranch.cpp for detailed
2011 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
2012 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
2013 (ins brtarget:$tgt, brtarget:$baltgt), []>;
2014 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
2015 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2016 (ins brtarget:$tgt), []>;
2018 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2019 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2020 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
2021 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2022 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2023 (ins GPR32Opnd:$src, brtarget:$tgt), []>;
2025 //===----------------------------------------------------------------------===//
2026 // Instruction definition
2027 //===----------------------------------------------------------------------===//
2028 //===----------------------------------------------------------------------===//
2029 // MipsI Instructions
2030 //===----------------------------------------------------------------------===//
2032 /// Arithmetic Instructions (ALU Immediate)
2033 let AdditionalPredicates = [NotInMicroMips] in {
2034 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2035 II_ADDIU, immSExt16, add>,
2036 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2038 def ANDi : MMRel, StdMMR6Rel,
2039 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
2040 ADDI_FM<0xc>, ISA_MIPS1;
2041 def ORi : MMRel, StdMMR6Rel,
2042 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
2043 ADDI_FM<0xd>, ISA_MIPS1;
2044 def XORi : MMRel, StdMMR6Rel,
2045 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
2046 ADDI_FM<0xe>, ISA_MIPS1;
2047 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2048 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2049 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2050 SLTI_FM<0xa>, ISA_MIPS1;
2051 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2052 SLTI_FM<0xb>, ISA_MIPS1;
2054 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2057 /// Arithmetic Instructions (3-Operand, R-Type)
2058 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2059 ADD_FM<0, 0x21>, ISA_MIPS1;
2060 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2061 ADD_FM<0, 0x23>, ISA_MIPS1;
2063 let Defs = [HI0, LO0] in
2064 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2065 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2067 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2068 ADD_FM<0, 0x20>, ISA_MIPS1;
2069 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2070 ADD_FM<0, 0x22>, ISA_MIPS1;
2072 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2074 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2076 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2077 ADD_FM<0, 0x24>, ISA_MIPS1;
2078 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2079 ADD_FM<0, 0x25>, ISA_MIPS1;
2080 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2081 ADD_FM<0, 0x26>, ISA_MIPS1;
2082 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2086 let AdditionalPredicates = [NotInMicroMips] in {
2087 /// Shift Instructions
2088 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2089 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2090 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2091 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2092 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2093 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2094 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2095 SRLV_FM<4, 0>, ISA_MIPS1;
2096 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2097 SRLV_FM<6, 0>, ISA_MIPS1;
2098 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2099 SRLV_FM<7, 0>, ISA_MIPS1;
2101 // Rotate Instructions
2102 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2104 SRA_FM<2, 1>, ISA_MIPS32R2;
2105 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2106 SRLV_FM<6, 1>, ISA_MIPS32R2;
2109 /// Load and Store Instructions
2111 let AdditionalPredicates = [NotInMicroMips] in {
2112 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2113 LW_FM<0x20>, ISA_MIPS1;
2114 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2115 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2116 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2117 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2118 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2119 MMRel, LW_FM<0x25>, ISA_MIPS1;
2120 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2121 LW_FM<0x23>, ISA_MIPS1;
2122 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2123 LW_FM<0x28>, ISA_MIPS1;
2124 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2126 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>, ISA_MIPS1;
2129 /// load/store left/right
2130 let AdditionalPredicates = [NotInMicroMips] in {
2131 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2132 ISA_MIPS1_NOT_32R6_64R6;
2133 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2134 ISA_MIPS1_NOT_32R6_64R6;
2135 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2136 ISA_MIPS1_NOT_32R6_64R6;
2137 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2138 ISA_MIPS1_NOT_32R6_64R6;
2140 // COP2 Memory Instructions
2141 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2142 ISA_MIPS1_NOT_32R6_64R6;
2143 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2144 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2145 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2146 ISA_MIPS2_NOT_32R6_64R6;
2147 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2148 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2150 // COP3 Memory Instructions
2151 let DecoderNamespace = "COP3_" in {
2152 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2153 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2154 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2155 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2156 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2157 ISA_MIPS2, NOT_ASE_CNMIPS;
2158 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2159 ISA_MIPS2, NOT_ASE_CNMIPS;
2162 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2163 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2167 let AdditionalPredicates = [NotInMicroMips] in {
2168 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2170 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2172 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2174 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2176 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2178 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2181 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2182 ISA_MIPS2_NOT_32R6_64R6;
2183 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2184 ISA_MIPS2_NOT_32R6_64R6;
2185 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2186 ISA_MIPS2_NOT_32R6_64R6;
2187 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2188 ISA_MIPS2_NOT_32R6_64R6;
2189 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2190 ISA_MIPS2_NOT_32R6_64R6;
2191 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2192 ISA_MIPS2_NOT_32R6_64R6;
2195 let AdditionalPredicates = [NotInMicroMips] in {
2196 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2197 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2199 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2200 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2201 ISA_MIPS32_NOT_32R6_64R6;
2203 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2204 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2206 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2208 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2210 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2213 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2216 let AdditionalPredicates = [NotInMicroMips] in {
2217 /// Load-linked, Store-conditional
2218 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2219 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2221 /// Jump and Branch Instructions
2222 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2223 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2224 IsBranch, ISA_MIPS1;
2226 let AdditionalPredicates = [NotInMicroMips] in {
2227 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
2228 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2230 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2231 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2232 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2234 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2235 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2236 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2237 BGEZ_FM<1, 1>, ISA_MIPS1;
2238 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2239 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2240 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2241 BGEZ_FM<7, 0>, ISA_MIPS1;
2242 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2243 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2244 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2245 BGEZ_FM<6, 0>, ISA_MIPS1;
2246 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2247 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2248 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2249 BGEZ_FM<1, 0>, ISA_MIPS1;
2250 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2251 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2252 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2254 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2258 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2259 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2260 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2263 let AdditionalPredicates = [NotInMicroMips] in {
2264 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2265 ISA_MIPS32_NOT_32R6_64R6;
2266 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2267 ISA_MIPS1_NOT_32R6_64R6;
2268 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2269 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2270 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2271 ISA_MIPS1_NOT_32R6_64R6;
2272 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2273 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2274 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2276 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2277 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2279 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2280 NoIndirectJumpGuards] in
2281 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2283 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2284 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2285 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2286 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2287 II_IndirectBranchPseudo>,
2288 PseudoInstExpansion<(JumpInst RO:$rs)> {
2291 let hasDelaySlot = 1;
2293 let isIndirectBranch = 1;
2297 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2298 NoIndirectJumpGuards] in
2299 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2300 ISA_MIPS1_NOT_32R6_64R6;
2302 // Return instructions are matched as a RetRA instruction, then are expanded
2303 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2304 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2306 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2307 [], II_ReturnPseudo> {
2308 let isTerminator = 1;
2310 let hasDelaySlot = 1;
2312 let isCodeGenOnly = 1;
2314 let hasExtraSrcRegAllocReq = 1;
2318 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2320 // Exception handling related node and instructions.
2321 // The conversion sequence is:
2322 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2323 // MIPSeh_return -> (stack change + indirect branch)
2325 // MIPSeh_return takes the place of regular return instruction
2326 // but takes two arguments (V1, V0) which are used for storing
2327 // the offset and return address respectively.
2328 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2330 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2331 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2333 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in {
2334 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2335 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2336 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
2338 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2341 /// Multiply and Divide Instructions.
2342 let AdditionalPredicates = [NotInMicroMips] in {
2343 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2344 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2345 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2346 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2347 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2348 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2349 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2350 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2351 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2352 ISA_MIPS1_NOT_32R6_64R6;
2353 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2354 ISA_MIPS1_NOT_32R6_64R6;
2355 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2356 ISA_MIPS1_NOT_32R6_64R6;
2357 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2358 ISA_MIPS1_NOT_32R6_64R6;
2360 /// Sign Ext In Register Instructions.
2361 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2362 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2363 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2364 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2367 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2368 ISA_MIPS32_NOT_32R6_64R6;
2369 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2370 ISA_MIPS32_NOT_32R6_64R6;
2372 /// Word Swap Bytes Within Halfwords
2373 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2377 def NOP : PseudoSE<(outs), (ins), []>,
2378 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2380 // FrameIndexes are legalized when they are operands from load/store
2381 // instructions. The same not happens for stack address copies, so an
2382 // add op with mem ComplexPattern is used and the stack address copy
2383 // can be matched. It's similar to Sparc LEA_ADDRi
2384 let AdditionalPredicates = [NotInMicroMips] in
2385 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>, ISA_MIPS1;
2388 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2389 ISA_MIPS32_NOT_32R6_64R6;
2390 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2391 ISA_MIPS32_NOT_32R6_64R6;
2392 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2393 ISA_MIPS32_NOT_32R6_64R6;
2394 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2395 ISA_MIPS32_NOT_32R6_64R6;
2398 let AdditionalPredicates = [NotDSP] in {
2399 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2400 ISA_MIPS1_NOT_32R6_64R6;
2401 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2402 ISA_MIPS1_NOT_32R6_64R6;
2403 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2404 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2405 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2406 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2407 ISA_MIPS32_NOT_32R6_64R6;
2408 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2409 ISA_MIPS32_NOT_32R6_64R6;
2410 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2411 ISA_MIPS32_NOT_32R6_64R6;
2412 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2413 ISA_MIPS32_NOT_32R6_64R6;
2416 let AdditionalPredicates = [NotInMicroMips] in {
2417 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2418 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2419 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2420 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2421 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2422 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2423 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2424 immZExt5, immZExt5Plus1, MipsExt>,
2425 EXT_FM<0>, ISA_MIPS32R2;
2426 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2427 uimm5_inssize_plus1, immZExt5,
2429 EXT_FM<4>, ISA_MIPS32R2;
2431 /// Move Control Registers From/To CPU Registers
2432 let AdditionalPredicates = [NotInMicroMips] in {
2433 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2434 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2435 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2436 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2437 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2438 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2439 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2440 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2443 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2444 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2445 let AdditionalPredicates = [NotInMicroMips] in {
2446 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2448 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2451 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2455 // JR_HB and JALR_HB are defined here using the new style naming
2456 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2457 // and because of that it doesn't follow the naming convention of the
2458 // rest of the file. To avoid a mixture of old vs new style, the new
2459 // style was chosen.
2460 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2461 dag OutOperandList = (outs);
2462 dag InOperandList = (ins GPROpnd:$rs);
2463 string AsmString = !strconcat(instr_asm, "\t$rs");
2464 list<dag> Pattern = [];
2467 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2468 dag OutOperandList = (outs GPROpnd:$rd);
2469 dag InOperandList = (ins GPROpnd:$rs);
2470 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2471 list<dag> Pattern = [];
2474 class JR_HB_DESC<RegisterOperand RO> :
2475 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2477 let isIndirectBranch=1;
2484 class JALR_HB_DESC<RegisterOperand RO> :
2485 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2487 let isIndirectBranch=1;
2492 class JR_HB_ENC : JR_HB_FM<8>;
2493 class JALR_HB_ENC : JALR_HB_FM<9>;
2495 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2496 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2498 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2499 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2502 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2503 UseIndirectJumpsHazard] in {
2504 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2505 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2506 ISA_MIPS32R2_NOT_32R6_64R6;
2509 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2510 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2511 let AdditionalPredicates = [NotInMicroMips] in {
2512 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2513 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2514 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2515 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2517 class CacheOp<string instr_asm, Operand MemOpnd,
2518 InstrItinClass itin = NoItinerary> :
2519 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2520 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2522 let DecoderMethod = "DecodeCacheOp";
2525 let AdditionalPredicates = [NotInMicroMips] in {
2526 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2527 INSN_MIPS3_32_NOT_32R6_64R6;
2528 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2529 INSN_MIPS3_32_NOT_32R6_64R6;
2531 // FIXME: We are missing the prefx instruction.
2532 def ROL : MipsAsmPseudoInst<(outs),
2533 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2534 "rol\t$rs, $rt, $rd">;
2535 def ROLImm : MipsAsmPseudoInst<(outs),
2536 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2537 "rol\t$rs, $rt, $imm">;
2538 def : MipsInstAlias<"rol $rd, $rs",
2539 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2540 def : MipsInstAlias<"rol $rd, $imm",
2541 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2543 def ROR : MipsAsmPseudoInst<(outs),
2544 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2545 "ror\t$rs, $rt, $rd">;
2546 def RORImm : MipsAsmPseudoInst<(outs),
2547 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2548 "ror\t$rs, $rt, $imm">;
2549 def : MipsInstAlias<"ror $rd, $rs",
2550 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2551 def : MipsInstAlias<"ror $rd, $imm",
2552 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2554 def DROL : MipsAsmPseudoInst<(outs),
2555 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2556 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2557 def DROLImm : MipsAsmPseudoInst<(outs),
2558 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2559 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2560 def : MipsInstAlias<"drol $rd, $rs",
2561 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2562 def : MipsInstAlias<"drol $rd, $imm",
2563 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2565 def DROR : MipsAsmPseudoInst<(outs),
2566 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2567 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2568 def DRORImm : MipsAsmPseudoInst<(outs),
2569 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2570 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2571 def : MipsInstAlias<"dror $rd, $rs",
2572 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2573 def : MipsInstAlias<"dror $rd, $imm",
2574 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2576 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2579 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2580 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2581 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2583 def : MipsInstAlias<"seq $rd, $rs",
2584 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2587 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2588 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2589 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2591 def : MipsInstAlias<"seq $rd, $imm",
2592 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2595 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2596 simm32_relaxed:$imm),
2597 "mul\t$rd, $rs, $imm">,
2598 ISA_MIPS1_NOT_32R6_64R6;
2599 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2601 "mulo\t$rd, $rs, $rt">,
2602 ISA_MIPS1_NOT_32R6_64R6;
2603 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2605 "mulou\t$rd, $rs, $rt">,
2606 ISA_MIPS1_NOT_32R6_64R6;
2608 // Virtualization ASE
2609 class HYPCALL_FT<string opstr> :
2610 InstSE<(outs), (ins uimm10:$code_),
2611 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2612 let BaseOpcode = opstr;
2615 let AdditionalPredicates = [NotInMicroMips] in {
2616 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2617 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2618 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2619 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2620 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2621 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2622 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2623 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2624 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2625 ISA_MIPS32R5, ASE_VIRT;
2626 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2627 ISA_MIPS32R5, ASE_VIRT;
2628 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2629 ISA_MIPS32R5, ASE_VIRT;
2630 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2631 ISA_MIPS32R5, ASE_VIRT;
2632 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2633 ISA_MIPS32R5, ASE_VIRT;
2634 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2635 ISA_MIPS32R5, ASE_VIRT;
2636 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2637 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2640 //===----------------------------------------------------------------------===//
2641 // Instruction aliases
2642 //===----------------------------------------------------------------------===//
2644 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2646 RegisterOperand RO = GPR32Opnd,
2647 Operand Imm = simm32_relaxed> {
2648 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2652 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2658 let AdditionalPredicates = [NotInMicroMips] in {
2659 def : MipsInstAlias<"move $dst, $src",
2660 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2662 def : MipsInstAlias<"move $dst, $src",
2663 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2666 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2667 ISA_MIPS1_NOT_32R6_64R6;
2669 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2671 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2673 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2676 def : MipsInstAlias<"neg $rt, $rs",
2677 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2678 def : MipsInstAlias<"neg $rt",
2679 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2680 def : MipsInstAlias<"negu $rt, $rs",
2681 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2682 def : MipsInstAlias<"negu $rt",
2683 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2684 def : MipsInstAlias<
2685 "sgt $rd, $rs, $rt",
2686 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2687 def : MipsInstAlias<
2689 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2690 def : MipsInstAlias<
2691 "sgtu $rd, $rs, $rt",
2692 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2693 def : MipsInstAlias<
2695 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2696 def : MipsInstAlias<
2698 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2699 def : MipsInstAlias<
2701 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2703 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2705 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2707 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2709 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2711 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2713 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2715 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2717 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2719 def : MipsInstAlias<"mfgc0 $rt, $rd",
2720 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2721 ISA_MIPS32R5, ASE_VIRT;
2722 def : MipsInstAlias<"mtgc0 $rt, $rd",
2723 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2724 ISA_MIPS32R5, ASE_VIRT;
2725 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2726 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2727 ISA_MIPS32R5, ASE_VIRT;
2728 def : MipsInstAlias<"mthgc0 $rt, $rd",
2729 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2730 ISA_MIPS32R5, ASE_VIRT;
2731 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2733 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2735 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2737 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2740 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2743 def : MipsInstAlias<"bnez $rs,$offset",
2744 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2746 def : MipsInstAlias<"bnezl $rs,$offset",
2747 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2749 def : MipsInstAlias<"beqz $rs,$offset",
2750 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2752 def : MipsInstAlias<"beqzl $rs,$offset",
2753 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2756 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2758 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2759 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2760 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2761 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2763 def : MipsInstAlias<"teq $rs, $rt",
2764 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2765 def : MipsInstAlias<"tge $rs, $rt",
2766 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2767 def : MipsInstAlias<"tgeu $rs, $rt",
2768 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2769 def : MipsInstAlias<"tlt $rs, $rt",
2770 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2771 def : MipsInstAlias<"tltu $rs, $rt",
2772 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2773 def : MipsInstAlias<"tne $rs, $rt",
2774 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2775 def : MipsInstAlias<"rdhwr $rt, $rs",
2776 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2779 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2780 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2781 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2782 def : MipsInstAlias<"sub $rs, $imm",
2783 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2784 0>, ISA_MIPS1_NOT_32R6_64R6;
2785 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2786 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2787 InvertedImOperand:$imm), 0>;
2788 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2789 InvertedImOperand:$imm), 0>;
2790 let AdditionalPredicates = [NotInMicroMips] in {
2791 def : MipsInstAlias<"sll $rd, $rt, $rs",
2792 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2793 def : MipsInstAlias<"sra $rd, $rt, $rs",
2794 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2795 def : MipsInstAlias<"srl $rd, $rt, $rs",
2796 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2797 def : MipsInstAlias<"sll $rd, $rt",
2798 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2799 def : MipsInstAlias<"sra $rd, $rt",
2800 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2801 def : MipsInstAlias<"srl $rd, $rt",
2802 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2803 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2805 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2808 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2809 let AdditionalPredicates = [NotInMicroMips] in
2810 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2812 def : MipsInstAlias<"mulo $rs, $rt",
2813 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2814 ISA_MIPS1_NOT_32R6_64R6;
2815 def : MipsInstAlias<"mulou $rs, $rt",
2816 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2817 ISA_MIPS1_NOT_32R6_64R6;
2819 let AdditionalPredicates = [NotInMicroMips] in
2820 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2822 //===----------------------------------------------------------------------===//
2823 // Assembler Pseudo Instructions
2824 //===----------------------------------------------------------------------===//
2826 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2828 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2829 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2830 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2831 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2833 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2834 RegisterOperand RO> :
2835 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2836 !strconcat(instr_asm, "\t$rt, $addr")> ;
2837 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2839 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2840 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2841 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2842 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2844 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2846 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2849 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2850 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2851 "nor\t$rs, $rt, $imm">;
2852 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2853 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2854 simm32_relaxed:$imm)>, GPR_32;
2856 let hasDelaySlot = 1, isCTI = 1 in {
2857 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2858 (ins imm64:$imm64, brtarget:$offset),
2859 "bne\t$rt, $imm64, $offset">;
2860 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2861 (ins imm64:$imm64, brtarget:$offset),
2862 "beq\t$rt, $imm64, $offset">;
2864 class CondBranchPseudo<string instr_asm> :
2865 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2867 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2870 def BLT : CondBranchPseudo<"blt">;
2871 def BLE : CondBranchPseudo<"ble">;
2872 def BGE : CondBranchPseudo<"bge">;
2873 def BGT : CondBranchPseudo<"bgt">;
2874 def BLTU : CondBranchPseudo<"bltu">;
2875 def BLEU : CondBranchPseudo<"bleu">;
2876 def BGEU : CondBranchPseudo<"bgeu">;
2877 def BGTU : CondBranchPseudo<"bgtu">;
2878 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2879 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2880 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2881 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2882 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2883 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2884 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2885 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2888 class CondBranchImmPseudo<string instr_asm> :
2889 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2890 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2892 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2893 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2895 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2896 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2897 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2898 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2899 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2900 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2901 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2902 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2903 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2904 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2905 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2906 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2907 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2908 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2909 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2910 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2912 // FIXME: Predicates are removed because instructions are matched regardless of
2913 // predicates, because PredicateControl was not in the hierarchy. This was
2914 // done to emit more precise error message from expansion function.
2915 // Once the tablegen-erated errors are made better, this needs to be fixed and
2916 // predicates needs to be restored.
2918 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2919 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2920 "div\t$rd, $rs, $rt">,
2921 ISA_MIPS1_NOT_32R6_64R6;
2922 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2923 (ins GPR32Opnd:$rs, simm32:$imm),
2924 "div\t$rd, $rs, $imm">,
2925 ISA_MIPS1_NOT_32R6_64R6;
2926 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2927 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2928 "divu\t$rd, $rs, $rt">,
2929 ISA_MIPS1_NOT_32R6_64R6;
2930 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2931 (ins GPR32Opnd:$rs, simm32:$imm),
2932 "divu\t$rd, $rs, $imm">,
2933 ISA_MIPS1_NOT_32R6_64R6;
2936 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2938 ISA_MIPS1_NOT_32R6_64R6;
2939 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
2940 GPR32NonZeroOpnd:$rs,
2942 ISA_MIPS1_NOT_32R6_64R6;
2943 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2945 ISA_MIPS1_NOT_32R6_64R6;
2947 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
2949 ISA_MIPS1_NOT_32R6_64R6;
2950 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
2951 GPR32NonZeroOpnd:$rt,
2953 ISA_MIPS1_NOT_32R6_64R6;
2955 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2957 ISA_MIPS1_NOT_32R6_64R6;
2959 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2960 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2961 "rem\t$rd, $rs, $rt">,
2962 ISA_MIPS1_NOT_32R6_64R6;
2963 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2964 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2965 "rem\t$rd, $rs, $imm">,
2966 ISA_MIPS1_NOT_32R6_64R6;
2967 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2968 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2969 "remu\t$rd, $rs, $rt">,
2970 ISA_MIPS1_NOT_32R6_64R6;
2971 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2972 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2973 "remu\t$rd, $rs, $imm">,
2974 ISA_MIPS1_NOT_32R6_64R6;
2976 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2978 ISA_MIPS1_NOT_32R6_64R6;
2979 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2980 simm32_relaxed:$imm), 0>,
2981 ISA_MIPS1_NOT_32R6_64R6;
2982 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2984 ISA_MIPS1_NOT_32R6_64R6;
2985 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2986 simm32_relaxed:$imm), 0>,
2987 ISA_MIPS1_NOT_32R6_64R6;
2989 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2990 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2992 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2993 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2995 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2996 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2998 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2999 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3001 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3002 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3004 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3005 (ins mem_simm16:$addr), "ld $rt, $addr">,
3006 ISA_MIPS1_NOT_MIPS3;
3007 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3008 (ins mem_simm16:$addr), "sd $rt, $addr">,
3009 ISA_MIPS1_NOT_MIPS3;
3010 //===----------------------------------------------------------------------===//
3011 // Arbitrary patterns that map to one or more instructions
3012 //===----------------------------------------------------------------------===//
3014 // Load/store pattern templates.
3015 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3016 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3018 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3019 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3021 // Materialize constants.
3022 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3023 Instruction ADDiuOp, Instruction LUiOp,
3024 Instruction ORiOp> {
3026 // Constant synthesis previously relied on the ordering of the patterns below.
3027 // By making the predicates they use non-overlapping, the patterns were
3028 // reordered so that the effect of the newly introduced predicates can be
3031 // Arbitrary immediates
3032 def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3034 // Bits 32-16 set, sign/zero extended.
3035 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3038 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3039 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3042 let AdditionalPredicates = [NotInMicroMips] in
3043 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3045 // Carry MipsPatterns
3046 let AdditionalPredicates = [NotInMicroMips] in {
3047 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3048 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3050 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3051 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3052 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3053 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3055 // Support multiplication for pre-Mips32 targets that don't have
3056 // the MUL instruction.
3057 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3058 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3059 ISA_MIPS1_NOT_32R6_64R6;
3062 def : MipsPat<(MipsSync (i32 immz)),
3063 (SYNC 0)>, ISA_MIPS2;
3066 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3067 (JAL texternalsym:$dst)>, ISA_MIPS1;
3068 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3069 // (JALR GPR32:$dst)>;
3072 let AdditionalPredicates = [NotInMicroMips] in {
3073 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3074 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3075 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3076 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3079 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3080 Register ZeroReg, RegisterOperand GPROpnd> {
3081 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3082 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3083 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3084 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3085 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3087 def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
3088 def : MipsPat<(MipsLo tblockaddress:$in),
3089 (Addiu ZeroReg, tblockaddress:$in)>;
3090 def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
3091 def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
3092 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3093 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3094 def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
3096 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3097 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3098 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3099 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3100 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3101 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3102 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3103 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3104 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3105 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3109 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3110 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3112 let AdditionalPredicates = [NotInMicroMips] in {
3113 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3115 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3116 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3119 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3123 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3124 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3125 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3126 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3128 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3129 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3130 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3131 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3132 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3133 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3135 // Mips does not have "not", so we expand our way
3136 def : MipsPat<(not GPR32:$in),
3137 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3141 let AdditionalPredicates = [NotInMicroMips] in {
3142 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3143 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3144 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3147 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3151 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3152 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3153 Instruction SLTiOp, Instruction SLTiuOp,
3155 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3156 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3157 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3158 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3160 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3161 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3162 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3163 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3164 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3165 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3166 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3167 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3168 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3169 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3170 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3171 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3173 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3174 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3175 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3176 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3178 def : MipsPat<(brcond RC:$cond, bb:$dst),
3179 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3181 let AdditionalPredicates = [NotInMicroMips] in {
3182 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3184 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3185 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3186 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3187 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3191 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3192 Instruction SLTuOp, Register ZEROReg> {
3193 def : MipsPat<(seteq RC:$lhs, 0),
3194 (SLTiuOp RC:$lhs, 1)>;
3195 def : MipsPat<(setne RC:$lhs, 0),
3196 (SLTuOp ZEROReg, RC:$lhs)>;
3197 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3198 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3199 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3200 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3203 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3204 Instruction SLTuOp> {
3205 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3206 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3207 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3208 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3211 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3212 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3213 (SLTOp RC:$rhs, RC:$lhs)>;
3214 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3215 (SLTuOp RC:$rhs, RC:$lhs)>;
3218 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3219 Instruction SLTuOp> {
3220 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3221 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3222 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3223 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3226 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3227 Instruction SLTiOp, Instruction SLTiuOp> {
3228 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3229 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3230 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3231 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3234 let AdditionalPredicates = [NotInMicroMips] in {
3235 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3236 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3237 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3238 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3239 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3242 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3245 // Load halfword/word patterns.
3246 let AdditionalPredicates = [NotInMicroMips] in {
3247 let AddedComplexity = 40 in {
3248 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3249 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3250 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3251 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3252 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3255 // Atomic load patterns.
3256 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3257 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3258 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3260 // Atomic store patterns.
3261 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3263 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3265 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3269 //===----------------------------------------------------------------------===//
3270 // Floating Point Support
3271 //===----------------------------------------------------------------------===//
3273 include "MipsInstrFPU.td"
3274 include "Mips64InstrInfo.td"
3275 include "MipsCondMov.td"
3277 include "Mips32r6InstrInfo.td"
3278 include "Mips64r6InstrInfo.td"
3283 include "Mips16InstrFormats.td"
3284 include "Mips16InstrInfo.td"
3287 include "MipsDSPInstrFormats.td"
3288 include "MipsDSPInstrInfo.td"
3291 include "MipsMSAInstrFormats.td"
3292 include "MipsMSAInstrInfo.td"
3295 include "MipsEVAInstrFormats.td"
3296 include "MipsEVAInstrInfo.td"
3299 include "MipsMTInstrFormats.td"
3300 include "MipsMTInstrInfo.td"
3303 include "MicroMipsInstrFormats.td"
3304 include "MicroMipsInstrInfo.td"
3305 include "MicroMipsInstrFPU.td"
3308 include "MicroMips32r6InstrFormats.td"
3309 include "MicroMips32r6InstrInfo.td"
3312 include "MicroMipsDSPInstrFormats.td"
3313 include "MicroMipsDSPInstrInfo.td"