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 //===----------------------------------------------------------------------===//
18 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
19 def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
23 def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
24 def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
25 def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
26 def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
27 SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
28 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
30 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
31 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
32 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
33 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
35 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
37 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
39 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
40 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
41 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
42 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
45 def SDTMipsLoadLR : SDTypeProfile<1, 2,
46 [SDTCisInt<0>, SDTCisPtrTy<1>,
50 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
51 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
55 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
56 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
58 // Hi and Lo nodes are used to handle global addresses. Used on
59 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
60 // static model. (nothing to do with Mips Registers Hi and Lo)
62 // Hi is the odd node out, on MIPS64 it can expand to either daddiu when
63 // using static relocations with 64 bit symbols, or lui when using 32 bit
65 def MipsHigher : SDNode<"MipsISD::Higher", SDTIntUnaryOp>;
66 def MipsHighest : SDNode<"MipsISD::Highest", SDTIntUnaryOp>;
67 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
68 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
70 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
72 // Hi node for accessing the GOT.
73 def MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>;
75 // Hi node for handling TLS offsets
76 def MipsTlsHi : SDNode<"MipsISD::TlsHi", SDTIntUnaryOp>;
79 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
82 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
83 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
85 def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
86 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
88 // These are target-independent nodes, but have target-specific formats.
89 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
90 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
91 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
92 [SDNPHasChain, SDNPSideEffect,
93 SDNPOptInGlue, SDNPOutGlue]>;
95 // Nodes used to extract LO/HI registers.
96 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
97 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
99 // Node used to insert 32-bit integers to LOHI register pair.
100 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
103 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
104 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
107 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
108 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
109 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
110 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
113 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
114 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
115 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
117 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
120 // Target constant nodes that are not part of any isel patterns and remain
121 // unchanged can cause instructions with illegal operands to be emitted.
122 // Wrapper node patterns give the instruction selector a chance to replace
123 // target constant nodes that would otherwise remain unchanged with ADDiu
124 // nodes. Without these wrapper node patterns, the following conditional move
125 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
127 // movn %got(d)($gp), %got(c)($gp), $4
128 // This instruction is illegal since movn can take only register operands.
130 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
132 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
134 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
135 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
136 def MipsCIns : SDNode<"MipsISD::CIns", SDT_Ext>;
138 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
139 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
140 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
141 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
143 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
144 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
145 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
147 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
148 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
149 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
150 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
151 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
152 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
153 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
155 //===----------------------------------------------------------------------===//
156 // Mips Instruction Predicate Definitions.
157 //===----------------------------------------------------------------------===//
158 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
159 AssemblerPredicate<"FeatureMips2">;
160 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
161 AssemblerPredicate<"FeatureMips3_32">;
162 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
163 AssemblerPredicate<"FeatureMips3_32r2">;
164 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
165 AssemblerPredicate<"FeatureMips3">;
166 def NotMips3 : Predicate<"!Subtarget->hasMips3()">,
167 AssemblerPredicate<"!FeatureMips3">;
168 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
169 AssemblerPredicate<"FeatureMips4_32">;
170 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
171 AssemblerPredicate<"!FeatureMips4_32">;
172 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
173 AssemblerPredicate<"FeatureMips4_32r2">;
174 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
175 AssemblerPredicate<"FeatureMips5_32r2">;
176 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
177 AssemblerPredicate<"FeatureMips32">;
178 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
179 AssemblerPredicate<"FeatureMips32r2">;
180 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
181 AssemblerPredicate<"FeatureMips32r5">;
182 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
183 AssemblerPredicate<"FeatureMips32r6">;
184 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
185 AssemblerPredicate<"!FeatureMips32r6">;
186 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
187 AssemblerPredicate<"FeatureGP64Bit">;
188 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
189 AssemblerPredicate<"!FeatureGP64Bit">;
190 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
191 AssemblerPredicate<"FeaturePTR64Bit">;
192 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
193 AssemblerPredicate<"!FeaturePTR64Bit">;
194 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
195 AssemblerPredicate<"FeatureMips64">;
196 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
197 AssemblerPredicate<"!FeatureMips64">;
198 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
199 AssemblerPredicate<"FeatureMips64r2">;
200 def HasMips64r5 : Predicate<"Subtarget->hasMips64r5()">,
201 AssemblerPredicate<"FeatureMips64r5">;
202 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
203 AssemblerPredicate<"FeatureMips64r6">;
204 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
205 AssemblerPredicate<"!FeatureMips64r6">;
206 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
207 AssemblerPredicate<"FeatureMips16">;
208 def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
209 AssemblerPredicate<"!FeatureMips16">;
210 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
211 AssemblerPredicate<"FeatureCnMips">;
212 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
213 AssemblerPredicate<"!FeatureCnMips">;
214 def HasCnMipsP : Predicate<"Subtarget->hasCnMipsP()">,
215 AssemblerPredicate<"FeatureCnMipsP">;
216 def NotCnMipsP : Predicate<"!Subtarget->hasCnMipsP()">,
217 AssemblerPredicate<"!FeatureCnMipsP">;
218 def IsSym32 : Predicate<"Subtarget->hasSym32()">,
219 AssemblerPredicate<"FeatureSym32">;
220 def IsSym64 : Predicate<"!Subtarget->hasSym32()">,
221 AssemblerPredicate<"!FeatureSym32">;
222 def IsN64 : Predicate<"Subtarget->isABI_N64()">;
223 def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">;
224 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
225 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
226 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
227 def UseAbs : Predicate<"Subtarget->inAbs2008Mode() ||"
228 "TM.Options.NoNaNsFPMath">;
229 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
230 AssemblerPredicate<"!FeatureMips16">;
231 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
232 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
233 AssemblerPredicate<"FeatureMicroMips">;
234 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
235 AssemblerPredicate<"!FeatureMicroMips">;
236 def IsLE : Predicate<"Subtarget->isLittle()">;
237 def IsBE : Predicate<"!Subtarget->isLittle()">;
238 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
239 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
240 def HasEVA : Predicate<"Subtarget->hasEVA()">,
241 AssemblerPredicate<"FeatureEVA">;
242 def HasMSA : Predicate<"Subtarget->hasMSA()">,
243 AssemblerPredicate<"FeatureMSA">;
244 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
245 AssemblerPredicate<"!FeatureMadd4">;
246 def HasMT : Predicate<"Subtarget->hasMT()">,
247 AssemblerPredicate<"FeatureMT">;
248 def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
249 AssemblerPredicate<"FeatureUseIndirectJumpsHazard">;
250 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
251 AssemblerPredicate<"!FeatureUseIndirectJumpsHazard">;
252 def HasCRC : Predicate<"Subtarget->hasCRC()">,
253 AssemblerPredicate<"FeatureCRC">;
254 def HasVirt : Predicate<"Subtarget->hasVirt()">,
255 AssemblerPredicate<"FeatureVirt">;
256 def HasGINV : Predicate<"Subtarget->hasGINV()">,
257 AssemblerPredicate<"FeatureGINV">;
258 // TODO: Add support for FPOpFusion::Standard
259 def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
260 " FPOpFusion::Fast">;
261 //===----------------------------------------------------------------------===//
262 // Mips GPR size adjectives.
263 // They are mutually exclusive.
264 //===----------------------------------------------------------------------===//
266 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
267 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
269 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
270 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
272 //===----------------------------------------------------------------------===//
273 // Mips Symbol size adjectives.
274 // They are mutally exculsive.
275 //===----------------------------------------------------------------------===//
277 class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
278 class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
280 //===----------------------------------------------------------------------===//
281 // Mips ISA/ASE membership and instruction group membership adjectives.
282 // They are mutually exclusive.
283 //===----------------------------------------------------------------------===//
285 // FIXME: I'd prefer to use additive predicates to build the instruction sets
286 // but we are short on assembler feature bits at the moment. Using a
287 // subtractive predicate will hopefully keep us under the 32 predicate
288 // limit long enough to develop an alternative way to handle P1||P2
291 list<Predicate> EncodingPredicates = [HasStdEnc];
293 class ISA_MIPS1_NOT_MIPS3 {
294 list<Predicate> InsnPredicates = [NotMips3];
295 list<Predicate> EncodingPredicates = [HasStdEnc];
297 class ISA_MIPS1_NOT_4_32 {
298 list<Predicate> InsnPredicates = [NotMips4_32];
299 list<Predicate> EncodingPredicates = [HasStdEnc];
301 class ISA_MIPS1_NOT_32R6_64R6 {
302 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
303 list<Predicate> EncodingPredicates = [HasStdEnc];
306 list<Predicate> InsnPredicates = [HasMips2];
307 list<Predicate> EncodingPredicates = [HasStdEnc];
309 class ISA_MIPS2_NOT_32R6_64R6 {
310 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
311 list<Predicate> EncodingPredicates = [HasStdEnc];
314 list<Predicate> InsnPredicates = [HasMips3];
315 list<Predicate> EncodingPredicates = [HasStdEnc];
317 class ISA_MIPS3_NOT_32R6_64R6 {
318 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
319 list<Predicate> EncodingPredicates = [HasStdEnc];
322 list<Predicate> InsnPredicates = [HasMips32];
323 list<Predicate> EncodingPredicates = [HasStdEnc];
325 class ISA_MIPS32_NOT_32R6_64R6 {
326 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
327 list<Predicate> EncodingPredicates = [HasStdEnc];
330 list<Predicate> InsnPredicates = [HasMips32r2];
331 list<Predicate> EncodingPredicates = [HasStdEnc];
333 class ISA_MIPS32R2_NOT_32R6_64R6 {
334 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
335 list<Predicate> EncodingPredicates = [HasStdEnc];
338 list<Predicate> InsnPredicates = [HasMips32r5];
339 list<Predicate> EncodingPredicates = [HasStdEnc];
342 list<Predicate> InsnPredicates = [HasMips64];
343 list<Predicate> EncodingPredicates = [HasStdEnc];
345 class ISA_MIPS64_NOT_64R6 {
346 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
347 list<Predicate> EncodingPredicates = [HasStdEnc];
350 list<Predicate> InsnPredicates = [HasMips64r2];
351 list<Predicate> EncodingPredicates = [HasStdEnc];
354 list<Predicate> InsnPredicates = [HasMips64r5];
355 list<Predicate> EncodingPredicates = [HasStdEnc];
358 list<Predicate> InsnPredicates = [HasMips32r6];
359 list<Predicate> EncodingPredicates = [HasStdEnc];
362 list<Predicate> InsnPredicates = [HasMips64r6];
363 list<Predicate> EncodingPredicates = [HasStdEnc];
365 class ISA_MICROMIPS {
366 list<Predicate> EncodingPredicates = [InMicroMips];
368 class ISA_MICROMIPS32R5 {
369 list<Predicate> InsnPredicates = [HasMips32r5];
370 list<Predicate> EncodingPredicates = [InMicroMips];
372 class ISA_MICROMIPS32R6 {
373 list<Predicate> InsnPredicates = [HasMips32r6];
374 list<Predicate> EncodingPredicates = [InMicroMips];
376 class ISA_MICROMIPS64R6 {
377 list<Predicate> InsnPredicates = [HasMips64r6];
378 list<Predicate> EncodingPredicates = [InMicroMips];
380 class ISA_MICROMIPS32_NOT_MIPS32R6 {
381 list<Predicate> InsnPredicates = [NotMips32r6];
382 list<Predicate> EncodingPredicates = [InMicroMips];
384 class ASE_EVA { list<Predicate> ASEPredicate = [HasEVA]; }
386 // The portions of MIPS-III that were also added to MIPS32
387 class INSN_MIPS3_32 {
388 list<Predicate> InsnPredicates = [HasMips3_32];
389 list<Predicate> EncodingPredicates = [HasStdEnc];
392 // The portions of MIPS-III that were also added to MIPS32 but were removed in
393 // MIPS32r6 and MIPS64r6.
394 class INSN_MIPS3_32_NOT_32R6_64R6 {
395 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
396 list<Predicate> EncodingPredicates = [HasStdEnc];
399 // The portions of MIPS-III that were also added to MIPS32
400 class INSN_MIPS3_32R2 {
401 list<Predicate> InsnPredicates = [HasMips3_32r2];
402 list<Predicate> EncodingPredicates = [HasStdEnc];
405 // The portions of MIPS-IV that were also added to MIPS32.
406 class INSN_MIPS4_32 {
407 list <Predicate> InsnPredicates = [HasMips4_32];
408 list<Predicate> EncodingPredicates = [HasStdEnc];
411 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
412 // MIPS32r6 and MIPS64r6.
413 class INSN_MIPS4_32_NOT_32R6_64R6 {
414 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
415 list<Predicate> EncodingPredicates = [HasStdEnc];
418 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
419 // MIPS32r6 and MIPS64r6.
420 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
421 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
422 list<Predicate> EncodingPredicates = [HasStdEnc];
425 // The portions of MIPS-IV that were also added to MIPS32r2.
426 class INSN_MIPS4_32R2 {
427 list<Predicate> InsnPredicates = [HasMips4_32r2];
428 list<Predicate> EncodingPredicates = [HasStdEnc];
431 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
432 // MIPS32r6 and MIPS64r6.
433 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
434 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
435 list<Predicate> EncodingPredicates = [HasStdEnc];
439 list<Predicate> ASEPredicate = [HasCnMips];
442 class NOT_ASE_CNMIPS {
443 list<Predicate> ASEPredicate = [NotCnMips];
447 list<Predicate> ASEPredicate = [HasCnMipsP];
450 class NOT_ASE_CNMIPSP {
451 list<Predicate> ASEPredicate = [NotCnMipsP];
454 class ASE_MIPS64_CNMIPS {
455 list<Predicate> ASEPredicate = [HasMips64, HasCnMips];
459 list<Predicate> ASEPredicate = [HasMSA];
462 class ASE_MSA_NOT_MSA64 {
463 list<Predicate> ASEPredicate = [HasMSA, NotMips64];
467 list<Predicate> ASEPredicate = [HasMSA, HasMips64];
471 list <Predicate> ASEPredicate = [HasMT];
475 list <Predicate> ASEPredicate = [HasCRC];
479 list <Predicate> ASEPredicate = [HasVirt];
483 list <Predicate> ASEPredicate = [HasGINV];
486 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
487 // It can be used only on instructions that doesn't inherit PredicateControl.
488 class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
489 let InsnPredicates = [NotMips32r6];
490 let EncodingPredicates = [InMicroMips];
494 list<Predicate> ASEPredicate = [NotDSP];
498 list<Predicate> AdditionalPredicates = [HasMadd4];
501 // Classses used for separating expansions that differ based on the ABI in
504 list<Predicate> AdditionalPredicates = [IsN64];
508 list<Predicate> AdditionalPredicates = [IsNotN64];
511 class FPOP_FUSION_FAST {
512 list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
515 //===----------------------------------------------------------------------===//
517 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl;
519 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
520 InstAlias<Asm, Result, Emit>, PredicateControl;
523 bit isCommutable = 1;
543 bit isTerminator = 1;
546 bit hasExtraSrcRegAllocReq = 1;
547 bit isCodeGenOnly = 1;
551 class IsAsCheapAsAMove {
552 bit isAsCheapAsAMove = 1;
555 class NeverHasSideEffects {
556 bit hasSideEffects = 0;
559 //===----------------------------------------------------------------------===//
560 // Instruction format superclass
561 //===----------------------------------------------------------------------===//
563 include "MipsInstrFormats.td"
565 //===----------------------------------------------------------------------===//
566 // Mips Operand, Complex Patterns and Transformations Definitions.
567 //===----------------------------------------------------------------------===//
569 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
570 int Offset = 0> : AsmOperandClass {
571 let Name = "ConstantSImm" # Bits # "_" # Offset;
572 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
573 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
574 let SuperClasses = Supers;
575 let DiagnosticType = "SImm" # Bits # "_" # Offset;
578 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
579 int Shift = 0> : AsmOperandClass {
580 let Name = "Simm" # Bits # "_Lsl" # Shift;
581 let RenderMethod = "addImmOperands";
582 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
583 let SuperClasses = Supers;
584 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
587 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
588 int Offset = 0> : AsmOperandClass {
589 let Name = "ConstantUImm" # Bits # "_" # Offset;
590 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
591 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
592 let SuperClasses = Supers;
593 let DiagnosticType = "UImm" # Bits # "_" # Offset;
596 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
597 list<AsmOperandClass> Supers = []>
599 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
600 let RenderMethod = "addImmOperands";
601 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
602 let SuperClasses = Supers;
603 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
606 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
608 let Name = "SImm" # Bits;
609 let RenderMethod = "addSImmOperands<" # Bits # ">";
610 let PredicateMethod = "isSImm<" # Bits # ">";
611 let SuperClasses = Supers;
612 let DiagnosticType = "SImm" # Bits;
615 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
617 let Name = "UImm" # Bits;
618 let RenderMethod = "addUImmOperands<" # Bits # ">";
619 let PredicateMethod = "isUImm<" # Bits # ">";
620 let SuperClasses = Supers;
621 let DiagnosticType = "UImm" # Bits;
624 // Generic case - only to support certain assembly pseudo instructions.
625 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
628 let RenderMethod = "addConstantUImmOperands<32>";
629 let PredicateMethod = "isSImm<" # Bits # ">";
630 let SuperClasses = Supers;
631 let DiagnosticType = "ImmAny";
634 // AsmOperandClasses require a strict ordering which is difficult to manage
635 // as a hierarchy. Instead, we use a linear ordering and impose an order that
636 // is in some places arbitrary.
638 // Here the rules that are in use:
639 // * Wider immediates are a superset of narrower immediates:
640 // uimm4 < uimm5 < uimm6
641 // * For the same bit-width, unsigned immediates are a superset of signed
643 // simm4 < uimm4 < simm5 < uimm5
644 // * For the same upper-bound, signed immediates are a superset of unsigned
646 // uimm3 < simm4 < uimm4 < simm4
647 // * Modified immediates are a superset of ordinary immediates:
648 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
649 // The term 'superset' starts to break down here since the uimm5_plus* classes
650 // are not true supersets of uimm5 (but they are still subsets of uimm6).
651 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
652 // uimm16 < uimm16_relaxed
653 // * The codeGen pattern type is arbitrarily ordered.
654 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
655 // This is entirely arbitrary. We need an ordering and what we pick is
656 // unimportant since only one is possible for a given mnemonic.
658 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
659 let Name = "UImm32_Coerced";
660 let DiagnosticType = "UImm32_Coerced";
662 def SImm32RelaxedAsmOperandClass
663 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
664 let Name = "SImm32_Relaxed";
665 let PredicateMethod = "isAnyImm<33>";
666 let DiagnosticType = "SImm32_Relaxed";
668 def SImm32AsmOperandClass
669 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
670 def ConstantUImm26AsmOperandClass
671 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
672 def ConstantUImm20AsmOperandClass
673 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
674 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
675 let Name = "SImm19Lsl2";
676 let RenderMethod = "addImmOperands";
677 let PredicateMethod = "isScaledSImm<19, 2>";
678 let SuperClasses = [ConstantUImm20AsmOperandClass];
679 let DiagnosticType = "SImm19_Lsl2";
681 def UImm16RelaxedAsmOperandClass
682 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
683 let Name = "UImm16_Relaxed";
684 let PredicateMethod = "isAnyImm<16>";
685 let DiagnosticType = "UImm16_Relaxed";
687 // Similar to the relaxed classes which take an SImm and render it as
688 // an UImm, this takes a UImm and renders it as an SImm.
689 def UImm16AltRelaxedAsmOperandClass
690 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
691 let Name = "UImm16_AltRelaxed";
692 let PredicateMethod = "isUImm<16>";
693 let DiagnosticType = "UImm16_AltRelaxed";
695 // FIXME: One of these should probably have UImm16AsmOperandClass as the
696 // superclass instead of UImm16RelaxedasmOPerandClass.
697 def UImm16AsmOperandClass
698 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
699 def SImm16RelaxedAsmOperandClass
700 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
701 let Name = "SImm16_Relaxed";
702 let PredicateMethod = "isAnyImm<16>";
703 let DiagnosticType = "SImm16_Relaxed";
705 def SImm16AsmOperandClass
706 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
707 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
708 let Name = "SImm10Lsl3";
709 let RenderMethod = "addImmOperands";
710 let PredicateMethod = "isScaledSImm<10, 3>";
711 let SuperClasses = [SImm16AsmOperandClass];
712 let DiagnosticType = "SImm10_Lsl3";
714 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
715 let Name = "SImm10Lsl2";
716 let RenderMethod = "addImmOperands";
717 let PredicateMethod = "isScaledSImm<10, 2>";
718 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
719 let DiagnosticType = "SImm10_Lsl2";
721 def ConstantSImm11AsmOperandClass
722 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
723 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
724 let Name = "SImm10Lsl1";
725 let RenderMethod = "addImmOperands";
726 let PredicateMethod = "isScaledSImm<10, 1>";
727 let SuperClasses = [ConstantSImm11AsmOperandClass];
728 let DiagnosticType = "SImm10_Lsl1";
730 def ConstantUImm10AsmOperandClass
731 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
732 def ConstantSImm10AsmOperandClass
733 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
734 def ConstantSImm9AsmOperandClass
735 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
736 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
737 let Name = "SImm7Lsl2";
738 let RenderMethod = "addImmOperands";
739 let PredicateMethod = "isScaledSImm<7, 2>";
740 let SuperClasses = [ConstantSImm9AsmOperandClass];
741 let DiagnosticType = "SImm7_Lsl2";
743 def ConstantUImm8AsmOperandClass
744 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
745 def ConstantUImm7Sub1AsmOperandClass
746 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
747 // Specify the names since the -1 offset causes invalid identifiers otherwise.
748 let Name = "UImm7_N1";
749 let DiagnosticType = "UImm7_N1";
751 def ConstantUImm7AsmOperandClass
752 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
753 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
754 let Name = "UImm6Lsl2";
755 let RenderMethod = "addImmOperands";
756 let PredicateMethod = "isScaledUImm<6, 2>";
757 let SuperClasses = [ConstantUImm7AsmOperandClass];
758 let DiagnosticType = "UImm6_Lsl2";
760 def ConstantUImm6AsmOperandClass
761 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
762 def ConstantSImm6AsmOperandClass
763 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
764 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
765 let Name = "UImm5Lsl2";
766 let RenderMethod = "addImmOperands";
767 let PredicateMethod = "isScaledUImm<5, 2>";
768 let SuperClasses = [ConstantSImm6AsmOperandClass];
769 let DiagnosticType = "UImm5_Lsl2";
771 def ConstantUImm5_Range2_64AsmOperandClass
772 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
773 def ConstantUImm5Plus33AsmOperandClass
774 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
776 def ConstantUImm5ReportUImm6AsmOperandClass
777 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
778 let Name = "ConstantUImm5_0_Report_UImm6";
779 let DiagnosticType = "UImm5_0_Report_UImm6";
781 def ConstantUImm5Plus32AsmOperandClass
782 : ConstantUImmAsmOperandClass<
783 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
784 def ConstantUImm5Plus32NormalizeAsmOperandClass
785 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
786 let Name = "ConstantUImm5_32_Norm";
787 // We must also subtract 32 when we render the operand.
788 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
790 def ConstantUImm5Plus1ReportUImm6AsmOperandClass
791 : ConstantUImmAsmOperandClass<
792 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
793 let Name = "ConstantUImm5_Plus1_Report_UImm6";
795 def ConstantUImm5Plus1AsmOperandClass
796 : ConstantUImmAsmOperandClass<
797 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
798 def ConstantUImm5AsmOperandClass
799 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
800 def ConstantSImm5AsmOperandClass
801 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
802 def ConstantUImm4AsmOperandClass
803 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
804 def ConstantSImm4AsmOperandClass
805 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
806 def ConstantUImm3AsmOperandClass
807 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
808 def ConstantUImm2Plus1AsmOperandClass
809 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
810 def ConstantUImm2AsmOperandClass
811 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
812 def ConstantUImm1AsmOperandClass
813 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
814 def ConstantImmzAsmOperandClass : AsmOperandClass {
815 let Name = "ConstantImmz";
816 let RenderMethod = "addConstantUImmOperands<1>";
817 let PredicateMethod = "isConstantImmz";
818 let SuperClasses = [ConstantUImm1AsmOperandClass];
819 let DiagnosticType = "Immz";
822 def Simm19Lsl2AsmOperand
823 : SimmLslAsmOperandClass<19, [], 2>;
825 def MipsJumpTargetAsmOperand : AsmOperandClass {
826 let Name = "JumpTarget";
827 let ParserMethod = "parseJumpTarget";
828 let PredicateMethod = "isImm";
829 let RenderMethod = "addImmOperands";
832 // Instruction operand types
833 def jmptarget : Operand<OtherVT> {
834 let EncoderMethod = "getJumpTargetOpValue";
835 let ParserMatchClass = MipsJumpTargetAsmOperand;
837 def brtarget : Operand<OtherVT> {
838 let EncoderMethod = "getBranchTargetOpValue";
839 let OperandType = "OPERAND_PCREL";
840 let DecoderMethod = "DecodeBranchTarget";
841 let ParserMatchClass = MipsJumpTargetAsmOperand;
843 def brtarget1SImm16 : Operand<OtherVT> {
844 let EncoderMethod = "getBranchTargetOpValue1SImm16";
845 let OperandType = "OPERAND_PCREL";
846 let DecoderMethod = "DecodeBranchTarget1SImm16";
847 let ParserMatchClass = MipsJumpTargetAsmOperand;
849 def calltarget : Operand<iPTR> {
850 let EncoderMethod = "getJumpTargetOpValue";
851 let ParserMatchClass = MipsJumpTargetAsmOperand;
854 def imm64: Operand<i64>;
856 def simm19_lsl2 : Operand<i32> {
857 let EncoderMethod = "getSimm19Lsl2Encoding";
858 let DecoderMethod = "DecodeSimm19Lsl2";
859 let ParserMatchClass = Simm19Lsl2AsmOperand;
862 def simm18_lsl3 : Operand<i32> {
863 let EncoderMethod = "getSimm18Lsl3Encoding";
864 let DecoderMethod = "DecodeSimm18Lsl3";
865 let ParserMatchClass = MipsJumpTargetAsmOperand;
869 def uimmz : Operand<i32> {
870 let PrintMethod = "printUImm<0>";
871 let ParserMatchClass = ConstantImmzAsmOperandClass;
874 // size operand of ins instruction
875 def uimm_range_2_64 : Operand<i32> {
876 let PrintMethod = "printUImm<6, 2>";
877 let EncoderMethod = "getSizeInsEncoding";
878 let DecoderMethod = "DecodeInsSize";
879 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
883 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
884 def uimm # I : Operand<i32> {
885 let PrintMethod = "printUImm<" # I # ">";
886 let ParserMatchClass =
887 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
890 def uimm2_plus1 : Operand<i32> {
891 let PrintMethod = "printUImm<2, 1>";
892 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
893 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
894 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
897 def uimm5_plus1 : Operand<i32> {
898 let PrintMethod = "printUImm<5, 1>";
899 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
900 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
901 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
904 def uimm5_plus1_report_uimm6 : Operand<i32> {
905 let PrintMethod = "printUImm<6, 1>";
906 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
907 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
908 let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
911 def uimm5_plus32 : Operand<i32> {
912 let PrintMethod = "printUImm<5, 32>";
913 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
916 def uimm5_plus33 : Operand<i32> {
917 let PrintMethod = "printUImm<5, 33>";
918 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
919 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
920 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
923 def uimm5_inssize_plus1 : Operand<i32> {
924 let PrintMethod = "printUImm<6>";
925 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
926 let EncoderMethod = "getSizeInsEncoding";
927 let DecoderMethod = "DecodeInsSize";
930 def uimm5_plus32_normalize : Operand<i32> {
931 let PrintMethod = "printUImm<5>";
932 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
935 def uimm5_lsl2 : Operand<OtherVT> {
936 let EncoderMethod = "getUImm5Lsl2Encoding";
937 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
938 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
941 def uimm5_plus32_normalize_64 : Operand<i64> {
942 let PrintMethod = "printUImm<5>";
943 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
946 def uimm6_lsl2 : Operand<OtherVT> {
947 let EncoderMethod = "getUImm6Lsl2Encoding";
948 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
949 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
953 def uimm # I : Operand<i32> {
954 let PrintMethod = "printUImm<" # I # ">";
955 let ParserMatchClass =
956 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
959 // Like uimm16_64 but coerces simm16 to uimm16.
960 def uimm16_relaxed : Operand<i32> {
961 let PrintMethod = "printUImm<16>";
962 let ParserMatchClass = UImm16RelaxedAsmOperandClass;
966 def uimm # I # _64 : Operand<i64> {
967 let PrintMethod = "printUImm<" # I # ">";
968 let ParserMatchClass =
969 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
973 def uimm # I # _64 : Operand<i64> {
974 let PrintMethod = "printUImm<" # I # ">";
975 let ParserMatchClass =
976 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
979 // Like uimm16_64 but coerces simm16 to uimm16.
980 def uimm16_64_relaxed : Operand<i64> {
981 let PrintMethod = "printUImm<16>";
982 let ParserMatchClass = UImm16RelaxedAsmOperandClass;
985 def uimm16_altrelaxed : Operand<i32> {
986 let PrintMethod = "printUImm<16>";
987 let ParserMatchClass = UImm16AltRelaxedAsmOperandClass;
989 // Like uimm5 but reports a less confusing error for 32-63 when
990 // an instruction alias permits that.
991 def uimm5_report_uimm6 : Operand<i32> {
992 let PrintMethod = "printUImm<6>";
993 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
996 // Like uimm5_64 but reports a less confusing error for 32-63 when
997 // an instruction alias permits that.
998 def uimm5_64_report_uimm6 : Operand<i64> {
999 let PrintMethod = "printUImm<5>";
1000 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
1003 foreach I = {1, 2, 3, 4} in
1004 def uimm # I # _ptr : Operand<iPTR> {
1005 let PrintMethod = "printUImm<" # I # ">";
1006 let ParserMatchClass =
1007 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1010 foreach I = {1, 2, 3, 4, 5, 6, 8} in
1011 def vsplat_uimm # I : Operand<vAny> {
1012 let PrintMethod = "printUImm<" # I # ">";
1013 let ParserMatchClass =
1014 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1018 foreach I = {4, 5, 6, 9, 10, 11} in
1019 def simm # I : Operand<i32> {
1020 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1021 let ParserMatchClass =
1022 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1025 foreach I = {1, 2, 3} in
1026 def simm10_lsl # I : Operand<i32> {
1027 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
1028 let ParserMatchClass =
1029 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
1033 def simm # I # _64 : Operand<i64> {
1034 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1035 let ParserMatchClass =
1036 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1039 foreach I = {5, 10} in
1040 def vsplat_simm # I : Operand<vAny> {
1041 let ParserMatchClass =
1042 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1045 def simm7_lsl2 : Operand<OtherVT> {
1046 let EncoderMethod = "getSImm7Lsl2Encoding";
1047 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
1048 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
1051 foreach I = {16, 32} in
1052 def simm # I : Operand<i32> {
1053 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1054 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
1057 // Like simm16 but coerces uimm16 to simm16.
1058 def simm16_relaxed : Operand<i32> {
1059 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1060 let ParserMatchClass = SImm16RelaxedAsmOperandClass;
1063 def simm16_64 : Operand<i64> {
1064 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1065 let ParserMatchClass = SImm16AsmOperandClass;
1068 // like simm32 but coerces simm32 to uimm32.
1069 def uimm32_coerced : Operand<i32> {
1070 let ParserMatchClass = UImm32CoercedAsmOperandClass;
1072 // Like simm32 but coerces uimm32 to simm32.
1073 def simm32_relaxed : Operand<i32> {
1074 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1075 let ParserMatchClass = SImm32RelaxedAsmOperandClass;
1078 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
1079 def li16_imm : Operand<i32> {
1080 let DecoderMethod = "DecodeLi16Imm";
1081 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
1084 def MipsMemAsmOperand : AsmOperandClass {
1086 let ParserMethod = "parseMemOperand";
1089 class MipsMemSimmAsmOperand<int Width, int Shift = 0> : AsmOperandClass {
1090 let Name = "MemOffsetSimm" # Width # "_" # Shift;
1091 let SuperClasses = [MipsMemAsmOperand];
1092 let RenderMethod = "addMemOperands";
1093 let ParserMethod = "parseMemOperand";
1094 let PredicateMethod = "isMemWithSimmOffset<" # Width # ", " # Shift # ">";
1095 let DiagnosticType = !if(!eq(Shift, 0), "MemSImm" # Width,
1096 "MemSImm" # Width # "Lsl" # Shift);
1099 def MipsMemSimmPtrAsmOperand : AsmOperandClass {
1100 let Name = "MemOffsetSimmPtr";
1101 let SuperClasses = [MipsMemAsmOperand];
1102 let RenderMethod = "addMemOperands";
1103 let ParserMethod = "parseMemOperand";
1104 let PredicateMethod = "isMemWithPtrSizeOffset";
1105 let DiagnosticType = "MemSImmPtr";
1108 def MipsInvertedImmoperand : AsmOperandClass {
1109 let Name = "InvNum";
1110 let RenderMethod = "addImmOperands";
1111 let ParserMethod = "parseInvNum";
1114 def InvertedImOperand : Operand<i32> {
1115 let ParserMatchClass = MipsInvertedImmoperand;
1118 def InvertedImOperand64 : Operand<i64> {
1119 let ParserMatchClass = MipsInvertedImmoperand;
1122 class mem_generic : Operand<iPTR> {
1123 let PrintMethod = "printMemOperand";
1124 let MIOperandInfo = (ops ptr_rc, simm16);
1125 let EncoderMethod = "getMemEncoding";
1126 let ParserMatchClass = MipsMemAsmOperand;
1127 let OperandType = "OPERAND_MEMORY";
1131 def mem : mem_generic;
1133 // MSA specific address operand
1134 def mem_msa : mem_generic {
1135 let MIOperandInfo = (ops ptr_rc, simm10);
1136 let EncoderMethod = "getMSAMemEncoding";
1139 def simm12 : Operand<i32> {
1140 let DecoderMethod = "DecodeSimm12";
1143 def mem_simm9_exp : mem_generic {
1144 let MIOperandInfo = (ops ptr_rc, simm9);
1145 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1146 let OperandNamespace = "MipsII";
1147 let OperandType = "OPERAND_MEM_SIMM9";
1150 foreach I = {9, 10, 11, 12, 16} in
1151 def mem_simm # I : mem_generic {
1152 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm" # I));
1153 let ParserMatchClass = MipsMemSimmAsmOperand<I>;
1156 foreach I = {1, 2, 3} in
1157 def mem_simm10_lsl # I : mem_generic {
1158 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1159 let EncoderMethod = "getMemEncoding<" # I # ">";
1160 let ParserMatchClass = MipsMemSimmAsmOperand<10, I>;
1163 def mem_simmptr : mem_generic {
1164 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1167 def mem_ea : Operand<iPTR> {
1168 let PrintMethod = "printMemOperandEA";
1169 let MIOperandInfo = (ops ptr_rc, simm16);
1170 let EncoderMethod = "getMemEncoding";
1171 let OperandType = "OPERAND_MEMORY";
1174 def PtrRC : Operand<iPTR> {
1175 let MIOperandInfo = (ops ptr_rc);
1176 let DecoderMethod = "DecodePtrRegisterClass";
1177 let ParserMatchClass = GPR32AsmOperand;
1180 // size operand of ins instruction
1181 def size_ins : Operand<i32> {
1182 let EncoderMethod = "getSizeInsEncoding";
1183 let DecoderMethod = "DecodeInsSize";
1186 // Transformation Function - get the lower 16 bits.
1187 def LO16 : SDNodeXForm<imm, [{
1188 return getImm(N, N->getZExtValue() & 0xFFFF);
1191 // Transformation Function - get the higher 16 bits.
1192 def HI16 : SDNodeXForm<imm, [{
1193 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1197 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1199 // Node immediate is zero (e.g. insve.d)
1200 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1202 // Node immediate fits as 16-bit sign extended on target immediate.
1204 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1206 // Node immediate fits as 16-bit sign extended on target immediate.
1208 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1209 def imm32SExt16 : IntImmLeaf<i32, [{ return isInt<16>(Imm.getSExtValue()); }]>;
1211 // Node immediate fits as 7-bit zero extended on target immediate.
1212 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1213 def timmZExt7 : PatLeaf<(timm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1215 // Node immediate fits as 16-bit zero extended on target immediate.
1216 // The LO16 param means that only the lower 16 bits of the node
1217 // immediate are caught.
1218 // e.g. addiu, sltiu
1219 def immZExt16 : PatLeaf<(imm), [{
1220 if (N->getValueType(0) == MVT::i32)
1221 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1223 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1225 def imm32ZExt16 : IntImmLeaf<i32, [{
1226 return (uint32_t)Imm.getZExtValue() == (unsigned short)Imm.getZExtValue();
1229 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1230 def immSExt32Low16Zero : PatLeaf<(imm), [{
1231 int64_t Val = N->getSExtValue();
1232 return isInt<32>(Val) && !(Val & 0xffff);
1235 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1236 def immZExt32Low16Zero : PatLeaf<(imm), [{
1237 uint64_t Val = N->getZExtValue();
1238 return isUInt<32>(Val) && !(Val & 0xffff);
1241 // Note immediate fits as a 32 bit signed extended on target immediate.
1242 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1244 // Note immediate fits as a 32 bit zero extended on target immediate.
1245 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1247 // shamt field must fit in 5 bits.
1248 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1249 def timmZExt5 : TImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1251 def immZExt5Plus1 : PatLeaf<(imm), [{
1252 return isUInt<5>(N->getZExtValue() - 1);
1254 def immZExt5Plus32 : PatLeaf<(imm), [{
1255 return isUInt<5>(N->getZExtValue() - 32);
1257 def immZExt5Plus33 : PatLeaf<(imm), [{
1258 return isUInt<5>(N->getZExtValue() - 33);
1261 def immZExt5To31 : SDNodeXForm<imm, [{
1262 return getImm(N, 31 - N->getZExtValue());
1265 // True if (N + 1) fits in 16-bit field.
1266 def immSExt16Plus1 : PatLeaf<(imm), [{
1267 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1270 def immZExtRange2To64 : PatLeaf<(imm), [{
1271 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1272 (N->getZExtValue() <= 64);
1275 def ORiPred : PatLeaf<(imm), [{
1276 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1279 def LUiPred : PatLeaf<(imm), [{
1280 int64_t Val = N->getSExtValue();
1281 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1284 def LUiORiPred : PatLeaf<(imm), [{
1285 int64_t SVal = N->getSExtValue();
1286 return isInt<32>(SVal) && (SVal & 0xffff);
1289 // Mips Address Mode! SDNode frameindex could possibily be a match
1290 // since load and store instructions from stack used it.
1292 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1295 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1298 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1300 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1301 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1303 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1305 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1308 //===----------------------------------------------------------------------===//
1309 // Instructions specific format
1310 //===----------------------------------------------------------------------===//
1312 // Arithmetic and logical instructions with 3 register operands.
1313 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1314 InstrItinClass Itin = NoItinerary,
1315 SDPatternOperator OpNode = null_frag>:
1316 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1317 !strconcat(opstr, "\t$rd, $rs, $rt"),
1318 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1319 let isCommutable = isComm;
1320 let isReMaterializable = 1;
1321 let TwoOperandAliasConstraint = "$rd = $rs";
1324 // Arithmetic and logical instructions with 2 register operands.
1325 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1326 InstrItinClass Itin = NoItinerary,
1327 SDPatternOperator imm_type = null_frag,
1328 SDPatternOperator OpNode = null_frag> :
1329 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1330 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1331 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1332 Itin, FrmI, opstr> {
1333 let isReMaterializable = 1;
1334 let TwoOperandAliasConstraint = "$rs = $rt";
1337 // Arithmetic Multiply ADD/SUB
1338 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1339 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1340 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1341 let Defs = [HI0, LO0];
1342 let Uses = [HI0, LO0];
1343 let isCommutable = isComm;
1347 class LogicNOR<string opstr, RegisterOperand RO>:
1348 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1349 !strconcat(opstr, "\t$rd, $rs, $rt"),
1350 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1351 let isCommutable = 1;
1355 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1356 RegisterOperand RO, InstrItinClass itin,
1357 SDPatternOperator OpNode = null_frag,
1358 SDPatternOperator PF = null_frag> :
1359 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1360 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1361 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1362 let TwoOperandAliasConstraint = "$rt = $rd";
1365 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1366 SDPatternOperator OpNode = null_frag>:
1367 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1368 !strconcat(opstr, "\t$rd, $rt, $rs"),
1369 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1372 // Load Upper Immediate
1373 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1374 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1375 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1376 let hasSideEffects = 0;
1377 let isReMaterializable = 1;
1380 // Memory Load/Store
1381 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1382 SDPatternOperator OpNode = null_frag,
1383 InstrItinClass Itin = NoItinerary,
1384 ComplexPattern Addr = addr> :
1385 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1386 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1387 let DecoderMethod = "DecodeMem";
1388 let canFoldAsLoad = 1;
1389 string BaseOpcode = opstr;
1393 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1394 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1395 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1397 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1398 SDPatternOperator OpNode = null_frag,
1399 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1400 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1401 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1402 let DecoderMethod = "DecodeMem";
1403 string BaseOpcode = opstr;
1407 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1408 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1409 DAGOperand MO = mem> :
1410 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1412 // Load/Store Left/Right
1413 let canFoldAsLoad = 1 in
1414 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1415 InstrItinClass Itin> :
1416 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1417 !strconcat(opstr, "\t$rt, $addr"),
1418 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1419 let DecoderMethod = "DecodeMem";
1420 string Constraints = "$src = $rt";
1421 let BaseOpcode = opstr;
1424 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1425 InstrItinClass Itin> :
1426 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1427 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1428 let DecoderMethod = "DecodeMem";
1429 let BaseOpcode = opstr;
1433 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1434 SDPatternOperator OpNode= null_frag> :
1435 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1436 !strconcat(opstr, "\t$rt, $addr"),
1437 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1438 let DecoderMethod = "DecodeFMem2";
1442 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1443 SDPatternOperator OpNode= null_frag> :
1444 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1445 !strconcat(opstr, "\t$rt, $addr"),
1446 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1447 let DecoderMethod = "DecodeFMem2";
1452 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1453 SDPatternOperator OpNode= null_frag> :
1454 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1455 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1456 let DecoderMethod = "DecodeFMem3";
1460 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1461 SDPatternOperator OpNode= null_frag> :
1462 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1463 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1464 let DecoderMethod = "DecodeFMem3";
1468 // Conditional Branch
1469 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1470 RegisterOperand RO> :
1471 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1472 !strconcat(opstr, "\t$rs, $rt, $offset"),
1473 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1476 let isTerminator = 1;
1477 let hasDelaySlot = 1;
1482 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1483 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1484 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1486 let isTerminator = 1;
1487 let hasDelaySlot = 1;
1492 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1493 RegisterOperand RO> :
1494 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1495 !strconcat(opstr, "\t$rs, $offset"),
1496 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1499 let isTerminator = 1;
1500 let hasDelaySlot = 1;
1505 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1506 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1507 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1509 let isTerminator = 1;
1510 let hasDelaySlot = 1;
1516 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1517 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1518 !strconcat(opstr, "\t$rd, $rs, $rt"),
1519 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1520 II_SLT_SLTU, FrmR, opstr>;
1522 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1523 RegisterOperand RO>:
1524 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1525 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1526 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1527 II_SLTI_SLTIU, FrmI, opstr>;
1530 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1531 SDPatternOperator targetoperator, string bopstr> :
1532 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1533 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1536 let hasDelaySlot = 1;
1537 let DecoderMethod = "DecodeJumpTarget";
1542 // Unconditional branch
1543 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1544 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1545 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1547 let isTerminator = 1;
1549 let hasDelaySlot = 1;
1550 let AdditionalPredicates = [RelocPIC];
1555 // Base class for indirect branch and return instruction classes.
1556 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1557 class JumpFR<string opstr, RegisterOperand RO,
1558 SDPatternOperator operator = null_frag>:
1559 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1563 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1565 let isIndirectBranch = 1;
1568 // Jump and Link (Call)
1569 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1570 class JumpLink<string opstr, DAGOperand opnd> :
1571 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1572 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1573 let DecoderMethod = "DecodeJumpTarget";
1576 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1577 Register RetReg, RegisterOperand ResRO = RO>:
1578 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1579 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1580 let hasPostISelHook = 1;
1583 class JumpLinkReg<string opstr, RegisterOperand RO>:
1584 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1585 [], II_JALR, FrmR, opstr> {
1586 let hasPostISelHook = 1;
1589 class BGEZAL_FT<string opstr, DAGOperand opnd,
1590 RegisterOperand RO> :
1591 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1592 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1593 let hasDelaySlot = 1;
1598 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1599 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1600 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1601 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1602 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1604 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1605 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1606 PseudoInstExpansion<(JumpInst RO:$rs)> {
1607 let hasPostISelHook = 1;
1611 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1612 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1613 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1615 let isTerminator = 1;
1617 let hasDelaySlot = 1;
1624 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1625 InstSE<(outs), (ins ImmOp:$code_),
1626 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1628 class BRK_FT<string opstr> :
1629 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1630 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1634 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1635 InstSE<(outs), (ins),
1636 opstr, [], itin, FrmOther, opstr>;
1639 class WAIT_FT<string opstr> :
1640 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1644 class DEI_FT<string opstr, RegisterOperand RO,
1645 InstrItinClass itin = NoItinerary> :
1646 InstSE<(outs RO:$rt), (ins),
1647 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1650 let hasSideEffects = 1 in
1651 class SYNC_FT<string opstr> :
1652 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1653 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1655 class SYNCI_FT<string opstr, DAGOperand MO> :
1656 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1657 II_SYNCI, FrmOther, opstr> {
1658 let hasSideEffects = 1;
1659 let DecoderMethod = "DecodeSyncI";
1662 let hasSideEffects = 1, isCTI = 1 in {
1663 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1664 InstrItinClass itin = NoItinerary> :
1665 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1666 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1668 class TEQI_FT<string opstr, RegisterOperand RO,
1669 InstrItinClass itin = NoItinerary> :
1670 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1671 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1675 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1676 list<Register> DefRegs> :
1677 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1678 itin, FrmR, opstr> {
1679 let isCommutable = 1;
1681 let hasSideEffects = 0;
1684 // Pseudo multiply/divide instruction with explicit accumulator register
1686 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1687 SDPatternOperator OpNode, InstrItinClass Itin,
1688 bit IsComm = 1, bit HasSideEffects = 0,
1689 bit UsesCustomInserter = 0> :
1690 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1691 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1692 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1693 let isCommutable = IsComm;
1694 let hasSideEffects = HasSideEffects;
1695 let usesCustomInserter = UsesCustomInserter;
1698 // Pseudo multiply add/sub instruction with explicit accumulator register
1700 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1701 InstrItinClass itin>
1702 : PseudoSE<(outs ACC64:$ac),
1703 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1705 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1707 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1708 string Constraints = "$acin = $ac";
1711 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1712 list<Register> DefRegs> :
1713 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1714 [], itin, FrmR, opstr> {
1719 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1720 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1721 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1723 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1724 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1726 let Uses = [UseReg];
1727 let hasSideEffects = 0;
1731 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1732 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1733 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1736 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1737 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1740 let hasSideEffects = 0;
1744 class EffectiveAddress<string opstr, RegisterOperand RO> :
1745 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1746 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1747 !strconcat(opstr, "_lea")> {
1748 let isCodeGenOnly = 1;
1749 let hasNoSchedulingInfo = 1;
1750 let DecoderMethod = "DecodeMem";
1753 // Count Leading Ones/Zeros in Word
1754 class CountLeading0<string opstr, RegisterOperand RO,
1755 InstrItinClass itin = NoItinerary>:
1756 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1757 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1759 class CountLeading1<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 (not RO:$rs)))], itin, FrmR, opstr>;
1764 // Sign Extend in Register.
1765 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1766 InstrItinClass itin> :
1767 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1768 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1771 class SubwordSwap<string opstr, RegisterOperand RO,
1772 InstrItinClass itin = NoItinerary>:
1773 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1775 let hasSideEffects = 0;
1779 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1780 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1781 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1784 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1785 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1786 SDPatternOperator Op = null_frag> :
1787 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1788 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1789 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1792 // 'ins' and its' 64 bit variants are matched by C++ code.
1793 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1794 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1795 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1796 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1797 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1799 II_INS, FrmR, opstr> {
1800 let Constraints = "$src = $rt";
1803 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1804 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1805 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1806 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
1807 let hasNoSchedulingInfo = 1;
1810 class Atomic2OpsPostRA<RegisterClass RC> :
1811 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1816 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1817 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1818 RC:$shiftamnt), []>;
1820 // Atomic Compare & Swap.
1821 // Atomic compare and swap is lowered into two stages. The first stage happens
1822 // during ISelLowering, which produces the PostRA version of this instruction.
1823 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1824 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1825 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
1826 let hasNoSchedulingInfo = 1;
1829 class AtomicCmpSwapPostRA<RegisterClass RC> :
1830 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1835 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1836 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1837 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1842 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1843 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1844 [], II_LL, FrmI, opstr> {
1845 let DecoderMethod = "DecodeMem";
1849 class SCBase<string opstr, RegisterOperand RO> :
1850 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1851 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1852 let DecoderMethod = "DecodeMem";
1854 let Constraints = "$rt = $dst";
1857 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1858 InstrItinClass itin> :
1859 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1860 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1861 let BaseOpcode = asmstr;
1864 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1865 InstrItinClass itin> :
1866 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1867 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1868 let BaseOpcode = asmstr;
1871 class TrapBase<Instruction RealInst>
1872 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1873 PseudoInstExpansion<(RealInst 0, 0)> {
1875 let isTerminator = 1;
1876 let isCodeGenOnly = 1;
1880 //===----------------------------------------------------------------------===//
1881 // Pseudo instructions
1882 //===----------------------------------------------------------------------===//
1885 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1886 let hasDelaySlot=1 in
1887 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1889 let hasSideEffects=1 in
1890 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1893 let Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
1894 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1895 [(callseq_start timm:$amt1, timm:$amt2)]>;
1896 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1897 [(callseq_end timm:$amt1, timm:$amt2)]>;
1900 let usesCustomInserter = 1 in {
1901 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1902 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1903 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1904 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1905 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1906 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1907 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1908 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1909 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1910 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1911 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1912 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1913 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1914 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1915 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1916 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1917 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1918 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1920 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1921 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1922 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1924 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1925 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1926 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1928 def ATOMIC_LOAD_MIN_I8 : Atomic2Ops<atomic_load_min_8, GPR32>;
1929 def ATOMIC_LOAD_MIN_I16 : Atomic2Ops<atomic_load_min_16, GPR32>;
1930 def ATOMIC_LOAD_MIN_I32 : Atomic2Ops<atomic_load_min_32, GPR32>;
1931 def ATOMIC_LOAD_MAX_I8 : Atomic2Ops<atomic_load_max_8, GPR32>;
1932 def ATOMIC_LOAD_MAX_I16 : Atomic2Ops<atomic_load_max_16, GPR32>;
1933 def ATOMIC_LOAD_MAX_I32 : Atomic2Ops<atomic_load_max_32, GPR32>;
1934 def ATOMIC_LOAD_UMIN_I8 : Atomic2Ops<atomic_load_umin_8, GPR32>;
1935 def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops<atomic_load_umin_16, GPR32>;
1936 def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops<atomic_load_umin_32, GPR32>;
1937 def ATOMIC_LOAD_UMAX_I8 : Atomic2Ops<atomic_load_umax_8, GPR32>;
1938 def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops<atomic_load_umax_16, GPR32>;
1939 def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops<atomic_load_umax_32, GPR32>;
1942 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1943 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1944 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1945 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1946 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1947 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1948 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1949 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1950 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1951 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1952 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1953 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1954 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1955 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1956 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1957 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1958 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1959 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1961 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1962 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1963 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1965 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1966 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1967 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
1969 def ATOMIC_LOAD_MIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1970 def ATOMIC_LOAD_MIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1971 def ATOMIC_LOAD_MIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1972 def ATOMIC_LOAD_MAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1973 def ATOMIC_LOAD_MAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1974 def ATOMIC_LOAD_MAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1975 def ATOMIC_LOAD_UMIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1976 def ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1977 def ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1978 def ATOMIC_LOAD_UMAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1979 def ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1980 def ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1982 /// Pseudo instructions for loading and storing accumulator registers.
1983 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1984 def LOAD_ACC64 : Load<"", ACC64>;
1985 def STORE_ACC64 : Store<"", ACC64>;
1988 // We need these two pseudo instructions to avoid offset calculation for long
1989 // branches. See the comment in file MipsLongBranch.cpp for detailed
1992 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
1993 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1994 (ins brtarget:$tgt, brtarget:$baltgt), []> {
1995 bit hasNoSchedulingInfo = 1;
1997 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
1998 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
1999 (ins brtarget:$tgt), []> {
2000 bit hasNoSchedulingInfo = 1;
2003 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2004 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2005 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
2006 bit hasNoSchedulingInfo = 1;
2008 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2009 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2010 (ins GPR32Opnd:$src, brtarget:$tgt), []> {
2011 bit hasNoSchedulingInfo = 1;
2014 //===----------------------------------------------------------------------===//
2015 // Instruction definition
2016 //===----------------------------------------------------------------------===//
2017 //===----------------------------------------------------------------------===//
2018 // MipsI Instructions
2019 //===----------------------------------------------------------------------===//
2021 /// Arithmetic Instructions (ALU Immediate)
2022 let AdditionalPredicates = [NotInMicroMips] in {
2023 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2024 II_ADDIU, imm32SExt16, add>,
2025 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2027 def ANDi : MMRel, StdMMR6Rel,
2028 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, imm32ZExt16, and>,
2029 ADDI_FM<0xc>, ISA_MIPS1;
2030 def ORi : MMRel, StdMMR6Rel,
2031 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, imm32ZExt16, or>,
2032 ADDI_FM<0xd>, ISA_MIPS1;
2033 def XORi : MMRel, StdMMR6Rel,
2034 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, imm32ZExt16, xor>,
2035 ADDI_FM<0xe>, ISA_MIPS1;
2036 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2037 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2038 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2039 SLTI_FM<0xa>, ISA_MIPS1;
2040 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2041 SLTI_FM<0xb>, ISA_MIPS1;
2043 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2046 /// Arithmetic Instructions (3-Operand, R-Type)
2047 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2048 ADD_FM<0, 0x21>, ISA_MIPS1;
2049 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2050 ADD_FM<0, 0x23>, ISA_MIPS1;
2052 let Defs = [HI0, LO0] in
2053 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2054 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2056 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2057 ADD_FM<0, 0x20>, ISA_MIPS1;
2058 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2059 ADD_FM<0, 0x22>, ISA_MIPS1;
2061 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2063 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2065 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2066 ADD_FM<0, 0x24>, ISA_MIPS1;
2067 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2068 ADD_FM<0, 0x25>, ISA_MIPS1;
2069 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2070 ADD_FM<0, 0x26>, ISA_MIPS1;
2071 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2075 let AdditionalPredicates = [NotInMicroMips] in {
2076 /// Shift Instructions
2077 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2078 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2079 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2080 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2081 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2082 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2083 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2084 SRLV_FM<4, 0>, ISA_MIPS1;
2085 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2086 SRLV_FM<6, 0>, ISA_MIPS1;
2087 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2088 SRLV_FM<7, 0>, ISA_MIPS1;
2090 // Rotate Instructions
2091 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2093 SRA_FM<2, 1>, ISA_MIPS32R2;
2094 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2095 SRLV_FM<6, 1>, ISA_MIPS32R2;
2098 /// Load and Store Instructions
2100 let AdditionalPredicates = [NotInMicroMips] in {
2101 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2102 LW_FM<0x20>, ISA_MIPS1;
2103 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2104 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2105 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2106 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2107 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2108 MMRel, LW_FM<0x25>, ISA_MIPS1;
2109 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2110 LW_FM<0x23>, ISA_MIPS1;
2111 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2112 LW_FM<0x28>, ISA_MIPS1;
2113 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2115 def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>,
2116 MMRel, LW_FM<0x2b>, ISA_MIPS1;
2119 /// load/store left/right
2120 let AdditionalPredicates = [NotInMicroMips] in {
2121 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2122 ISA_MIPS1_NOT_32R6_64R6;
2123 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2124 ISA_MIPS1_NOT_32R6_64R6;
2125 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2126 ISA_MIPS1_NOT_32R6_64R6;
2127 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2128 ISA_MIPS1_NOT_32R6_64R6;
2130 // COP2 Memory Instructions
2131 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2132 ISA_MIPS1_NOT_32R6_64R6;
2133 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2134 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2135 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2136 ISA_MIPS2_NOT_32R6_64R6;
2137 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2138 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2140 // COP3 Memory Instructions
2141 let DecoderNamespace = "COP3_" in {
2142 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2143 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2144 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2145 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2146 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2147 ISA_MIPS2, NOT_ASE_CNMIPS;
2148 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2149 ISA_MIPS2, NOT_ASE_CNMIPS;
2152 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2153 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2157 let AdditionalPredicates = [NotInMicroMips] in {
2158 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2160 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2162 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2164 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2166 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2168 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2171 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2172 ISA_MIPS2_NOT_32R6_64R6;
2173 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2174 ISA_MIPS2_NOT_32R6_64R6;
2175 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2176 ISA_MIPS2_NOT_32R6_64R6;
2177 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2178 ISA_MIPS2_NOT_32R6_64R6;
2179 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2180 ISA_MIPS2_NOT_32R6_64R6;
2181 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2182 ISA_MIPS2_NOT_32R6_64R6;
2185 let AdditionalPredicates = [NotInMicroMips] in {
2186 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2187 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2189 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2190 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2191 ISA_MIPS32_NOT_32R6_64R6;
2193 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2194 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2196 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2198 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2200 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2203 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2206 let AdditionalPredicates = [NotInMicroMips] in {
2207 /// Load-linked, Store-conditional
2208 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2209 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2211 /// Jump and Branch Instructions
2212 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2213 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2214 IsBranch, ISA_MIPS1;
2216 let AdditionalPredicates = [NotInMicroMips] in {
2217 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>,
2218 ISA_MIPS1_NOT_32R6_64R6;
2219 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2221 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2222 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2223 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2225 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2226 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2227 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2228 BGEZ_FM<1, 1>, ISA_MIPS1;
2229 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2230 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2231 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2232 BGEZ_FM<7, 0>, ISA_MIPS1;
2233 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2234 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2235 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2236 BGEZ_FM<6, 0>, ISA_MIPS1;
2237 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2238 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2239 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2240 BGEZ_FM<1, 0>, ISA_MIPS1;
2241 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2242 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2243 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2245 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2249 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2250 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2251 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2254 let AdditionalPredicates = [NotInMicroMips] in {
2255 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2256 ISA_MIPS32_NOT_32R6_64R6;
2257 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2258 ISA_MIPS1_NOT_32R6_64R6;
2259 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2260 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2261 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2262 ISA_MIPS1_NOT_32R6_64R6;
2263 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2264 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2265 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2267 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2268 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2270 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2271 NoIndirectJumpGuards] in
2272 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2274 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2275 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2276 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2277 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2278 II_IndirectBranchPseudo>,
2279 PseudoInstExpansion<(JumpInst RO:$rs)> {
2282 let hasDelaySlot = 1;
2284 let isIndirectBranch = 1;
2288 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2289 NoIndirectJumpGuards] in
2290 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2291 ISA_MIPS1_NOT_32R6_64R6;
2293 // Return instructions are matched as a RetRA instruction, then are expanded
2294 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2295 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2297 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2298 [], II_ReturnPseudo> {
2299 let isTerminator = 1;
2301 let hasDelaySlot = 1;
2303 let isCodeGenOnly = 1;
2305 let hasExtraSrcRegAllocReq = 1;
2309 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2311 // Exception handling related node and instructions.
2312 // The conversion sequence is:
2313 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2314 // MIPSeh_return -> (stack change + indirect branch)
2316 // MIPSeh_return takes the place of regular return instruction
2317 // but takes two arguments (V1, V0) which are used for storing
2318 // the offset and return address respectively.
2319 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2321 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2322 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2324 let Uses = [V0, V1], isTerminator = 1, isReturn = 1,
2325 isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
2326 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2327 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2328 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
2329 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2332 /// Multiply and Divide Instructions.
2333 let AdditionalPredicates = [NotInMicroMips] in {
2334 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2335 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2336 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2337 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2338 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2339 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2340 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2341 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2342 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2343 ISA_MIPS1_NOT_32R6_64R6;
2344 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2345 ISA_MIPS1_NOT_32R6_64R6;
2346 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2347 ISA_MIPS1_NOT_32R6_64R6;
2348 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2349 ISA_MIPS1_NOT_32R6_64R6;
2351 /// Sign Ext In Register Instructions.
2352 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2353 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2354 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2355 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2358 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2359 ISA_MIPS32_NOT_32R6_64R6;
2360 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2361 ISA_MIPS32_NOT_32R6_64R6;
2363 /// Word Swap Bytes Within Halfwords
2364 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2368 def NOP : PseudoSE<(outs), (ins), []>,
2369 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2371 // FrameIndexes are legalized when they are operands from load/store
2372 // instructions. The same not happens for stack address copies, so an
2373 // add op with mem ComplexPattern is used and the stack address copy
2374 // can be matched. It's similar to Sparc LEA_ADDRi
2375 let AdditionalPredicates = [NotInMicroMips] in
2376 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>,
2380 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2381 ISA_MIPS32_NOT_32R6_64R6;
2382 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2383 ISA_MIPS32_NOT_32R6_64R6;
2384 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2385 ISA_MIPS32_NOT_32R6_64R6;
2386 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2387 ISA_MIPS32_NOT_32R6_64R6;
2390 let AdditionalPredicates = [NotDSP] in {
2391 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2392 ISA_MIPS1_NOT_32R6_64R6;
2393 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2394 ISA_MIPS1_NOT_32R6_64R6;
2395 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2396 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2397 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2398 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2399 ISA_MIPS32_NOT_32R6_64R6;
2400 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2401 ISA_MIPS32_NOT_32R6_64R6;
2402 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2403 ISA_MIPS32_NOT_32R6_64R6;
2404 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2405 ISA_MIPS32_NOT_32R6_64R6;
2408 let AdditionalPredicates = [NotInMicroMips] in {
2409 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2410 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2411 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2412 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2413 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2414 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2415 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2416 immZExt5, immZExt5Plus1, MipsExt>,
2417 EXT_FM<0>, ISA_MIPS32R2;
2418 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2419 uimm5_inssize_plus1, immZExt5,
2421 EXT_FM<4>, ISA_MIPS32R2;
2423 /// Move Control Registers From/To CPU Registers
2424 let AdditionalPredicates = [NotInMicroMips] in {
2425 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2426 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2427 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2428 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2429 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2430 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2431 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2432 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2435 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2436 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2437 let AdditionalPredicates = [NotInMicroMips] in {
2438 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2440 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2443 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2447 // JR_HB and JALR_HB are defined here using the new style naming
2448 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2449 // and because of that it doesn't follow the naming convention of the
2450 // rest of the file. To avoid a mixture of old vs new style, the new
2451 // style was chosen.
2452 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2453 dag OutOperandList = (outs);
2454 dag InOperandList = (ins GPROpnd:$rs);
2455 string AsmString = !strconcat(instr_asm, "\t$rs");
2456 list<dag> Pattern = [];
2459 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2460 dag OutOperandList = (outs GPROpnd:$rd);
2461 dag InOperandList = (ins GPROpnd:$rs);
2462 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2463 list<dag> Pattern = [];
2466 class JR_HB_DESC<RegisterOperand RO> :
2467 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2469 let isIndirectBranch=1;
2476 class JALR_HB_DESC<RegisterOperand RO> :
2477 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2479 let isIndirectBranch=1;
2484 class JR_HB_ENC : JR_HB_FM<8>;
2485 class JALR_HB_ENC : JALR_HB_FM<9>;
2487 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2488 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2490 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2491 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2494 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2495 UseIndirectJumpsHazard] in {
2496 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2497 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2498 ISA_MIPS32R2_NOT_32R6_64R6;
2501 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2502 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2503 let AdditionalPredicates = [NotInMicroMips] in {
2504 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2505 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2506 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2507 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2509 class CacheOp<string instr_asm, Operand MemOpnd,
2510 InstrItinClass itin = NoItinerary> :
2511 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2512 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2514 let DecoderMethod = "DecodeCacheOp";
2517 let AdditionalPredicates = [NotInMicroMips] in {
2518 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2519 INSN_MIPS3_32_NOT_32R6_64R6;
2520 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2521 INSN_MIPS3_32_NOT_32R6_64R6;
2523 // FIXME: We are missing the prefx instruction.
2524 def ROL : MipsAsmPseudoInst<(outs),
2525 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2526 "rol\t$rs, $rt, $rd">;
2527 def ROLImm : MipsAsmPseudoInst<(outs),
2528 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2529 "rol\t$rs, $rt, $imm">;
2530 def : MipsInstAlias<"rol $rd, $rs",
2531 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2532 def : MipsInstAlias<"rol $rd, $imm",
2533 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2535 def ROR : MipsAsmPseudoInst<(outs),
2536 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2537 "ror\t$rs, $rt, $rd">;
2538 def RORImm : MipsAsmPseudoInst<(outs),
2539 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2540 "ror\t$rs, $rt, $imm">;
2541 def : MipsInstAlias<"ror $rd, $rs",
2542 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2543 def : MipsInstAlias<"ror $rd, $imm",
2544 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2546 def DROL : MipsAsmPseudoInst<(outs),
2547 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2548 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2549 def DROLImm : MipsAsmPseudoInst<(outs),
2550 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2551 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2552 def : MipsInstAlias<"drol $rd, $rs",
2553 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2555 def : MipsInstAlias<"drol $rd, $imm",
2556 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2559 def DROR : MipsAsmPseudoInst<(outs),
2560 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2561 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2562 def DRORImm : MipsAsmPseudoInst<(outs),
2563 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2564 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2565 def : MipsInstAlias<"dror $rd, $rs",
2566 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2568 def : MipsInstAlias<"dror $rd, $imm",
2569 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2572 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2575 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2576 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2577 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2579 def : MipsInstAlias<"seq $rd, $rs",
2580 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2583 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2584 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2585 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2587 def : MipsInstAlias<"seq $rd, $imm",
2588 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2591 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2592 simm32_relaxed:$imm),
2593 "mul\t$rd, $rs, $imm">,
2594 ISA_MIPS1_NOT_32R6_64R6;
2595 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2597 "mulo\t$rd, $rs, $rt">,
2598 ISA_MIPS1_NOT_32R6_64R6;
2599 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2601 "mulou\t$rd, $rs, $rt">,
2602 ISA_MIPS1_NOT_32R6_64R6;
2604 // Virtualization ASE
2605 class HYPCALL_FT<string opstr> :
2606 InstSE<(outs), (ins uimm10:$code_),
2607 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2608 let BaseOpcode = opstr;
2611 let AdditionalPredicates = [NotInMicroMips] in {
2612 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2613 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2614 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2615 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2616 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2617 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2618 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2619 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2620 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2621 ISA_MIPS32R5, ASE_VIRT;
2622 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2623 ISA_MIPS32R5, ASE_VIRT;
2624 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2625 ISA_MIPS32R5, ASE_VIRT;
2626 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2627 ISA_MIPS32R5, ASE_VIRT;
2628 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2629 ISA_MIPS32R5, ASE_VIRT;
2630 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2631 ISA_MIPS32R5, ASE_VIRT;
2632 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2633 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2636 //===----------------------------------------------------------------------===//
2637 // Instruction aliases
2638 //===----------------------------------------------------------------------===//
2640 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2642 RegisterOperand RO = GPR32Opnd,
2643 Operand Imm = simm32_relaxed> {
2644 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2648 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2654 let AdditionalPredicates = [NotInMicroMips] in {
2655 def : MipsInstAlias<"move $dst, $src",
2656 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2658 def : MipsInstAlias<"move $dst, $src",
2659 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2662 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2663 ISA_MIPS1_NOT_32R6_64R6;
2665 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2667 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2669 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2672 def : MipsInstAlias<"neg $rt, $rs",
2673 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2674 def : MipsInstAlias<"neg $rt",
2675 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2676 def : MipsInstAlias<"negu $rt, $rs",
2677 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2678 def : MipsInstAlias<"negu $rt",
2679 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2681 def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2682 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2683 "sge\t$rd, $rs, $rt">, ISA_MIPS1;
2684 def : MipsInstAlias<"sge $rs, $rt",
2685 (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2687 def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2688 (ins GPR32Opnd:$rs, simm32:$imm),
2689 "sge\t$rd, $rs, $imm">, GPR_32;
2690 def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
2695 def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2696 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2697 "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
2698 def : MipsInstAlias<"sgeu $rs, $rt",
2699 (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2701 def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2702 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2703 "sgeu\t$rd, $rs, $imm">, GPR_32;
2704 def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
2706 uimm32_coerced:$imm), 0>,
2709 def : MipsInstAlias<
2710 "sgt $rd, $rs, $rt",
2711 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2712 def : MipsInstAlias<
2714 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2716 def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2717 (ins GPR32Opnd:$rs, simm32:$imm),
2718 "sgt\t$rd, $rs, $imm">, GPR_32;
2719 def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
2723 def : MipsInstAlias<
2724 "sgtu $rd, $rs, $rt",
2725 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2726 def : MipsInstAlias<
2728 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2730 def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2731 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2732 "sgtu\t$rd, $rs, $imm">, GPR_32;
2733 def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
2735 uimm32_coerced:$imm), 0>,
2738 def : MipsInstAlias<
2740 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2741 def : MipsInstAlias<
2743 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2745 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2747 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>,
2748 ISA_MIPS1_NOT_32R6_64R6;
2750 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2752 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2754 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2756 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2758 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2760 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2762 def : MipsInstAlias<"mfgc0 $rt, $rd",
2763 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2764 ISA_MIPS32R5, ASE_VIRT;
2765 def : MipsInstAlias<"mtgc0 $rt, $rd",
2766 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2767 ISA_MIPS32R5, ASE_VIRT;
2768 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2769 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2770 ISA_MIPS32R5, ASE_VIRT;
2771 def : MipsInstAlias<"mthgc0 $rt, $rd",
2772 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2773 ISA_MIPS32R5, ASE_VIRT;
2774 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2776 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2778 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2780 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2783 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2786 def : MipsInstAlias<"bnez $rs,$offset",
2787 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2789 def : MipsInstAlias<"bnezl $rs, $offset",
2790 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2792 def : MipsInstAlias<"beqz $rs,$offset",
2793 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2795 def : MipsInstAlias<"beqzl $rs, $offset",
2796 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2799 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2801 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2802 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2803 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2804 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2806 def : MipsInstAlias<"teq $rs, $rt",
2807 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2808 def : MipsInstAlias<"tge $rs, $rt",
2809 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2810 def : MipsInstAlias<"tgeu $rs, $rt",
2811 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2812 def : MipsInstAlias<"tlt $rs, $rt",
2813 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2814 def : MipsInstAlias<"tltu $rs, $rt",
2815 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2816 def : MipsInstAlias<"tne $rs, $rt",
2817 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2818 def : MipsInstAlias<"rdhwr $rt, $rs",
2819 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2822 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2823 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2824 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2825 def : MipsInstAlias<"sub $rs, $imm",
2826 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2827 0>, ISA_MIPS1_NOT_32R6_64R6;
2828 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2829 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2830 InvertedImOperand:$imm), 0>;
2831 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2832 InvertedImOperand:$imm), 0>;
2833 let AdditionalPredicates = [NotInMicroMips] in {
2834 def : MipsInstAlias<"sll $rd, $rt, $rs",
2835 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2836 def : MipsInstAlias<"sra $rd, $rt, $rs",
2837 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2838 def : MipsInstAlias<"srl $rd, $rt, $rs",
2839 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2840 def : MipsInstAlias<"sll $rd, $rt",
2841 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2842 def : MipsInstAlias<"sra $rd, $rt",
2843 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2844 def : MipsInstAlias<"srl $rd, $rt",
2845 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2846 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2848 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2851 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2852 let AdditionalPredicates = [NotInMicroMips] in
2853 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2855 def : MipsInstAlias<"mulo $rs, $rt",
2856 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2857 ISA_MIPS1_NOT_32R6_64R6;
2858 def : MipsInstAlias<"mulou $rs, $rt",
2859 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2860 ISA_MIPS1_NOT_32R6_64R6;
2862 let AdditionalPredicates = [NotInMicroMips] in
2863 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2865 //===----------------------------------------------------------------------===//
2866 // Assembler Pseudo Instructions
2867 //===----------------------------------------------------------------------===//
2869 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2871 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2872 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2873 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2874 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2876 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2877 RegisterOperand RO> :
2878 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2879 !strconcat(instr_asm, "\t$rt, $addr")> ;
2880 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2882 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2883 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2884 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2885 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2887 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2889 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2892 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2893 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2894 "nor\t$rs, $rt, $imm">;
2895 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2896 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2897 simm32_relaxed:$imm)>, GPR_32;
2899 let hasDelaySlot = 1, isCTI = 1 in {
2900 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2901 (ins imm64:$imm64, brtarget:$offset),
2902 "bne\t$rt, $imm64, $offset">;
2903 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2904 (ins imm64:$imm64, brtarget:$offset),
2905 "beq\t$rt, $imm64, $offset">;
2907 class CondBranchPseudo<string instr_asm> :
2908 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2910 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2913 def BLT : CondBranchPseudo<"blt">;
2914 def BLE : CondBranchPseudo<"ble">;
2915 def BGE : CondBranchPseudo<"bge">;
2916 def BGT : CondBranchPseudo<"bgt">;
2917 def BLTU : CondBranchPseudo<"bltu">;
2918 def BLEU : CondBranchPseudo<"bleu">;
2919 def BGEU : CondBranchPseudo<"bgeu">;
2920 def BGTU : CondBranchPseudo<"bgtu">;
2921 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2922 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2923 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2924 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2925 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2926 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2927 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2928 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2931 class CondBranchImmPseudo<string instr_asm> :
2932 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2933 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2935 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2936 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2938 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2939 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2940 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2941 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2942 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2943 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2944 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2945 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2946 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2947 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2948 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2949 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2950 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2951 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2952 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2953 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2955 // FIXME: Predicates are removed because instructions are matched regardless of
2956 // predicates, because PredicateControl was not in the hierarchy. This was
2957 // done to emit more precise error message from expansion function.
2958 // Once the tablegen-erated errors are made better, this needs to be fixed and
2959 // predicates needs to be restored.
2961 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2962 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2963 "div\t$rd, $rs, $rt">,
2964 ISA_MIPS1_NOT_32R6_64R6;
2965 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2966 (ins GPR32Opnd:$rs, simm32:$imm),
2967 "div\t$rd, $rs, $imm">,
2968 ISA_MIPS1_NOT_32R6_64R6;
2969 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2970 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2971 "divu\t$rd, $rs, $rt">,
2972 ISA_MIPS1_NOT_32R6_64R6;
2973 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2974 (ins GPR32Opnd:$rs, simm32:$imm),
2975 "divu\t$rd, $rs, $imm">,
2976 ISA_MIPS1_NOT_32R6_64R6;
2979 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2981 ISA_MIPS1_NOT_32R6_64R6;
2982 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
2983 GPR32NonZeroOpnd:$rs,
2985 ISA_MIPS1_NOT_32R6_64R6;
2986 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2988 ISA_MIPS1_NOT_32R6_64R6;
2990 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
2992 ISA_MIPS1_NOT_32R6_64R6;
2993 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
2994 GPR32NonZeroOpnd:$rt,
2996 ISA_MIPS1_NOT_32R6_64R6;
2998 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3000 ISA_MIPS1_NOT_32R6_64R6;
3002 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3003 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3004 "rem\t$rd, $rs, $rt">,
3005 ISA_MIPS1_NOT_32R6_64R6;
3006 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3007 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3008 "rem\t$rd, $rs, $imm">,
3009 ISA_MIPS1_NOT_32R6_64R6;
3010 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3011 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3012 "remu\t$rd, $rs, $rt">,
3013 ISA_MIPS1_NOT_32R6_64R6;
3014 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3015 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3016 "remu\t$rd, $rs, $imm">,
3017 ISA_MIPS1_NOT_32R6_64R6;
3019 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3021 ISA_MIPS1_NOT_32R6_64R6;
3022 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3023 simm32_relaxed:$imm), 0>,
3024 ISA_MIPS1_NOT_32R6_64R6;
3025 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3027 ISA_MIPS1_NOT_32R6_64R6;
3028 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3029 simm32_relaxed:$imm), 0>,
3030 ISA_MIPS1_NOT_32R6_64R6;
3032 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3033 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3035 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3036 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3038 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3039 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3041 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3042 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3044 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3045 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3047 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3048 (ins mem_simm16:$addr), "ld $rt, $addr">,
3049 ISA_MIPS1_NOT_MIPS3;
3050 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3051 (ins mem_simm16:$addr), "sd $rt, $addr">,
3052 ISA_MIPS1_NOT_MIPS3;
3053 //===----------------------------------------------------------------------===//
3054 // Arbitrary patterns that map to one or more instructions
3055 //===----------------------------------------------------------------------===//
3057 // Load/store pattern templates.
3058 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3059 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3061 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3062 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3064 // Materialize constants.
3065 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3066 Instruction ADDiuOp, Instruction LUiOp,
3067 Instruction ORiOp> {
3069 // Constant synthesis previously relied on the ordering of the patterns below.
3070 // By making the predicates they use non-overlapping, the patterns were
3071 // reordered so that the effect of the newly introduced predicates can be
3074 // Arbitrary immediates
3075 def : MipsPat<(VT LUiORiPred:$imm),
3076 (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3078 // Bits 32-16 set, sign/zero extended.
3079 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3082 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3083 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3086 let AdditionalPredicates = [NotInMicroMips] in
3087 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3089 // Carry MipsPatterns
3090 let AdditionalPredicates = [NotInMicroMips] in {
3091 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3092 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3094 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3095 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3096 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3097 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3099 // Support multiplication for pre-Mips32 targets that don't have
3100 // the MUL instruction.
3101 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3102 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3103 ISA_MIPS1_NOT_32R6_64R6;
3106 def : MipsPat<(MipsSync (i32 immz)),
3107 (SYNC 0)>, ISA_MIPS2;
3110 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3111 (JAL texternalsym:$dst)>, ISA_MIPS1;
3112 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3113 // (JALR GPR32:$dst)>;
3116 let AdditionalPredicates = [NotInMicroMips] in {
3117 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3118 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3119 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3120 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3123 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3124 Register ZeroReg, RegisterOperand GPROpnd> {
3125 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3126 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3127 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3128 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3129 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3131 def : MipsPat<(MipsLo tglobaladdr:$in),
3132 (Addiu ZeroReg, tglobaladdr:$in)>;
3133 def : MipsPat<(MipsLo tblockaddress:$in),
3134 (Addiu ZeroReg, tblockaddress:$in)>;
3135 def : MipsPat<(MipsLo tjumptable:$in),
3136 (Addiu ZeroReg, tjumptable:$in)>;
3137 def : MipsPat<(MipsLo tconstpool:$in),
3138 (Addiu ZeroReg, tconstpool:$in)>;
3139 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3140 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3141 def : MipsPat<(MipsLo texternalsym:$in),
3142 (Addiu ZeroReg, texternalsym:$in)>;
3144 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3145 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3146 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3147 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3148 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3149 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3150 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3151 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3152 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3153 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3154 def : MipsPat<(add GPROpnd:$hi, (MipsLo texternalsym:$lo)),
3155 (Addiu GPROpnd:$hi, texternalsym:$lo)>;
3159 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3160 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3162 let AdditionalPredicates = [NotInMicroMips] in {
3163 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3165 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3166 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3169 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3173 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3174 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3175 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3176 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3178 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3179 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3180 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3181 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3182 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3183 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3185 // Mips does not have "not", so we expand our way
3186 def : MipsPat<(not GPR32:$in),
3187 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3191 let AdditionalPredicates = [NotInMicroMips] in {
3192 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3193 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3194 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3197 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3201 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3202 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3203 Instruction SLTiOp, Instruction SLTiuOp,
3205 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3206 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3207 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3208 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3210 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3211 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3212 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3213 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3214 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3215 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3216 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3217 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3218 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3219 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3220 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3221 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3223 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3224 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3225 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3226 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3228 def : MipsPat<(brcond RC:$cond, bb:$dst),
3229 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3231 let AdditionalPredicates = [NotInMicroMips] in {
3232 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3234 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3235 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3236 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3237 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3241 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3242 Instruction SLTuOp, Register ZEROReg> {
3243 def : MipsPat<(seteq RC:$lhs, 0),
3244 (SLTiuOp RC:$lhs, 1)>;
3245 def : MipsPat<(setne RC:$lhs, 0),
3246 (SLTuOp ZEROReg, RC:$lhs)>;
3247 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3248 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3249 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3250 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3253 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3254 Instruction SLTuOp> {
3255 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3256 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3257 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3258 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3261 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3262 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3263 (SLTOp RC:$rhs, RC:$lhs)>;
3264 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3265 (SLTuOp RC:$rhs, RC:$lhs)>;
3268 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3269 Instruction SLTuOp> {
3270 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3271 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3272 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3273 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3276 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3277 Instruction SLTiOp, Instruction SLTiuOp> {
3278 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3279 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3280 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3281 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3284 let AdditionalPredicates = [NotInMicroMips] in {
3285 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3286 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3287 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3288 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3289 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3292 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3295 // Load halfword/word patterns.
3296 let AdditionalPredicates = [NotInMicroMips] in {
3297 let AddedComplexity = 40 in {
3298 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3299 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3300 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3301 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3302 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3305 // Atomic load patterns.
3306 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3307 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3308 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3310 // Atomic store patterns.
3311 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3313 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3315 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3319 //===----------------------------------------------------------------------===//
3320 // Floating Point Support
3321 //===----------------------------------------------------------------------===//
3323 include "MipsInstrFPU.td"
3324 include "Mips64InstrInfo.td"
3325 include "MipsCondMov.td"
3327 include "Mips32r6InstrInfo.td"
3328 include "Mips64r6InstrInfo.td"
3333 include "Mips16InstrFormats.td"
3334 include "Mips16InstrInfo.td"
3337 include "MipsDSPInstrFormats.td"
3338 include "MipsDSPInstrInfo.td"
3341 include "MipsMSAInstrFormats.td"
3342 include "MipsMSAInstrInfo.td"
3345 include "MipsEVAInstrFormats.td"
3346 include "MipsEVAInstrInfo.td"
3349 include "MipsMTInstrFormats.td"
3350 include "MipsMTInstrInfo.td"
3353 include "MicroMipsInstrFormats.td"
3354 include "MicroMipsInstrInfo.td"
3355 include "MicroMipsInstrFPU.td"
3358 include "MicroMips32r6InstrFormats.td"
3359 include "MicroMips32r6InstrInfo.td"
3362 include "MicroMipsDSPInstrFormats.td"
3363 include "MicroMipsDSPInstrInfo.td"