1 //===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the Mips implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Mips profiles and nodes
16 //===----------------------------------------------------------------------===//
17 include "MipsInstrCompiler.td"
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<(all_of FeatureMips2)>;
161 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
162 AssemblerPredicate<(all_of FeatureMips3_32)>;
163 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
164 AssemblerPredicate<(all_of FeatureMips3_32r2)>;
165 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
166 AssemblerPredicate<(all_of FeatureMips3)>;
167 def NotMips3 : Predicate<"!Subtarget->hasMips3()">,
168 AssemblerPredicate<(all_of (not FeatureMips3))>;
169 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
170 AssemblerPredicate<(all_of FeatureMips4_32)>;
171 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
172 AssemblerPredicate<(all_of (not FeatureMips4_32))>;
173 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
174 AssemblerPredicate<(all_of FeatureMips4_32r2)>;
175 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
176 AssemblerPredicate<(all_of FeatureMips5_32r2)>;
177 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
178 AssemblerPredicate<(all_of FeatureMips32)>;
179 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
180 AssemblerPredicate<(all_of FeatureMips32r2)>;
181 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
182 AssemblerPredicate<(all_of FeatureMips32r5)>;
183 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
184 AssemblerPredicate<(all_of FeatureMips32r6)>;
185 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
186 AssemblerPredicate<(all_of (not FeatureMips32r6))>;
187 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
188 AssemblerPredicate<(all_of FeatureGP64Bit)>;
189 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
190 AssemblerPredicate<(all_of (not FeatureGP64Bit))>;
191 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
192 AssemblerPredicate<(all_of FeaturePTR64Bit)>;
193 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
194 AssemblerPredicate<(all_of (not FeaturePTR64Bit))>;
195 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
196 AssemblerPredicate<(all_of FeatureMips64)>;
197 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
198 AssemblerPredicate<(all_of (not FeatureMips64))>;
199 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
200 AssemblerPredicate<(all_of FeatureMips64r2)>;
201 def HasMips64r5 : Predicate<"Subtarget->hasMips64r5()">,
202 AssemblerPredicate<(all_of FeatureMips64r5)>;
203 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
204 AssemblerPredicate<(all_of FeatureMips64r6)>;
205 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
206 AssemblerPredicate<(all_of (not FeatureMips64r6))>;
207 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
208 AssemblerPredicate<(all_of FeatureMips16)>;
209 def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
210 AssemblerPredicate<(all_of (not FeatureMips16))>;
211 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
212 AssemblerPredicate<(all_of FeatureCnMips)>;
213 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
214 AssemblerPredicate<(all_of (not FeatureCnMips))>;
215 def HasCnMipsP : Predicate<"Subtarget->hasCnMipsP()">,
216 AssemblerPredicate<(all_of FeatureCnMipsP)>;
217 def NotCnMipsP : Predicate<"!Subtarget->hasCnMipsP()">,
218 AssemblerPredicate<(all_of (not FeatureCnMipsP))>;
219 def IsSym32 : Predicate<"Subtarget->hasSym32()">,
220 AssemblerPredicate<(all_of FeatureSym32)>;
221 def IsSym64 : Predicate<"!Subtarget->hasSym32()">,
222 AssemblerPredicate<(all_of (not FeatureSym32))>;
223 def IsN64 : Predicate<"Subtarget->isABI_N64()">;
224 def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">;
225 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
226 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
227 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
228 def UseAbs : Predicate<"Subtarget->inAbs2008Mode() ||"
229 "TM.Options.NoNaNsFPMath">;
230 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
231 AssemblerPredicate<(all_of (not FeatureMips16))>;
232 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
233 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
234 AssemblerPredicate<(all_of FeatureMicroMips)>;
235 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
236 AssemblerPredicate<(all_of (not FeatureMicroMips))>;
237 def IsLE : Predicate<"Subtarget->isLittle()">;
238 def IsBE : Predicate<"!Subtarget->isLittle()">;
239 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
240 def UseTCCInDIV : AssemblerPredicate<(all_of FeatureUseTCCInDIV)>;
241 def HasEVA : Predicate<"Subtarget->hasEVA()">,
242 AssemblerPredicate<(all_of FeatureEVA)>;
243 def HasMSA : Predicate<"Subtarget->hasMSA()">,
244 AssemblerPredicate<(all_of FeatureMSA)>;
245 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
246 AssemblerPredicate<(all_of (not FeatureNoMadd4))>;
247 def HasMT : Predicate<"Subtarget->hasMT()">,
248 AssemblerPredicate<(all_of FeatureMT)>;
249 def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
250 AssemblerPredicate<(all_of FeatureUseIndirectJumpsHazard)>;
251 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
252 AssemblerPredicate<(all_of (not FeatureUseIndirectJumpsHazard))>;
253 def HasCRC : Predicate<"Subtarget->hasCRC()">,
254 AssemblerPredicate<(all_of FeatureCRC)>;
255 def HasVirt : Predicate<"Subtarget->hasVirt()">,
256 AssemblerPredicate<(all_of FeatureVirt)>;
257 def HasGINV : Predicate<"Subtarget->hasGINV()">,
258 AssemblerPredicate<(all_of FeatureGINV)>;
259 // TODO: Add support for FPOpFusion::Standard
260 def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
261 " FPOpFusion::Fast">;
262 //===----------------------------------------------------------------------===//
263 // Mips GPR size adjectives.
264 // They are mutually exclusive.
265 //===----------------------------------------------------------------------===//
267 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
268 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
270 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
271 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
273 //===----------------------------------------------------------------------===//
274 // Mips Symbol size adjectives.
275 // They are mutally exculsive.
276 //===----------------------------------------------------------------------===//
278 class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
279 class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
281 //===----------------------------------------------------------------------===//
282 // Mips ISA/ASE membership and instruction group membership adjectives.
283 // They are mutually exclusive.
284 //===----------------------------------------------------------------------===//
286 // FIXME: I'd prefer to use additive predicates to build the instruction sets
287 // but we are short on assembler feature bits at the moment. Using a
288 // subtractive predicate will hopefully keep us under the 32 predicate
289 // limit long enough to develop an alternative way to handle P1||P2
292 list<Predicate> EncodingPredicates = [HasStdEnc];
294 class ISA_MIPS1_NOT_MIPS3 {
295 list<Predicate> InsnPredicates = [NotMips3];
296 list<Predicate> EncodingPredicates = [HasStdEnc];
298 class ISA_MIPS1_NOT_4_32 {
299 list<Predicate> InsnPredicates = [NotMips4_32];
300 list<Predicate> EncodingPredicates = [HasStdEnc];
302 class ISA_MIPS1_NOT_32R6_64R6 {
303 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
304 list<Predicate> EncodingPredicates = [HasStdEnc];
307 list<Predicate> InsnPredicates = [HasMips2];
308 list<Predicate> EncodingPredicates = [HasStdEnc];
310 class ISA_MIPS2_NOT_32R6_64R6 {
311 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
312 list<Predicate> EncodingPredicates = [HasStdEnc];
315 list<Predicate> InsnPredicates = [HasMips3];
316 list<Predicate> EncodingPredicates = [HasStdEnc];
318 class ISA_MIPS3_NOT_32R6_64R6 {
319 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
320 list<Predicate> EncodingPredicates = [HasStdEnc];
323 list<Predicate> InsnPredicates = [HasMips32];
324 list<Predicate> EncodingPredicates = [HasStdEnc];
326 class ISA_MIPS32_NOT_32R6_64R6 {
327 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
328 list<Predicate> EncodingPredicates = [HasStdEnc];
331 list<Predicate> InsnPredicates = [HasMips32r2];
332 list<Predicate> EncodingPredicates = [HasStdEnc];
334 class ISA_MIPS32R2_NOT_32R6_64R6 {
335 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
336 list<Predicate> EncodingPredicates = [HasStdEnc];
339 list<Predicate> InsnPredicates = [HasMips32r5];
340 list<Predicate> EncodingPredicates = [HasStdEnc];
343 list<Predicate> InsnPredicates = [HasMips64];
344 list<Predicate> EncodingPredicates = [HasStdEnc];
346 class ISA_MIPS64_NOT_64R6 {
347 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
348 list<Predicate> EncodingPredicates = [HasStdEnc];
351 list<Predicate> InsnPredicates = [HasMips64r2];
352 list<Predicate> EncodingPredicates = [HasStdEnc];
355 list<Predicate> InsnPredicates = [HasMips64r5];
356 list<Predicate> EncodingPredicates = [HasStdEnc];
359 list<Predicate> InsnPredicates = [HasMips32r6];
360 list<Predicate> EncodingPredicates = [HasStdEnc];
363 list<Predicate> InsnPredicates = [HasMips64r6];
364 list<Predicate> EncodingPredicates = [HasStdEnc];
366 class ISA_MICROMIPS {
367 list<Predicate> EncodingPredicates = [InMicroMips];
369 class ISA_MICROMIPS32R5 {
370 list<Predicate> InsnPredicates = [HasMips32r5];
371 list<Predicate> EncodingPredicates = [InMicroMips];
373 class ISA_MICROMIPS32R6 {
374 list<Predicate> InsnPredicates = [HasMips32r6];
375 list<Predicate> EncodingPredicates = [InMicroMips];
377 class ISA_MICROMIPS64R6 {
378 list<Predicate> InsnPredicates = [HasMips64r6];
379 list<Predicate> EncodingPredicates = [InMicroMips];
381 class ISA_MICROMIPS32_NOT_MIPS32R6 {
382 list<Predicate> InsnPredicates = [NotMips32r6];
383 list<Predicate> EncodingPredicates = [InMicroMips];
385 class ASE_EVA { list<Predicate> ASEPredicate = [HasEVA]; }
387 // The portions of MIPS-III that were also added to MIPS32
388 class INSN_MIPS3_32 {
389 list<Predicate> InsnPredicates = [HasMips3_32];
390 list<Predicate> EncodingPredicates = [HasStdEnc];
393 // The portions of MIPS-III that were also added to MIPS32 but were removed in
394 // MIPS32r6 and MIPS64r6.
395 class INSN_MIPS3_32_NOT_32R6_64R6 {
396 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
397 list<Predicate> EncodingPredicates = [HasStdEnc];
400 // The portions of MIPS-III that were also added to MIPS32
401 class INSN_MIPS3_32R2 {
402 list<Predicate> InsnPredicates = [HasMips3_32r2];
403 list<Predicate> EncodingPredicates = [HasStdEnc];
406 // The portions of MIPS-IV that were also added to MIPS32.
407 class INSN_MIPS4_32 {
408 list <Predicate> InsnPredicates = [HasMips4_32];
409 list<Predicate> EncodingPredicates = [HasStdEnc];
412 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
413 // MIPS32r6 and MIPS64r6.
414 class INSN_MIPS4_32_NOT_32R6_64R6 {
415 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
416 list<Predicate> EncodingPredicates = [HasStdEnc];
419 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
420 // MIPS32r6 and MIPS64r6.
421 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
422 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
423 list<Predicate> EncodingPredicates = [HasStdEnc];
426 // The portions of MIPS-IV that were also added to MIPS32r2.
427 class INSN_MIPS4_32R2 {
428 list<Predicate> InsnPredicates = [HasMips4_32r2];
429 list<Predicate> EncodingPredicates = [HasStdEnc];
432 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
433 // MIPS32r6 and MIPS64r6.
434 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
435 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
436 list<Predicate> EncodingPredicates = [HasStdEnc];
440 list<Predicate> ASEPredicate = [HasCnMips];
443 class NOT_ASE_CNMIPS {
444 list<Predicate> ASEPredicate = [NotCnMips];
448 list<Predicate> ASEPredicate = [HasCnMipsP];
451 class NOT_ASE_CNMIPSP {
452 list<Predicate> ASEPredicate = [NotCnMipsP];
455 class ASE_MIPS64_CNMIPS {
456 list<Predicate> ASEPredicate = [HasMips64, HasCnMips];
460 list<Predicate> ASEPredicate = [HasMSA];
463 class ASE_MSA_NOT_MSA64 {
464 list<Predicate> ASEPredicate = [HasMSA, NotMips64];
468 list<Predicate> ASEPredicate = [HasMSA, HasMips64];
472 list <Predicate> ASEPredicate = [HasMT];
476 list <Predicate> ASEPredicate = [HasCRC];
480 list <Predicate> ASEPredicate = [HasVirt];
484 list <Predicate> ASEPredicate = [HasGINV];
487 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
488 // It can be used only on instructions that doesn't inherit PredicateControl.
489 class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
490 let InsnPredicates = [NotMips32r6];
491 let EncodingPredicates = [InMicroMips];
495 list<Predicate> ASEPredicate = [NotDSP];
499 list<Predicate> AdditionalPredicates = [HasMadd4];
502 // Classes used for separating expansions that differ based on the ABI in
505 list<Predicate> AdditionalPredicates = [IsN64];
509 list<Predicate> AdditionalPredicates = [IsNotN64];
512 class FPOP_FUSION_FAST {
513 list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
516 //===----------------------------------------------------------------------===//
518 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl;
520 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
521 InstAlias<Asm, Result, Emit>, PredicateControl;
524 bit isCommutable = 1;
544 bit isTerminator = 1;
547 bit hasExtraSrcRegAllocReq = 1;
548 bit isCodeGenOnly = 1;
552 class IsAsCheapAsAMove {
553 bit isAsCheapAsAMove = 1;
556 class NeverHasSideEffects {
557 bit hasSideEffects = 0;
560 //===----------------------------------------------------------------------===//
561 // Instruction format superclass
562 //===----------------------------------------------------------------------===//
564 include "MipsInstrFormats.td"
566 //===----------------------------------------------------------------------===//
567 // Mips Operand, Complex Patterns and Transformations Definitions.
568 //===----------------------------------------------------------------------===//
570 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
571 int Offset = 0> : AsmOperandClass {
572 let Name = "ConstantSImm" # Bits # "_" # Offset;
573 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
574 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
575 let SuperClasses = Supers;
576 let DiagnosticType = "SImm" # Bits # "_" # Offset;
579 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
580 int Shift = 0> : AsmOperandClass {
581 let Name = "Simm" # Bits # "_Lsl" # Shift;
582 let RenderMethod = "addImmOperands";
583 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
584 let SuperClasses = Supers;
585 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
588 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
589 int Offset = 0> : AsmOperandClass {
590 let Name = "ConstantUImm" # Bits # "_" # Offset;
591 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
592 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
593 let SuperClasses = Supers;
594 let DiagnosticType = "UImm" # Bits # "_" # Offset;
597 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
598 list<AsmOperandClass> Supers = []>
600 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
601 let RenderMethod = "addImmOperands";
602 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
603 let SuperClasses = Supers;
604 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
607 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
609 let Name = "SImm" # Bits;
610 let RenderMethod = "addSImmOperands<" # Bits # ">";
611 let PredicateMethod = "isSImm<" # Bits # ">";
612 let SuperClasses = Supers;
613 let DiagnosticType = "SImm" # Bits;
616 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
618 let Name = "UImm" # Bits;
619 let RenderMethod = "addUImmOperands<" # Bits # ">";
620 let PredicateMethod = "isUImm<" # Bits # ">";
621 let SuperClasses = Supers;
622 let DiagnosticType = "UImm" # Bits;
625 // Generic case - only to support certain assembly pseudo instructions.
626 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
629 let RenderMethod = "addConstantUImmOperands<32>";
630 let PredicateMethod = "isSImm<" # Bits # ">";
631 let SuperClasses = Supers;
632 let DiagnosticType = "ImmAny";
635 // AsmOperandClasses require a strict ordering which is difficult to manage
636 // as a hierarchy. Instead, we use a linear ordering and impose an order that
637 // is in some places arbitrary.
639 // Here the rules that are in use:
640 // * Wider immediates are a superset of narrower immediates:
641 // uimm4 < uimm5 < uimm6
642 // * For the same bit-width, unsigned immediates are a superset of signed
644 // simm4 < uimm4 < simm5 < uimm5
645 // * For the same upper-bound, signed immediates are a superset of unsigned
647 // uimm3 < simm4 < uimm4 < simm4
648 // * Modified immediates are a superset of ordinary immediates:
649 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
650 // The term 'superset' starts to break down here since the uimm5_plus* classes
651 // are not true supersets of uimm5 (but they are still subsets of uimm6).
652 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
653 // uimm16 < uimm16_relaxed
654 // * The codeGen pattern type is arbitrarily ordered.
655 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
656 // This is entirely arbitrary. We need an ordering and what we pick is
657 // unimportant since only one is possible for a given mnemonic.
659 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
660 let Name = "UImm32_Coerced";
661 let DiagnosticType = "UImm32_Coerced";
663 def SImm32RelaxedAsmOperandClass
664 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
665 let Name = "SImm32_Relaxed";
666 let PredicateMethod = "isAnyImm<33>";
667 let DiagnosticType = "SImm32_Relaxed";
669 def SImm32AsmOperandClass
670 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
671 def ConstantUImm26AsmOperandClass
672 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
673 def ConstantUImm20AsmOperandClass
674 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
675 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
676 let Name = "SImm19Lsl2";
677 let RenderMethod = "addImmOperands";
678 let PredicateMethod = "isScaledSImm<19, 2>";
679 let SuperClasses = [ConstantUImm20AsmOperandClass];
680 let DiagnosticType = "SImm19_Lsl2";
682 def UImm16RelaxedAsmOperandClass
683 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
684 let Name = "UImm16_Relaxed";
685 let PredicateMethod = "isAnyImm<16>";
686 let DiagnosticType = "UImm16_Relaxed";
688 // Similar to the relaxed classes which take an SImm and render it as
689 // an UImm, this takes a UImm and renders it as an SImm.
690 def UImm16AltRelaxedAsmOperandClass
691 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
692 let Name = "UImm16_AltRelaxed";
693 let PredicateMethod = "isUImm<16>";
694 let DiagnosticType = "UImm16_AltRelaxed";
696 // FIXME: One of these should probably have UImm16AsmOperandClass as the
697 // superclass instead of UImm16RelaxedasmOPerandClass.
698 def UImm16AsmOperandClass
699 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
700 def SImm16RelaxedAsmOperandClass
701 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
702 let Name = "SImm16_Relaxed";
703 let PredicateMethod = "isAnyImm<16>";
704 let DiagnosticType = "SImm16_Relaxed";
706 def SImm16AsmOperandClass
707 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
708 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
709 let Name = "SImm10Lsl3";
710 let RenderMethod = "addImmOperands";
711 let PredicateMethod = "isScaledSImm<10, 3>";
712 let SuperClasses = [SImm16AsmOperandClass];
713 let DiagnosticType = "SImm10_Lsl3";
715 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
716 let Name = "SImm10Lsl2";
717 let RenderMethod = "addImmOperands";
718 let PredicateMethod = "isScaledSImm<10, 2>";
719 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
720 let DiagnosticType = "SImm10_Lsl2";
722 def ConstantSImm11AsmOperandClass
723 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
724 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
725 let Name = "SImm10Lsl1";
726 let RenderMethod = "addImmOperands";
727 let PredicateMethod = "isScaledSImm<10, 1>";
728 let SuperClasses = [ConstantSImm11AsmOperandClass];
729 let DiagnosticType = "SImm10_Lsl1";
731 def ConstantUImm10AsmOperandClass
732 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
733 def ConstantSImm10AsmOperandClass
734 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
735 def ConstantSImm9AsmOperandClass
736 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
737 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
738 let Name = "SImm7Lsl2";
739 let RenderMethod = "addImmOperands";
740 let PredicateMethod = "isScaledSImm<7, 2>";
741 let SuperClasses = [ConstantSImm9AsmOperandClass];
742 let DiagnosticType = "SImm7_Lsl2";
744 def ConstantUImm8AsmOperandClass
745 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
746 def ConstantUImm7Sub1AsmOperandClass
747 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
748 // Specify the names since the -1 offset causes invalid identifiers otherwise.
749 let Name = "UImm7_N1";
750 let DiagnosticType = "UImm7_N1";
752 def ConstantUImm7AsmOperandClass
753 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
754 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
755 let Name = "UImm6Lsl2";
756 let RenderMethod = "addImmOperands";
757 let PredicateMethod = "isScaledUImm<6, 2>";
758 let SuperClasses = [ConstantUImm7AsmOperandClass];
759 let DiagnosticType = "UImm6_Lsl2";
761 def ConstantUImm6AsmOperandClass
762 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
763 def ConstantSImm6AsmOperandClass
764 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
765 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
766 let Name = "UImm5Lsl2";
767 let RenderMethod = "addImmOperands";
768 let PredicateMethod = "isScaledUImm<5, 2>";
769 let SuperClasses = [ConstantSImm6AsmOperandClass];
770 let DiagnosticType = "UImm5_Lsl2";
772 def ConstantUImm5_Range2_64AsmOperandClass
773 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
774 def ConstantUImm5Plus33AsmOperandClass
775 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
777 def ConstantUImm5ReportUImm6AsmOperandClass
778 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
779 let Name = "ConstantUImm5_0_Report_UImm6";
780 let DiagnosticType = "UImm5_0_Report_UImm6";
782 def ConstantUImm5Plus32AsmOperandClass
783 : ConstantUImmAsmOperandClass<
784 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
785 def ConstantUImm5Plus32NormalizeAsmOperandClass
786 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
787 let Name = "ConstantUImm5_32_Norm";
788 // We must also subtract 32 when we render the operand.
789 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
791 def ConstantUImm5Plus1ReportUImm6AsmOperandClass
792 : ConstantUImmAsmOperandClass<
793 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
794 let Name = "ConstantUImm5_Plus1_Report_UImm6";
796 def ConstantUImm5Plus1AsmOperandClass
797 : ConstantUImmAsmOperandClass<
798 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
799 def ConstantUImm5AsmOperandClass
800 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
801 def ConstantSImm5AsmOperandClass
802 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
803 def ConstantUImm4AsmOperandClass
804 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
805 def ConstantSImm4AsmOperandClass
806 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
807 def ConstantUImm3AsmOperandClass
808 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
809 def ConstantUImm2Plus1AsmOperandClass
810 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
811 def ConstantUImm2AsmOperandClass
812 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
813 def ConstantUImm1AsmOperandClass
814 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
815 def ConstantImmzAsmOperandClass : AsmOperandClass {
816 let Name = "ConstantImmz";
817 let RenderMethod = "addConstantUImmOperands<1>";
818 let PredicateMethod = "isConstantImmz";
819 let SuperClasses = [ConstantUImm1AsmOperandClass];
820 let DiagnosticType = "Immz";
823 def Simm19Lsl2AsmOperand
824 : SimmLslAsmOperandClass<19, [], 2>;
826 def MipsJumpTargetAsmOperand : AsmOperandClass {
827 let Name = "JumpTarget";
828 let ParserMethod = "parseJumpTarget";
829 let PredicateMethod = "isImm";
830 let RenderMethod = "addImmOperands";
833 // Instruction operand types
834 def jmptarget : Operand<OtherVT> {
835 let EncoderMethod = "getJumpTargetOpValue";
836 let ParserMatchClass = MipsJumpTargetAsmOperand;
837 let PrintMethod = "printJumpOperand";
839 def brtarget : Operand<OtherVT> {
840 let EncoderMethod = "getBranchTargetOpValue";
841 let OperandType = "OPERAND_PCREL";
842 let DecoderMethod = "DecodeBranchTarget";
843 let ParserMatchClass = MipsJumpTargetAsmOperand;
844 let PrintMethod = "printBranchOperand";
846 def brtarget1SImm16 : Operand<OtherVT> {
847 let EncoderMethod = "getBranchTargetOpValue1SImm16";
848 let OperandType = "OPERAND_PCREL";
849 let DecoderMethod = "DecodeBranchTarget1SImm16";
850 let ParserMatchClass = MipsJumpTargetAsmOperand;
851 let PrintMethod = "printBranchOperand";
853 def calltarget : Operand<iPTR> {
854 let EncoderMethod = "getJumpTargetOpValue";
855 let ParserMatchClass = MipsJumpTargetAsmOperand;
856 let PrintMethod = "printJumpOperand";
859 def imm64: Operand<i64>;
861 def simm19_lsl2 : Operand<i32> {
862 let EncoderMethod = "getSimm19Lsl2Encoding";
863 let DecoderMethod = "DecodeSimm19Lsl2";
864 let ParserMatchClass = Simm19Lsl2AsmOperand;
867 def simm18_lsl3 : Operand<i32> {
868 let EncoderMethod = "getSimm18Lsl3Encoding";
869 let DecoderMethod = "DecodeSimm18Lsl3";
870 let ParserMatchClass = MipsJumpTargetAsmOperand;
874 def uimmz : Operand<i32> {
875 let PrintMethod = "printUImm<0>";
876 let ParserMatchClass = ConstantImmzAsmOperandClass;
879 // size operand of ins instruction
880 def uimm_range_2_64 : Operand<i32> {
881 let PrintMethod = "printUImm<6, 2>";
882 let EncoderMethod = "getSizeInsEncoding";
883 let DecoderMethod = "DecodeInsSize";
884 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
888 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
889 def uimm # I : Operand<i32> {
890 let PrintMethod = "printUImm<" # I # ">";
891 let ParserMatchClass =
892 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
895 def uimm2_plus1 : Operand<i32> {
896 let PrintMethod = "printUImm<2, 1>";
897 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
898 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
899 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
902 def uimm5_plus1 : Operand<i32> {
903 let PrintMethod = "printUImm<5, 1>";
904 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
905 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
906 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
909 def uimm5_plus1_report_uimm6 : Operand<i32> {
910 let PrintMethod = "printUImm<6, 1>";
911 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
912 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
913 let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
916 def uimm5_plus32 : Operand<i32> {
917 let PrintMethod = "printUImm<5, 32>";
918 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
921 def uimm5_plus33 : Operand<i32> {
922 let PrintMethod = "printUImm<5, 33>";
923 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
924 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
925 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
928 def uimm5_inssize_plus1 : Operand<i32> {
929 let PrintMethod = "printUImm<6>";
930 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
931 let EncoderMethod = "getSizeInsEncoding";
932 let DecoderMethod = "DecodeInsSize";
935 def uimm5_plus32_normalize : Operand<i32> {
936 let PrintMethod = "printUImm<5>";
937 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
940 def uimm5_lsl2 : Operand<OtherVT> {
941 let EncoderMethod = "getUImm5Lsl2Encoding";
942 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
943 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
946 def uimm5_plus32_normalize_64 : Operand<i64> {
947 let PrintMethod = "printUImm<5>";
948 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
951 def uimm6_lsl2 : Operand<OtherVT> {
952 let EncoderMethod = "getUImm6Lsl2Encoding";
953 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
954 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
958 def uimm # I : Operand<i32> {
959 let PrintMethod = "printUImm<" # I # ">";
960 let ParserMatchClass =
961 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
964 // Like uimm16_64 but coerces simm16 to uimm16.
965 def uimm16_relaxed : Operand<i32> {
966 let PrintMethod = "printUImm<16>";
967 let ParserMatchClass = UImm16RelaxedAsmOperandClass;
971 def uimm # I # _64 : Operand<i64> {
972 let PrintMethod = "printUImm<" # I # ">";
973 let ParserMatchClass =
974 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
978 def uimm # I # _64 : Operand<i64> {
979 let PrintMethod = "printUImm<" # I # ">";
980 let ParserMatchClass =
981 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
984 // Like uimm16_64 but coerces simm16 to uimm16.
985 def uimm16_64_relaxed : Operand<i64> {
986 let PrintMethod = "printUImm<16>";
987 let ParserMatchClass = UImm16RelaxedAsmOperandClass;
990 def uimm16_altrelaxed : Operand<i32> {
991 let PrintMethod = "printUImm<16>";
992 let ParserMatchClass = UImm16AltRelaxedAsmOperandClass;
994 // Like uimm5 but reports a less confusing error for 32-63 when
995 // an instruction alias permits that.
996 def uimm5_report_uimm6 : Operand<i32> {
997 let PrintMethod = "printUImm<6>";
998 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
1001 // Like uimm5_64 but reports a less confusing error for 32-63 when
1002 // an instruction alias permits that.
1003 def uimm5_64_report_uimm6 : Operand<i64> {
1004 let PrintMethod = "printUImm<5>";
1005 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
1008 foreach I = {1, 2, 3, 4} in
1009 def uimm # I # _ptr : Operand<iPTR> {
1010 let PrintMethod = "printUImm<" # I # ">";
1011 let ParserMatchClass =
1012 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1015 foreach I = {1, 2, 3, 4, 5, 6, 8} in
1016 def vsplat_uimm # I : Operand<vAny> {
1017 let PrintMethod = "printUImm<" # I # ">";
1018 let ParserMatchClass =
1019 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1023 foreach I = {4, 5, 6, 9, 10, 11} in
1024 def simm # I : Operand<i32> {
1025 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1026 let ParserMatchClass =
1027 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1030 foreach I = {1, 2, 3} in
1031 def simm10_lsl # I : Operand<i32> {
1032 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
1033 let ParserMatchClass =
1034 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
1038 def simm # I # _64 : Operand<i64> {
1039 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1040 let ParserMatchClass =
1041 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1044 foreach I = {5, 10} in
1045 def vsplat_simm # I : Operand<vAny> {
1046 let ParserMatchClass =
1047 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1050 def simm7_lsl2 : Operand<OtherVT> {
1051 let EncoderMethod = "getSImm7Lsl2Encoding";
1052 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
1053 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
1056 foreach I = {16, 32} in
1057 def simm # I : Operand<i32> {
1058 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1059 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
1062 // Like simm16 but coerces uimm16 to simm16.
1063 def simm16_relaxed : Operand<i32> {
1064 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1065 let ParserMatchClass = SImm16RelaxedAsmOperandClass;
1068 def simm16_64 : Operand<i64> {
1069 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1070 let ParserMatchClass = SImm16AsmOperandClass;
1073 // like simm32 but coerces simm32 to uimm32.
1074 def uimm32_coerced : Operand<i32> {
1075 let ParserMatchClass = UImm32CoercedAsmOperandClass;
1077 // Like simm32 but coerces uimm32 to simm32.
1078 def simm32_relaxed : Operand<i32> {
1079 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1080 let ParserMatchClass = SImm32RelaxedAsmOperandClass;
1083 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
1084 def li16_imm : Operand<i32> {
1085 let DecoderMethod = "DecodeLi16Imm";
1086 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
1089 def MipsMemAsmOperand : AsmOperandClass {
1091 let ParserMethod = "parseMemOperand";
1094 class MipsMemSimmAsmOperand<int Width, int Shift = 0> : AsmOperandClass {
1095 let Name = "MemOffsetSimm" # Width # "_" # Shift;
1096 let SuperClasses = [MipsMemAsmOperand];
1097 let RenderMethod = "addMemOperands";
1098 let ParserMethod = "parseMemOperand";
1099 let PredicateMethod = "isMemWithSimmOffset<" # Width # ", " # Shift # ">";
1100 let DiagnosticType = !if(!eq(Shift, 0), "MemSImm" # Width,
1101 "MemSImm" # Width # "Lsl" # Shift);
1104 def MipsMemSimmPtrAsmOperand : AsmOperandClass {
1105 let Name = "MemOffsetSimmPtr";
1106 let SuperClasses = [MipsMemAsmOperand];
1107 let RenderMethod = "addMemOperands";
1108 let ParserMethod = "parseMemOperand";
1109 let PredicateMethod = "isMemWithPtrSizeOffset";
1110 let DiagnosticType = "MemSImmPtr";
1113 def MipsInvertedImmoperand : AsmOperandClass {
1114 let Name = "InvNum";
1115 let RenderMethod = "addImmOperands";
1116 let ParserMethod = "parseInvNum";
1119 def InvertedImOperand : Operand<i32> {
1120 let ParserMatchClass = MipsInvertedImmoperand;
1123 def InvertedImOperand64 : Operand<i64> {
1124 let ParserMatchClass = MipsInvertedImmoperand;
1127 class mem_generic : Operand<iPTR> {
1128 let PrintMethod = "printMemOperand";
1129 let MIOperandInfo = (ops ptr_rc, simm16);
1130 let EncoderMethod = "getMemEncoding";
1131 let ParserMatchClass = MipsMemAsmOperand;
1132 let OperandType = "OPERAND_MEMORY";
1136 def mem : mem_generic;
1138 // MSA specific address operand
1139 def mem_msa : mem_generic {
1140 let MIOperandInfo = (ops ptr_rc, simm10);
1141 let EncoderMethod = "getMSAMemEncoding";
1144 def simm12 : Operand<i32> {
1145 let DecoderMethod = "DecodeSimm12";
1148 def mem_simm9_exp : mem_generic {
1149 let MIOperandInfo = (ops ptr_rc, simm9);
1150 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1151 let OperandNamespace = "MipsII";
1152 let OperandType = "OPERAND_MEM_SIMM9";
1155 foreach I = {9, 10, 11, 12, 16} in
1156 def mem_simm # I : mem_generic {
1157 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm" # I));
1158 let ParserMatchClass = MipsMemSimmAsmOperand<I>;
1161 foreach I = {1, 2, 3} in
1162 def mem_simm10_lsl # I : mem_generic {
1163 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1164 let EncoderMethod = "getMemEncoding<" # I # ">";
1165 let ParserMatchClass = MipsMemSimmAsmOperand<10, I>;
1168 def mem_simmptr : mem_generic {
1169 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1172 def mem_ea : Operand<iPTR> {
1173 let PrintMethod = "printMemOperandEA";
1174 let MIOperandInfo = (ops ptr_rc, simm16);
1175 let EncoderMethod = "getMemEncoding";
1176 let OperandType = "OPERAND_MEMORY";
1179 def PtrRC : Operand<iPTR> {
1180 let MIOperandInfo = (ops ptr_rc);
1181 let DecoderMethod = "DecodePtrRegisterClass";
1182 let ParserMatchClass = GPR32AsmOperand;
1185 // size operand of ins instruction
1186 def size_ins : Operand<i32> {
1187 let EncoderMethod = "getSizeInsEncoding";
1188 let DecoderMethod = "DecodeInsSize";
1191 // Transformation Function - get the lower 16 bits.
1192 def LO16 : SDNodeXForm<imm, [{
1193 return getImm(N, N->getZExtValue() & 0xFFFF);
1196 // Transformation Function - get the higher 16 bits.
1197 def HI16 : SDNodeXForm<imm, [{
1198 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1202 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1204 // Node immediate is zero (e.g. insve.d)
1205 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1207 // Node immediate fits as 16-bit sign extended on target immediate.
1209 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1211 // Node immediate fits as 16-bit sign extended on target immediate.
1213 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1214 def imm32SExt16 : IntImmLeaf<i32, [{ return isInt<16>(Imm.getSExtValue()); }]>;
1216 // Node immediate fits as 7-bit zero extended on target immediate.
1217 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1218 def timmZExt7 : PatLeaf<(timm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1220 // Node immediate fits as 16-bit zero extended on target immediate.
1221 // The LO16 param means that only the lower 16 bits of the node
1222 // immediate are caught.
1223 // e.g. addiu, sltiu
1224 def immZExt16 : PatLeaf<(imm), [{
1225 if (N->getValueType(0) == MVT::i32)
1226 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1228 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1230 def imm32ZExt16 : IntImmLeaf<i32, [{
1231 return (uint32_t)Imm.getZExtValue() == (unsigned short)Imm.getZExtValue();
1234 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1235 def immSExt32Low16Zero : PatLeaf<(imm), [{
1236 int64_t Val = N->getSExtValue();
1237 return isInt<32>(Val) && !(Val & 0xffff);
1240 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1241 def immZExt32Low16Zero : PatLeaf<(imm), [{
1242 uint64_t Val = N->getZExtValue();
1243 return isUInt<32>(Val) && !(Val & 0xffff);
1246 // Note immediate fits as a 32 bit signed extended on target immediate.
1247 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1249 // Note immediate fits as a 32 bit zero extended on target immediate.
1250 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1252 // shamt field must fit in 5 bits.
1253 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1254 def timmZExt5 : TImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1256 def immZExt5Plus1 : PatLeaf<(imm), [{
1257 return isUInt<5>(N->getZExtValue() - 1);
1259 def immZExt5Plus32 : PatLeaf<(imm), [{
1260 return isUInt<5>(N->getZExtValue() - 32);
1262 def immZExt5Plus33 : PatLeaf<(imm), [{
1263 return isUInt<5>(N->getZExtValue() - 33);
1266 def immZExt5To31 : SDNodeXForm<imm, [{
1267 return getImm(N, 31 - N->getZExtValue());
1270 // True if (N + 1) fits in 16-bit field.
1271 def immSExt16Plus1 : PatLeaf<(imm), [{
1272 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1275 def immZExtRange2To64 : PatLeaf<(imm), [{
1276 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1277 (N->getZExtValue() <= 64);
1280 def ORiPred : PatLeaf<(imm), [{
1281 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1284 def LUiPred : PatLeaf<(imm), [{
1285 int64_t Val = N->getSExtValue();
1286 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1289 def LUiORiPred : PatLeaf<(imm), [{
1290 int64_t SVal = N->getSExtValue();
1291 return isInt<32>(SVal) && (SVal & 0xffff);
1294 // Mips Address Mode! SDNode frameindex could possibly be a match
1295 // since load and store instructions from stack used it.
1297 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1300 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1303 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1305 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1306 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1308 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1310 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1313 //===----------------------------------------------------------------------===//
1314 // Instructions specific format
1315 //===----------------------------------------------------------------------===//
1317 // Arithmetic and logical instructions with 3 register operands.
1318 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1319 InstrItinClass Itin = NoItinerary,
1320 SDPatternOperator OpNode = null_frag>:
1321 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1322 !strconcat(opstr, "\t$rd, $rs, $rt"),
1323 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1324 let isCommutable = isComm;
1325 let isReMaterializable = 1;
1326 let TwoOperandAliasConstraint = "$rd = $rs";
1329 // Arithmetic and logical instructions with 2 register operands.
1330 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1331 InstrItinClass Itin = NoItinerary,
1332 SDPatternOperator imm_type = null_frag,
1333 SDPatternOperator OpNode = null_frag> :
1334 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1335 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1336 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1337 Itin, FrmI, opstr> {
1338 let isReMaterializable = 1;
1339 let TwoOperandAliasConstraint = "$rs = $rt";
1342 // Arithmetic Multiply ADD/SUB
1343 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1344 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1345 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1346 let Defs = [HI0, LO0];
1347 let Uses = [HI0, LO0];
1348 let isCommutable = isComm;
1352 class LogicNOR<string opstr, RegisterOperand RO>:
1353 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1354 !strconcat(opstr, "\t$rd, $rs, $rt"),
1355 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1356 let isCommutable = 1;
1360 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1361 RegisterOperand RO, InstrItinClass itin,
1362 SDPatternOperator OpNode = null_frag,
1363 SDPatternOperator PF = null_frag> :
1364 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1365 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1366 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1367 let TwoOperandAliasConstraint = "$rt = $rd";
1370 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1371 SDPatternOperator OpNode = null_frag>:
1372 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1373 !strconcat(opstr, "\t$rd, $rt, $rs"),
1374 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1377 // Load Upper Immediate
1378 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1379 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1380 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1381 let hasSideEffects = 0;
1382 let isReMaterializable = 1;
1385 // Memory Load/Store
1386 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1387 SDPatternOperator OpNode = null_frag,
1388 InstrItinClass Itin = NoItinerary,
1389 ComplexPattern Addr = addr> :
1390 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1391 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1392 let DecoderMethod = "DecodeMem";
1393 let canFoldAsLoad = 1;
1394 string BaseOpcode = opstr;
1398 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1399 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1400 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1402 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1403 SDPatternOperator OpNode = null_frag,
1404 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1405 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1406 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1407 let DecoderMethod = "DecodeMem";
1408 string BaseOpcode = opstr;
1412 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1413 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1414 DAGOperand MO = mem> :
1415 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1417 // Load/Store Left/Right
1418 let canFoldAsLoad = 1 in
1419 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1420 InstrItinClass Itin> :
1421 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1422 !strconcat(opstr, "\t$rt, $addr"),
1423 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1424 let DecoderMethod = "DecodeMem";
1425 string Constraints = "$src = $rt";
1426 let BaseOpcode = opstr;
1429 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1430 InstrItinClass Itin> :
1431 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1432 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1433 let DecoderMethod = "DecodeMem";
1434 let BaseOpcode = opstr;
1438 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1439 SDPatternOperator OpNode= null_frag> :
1440 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1441 !strconcat(opstr, "\t$rt, $addr"),
1442 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1443 let DecoderMethod = "DecodeFMem2";
1447 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1448 SDPatternOperator OpNode= null_frag> :
1449 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1450 !strconcat(opstr, "\t$rt, $addr"),
1451 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1452 let DecoderMethod = "DecodeFMem2";
1457 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1458 SDPatternOperator OpNode= null_frag> :
1459 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1460 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1461 let DecoderMethod = "DecodeFMem3";
1465 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1466 SDPatternOperator OpNode= null_frag> :
1467 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1468 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1469 let DecoderMethod = "DecodeFMem3";
1473 // Conditional Branch
1474 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1475 RegisterOperand RO> :
1476 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1477 !strconcat(opstr, "\t$rs, $rt, $offset"),
1478 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1481 let isTerminator = 1;
1482 let hasDelaySlot = 1;
1487 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1488 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1489 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1491 let isTerminator = 1;
1492 let hasDelaySlot = 1;
1497 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1498 RegisterOperand RO> :
1499 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1500 !strconcat(opstr, "\t$rs, $offset"),
1501 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1504 let isTerminator = 1;
1505 let hasDelaySlot = 1;
1510 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1511 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1512 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1514 let isTerminator = 1;
1515 let hasDelaySlot = 1;
1521 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1522 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1523 !strconcat(opstr, "\t$rd, $rs, $rt"),
1524 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1525 II_SLT_SLTU, FrmR, opstr>;
1527 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1528 RegisterOperand RO>:
1529 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1530 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1531 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1532 II_SLTI_SLTIU, FrmI, opstr>;
1535 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1536 SDPatternOperator targetoperator, string bopstr> :
1537 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1538 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1541 let hasDelaySlot = 1;
1542 let DecoderMethod = "DecodeJumpTarget";
1547 // Unconditional branch
1548 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1549 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1550 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1552 let isTerminator = 1;
1554 let hasDelaySlot = 1;
1555 let AdditionalPredicates = [RelocPIC];
1560 // Base class for indirect branch and return instruction classes.
1561 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1562 class JumpFR<string opstr, RegisterOperand RO,
1563 SDPatternOperator operator = null_frag>:
1564 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1568 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1570 let isIndirectBranch = 1;
1573 // Jump and Link (Call)
1574 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1575 class JumpLink<string opstr, DAGOperand opnd> :
1576 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1577 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1578 let DecoderMethod = "DecodeJumpTarget";
1581 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1582 Register RetReg, RegisterOperand ResRO = RO>:
1583 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1584 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1585 let hasPostISelHook = 1;
1588 class JumpLinkReg<string opstr, RegisterOperand RO>:
1589 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1590 [], II_JALR, FrmR, opstr> {
1591 let hasPostISelHook = 1;
1594 class BGEZAL_FT<string opstr, DAGOperand opnd,
1595 RegisterOperand RO> :
1596 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1597 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1598 let hasDelaySlot = 1;
1603 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1604 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1605 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1606 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1607 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1609 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1610 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1611 PseudoInstExpansion<(JumpInst RO:$rs)> {
1612 let hasPostISelHook = 1;
1616 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1617 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1618 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1620 let isTerminator = 1;
1622 let hasDelaySlot = 1;
1629 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1630 InstSE<(outs), (ins ImmOp:$code_),
1631 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1633 class BRK_FT<string opstr> :
1634 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1635 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1639 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1640 InstSE<(outs), (ins),
1641 opstr, [], itin, FrmOther, opstr>;
1644 class WAIT_FT<string opstr> :
1645 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1649 class DEI_FT<string opstr, RegisterOperand RO,
1650 InstrItinClass itin = NoItinerary> :
1651 InstSE<(outs RO:$rt), (ins),
1652 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1655 let hasSideEffects = 1 in
1656 class SYNC_FT<string opstr> :
1657 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1658 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1660 class SYNCI_FT<string opstr, DAGOperand MO> :
1661 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1662 II_SYNCI, FrmOther, opstr> {
1663 let hasSideEffects = 1;
1664 let DecoderMethod = "DecodeSyncI";
1667 let hasSideEffects = 1, isCTI = 1 in {
1668 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1669 InstrItinClass itin = NoItinerary> :
1670 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1671 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1673 class TEQI_FT<string opstr, RegisterOperand RO,
1674 InstrItinClass itin = NoItinerary> :
1675 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1676 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1680 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1681 list<Register> DefRegs> :
1682 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1683 itin, FrmR, opstr> {
1684 let isCommutable = 1;
1686 let hasSideEffects = 0;
1689 // Pseudo multiply/divide instruction with explicit accumulator register
1691 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1692 SDPatternOperator OpNode, InstrItinClass Itin,
1693 bit IsComm = 1, bit HasSideEffects = 0,
1694 bit UsesCustomInserter = 0> :
1695 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1696 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1697 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1698 let isCommutable = IsComm;
1699 let hasSideEffects = HasSideEffects;
1700 let usesCustomInserter = UsesCustomInserter;
1703 // Pseudo multiply add/sub instruction with explicit accumulator register
1705 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1706 InstrItinClass itin>
1707 : PseudoSE<(outs ACC64:$ac),
1708 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1710 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1712 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1713 string Constraints = "$acin = $ac";
1716 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1717 list<Register> DefRegs> :
1718 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1719 [], itin, FrmR, opstr> {
1724 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1725 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1726 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1728 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1729 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1731 let Uses = [UseReg];
1732 let hasSideEffects = 0;
1736 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1737 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1738 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1741 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1742 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1745 let hasSideEffects = 0;
1749 class EffectiveAddress<string opstr, RegisterOperand RO> :
1750 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1751 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1752 !strconcat(opstr, "_lea")> {
1753 let isCodeGenOnly = 1;
1754 let hasNoSchedulingInfo = 1;
1755 let DecoderMethod = "DecodeMem";
1758 // Count Leading Ones/Zeros in Word
1759 class CountLeading0<string opstr, RegisterOperand RO,
1760 InstrItinClass itin = NoItinerary>:
1761 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1762 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1764 class CountLeading1<string opstr, RegisterOperand RO,
1765 InstrItinClass itin = NoItinerary>:
1766 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1767 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1769 // Sign Extend in Register.
1770 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1771 InstrItinClass itin> :
1772 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1773 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1776 class SubwordSwap<string opstr, RegisterOperand RO,
1777 InstrItinClass itin = NoItinerary>:
1778 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1780 let hasSideEffects = 0;
1784 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1785 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1786 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1789 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1790 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1791 SDPatternOperator Op = null_frag> :
1792 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1793 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1794 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1797 // 'ins' and its' 64 bit variants are matched by C++ code.
1798 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1799 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1800 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1801 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1802 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1804 II_INS, FrmR, opstr> {
1805 let Constraints = "$src = $rt";
1808 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1809 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1810 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1811 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
1812 let hasNoSchedulingInfo = 1;
1815 class Atomic2OpsPostRA<RegisterClass RC> :
1816 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1821 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1822 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1823 RC:$shiftamnt), []>;
1825 // Atomic Compare & Swap.
1826 // Atomic compare and swap is lowered into two stages. The first stage happens
1827 // during ISelLowering, which produces the PostRA version of this instruction.
1828 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1829 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1830 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
1831 let hasNoSchedulingInfo = 1;
1834 class AtomicCmpSwapPostRA<RegisterClass RC> :
1835 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1840 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1841 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1842 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1847 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1848 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1849 [], II_LL, FrmI, opstr> {
1850 let DecoderMethod = "DecodeMem";
1854 class SCBase<string opstr, RegisterOperand RO> :
1855 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1856 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1857 let DecoderMethod = "DecodeMem";
1859 let Constraints = "$rt = $dst";
1862 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1863 InstrItinClass itin> :
1864 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1865 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1866 let BaseOpcode = asmstr;
1869 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1870 InstrItinClass itin> :
1871 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1872 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1873 let BaseOpcode = asmstr;
1876 class TrapBase<Instruction RealInst>
1877 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1878 PseudoInstExpansion<(RealInst 0, 0)> {
1881 let hasSideEffects = 1;
1883 let isCodeGenOnly = 1;
1886 //===----------------------------------------------------------------------===//
1887 // Pseudo instructions
1888 //===----------------------------------------------------------------------===//
1891 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1892 let hasDelaySlot=1 in
1893 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1895 let hasSideEffects=1 in
1896 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1899 let Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
1900 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1901 [(callseq_start timm:$amt1, timm:$amt2)]>;
1902 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1903 [(callseq_end timm:$amt1, timm:$amt2)]>;
1906 let usesCustomInserter = 1 in {
1907 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_i8, GPR32>;
1908 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_i16, GPR32>;
1909 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_i32, GPR32>;
1910 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_i8, GPR32>;
1911 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_i16, GPR32>;
1912 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_i32, GPR32>;
1913 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_i8, GPR32>;
1914 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_i16, GPR32>;
1915 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_i32, GPR32>;
1916 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_i8, GPR32>;
1917 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_i16, GPR32>;
1918 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_i32, GPR32>;
1919 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_i8, GPR32>;
1920 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_i16, GPR32>;
1921 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_i32, GPR32>;
1922 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_i8, GPR32>;
1923 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_i16, GPR32>;
1924 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_i32, GPR32>;
1926 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_i8, GPR32>;
1927 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_i16, GPR32>;
1928 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_i32, GPR32>;
1930 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_i8, GPR32>;
1931 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_i16, GPR32>;
1932 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_i32, GPR32>;
1934 def ATOMIC_LOAD_MIN_I8 : Atomic2Ops<atomic_load_min_i8, GPR32>;
1935 def ATOMIC_LOAD_MIN_I16 : Atomic2Ops<atomic_load_min_i16, GPR32>;
1936 def ATOMIC_LOAD_MIN_I32 : Atomic2Ops<atomic_load_min_i32, GPR32>;
1937 def ATOMIC_LOAD_MAX_I8 : Atomic2Ops<atomic_load_max_i8, GPR32>;
1938 def ATOMIC_LOAD_MAX_I16 : Atomic2Ops<atomic_load_max_i16, GPR32>;
1939 def ATOMIC_LOAD_MAX_I32 : Atomic2Ops<atomic_load_max_i32, GPR32>;
1940 def ATOMIC_LOAD_UMIN_I8 : Atomic2Ops<atomic_load_umin_i8, GPR32>;
1941 def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops<atomic_load_umin_i16, GPR32>;
1942 def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops<atomic_load_umin_i32, GPR32>;
1943 def ATOMIC_LOAD_UMAX_I8 : Atomic2Ops<atomic_load_umax_i8, GPR32>;
1944 def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops<atomic_load_umax_i16, GPR32>;
1945 def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops<atomic_load_umax_i32, GPR32>;
1948 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1949 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1950 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1951 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1952 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1953 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1954 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1955 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1956 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1957 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1958 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1959 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1960 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1961 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1962 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1963 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1964 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1965 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1967 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1968 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1969 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1971 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1972 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1973 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
1975 def ATOMIC_LOAD_MIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1976 def ATOMIC_LOAD_MIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1977 def ATOMIC_LOAD_MIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1978 def ATOMIC_LOAD_MAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1979 def ATOMIC_LOAD_MAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1980 def ATOMIC_LOAD_MAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1981 def ATOMIC_LOAD_UMIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1982 def ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1983 def ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1984 def ATOMIC_LOAD_UMAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1985 def ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1986 def ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1988 /// Pseudo instructions for loading and storing accumulator registers.
1989 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1990 def LOAD_ACC64 : Load<"", ACC64>;
1991 def STORE_ACC64 : Store<"", ACC64>;
1994 // We need these two pseudo instructions to avoid offset calculation for long
1995 // branches. See the comment in file MipsLongBranch.cpp for detailed
1998 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
1999 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
2000 (ins brtarget:$tgt, brtarget:$baltgt), []> {
2001 bit hasNoSchedulingInfo = 1;
2003 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
2004 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2005 (ins brtarget:$tgt), []> {
2006 bit hasNoSchedulingInfo = 1;
2009 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2010 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2011 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
2012 bit hasNoSchedulingInfo = 1;
2014 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2015 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2016 (ins GPR32Opnd:$src, brtarget:$tgt), []> {
2017 bit hasNoSchedulingInfo = 1;
2020 //===----------------------------------------------------------------------===//
2021 // Instruction definition
2022 //===----------------------------------------------------------------------===//
2023 //===----------------------------------------------------------------------===//
2024 // MipsI Instructions
2025 //===----------------------------------------------------------------------===//
2027 /// Arithmetic Instructions (ALU Immediate)
2028 let AdditionalPredicates = [NotInMicroMips] in {
2029 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2030 II_ADDIU, imm32SExt16, add>,
2031 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2033 def ANDi : MMRel, StdMMR6Rel,
2034 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, imm32ZExt16, and>,
2035 ADDI_FM<0xc>, ISA_MIPS1;
2036 def ORi : MMRel, StdMMR6Rel,
2037 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, imm32ZExt16, or>,
2038 ADDI_FM<0xd>, ISA_MIPS1;
2039 def XORi : MMRel, StdMMR6Rel,
2040 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, imm32ZExt16, xor>,
2041 ADDI_FM<0xe>, ISA_MIPS1;
2042 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2043 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2044 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2045 SLTI_FM<0xa>, ISA_MIPS1;
2046 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2047 SLTI_FM<0xb>, ISA_MIPS1;
2049 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2052 /// Arithmetic Instructions (3-Operand, R-Type)
2053 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2054 ADD_FM<0, 0x21>, ISA_MIPS1;
2055 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2056 ADD_FM<0, 0x23>, ISA_MIPS1;
2058 let Defs = [HI0, LO0] in
2059 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2060 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2062 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2063 ADD_FM<0, 0x20>, ISA_MIPS1;
2064 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2065 ADD_FM<0, 0x22>, ISA_MIPS1;
2067 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2069 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2071 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2072 ADD_FM<0, 0x24>, ISA_MIPS1;
2073 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2074 ADD_FM<0, 0x25>, ISA_MIPS1;
2075 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2076 ADD_FM<0, 0x26>, ISA_MIPS1;
2077 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2081 let AdditionalPredicates = [NotInMicroMips] in {
2082 /// Shift Instructions
2083 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, mshl_32,
2084 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2085 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, msrl_32,
2086 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2087 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, msra_32,
2088 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2089 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, mshl_32>,
2090 SRLV_FM<4, 0>, ISA_MIPS1;
2091 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, msrl_32>,
2092 SRLV_FM<6, 0>, ISA_MIPS1;
2093 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, msra_32>,
2094 SRLV_FM<7, 0>, ISA_MIPS1;
2096 // Rotate Instructions
2097 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2099 SRA_FM<2, 1>, ISA_MIPS32R2;
2100 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2101 SRLV_FM<6, 1>, ISA_MIPS32R2;
2104 /// Load and Store Instructions
2106 let AdditionalPredicates = [NotInMicroMips] in {
2107 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2108 LW_FM<0x20>, ISA_MIPS1;
2109 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2110 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2111 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2112 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2113 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2114 MMRel, LW_FM<0x25>, ISA_MIPS1;
2115 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2116 LW_FM<0x23>, ISA_MIPS1;
2117 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2118 LW_FM<0x28>, ISA_MIPS1;
2119 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2121 def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>,
2122 MMRel, LW_FM<0x2b>, ISA_MIPS1;
2125 /// load/store left/right
2126 let AdditionalPredicates = [NotInMicroMips] in {
2127 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2128 ISA_MIPS1_NOT_32R6_64R6;
2129 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2130 ISA_MIPS1_NOT_32R6_64R6;
2131 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2132 ISA_MIPS1_NOT_32R6_64R6;
2133 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2134 ISA_MIPS1_NOT_32R6_64R6;
2136 // COP2 Memory Instructions
2137 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2138 ISA_MIPS1_NOT_32R6_64R6;
2139 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2140 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2141 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2142 ISA_MIPS2_NOT_32R6_64R6;
2143 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2144 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2146 // COP3 Memory Instructions
2147 let DecoderNamespace = "COP3_" in {
2148 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2149 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2150 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2151 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2152 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2153 ISA_MIPS2, NOT_ASE_CNMIPS;
2154 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2155 ISA_MIPS2, NOT_ASE_CNMIPS;
2158 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2159 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2163 let AdditionalPredicates = [NotInMicroMips] in {
2164 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2166 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2168 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2170 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2172 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2174 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2177 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2178 ISA_MIPS2_NOT_32R6_64R6;
2179 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2180 ISA_MIPS2_NOT_32R6_64R6;
2181 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2182 ISA_MIPS2_NOT_32R6_64R6;
2183 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2184 ISA_MIPS2_NOT_32R6_64R6;
2185 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2186 ISA_MIPS2_NOT_32R6_64R6;
2187 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2188 ISA_MIPS2_NOT_32R6_64R6;
2191 let AdditionalPredicates = [NotInMicroMips] in {
2192 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2193 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2195 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2196 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2197 ISA_MIPS32_NOT_32R6_64R6;
2199 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2200 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2202 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2204 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2206 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2209 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2212 let AdditionalPredicates = [NotInMicroMips] in {
2213 /// Load-linked, Store-conditional
2214 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2215 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2217 /// Jump and Branch Instructions
2218 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2219 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2220 IsBranch, ISA_MIPS1;
2222 let AdditionalPredicates = [NotInMicroMips] in {
2223 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>,
2224 ISA_MIPS1_NOT_32R6_64R6;
2225 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2227 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2228 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2229 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2231 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2232 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2233 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2234 BGEZ_FM<1, 1>, ISA_MIPS1;
2235 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2236 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2237 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2238 BGEZ_FM<7, 0>, ISA_MIPS1;
2239 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2240 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2241 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2242 BGEZ_FM<6, 0>, ISA_MIPS1;
2243 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2244 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2245 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2246 BGEZ_FM<1, 0>, ISA_MIPS1;
2247 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2248 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2249 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2251 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2255 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2256 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2257 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2260 let AdditionalPredicates = [NotInMicroMips] in {
2261 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2262 ISA_MIPS32_NOT_32R6_64R6;
2263 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2264 ISA_MIPS1_NOT_32R6_64R6;
2265 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2266 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2267 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2268 ISA_MIPS1_NOT_32R6_64R6;
2269 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2270 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2271 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2273 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2274 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2276 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2277 NoIndirectJumpGuards] in
2278 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2280 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2281 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2282 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2283 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2284 II_IndirectBranchPseudo>,
2285 PseudoInstExpansion<(JumpInst RO:$rs)> {
2288 let hasDelaySlot = 1;
2290 let isIndirectBranch = 1;
2294 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2295 NoIndirectJumpGuards] in
2296 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2297 ISA_MIPS1_NOT_32R6_64R6;
2299 // Return instructions are matched as a RetRA instruction, then are expanded
2300 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2301 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2303 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2304 [], II_ReturnPseudo> {
2305 let isTerminator = 1;
2307 let hasDelaySlot = 1;
2309 let isCodeGenOnly = 1;
2311 let hasExtraSrcRegAllocReq = 1;
2315 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2317 // Exception handling related node and instructions.
2318 // The conversion sequence is:
2319 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2320 // MIPSeh_return -> (stack change + indirect branch)
2322 // MIPSeh_return takes the place of regular return instruction
2323 // but takes two arguments (V1, V0) which are used for storing
2324 // the offset and return address respectively.
2325 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2327 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2328 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2330 let Uses = [V0, V1], isTerminator = 1, isReturn = 1,
2331 isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
2332 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2333 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2334 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
2335 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2338 /// Multiply and Divide Instructions.
2339 let AdditionalPredicates = [NotInMicroMips] in {
2340 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2341 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2342 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2343 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2344 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2345 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2346 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2347 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2348 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2349 ISA_MIPS1_NOT_32R6_64R6;
2350 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2351 ISA_MIPS1_NOT_32R6_64R6;
2352 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2353 ISA_MIPS1_NOT_32R6_64R6;
2354 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2355 ISA_MIPS1_NOT_32R6_64R6;
2357 /// Sign Ext In Register Instructions.
2358 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2359 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2360 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2361 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2364 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2365 ISA_MIPS32_NOT_32R6_64R6;
2366 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2367 ISA_MIPS32_NOT_32R6_64R6;
2369 /// Word Swap Bytes Within Halfwords
2370 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2374 def NOP : PseudoSE<(outs), (ins), []>,
2375 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2377 // FrameIndexes are legalized when they are operands from load/store
2378 // instructions. The same not happens for stack address copies, so an
2379 // add op with mem ComplexPattern is used and the stack address copy
2380 // can be matched. It's similar to Sparc LEA_ADDRi
2381 let AdditionalPredicates = [NotInMicroMips] in
2382 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>,
2386 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2387 ISA_MIPS32_NOT_32R6_64R6;
2388 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2389 ISA_MIPS32_NOT_32R6_64R6;
2390 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2391 ISA_MIPS32_NOT_32R6_64R6;
2392 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2393 ISA_MIPS32_NOT_32R6_64R6;
2396 let AdditionalPredicates = [NotDSP] in {
2397 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2398 ISA_MIPS1_NOT_32R6_64R6;
2399 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2400 ISA_MIPS1_NOT_32R6_64R6;
2401 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2402 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2403 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2404 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2405 ISA_MIPS32_NOT_32R6_64R6;
2406 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2407 ISA_MIPS32_NOT_32R6_64R6;
2408 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2409 ISA_MIPS32_NOT_32R6_64R6;
2410 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2411 ISA_MIPS32_NOT_32R6_64R6;
2414 let AdditionalPredicates = [NotInMicroMips] in {
2415 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2416 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2417 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2418 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2419 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2420 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2421 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2422 immZExt5, immZExt5Plus1, MipsExt>,
2423 EXT_FM<0>, ISA_MIPS32R2;
2424 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2425 uimm5_inssize_plus1, immZExt5,
2427 EXT_FM<4>, ISA_MIPS32R2;
2429 /// Move Control Registers From/To CPU Registers
2430 let AdditionalPredicates = [NotInMicroMips] in {
2431 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2432 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2433 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2434 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2435 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2436 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2437 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2438 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2441 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2442 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2443 let AdditionalPredicates = [NotInMicroMips] in {
2444 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2446 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2449 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2453 // JR_HB and JALR_HB are defined here using the new style naming
2454 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2455 // and because of that it doesn't follow the naming convention of the
2456 // rest of the file. To avoid a mixture of old vs new style, the new
2457 // style was chosen.
2458 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2459 dag OutOperandList = (outs);
2460 dag InOperandList = (ins GPROpnd:$rs);
2461 string AsmString = !strconcat(instr_asm, "\t$rs");
2462 list<dag> Pattern = [];
2465 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2466 dag OutOperandList = (outs GPROpnd:$rd);
2467 dag InOperandList = (ins GPROpnd:$rs);
2468 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2469 list<dag> Pattern = [];
2472 class JR_HB_DESC<RegisterOperand RO> :
2473 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2475 let isIndirectBranch=1;
2482 class JALR_HB_DESC<RegisterOperand RO> :
2483 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2485 let isIndirectBranch=1;
2490 class JR_HB_ENC : JR_HB_FM<8>;
2491 class JALR_HB_ENC : JALR_HB_FM<9>;
2493 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2494 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2496 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2497 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2500 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2501 UseIndirectJumpsHazard] in {
2502 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2503 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2504 ISA_MIPS32R2_NOT_32R6_64R6;
2507 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2508 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2509 let AdditionalPredicates = [NotInMicroMips] in {
2510 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2511 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2512 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2513 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2515 class CacheOp<string instr_asm, Operand MemOpnd,
2516 InstrItinClass itin = NoItinerary> :
2517 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2518 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2520 let DecoderMethod = "DecodeCacheOp";
2523 let AdditionalPredicates = [NotInMicroMips] in {
2524 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2525 INSN_MIPS3_32_NOT_32R6_64R6;
2526 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2527 INSN_MIPS3_32_NOT_32R6_64R6;
2529 // FIXME: We are missing the prefx instruction.
2530 def ROL : MipsAsmPseudoInst<(outs),
2531 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2532 "rol\t$rs, $rt, $rd">;
2533 def ROLImm : MipsAsmPseudoInst<(outs),
2534 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2535 "rol\t$rs, $rt, $imm">;
2536 def : MipsInstAlias<"rol $rd, $rs",
2537 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2538 def : MipsInstAlias<"rol $rd, $imm",
2539 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2541 def ROR : MipsAsmPseudoInst<(outs),
2542 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2543 "ror\t$rs, $rt, $rd">;
2544 def RORImm : MipsAsmPseudoInst<(outs),
2545 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2546 "ror\t$rs, $rt, $imm">;
2547 def : MipsInstAlias<"ror $rd, $rs",
2548 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2549 def : MipsInstAlias<"ror $rd, $imm",
2550 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2552 def DROL : MipsAsmPseudoInst<(outs),
2553 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2554 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2555 def DROLImm : MipsAsmPseudoInst<(outs),
2556 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2557 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2558 def : MipsInstAlias<"drol $rd, $rs",
2559 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2561 def : MipsInstAlias<"drol $rd, $imm",
2562 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
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>,
2574 def : MipsInstAlias<"dror $rd, $imm",
2575 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2578 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2581 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2582 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2583 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2585 def : MipsInstAlias<"seq $rd, $rs",
2586 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2589 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2590 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2591 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2593 def : MipsInstAlias<"seq $rd, $imm",
2594 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2597 def SNEMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2598 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2599 "sne $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2601 def : MipsInstAlias<"sne $rd, $rs",
2602 (SNEMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2605 def SNEIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2606 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2607 "sne $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2609 def : MipsInstAlias<"sne $rd, $imm",
2610 (SNEIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2613 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2614 simm32_relaxed:$imm),
2615 "mul\t$rd, $rs, $imm">,
2616 ISA_MIPS1_NOT_32R6_64R6;
2617 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2619 "mulo\t$rd, $rs, $rt">,
2620 ISA_MIPS1_NOT_32R6_64R6;
2621 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2623 "mulou\t$rd, $rs, $rt">,
2624 ISA_MIPS1_NOT_32R6_64R6;
2626 // Virtualization ASE
2627 class HYPCALL_FT<string opstr> :
2628 InstSE<(outs), (ins uimm10:$code_),
2629 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2630 let BaseOpcode = opstr;
2633 let AdditionalPredicates = [NotInMicroMips] in {
2634 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2635 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2636 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2637 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2638 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2639 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2640 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2641 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2642 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2643 ISA_MIPS32R5, ASE_VIRT;
2644 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2645 ISA_MIPS32R5, ASE_VIRT;
2646 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2647 ISA_MIPS32R5, ASE_VIRT;
2648 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2649 ISA_MIPS32R5, ASE_VIRT;
2650 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2651 ISA_MIPS32R5, ASE_VIRT;
2652 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2653 ISA_MIPS32R5, ASE_VIRT;
2654 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2655 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2658 //===----------------------------------------------------------------------===//
2659 // Instruction aliases
2660 //===----------------------------------------------------------------------===//
2662 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2664 RegisterOperand RO = GPR32Opnd,
2665 Operand Imm = simm32_relaxed> {
2666 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2670 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2676 let AdditionalPredicates = [NotInMicroMips] in {
2677 def : MipsInstAlias<"move $dst, $src",
2678 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2680 def : MipsInstAlias<"move $dst, $src",
2681 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2684 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2685 ISA_MIPS1_NOT_32R6_64R6;
2687 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2689 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2691 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2694 def : MipsInstAlias<"neg $rt, $rs",
2695 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2696 def : MipsInstAlias<"neg $rt",
2697 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2698 def : MipsInstAlias<"negu $rt, $rs",
2699 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2700 def : MipsInstAlias<"negu $rt",
2701 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2703 def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2704 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2705 "sge\t$rd, $rs, $rt">, ISA_MIPS1;
2706 def : MipsInstAlias<"sge $rs, $rt",
2707 (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2709 def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2710 (ins GPR32Opnd:$rs, simm32:$imm),
2711 "sge\t$rd, $rs, $imm">, GPR_32;
2712 def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
2717 def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2718 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2719 "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
2720 def : MipsInstAlias<"sgeu $rs, $rt",
2721 (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2723 def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2724 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2725 "sgeu\t$rd, $rs, $imm">, GPR_32;
2726 def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
2728 uimm32_coerced:$imm), 0>,
2731 def : MipsInstAlias<
2732 "sgt $rd, $rs, $rt",
2733 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2734 def : MipsInstAlias<
2736 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2738 def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2739 (ins GPR32Opnd:$rs, simm32:$imm),
2740 "sgt\t$rd, $rs, $imm">, GPR_32;
2741 def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
2745 def : MipsInstAlias<
2746 "sgtu $rd, $rs, $rt",
2747 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2748 def : MipsInstAlias<
2750 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2752 def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2753 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2754 "sgtu\t$rd, $rs, $imm">, GPR_32;
2755 def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
2757 uimm32_coerced:$imm), 0>,
2760 def SLE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2761 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2762 "sle\t$rd, $rs, $rt">, ISA_MIPS1;
2763 def : MipsInstAlias<"sle $rs, $rt",
2764 (SLE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2766 def SLEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2767 (ins GPR32Opnd:$rs, simm32:$imm),
2768 "sle\t$rd, $rs, $imm">, GPR_32;
2769 def : MipsInstAlias<"sle $rs, $imm", (SLEImm GPR32Opnd:$rs,
2774 def SLEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2775 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2776 "sleu\t$rd, $rs, $rt">, ISA_MIPS1;
2777 def : MipsInstAlias<"sleu $rs, $rt",
2778 (SLEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2780 def SLEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2781 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2782 "sleu\t$rd, $rs, $imm">, GPR_32;
2783 def : MipsInstAlias<"sleu $rs, $imm", (SLEUImm GPR32Opnd:$rs,
2785 uimm32_coerced:$imm), 0>,
2788 def : MipsInstAlias<
2790 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2791 def : MipsInstAlias<
2793 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2795 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2797 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>,
2798 ISA_MIPS1_NOT_32R6_64R6;
2800 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2802 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2804 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2806 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2808 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2810 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2812 def : MipsInstAlias<"mfgc0 $rt, $rd",
2813 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2814 ISA_MIPS32R5, ASE_VIRT;
2815 def : MipsInstAlias<"mtgc0 $rt, $rd",
2816 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2817 ISA_MIPS32R5, ASE_VIRT;
2818 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2819 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2820 ISA_MIPS32R5, ASE_VIRT;
2821 def : MipsInstAlias<"mthgc0 $rt, $rd",
2822 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2823 ISA_MIPS32R5, ASE_VIRT;
2824 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2826 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2828 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2830 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2833 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2836 def : MipsInstAlias<"bnez $rs,$offset",
2837 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2839 def : MipsInstAlias<"bnezl $rs, $offset",
2840 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2842 def : MipsInstAlias<"beqz $rs,$offset",
2843 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2845 def : MipsInstAlias<"beqzl $rs, $offset",
2846 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2849 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2851 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2852 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2853 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2854 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2856 def : MipsInstAlias<"teq $rs, $rt",
2857 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2858 def : MipsInstAlias<"tge $rs, $rt",
2859 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2860 def : MipsInstAlias<"tgeu $rs, $rt",
2861 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2862 def : MipsInstAlias<"tlt $rs, $rt",
2863 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2864 def : MipsInstAlias<"tltu $rs, $rt",
2865 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2866 def : MipsInstAlias<"tne $rs, $rt",
2867 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2868 def : MipsInstAlias<"rdhwr $rt, $rs",
2869 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2872 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2873 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2874 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2875 def : MipsInstAlias<"sub $rs, $imm",
2876 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2877 0>, ISA_MIPS1_NOT_32R6_64R6;
2878 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2879 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2880 InvertedImOperand:$imm), 0>;
2881 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2882 InvertedImOperand:$imm), 0>;
2883 let AdditionalPredicates = [NotInMicroMips] in {
2884 def : MipsInstAlias<"sll $rd, $rt, $rs",
2885 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2886 def : MipsInstAlias<"sra $rd, $rt, $rs",
2887 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2888 def : MipsInstAlias<"srl $rd, $rt, $rs",
2889 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2890 def : MipsInstAlias<"sll $rd, $rt",
2891 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2892 def : MipsInstAlias<"sra $rd, $rt",
2893 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2894 def : MipsInstAlias<"srl $rd, $rt",
2895 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2896 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2898 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2901 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2902 let AdditionalPredicates = [NotInMicroMips] in
2903 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2905 def : MipsInstAlias<"mulo $rs, $rt",
2906 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2907 ISA_MIPS1_NOT_32R6_64R6;
2908 def : MipsInstAlias<"mulou $rs, $rt",
2909 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2910 ISA_MIPS1_NOT_32R6_64R6;
2912 let AdditionalPredicates = [NotInMicroMips] in
2913 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2915 //===----------------------------------------------------------------------===//
2916 // Assembler Pseudo Instructions
2917 //===----------------------------------------------------------------------===//
2919 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2921 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2922 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2923 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2924 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2926 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2927 RegisterOperand RO> :
2928 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2929 !strconcat(instr_asm, "\t$rt, $addr")> ;
2930 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2932 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2933 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2934 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2935 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2937 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2939 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2942 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2943 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2944 "nor\t$rs, $rt, $imm">;
2945 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2946 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2947 simm32_relaxed:$imm)>, GPR_32;
2949 let hasDelaySlot = 1, isCTI = 1 in {
2950 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2951 (ins imm64:$imm64, brtarget:$offset),
2952 "bne\t$rt, $imm64, $offset">;
2953 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2954 (ins imm64:$imm64, brtarget:$offset),
2955 "beq\t$rt, $imm64, $offset">;
2957 class CondBranchPseudo<string instr_asm> :
2958 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2960 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2963 def BLT : CondBranchPseudo<"blt">;
2964 def BLE : CondBranchPseudo<"ble">;
2965 def BGE : CondBranchPseudo<"bge">;
2966 def BGT : CondBranchPseudo<"bgt">;
2967 def BLTU : CondBranchPseudo<"bltu">;
2968 def BLEU : CondBranchPseudo<"bleu">;
2969 def BGEU : CondBranchPseudo<"bgeu">;
2970 def BGTU : CondBranchPseudo<"bgtu">;
2971 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2972 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2973 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2974 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2975 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2976 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2977 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2978 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2981 class CondBranchImmPseudo<string instr_asm> :
2982 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2983 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2985 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2986 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2988 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2989 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2990 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2991 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2992 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2993 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2994 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2995 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2996 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2997 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2998 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2999 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
3000 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
3001 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
3002 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
3003 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
3005 // FIXME: Predicates are removed because instructions are matched regardless of
3006 // predicates, because PredicateControl was not in the hierarchy. This was
3007 // done to emit more precise error message from expansion function.
3008 // Once the tablegen-erated errors are made better, this needs to be fixed and
3009 // predicates needs to be restored.
3011 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
3012 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3013 "div\t$rd, $rs, $rt">,
3014 ISA_MIPS1_NOT_32R6_64R6;
3015 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3016 (ins GPR32Opnd:$rs, simm32:$imm),
3017 "div\t$rd, $rs, $imm">,
3018 ISA_MIPS1_NOT_32R6_64R6;
3019 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3020 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3021 "divu\t$rd, $rs, $rt">,
3022 ISA_MIPS1_NOT_32R6_64R6;
3023 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3024 (ins GPR32Opnd:$rs, simm32:$imm),
3025 "divu\t$rd, $rs, $imm">,
3026 ISA_MIPS1_NOT_32R6_64R6;
3029 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
3031 ISA_MIPS1_NOT_32R6_64R6;
3032 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
3033 GPR32NonZeroOpnd:$rs,
3035 ISA_MIPS1_NOT_32R6_64R6;
3036 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3038 ISA_MIPS1_NOT_32R6_64R6;
3040 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
3042 ISA_MIPS1_NOT_32R6_64R6;
3043 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
3044 GPR32NonZeroOpnd:$rt,
3046 ISA_MIPS1_NOT_32R6_64R6;
3048 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3050 ISA_MIPS1_NOT_32R6_64R6;
3053 def : MipsInstAlias<"nal", (BLTZAL ZERO, 0), 1>, ISA_MIPS1_NOT_32R6_64R6;
3055 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3056 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3057 "rem\t$rd, $rs, $rt">,
3058 ISA_MIPS1_NOT_32R6_64R6;
3059 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3060 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3061 "rem\t$rd, $rs, $imm">,
3062 ISA_MIPS1_NOT_32R6_64R6;
3063 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3064 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3065 "remu\t$rd, $rs, $rt">,
3066 ISA_MIPS1_NOT_32R6_64R6;
3067 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3068 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3069 "remu\t$rd, $rs, $imm">,
3070 ISA_MIPS1_NOT_32R6_64R6;
3072 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3074 ISA_MIPS1_NOT_32R6_64R6;
3075 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3076 simm32_relaxed:$imm), 0>,
3077 ISA_MIPS1_NOT_32R6_64R6;
3078 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3080 ISA_MIPS1_NOT_32R6_64R6;
3081 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3082 simm32_relaxed:$imm), 0>,
3083 ISA_MIPS1_NOT_32R6_64R6;
3085 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3086 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3088 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3089 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3091 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3092 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3094 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3095 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3097 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3098 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3100 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3101 (ins mem_simm16:$addr), "ld $rt, $addr">,
3102 ISA_MIPS1_NOT_MIPS3;
3103 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3104 (ins mem_simm16:$addr), "sd $rt, $addr">,
3105 ISA_MIPS1_NOT_MIPS3;
3106 //===----------------------------------------------------------------------===//
3107 // Arbitrary patterns that map to one or more instructions
3108 //===----------------------------------------------------------------------===//
3110 // Load/store pattern templates.
3111 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3112 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3114 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3115 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3117 // Materialize constants.
3118 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3119 Instruction ADDiuOp, Instruction LUiOp,
3120 Instruction ORiOp> {
3122 // Constant synthesis previously relied on the ordering of the patterns below.
3123 // By making the predicates they use non-overlapping, the patterns were
3124 // reordered so that the effect of the newly introduced predicates can be
3127 // Arbitrary immediates
3128 def : MipsPat<(VT LUiORiPred:$imm),
3129 (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3131 // Bits 32-16 set, sign/zero extended.
3132 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3135 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3136 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3139 let AdditionalPredicates = [NotInMicroMips] in
3140 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3142 // Carry MipsPatterns
3143 let AdditionalPredicates = [NotInMicroMips] in {
3144 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3145 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3147 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3148 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3149 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3150 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3152 // Support multiplication for pre-Mips32 targets that don't have
3153 // the MUL instruction.
3154 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3155 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3156 ISA_MIPS1_NOT_32R6_64R6;
3159 def : MipsPat<(MipsSync (i32 immz)),
3160 (SYNC 0)>, ISA_MIPS2;
3163 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3164 (JAL texternalsym:$dst)>, ISA_MIPS1;
3165 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3166 // (JALR GPR32:$dst)>;
3169 let AdditionalPredicates = [NotInMicroMips] in {
3170 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3171 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3172 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3173 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3176 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3177 Register ZeroReg, RegisterOperand GPROpnd> {
3178 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3179 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3180 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3181 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3182 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3184 def : MipsPat<(MipsLo tglobaladdr:$in),
3185 (Addiu ZeroReg, tglobaladdr:$in)>;
3186 def : MipsPat<(MipsLo tblockaddress:$in),
3187 (Addiu ZeroReg, tblockaddress:$in)>;
3188 def : MipsPat<(MipsLo tjumptable:$in),
3189 (Addiu ZeroReg, tjumptable:$in)>;
3190 def : MipsPat<(MipsLo tconstpool:$in),
3191 (Addiu ZeroReg, tconstpool:$in)>;
3192 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3193 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3194 def : MipsPat<(MipsLo texternalsym:$in),
3195 (Addiu ZeroReg, texternalsym:$in)>;
3197 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3198 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3199 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3200 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3201 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3202 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3203 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3204 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3205 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3206 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3207 def : MipsPat<(add GPROpnd:$hi, (MipsLo texternalsym:$lo)),
3208 (Addiu GPROpnd:$hi, texternalsym:$lo)>;
3212 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3213 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3215 let AdditionalPredicates = [NotInMicroMips] in {
3216 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3218 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3219 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3222 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3226 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3227 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3228 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3229 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3231 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3232 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3233 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3234 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3235 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3236 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3238 // Mips does not have "not", so we expand our way
3239 def : MipsPat<(not GPR32:$in),
3240 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3244 let AdditionalPredicates = [NotInMicroMips] in {
3245 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3246 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3247 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3250 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3254 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3255 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3256 Instruction SLTiOp, Instruction SLTiuOp,
3258 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3259 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3260 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3261 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3263 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3264 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3265 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3266 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3267 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3268 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3269 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3270 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3271 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3272 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3273 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3274 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3276 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3277 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3278 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3279 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3281 def : MipsPat<(brcond RC:$cond, bb:$dst),
3282 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3284 let AdditionalPredicates = [NotInMicroMips] in {
3285 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3287 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3288 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3289 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3290 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3294 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3295 Instruction SLTuOp, Register ZEROReg> {
3296 def : MipsPat<(seteq RC:$lhs, 0),
3297 (SLTiuOp RC:$lhs, 1)>;
3298 def : MipsPat<(setne RC:$lhs, 0),
3299 (SLTuOp ZEROReg, RC:$lhs)>;
3300 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3301 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3302 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3303 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3306 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3307 Instruction SLTuOp> {
3308 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3309 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3310 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3311 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3314 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3315 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3316 (SLTOp RC:$rhs, RC:$lhs)>;
3317 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3318 (SLTuOp RC:$rhs, RC:$lhs)>;
3321 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3322 Instruction SLTuOp> {
3323 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3324 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3325 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3326 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3329 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3330 Instruction SLTiOp, Instruction SLTiuOp> {
3331 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3332 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3333 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3334 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3337 let AdditionalPredicates = [NotInMicroMips] in {
3338 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3339 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3340 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3341 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3342 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3345 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3348 // Load halfword/word patterns.
3349 let AdditionalPredicates = [NotInMicroMips] in {
3350 let AddedComplexity = 40 in {
3351 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3352 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3353 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3354 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3355 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3358 // Atomic load patterns.
3359 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3360 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3361 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3363 // Atomic store patterns.
3364 def : MipsPat<(atomic_store_8 GPR32:$v, addr:$a), (SB GPR32:$v, addr:$a)>,
3366 def : MipsPat<(atomic_store_16 GPR32:$v, addr:$a), (SH GPR32:$v, addr:$a)>,
3368 def : MipsPat<(atomic_store_32 GPR32:$v, addr:$a), (SW GPR32:$v, addr:$a)>,
3372 //===----------------------------------------------------------------------===//
3373 // Floating Point Support
3374 //===----------------------------------------------------------------------===//
3376 include "MipsInstrFPU.td"
3377 include "Mips64InstrInfo.td"
3378 include "MipsCondMov.td"
3380 include "Mips32r6InstrInfo.td"
3381 include "Mips64r6InstrInfo.td"
3386 include "Mips16InstrFormats.td"
3387 include "Mips16InstrInfo.td"
3390 include "MipsDSPInstrFormats.td"
3391 include "MipsDSPInstrInfo.td"
3394 include "MipsMSAInstrFormats.td"
3395 include "MipsMSAInstrInfo.td"
3398 include "MipsEVAInstrFormats.td"
3399 include "MipsEVAInstrInfo.td"
3402 include "MipsMTInstrFormats.td"
3403 include "MipsMTInstrInfo.td"
3406 include "MicroMipsInstrFormats.td"
3407 include "MicroMipsInstrInfo.td"
3408 include "MicroMipsInstrFPU.td"
3411 include "MicroMips32r6InstrFormats.td"
3412 include "MicroMips32r6InstrInfo.td"
3415 include "MicroMipsDSPInstrFormats.td"
3416 include "MicroMipsDSPInstrInfo.td"