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 =
963 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
967 def uimm # I # _64 : Operand<i64> {
968 let PrintMethod = "printUImm<" # I # ">";
969 let ParserMatchClass =
970 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
974 def uimm # I # _64 : Operand<i64> {
975 let PrintMethod = "printUImm<" # I # ">";
976 let ParserMatchClass =
977 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
980 // Like uimm16_64 but coerces simm16 to uimm16.
981 def uimm16_64_relaxed : Operand<i64> {
982 let PrintMethod = "printUImm<16>";
983 let ParserMatchClass =
984 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
987 def uimm16_altrelaxed : Operand<i32> {
988 let PrintMethod = "printUImm<16>";
989 let ParserMatchClass =
990 !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
992 // Like uimm5 but reports a less confusing error for 32-63 when
993 // an instruction alias permits that.
994 def uimm5_report_uimm6 : Operand<i32> {
995 let PrintMethod = "printUImm<6>";
996 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
999 // Like uimm5_64 but reports a less confusing error for 32-63 when
1000 // an instruction alias permits that.
1001 def uimm5_64_report_uimm6 : Operand<i64> {
1002 let PrintMethod = "printUImm<5>";
1003 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
1006 foreach I = {1, 2, 3, 4} in
1007 def uimm # I # _ptr : Operand<iPTR> {
1008 let PrintMethod = "printUImm<" # I # ">";
1009 let ParserMatchClass =
1010 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1013 foreach I = {1, 2, 3, 4, 5, 6, 8} in
1014 def vsplat_uimm # I : Operand<vAny> {
1015 let PrintMethod = "printUImm<" # I # ">";
1016 let ParserMatchClass =
1017 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1021 foreach I = {4, 5, 6, 9, 10, 11} in
1022 def simm # I : Operand<i32> {
1023 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1024 let ParserMatchClass =
1025 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1028 foreach I = {1, 2, 3} in
1029 def simm10_lsl # I : Operand<i32> {
1030 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
1031 let ParserMatchClass =
1032 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
1036 def simm # I # _64 : Operand<i64> {
1037 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1038 let ParserMatchClass =
1039 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1042 foreach I = {5, 10} in
1043 def vsplat_simm # I : Operand<vAny> {
1044 let ParserMatchClass =
1045 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1048 def simm7_lsl2 : Operand<OtherVT> {
1049 let EncoderMethod = "getSImm7Lsl2Encoding";
1050 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
1051 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
1054 foreach I = {16, 32} in
1055 def simm # I : Operand<i32> {
1056 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1057 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
1060 // Like simm16 but coerces uimm16 to simm16.
1061 def simm16_relaxed : Operand<i32> {
1062 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1063 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
1066 def simm16_64 : Operand<i64> {
1067 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1068 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
1071 // like simm32 but coerces simm32 to uimm32.
1072 def uimm32_coerced : Operand<i32> {
1073 let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
1075 // Like simm32 but coerces uimm32 to simm32.
1076 def simm32_relaxed : Operand<i32> {
1077 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1078 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
1081 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
1082 def li16_imm : Operand<i32> {
1083 let DecoderMethod = "DecodeLi16Imm";
1084 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
1087 def MipsMemAsmOperand : AsmOperandClass {
1089 let ParserMethod = "parseMemOperand";
1092 def MipsMemSimm9AsmOperand : AsmOperandClass {
1093 let Name = "MemOffsetSimm9";
1094 let SuperClasses = [MipsMemAsmOperand];
1095 let RenderMethod = "addMemOperands";
1096 let ParserMethod = "parseMemOperand";
1097 let PredicateMethod = "isMemWithSimmOffset<9>";
1098 let DiagnosticType = "MemSImm9";
1101 def MipsMemSimm10AsmOperand : AsmOperandClass {
1102 let Name = "MemOffsetSimm10";
1103 let SuperClasses = [MipsMemAsmOperand];
1104 let RenderMethod = "addMemOperands";
1105 let ParserMethod = "parseMemOperand";
1106 let PredicateMethod = "isMemWithSimmOffset<10>";
1107 let DiagnosticType = "MemSImm10";
1110 def MipsMemSimm12AsmOperand : AsmOperandClass {
1111 let Name = "MemOffsetSimm12";
1112 let SuperClasses = [MipsMemAsmOperand];
1113 let RenderMethod = "addMemOperands";
1114 let ParserMethod = "parseMemOperand";
1115 let PredicateMethod = "isMemWithSimmOffset<12>";
1116 let DiagnosticType = "MemSImm12";
1119 foreach I = {1, 2, 3} in
1120 def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
1121 let Name = "MemOffsetSimm10_" # I;
1122 let SuperClasses = [MipsMemAsmOperand];
1123 let RenderMethod = "addMemOperands";
1124 let ParserMethod = "parseMemOperand";
1125 let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
1126 let DiagnosticType = "MemSImm10Lsl" # I;
1129 def MipsMemSimm11AsmOperand : AsmOperandClass {
1130 let Name = "MemOffsetSimm11";
1131 let SuperClasses = [MipsMemAsmOperand];
1132 let RenderMethod = "addMemOperands";
1133 let ParserMethod = "parseMemOperand";
1134 let PredicateMethod = "isMemWithSimmOffset<11>";
1135 let DiagnosticType = "MemSImm11";
1138 def MipsMemSimm16AsmOperand : AsmOperandClass {
1139 let Name = "MemOffsetSimm16";
1140 let SuperClasses = [MipsMemAsmOperand];
1141 let RenderMethod = "addMemOperands";
1142 let ParserMethod = "parseMemOperand";
1143 let PredicateMethod = "isMemWithSimmOffset<16>";
1144 let DiagnosticType = "MemSImm16";
1147 def MipsMemSimmPtrAsmOperand : AsmOperandClass {
1148 let Name = "MemOffsetSimmPtr";
1149 let SuperClasses = [MipsMemAsmOperand];
1150 let RenderMethod = "addMemOperands";
1151 let ParserMethod = "parseMemOperand";
1152 let PredicateMethod = "isMemWithPtrSizeOffset";
1153 let DiagnosticType = "MemSImmPtr";
1156 def MipsInvertedImmoperand : AsmOperandClass {
1157 let Name = "InvNum";
1158 let RenderMethod = "addImmOperands";
1159 let ParserMethod = "parseInvNum";
1162 def InvertedImOperand : Operand<i32> {
1163 let ParserMatchClass = MipsInvertedImmoperand;
1166 def InvertedImOperand64 : Operand<i64> {
1167 let ParserMatchClass = MipsInvertedImmoperand;
1170 class mem_generic : Operand<iPTR> {
1171 let PrintMethod = "printMemOperand";
1172 let MIOperandInfo = (ops ptr_rc, simm16);
1173 let EncoderMethod = "getMemEncoding";
1174 let ParserMatchClass = MipsMemAsmOperand;
1175 let OperandType = "OPERAND_MEMORY";
1179 def mem : mem_generic;
1181 // MSA specific address operand
1182 def mem_msa : mem_generic {
1183 let MIOperandInfo = (ops ptr_rc, simm10);
1184 let EncoderMethod = "getMSAMemEncoding";
1187 def simm12 : Operand<i32> {
1188 let DecoderMethod = "DecodeSimm12";
1191 def mem_simm9 : mem_generic {
1192 let MIOperandInfo = (ops ptr_rc, simm9);
1193 let EncoderMethod = "getMemEncoding";
1194 let ParserMatchClass = MipsMemSimm9AsmOperand;
1197 def mem_simm10 : mem_generic {
1198 let MIOperandInfo = (ops ptr_rc, simm10);
1199 let EncoderMethod = "getMemEncoding";
1200 let ParserMatchClass = MipsMemSimm10AsmOperand;
1203 foreach I = {1, 2, 3} in
1204 def mem_simm10_lsl # I : mem_generic {
1205 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1206 let EncoderMethod = "getMemEncoding<" # I # ">";
1207 let ParserMatchClass =
1208 !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
1211 def mem_simm11 : mem_generic {
1212 let MIOperandInfo = (ops ptr_rc, simm11);
1213 let EncoderMethod = "getMemEncoding";
1214 let ParserMatchClass = MipsMemSimm11AsmOperand;
1217 def mem_simm12 : mem_generic {
1218 let MIOperandInfo = (ops ptr_rc, simm12);
1219 let EncoderMethod = "getMemEncoding";
1220 let ParserMatchClass = MipsMemSimm12AsmOperand;
1223 def mem_simm16 : mem_generic {
1224 let MIOperandInfo = (ops ptr_rc, simm16);
1225 let EncoderMethod = "getMemEncoding";
1226 let ParserMatchClass = MipsMemSimm16AsmOperand;
1229 def mem_simmptr : mem_generic {
1230 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1233 def mem_ea : Operand<iPTR> {
1234 let PrintMethod = "printMemOperandEA";
1235 let MIOperandInfo = (ops ptr_rc, simm16);
1236 let EncoderMethod = "getMemEncoding";
1237 let OperandType = "OPERAND_MEMORY";
1240 def PtrRC : Operand<iPTR> {
1241 let MIOperandInfo = (ops ptr_rc);
1242 let DecoderMethod = "DecodePtrRegisterClass";
1243 let ParserMatchClass = GPR32AsmOperand;
1246 // size operand of ins instruction
1247 def size_ins : Operand<i32> {
1248 let EncoderMethod = "getSizeInsEncoding";
1249 let DecoderMethod = "DecodeInsSize";
1252 // Transformation Function - get the lower 16 bits.
1253 def LO16 : SDNodeXForm<imm, [{
1254 return getImm(N, N->getZExtValue() & 0xFFFF);
1257 // Transformation Function - get the higher 16 bits.
1258 def HI16 : SDNodeXForm<imm, [{
1259 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1263 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1265 // Node immediate is zero (e.g. insve.d)
1266 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1268 // Node immediate fits as 16-bit sign extended on target immediate.
1270 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1272 // Node immediate fits as 16-bit sign extended on target immediate.
1274 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1276 // Node immediate fits as 7-bit zero extended on target immediate.
1277 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1279 // Node immediate fits as 16-bit zero extended on target immediate.
1280 // The LO16 param means that only the lower 16 bits of the node
1281 // immediate are caught.
1282 // e.g. addiu, sltiu
1283 def immZExt16 : PatLeaf<(imm), [{
1284 if (N->getValueType(0) == MVT::i32)
1285 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1287 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1290 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1291 def immSExt32Low16Zero : PatLeaf<(imm), [{
1292 int64_t Val = N->getSExtValue();
1293 return isInt<32>(Val) && !(Val & 0xffff);
1296 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1297 def immZExt32Low16Zero : PatLeaf<(imm), [{
1298 uint64_t Val = N->getZExtValue();
1299 return isUInt<32>(Val) && !(Val & 0xffff);
1302 // Note immediate fits as a 32 bit signed extended on target immediate.
1303 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1305 // Note immediate fits as a 32 bit zero extended on target immediate.
1306 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1308 // shamt field must fit in 5 bits.
1309 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1311 def immZExt5Plus1 : PatLeaf<(imm), [{
1312 return isUInt<5>(N->getZExtValue() - 1);
1314 def immZExt5Plus32 : PatLeaf<(imm), [{
1315 return isUInt<5>(N->getZExtValue() - 32);
1317 def immZExt5Plus33 : PatLeaf<(imm), [{
1318 return isUInt<5>(N->getZExtValue() - 33);
1321 def immZExt5To31 : SDNodeXForm<imm, [{
1322 return getImm(N, 31 - N->getZExtValue());
1325 // True if (N + 1) fits in 16-bit field.
1326 def immSExt16Plus1 : PatLeaf<(imm), [{
1327 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1330 def immZExtRange2To64 : PatLeaf<(imm), [{
1331 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1332 (N->getZExtValue() <= 64);
1335 def ORiPred : PatLeaf<(imm), [{
1336 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1339 def LUiPred : PatLeaf<(imm), [{
1340 int64_t Val = N->getSExtValue();
1341 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1344 def LUiORiPred : PatLeaf<(imm), [{
1345 int64_t SVal = N->getSExtValue();
1346 return isInt<32>(SVal) && (SVal & 0xffff);
1349 // Mips Address Mode! SDNode frameindex could possibily be a match
1350 // since load and store instructions from stack used it.
1352 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1355 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1358 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1360 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1361 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1363 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1365 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1368 //===----------------------------------------------------------------------===//
1369 // Instructions specific format
1370 //===----------------------------------------------------------------------===//
1372 // Arithmetic and logical instructions with 3 register operands.
1373 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1374 InstrItinClass Itin = NoItinerary,
1375 SDPatternOperator OpNode = null_frag>:
1376 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1377 !strconcat(opstr, "\t$rd, $rs, $rt"),
1378 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1379 let isCommutable = isComm;
1380 let isReMaterializable = 1;
1381 let TwoOperandAliasConstraint = "$rd = $rs";
1384 // Arithmetic and logical instructions with 2 register operands.
1385 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1386 InstrItinClass Itin = NoItinerary,
1387 SDPatternOperator imm_type = null_frag,
1388 SDPatternOperator OpNode = null_frag> :
1389 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1390 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1391 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1392 Itin, FrmI, opstr> {
1393 let isReMaterializable = 1;
1394 let TwoOperandAliasConstraint = "$rs = $rt";
1397 // Arithmetic Multiply ADD/SUB
1398 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1399 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1400 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1401 let Defs = [HI0, LO0];
1402 let Uses = [HI0, LO0];
1403 let isCommutable = isComm;
1407 class LogicNOR<string opstr, RegisterOperand RO>:
1408 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1409 !strconcat(opstr, "\t$rd, $rs, $rt"),
1410 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1411 let isCommutable = 1;
1415 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1416 RegisterOperand RO, InstrItinClass itin,
1417 SDPatternOperator OpNode = null_frag,
1418 SDPatternOperator PF = null_frag> :
1419 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1420 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1421 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1422 let TwoOperandAliasConstraint = "$rt = $rd";
1425 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1426 SDPatternOperator OpNode = null_frag>:
1427 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1428 !strconcat(opstr, "\t$rd, $rt, $rs"),
1429 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1432 // Load Upper Immediate
1433 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1434 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1435 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1436 let hasSideEffects = 0;
1437 let isReMaterializable = 1;
1440 // Memory Load/Store
1441 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1442 SDPatternOperator OpNode = null_frag,
1443 InstrItinClass Itin = NoItinerary,
1444 ComplexPattern Addr = addr> :
1445 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1446 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1447 let DecoderMethod = "DecodeMem";
1448 let canFoldAsLoad = 1;
1449 string BaseOpcode = opstr;
1453 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1454 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1455 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1457 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1458 SDPatternOperator OpNode = null_frag,
1459 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1460 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1461 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1462 let DecoderMethod = "DecodeMem";
1463 string BaseOpcode = opstr;
1467 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1468 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1469 DAGOperand MO = mem> :
1470 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1472 // Load/Store Left/Right
1473 let canFoldAsLoad = 1 in
1474 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1475 InstrItinClass Itin> :
1476 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1477 !strconcat(opstr, "\t$rt, $addr"),
1478 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1479 let DecoderMethod = "DecodeMem";
1480 string Constraints = "$src = $rt";
1481 let BaseOpcode = opstr;
1484 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1485 InstrItinClass Itin> :
1486 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1487 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1488 let DecoderMethod = "DecodeMem";
1489 let BaseOpcode = opstr;
1493 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1494 SDPatternOperator OpNode= null_frag> :
1495 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1496 !strconcat(opstr, "\t$rt, $addr"),
1497 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1498 let DecoderMethod = "DecodeFMem2";
1502 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1503 SDPatternOperator OpNode= null_frag> :
1504 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1505 !strconcat(opstr, "\t$rt, $addr"),
1506 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1507 let DecoderMethod = "DecodeFMem2";
1512 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1513 SDPatternOperator OpNode= null_frag> :
1514 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1515 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1516 let DecoderMethod = "DecodeFMem3";
1520 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1521 SDPatternOperator OpNode= null_frag> :
1522 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1523 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1524 let DecoderMethod = "DecodeFMem3";
1528 // Conditional Branch
1529 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1530 RegisterOperand RO> :
1531 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1532 !strconcat(opstr, "\t$rs, $rt, $offset"),
1533 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1536 let isTerminator = 1;
1537 let hasDelaySlot = 1;
1542 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1543 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1544 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1546 let isTerminator = 1;
1547 let hasDelaySlot = 1;
1552 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1553 RegisterOperand RO> :
1554 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1555 !strconcat(opstr, "\t$rs, $offset"),
1556 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1559 let isTerminator = 1;
1560 let hasDelaySlot = 1;
1565 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1566 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1567 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1569 let isTerminator = 1;
1570 let hasDelaySlot = 1;
1576 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1577 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1578 !strconcat(opstr, "\t$rd, $rs, $rt"),
1579 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1580 II_SLT_SLTU, FrmR, opstr>;
1582 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1583 RegisterOperand RO>:
1584 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1585 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1586 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1587 II_SLTI_SLTIU, FrmI, opstr>;
1590 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1591 SDPatternOperator targetoperator, string bopstr> :
1592 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1593 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1596 let hasDelaySlot = 1;
1597 let DecoderMethod = "DecodeJumpTarget";
1602 // Unconditional branch
1603 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1604 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1605 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1607 let isTerminator = 1;
1609 let hasDelaySlot = 1;
1610 let AdditionalPredicates = [RelocPIC];
1615 // Base class for indirect branch and return instruction classes.
1616 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1617 class JumpFR<string opstr, RegisterOperand RO,
1618 SDPatternOperator operator = null_frag>:
1619 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1623 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1625 let isIndirectBranch = 1;
1628 // Jump and Link (Call)
1629 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1630 class JumpLink<string opstr, DAGOperand opnd> :
1631 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1632 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1633 let DecoderMethod = "DecodeJumpTarget";
1636 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1637 Register RetReg, RegisterOperand ResRO = RO>:
1638 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1639 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1640 let hasPostISelHook = 1;
1643 class JumpLinkReg<string opstr, RegisterOperand RO>:
1644 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1645 [], II_JALR, FrmR, opstr> {
1646 let hasPostISelHook = 1;
1649 class BGEZAL_FT<string opstr, DAGOperand opnd,
1650 RegisterOperand RO> :
1651 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1652 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1653 let hasDelaySlot = 1;
1658 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1659 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1660 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1661 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1662 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1664 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1665 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1666 PseudoInstExpansion<(JumpInst RO:$rs)> {
1667 let hasPostISelHook = 1;
1671 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1672 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1673 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1675 let isTerminator = 1;
1677 let hasDelaySlot = 1;
1684 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1685 InstSE<(outs), (ins ImmOp:$code_),
1686 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1688 class BRK_FT<string opstr> :
1689 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1690 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1694 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1695 InstSE<(outs), (ins),
1696 opstr, [], itin, FrmOther, opstr>;
1699 class WAIT_FT<string opstr> :
1700 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1704 class DEI_FT<string opstr, RegisterOperand RO,
1705 InstrItinClass itin = NoItinerary> :
1706 InstSE<(outs RO:$rt), (ins),
1707 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1710 let hasSideEffects = 1 in
1711 class SYNC_FT<string opstr> :
1712 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1713 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1715 class SYNCI_FT<string opstr, DAGOperand MO> :
1716 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1717 II_SYNCI, FrmOther, opstr> {
1718 let hasSideEffects = 1;
1719 let DecoderMethod = "DecodeSyncI";
1722 let hasSideEffects = 1, isCTI = 1 in {
1723 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1724 InstrItinClass itin = NoItinerary> :
1725 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1726 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1728 class TEQI_FT<string opstr, RegisterOperand RO,
1729 InstrItinClass itin = NoItinerary> :
1730 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1731 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1735 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1736 list<Register> DefRegs> :
1737 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1738 itin, FrmR, opstr> {
1739 let isCommutable = 1;
1741 let hasSideEffects = 0;
1744 // Pseudo multiply/divide instruction with explicit accumulator register
1746 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1747 SDPatternOperator OpNode, InstrItinClass Itin,
1748 bit IsComm = 1, bit HasSideEffects = 0,
1749 bit UsesCustomInserter = 0> :
1750 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1751 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1752 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1753 let isCommutable = IsComm;
1754 let hasSideEffects = HasSideEffects;
1755 let usesCustomInserter = UsesCustomInserter;
1758 // Pseudo multiply add/sub instruction with explicit accumulator register
1760 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1761 InstrItinClass itin>
1762 : PseudoSE<(outs ACC64:$ac),
1763 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1765 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1767 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1768 string Constraints = "$acin = $ac";
1771 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1772 list<Register> DefRegs> :
1773 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1774 [], itin, FrmR, opstr> {
1779 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1780 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1781 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1783 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1784 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1786 let Uses = [UseReg];
1787 let hasSideEffects = 0;
1791 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1792 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1793 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1796 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1797 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1800 let hasSideEffects = 0;
1804 class EffectiveAddress<string opstr, RegisterOperand RO> :
1805 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1806 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1807 !strconcat(opstr, "_lea")> {
1808 let isCodeGenOnly = 1;
1809 let hasNoSchedulingInfo = 1;
1810 let DecoderMethod = "DecodeMem";
1813 // Count Leading Ones/Zeros in Word
1814 class CountLeading0<string opstr, RegisterOperand RO,
1815 InstrItinClass itin = NoItinerary>:
1816 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1817 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1819 class CountLeading1<string opstr, RegisterOperand RO,
1820 InstrItinClass itin = NoItinerary>:
1821 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1822 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1824 // Sign Extend in Register.
1825 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1826 InstrItinClass itin> :
1827 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1828 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1831 class SubwordSwap<string opstr, RegisterOperand RO,
1832 InstrItinClass itin = NoItinerary>:
1833 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1835 let hasSideEffects = 0;
1839 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1840 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1841 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1844 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1845 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1846 SDPatternOperator Op = null_frag> :
1847 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1848 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1849 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1852 // 'ins' and its' 64 bit variants are matched by C++ code.
1853 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1854 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1855 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1856 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1857 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1859 II_INS, FrmR, opstr> {
1860 let Constraints = "$src = $rt";
1863 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1864 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1865 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1866 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
1867 let hasNoSchedulingInfo = 1;
1870 class Atomic2OpsPostRA<RegisterClass RC> :
1871 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1876 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1877 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1878 RC:$shiftamnt), []>;
1880 // Atomic Compare & Swap.
1881 // Atomic compare and swap is lowered into two stages. The first stage happens
1882 // during ISelLowering, which produces the PostRA version of this instruction.
1883 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1884 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1885 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
1886 let hasNoSchedulingInfo = 1;
1889 class AtomicCmpSwapPostRA<RegisterClass RC> :
1890 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1895 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1896 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1897 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1902 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1903 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1904 [], II_LL, FrmI, opstr> {
1905 let DecoderMethod = "DecodeMem";
1909 class SCBase<string opstr, RegisterOperand RO> :
1910 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1911 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1912 let DecoderMethod = "DecodeMem";
1914 let Constraints = "$rt = $dst";
1917 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1918 InstrItinClass itin> :
1919 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1920 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1921 let BaseOpcode = asmstr;
1924 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1925 InstrItinClass itin> :
1926 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1927 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1928 let BaseOpcode = asmstr;
1931 class TrapBase<Instruction RealInst>
1932 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1933 PseudoInstExpansion<(RealInst 0, 0)> {
1935 let isTerminator = 1;
1936 let isCodeGenOnly = 1;
1940 //===----------------------------------------------------------------------===//
1941 // Pseudo instructions
1942 //===----------------------------------------------------------------------===//
1945 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1946 let hasDelaySlot=1 in
1947 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1949 let hasSideEffects=1 in
1950 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1953 let Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
1954 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1955 [(callseq_start timm:$amt1, timm:$amt2)]>;
1956 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1957 [(callseq_end timm:$amt1, timm:$amt2)]>;
1960 let usesCustomInserter = 1 in {
1961 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1962 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1963 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1964 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1965 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1966 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1967 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1968 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1969 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1970 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1971 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1972 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1973 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1974 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1975 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1976 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1977 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1978 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1980 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1981 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1982 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1984 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1985 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1986 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1990 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1991 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1992 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1993 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1994 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1995 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1996 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1997 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1998 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1999 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2000 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2001 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
2002 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2003 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2004 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
2005 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2006 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2007 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
2009 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2010 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2011 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
2013 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2014 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2015 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
2017 /// Pseudo instructions for loading and storing accumulator registers.
2018 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
2019 def LOAD_ACC64 : Load<"", ACC64>;
2020 def STORE_ACC64 : Store<"", ACC64>;
2023 // We need these two pseudo instructions to avoid offset calculation for long
2024 // branches. See the comment in file MipsLongBranch.cpp for detailed
2027 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
2028 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
2029 (ins brtarget:$tgt, brtarget:$baltgt), []> {
2030 bit hasNoSchedulingInfo = 1;
2032 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
2033 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2034 (ins brtarget:$tgt), []> {
2035 bit hasNoSchedulingInfo = 1;
2038 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2039 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2040 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
2041 bit hasNoSchedulingInfo = 1;
2043 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2044 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2045 (ins GPR32Opnd:$src, brtarget:$tgt), []> {
2046 bit hasNoSchedulingInfo = 1;
2049 //===----------------------------------------------------------------------===//
2050 // Instruction definition
2051 //===----------------------------------------------------------------------===//
2052 //===----------------------------------------------------------------------===//
2053 // MipsI Instructions
2054 //===----------------------------------------------------------------------===//
2056 /// Arithmetic Instructions (ALU Immediate)
2057 let AdditionalPredicates = [NotInMicroMips] in {
2058 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2059 II_ADDIU, immSExt16, add>,
2060 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2062 def ANDi : MMRel, StdMMR6Rel,
2063 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
2064 ADDI_FM<0xc>, ISA_MIPS1;
2065 def ORi : MMRel, StdMMR6Rel,
2066 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
2067 ADDI_FM<0xd>, ISA_MIPS1;
2068 def XORi : MMRel, StdMMR6Rel,
2069 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
2070 ADDI_FM<0xe>, ISA_MIPS1;
2071 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2072 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2073 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2074 SLTI_FM<0xa>, ISA_MIPS1;
2075 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2076 SLTI_FM<0xb>, ISA_MIPS1;
2078 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2081 /// Arithmetic Instructions (3-Operand, R-Type)
2082 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2083 ADD_FM<0, 0x21>, ISA_MIPS1;
2084 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2085 ADD_FM<0, 0x23>, ISA_MIPS1;
2087 let Defs = [HI0, LO0] in
2088 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2089 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2091 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2092 ADD_FM<0, 0x20>, ISA_MIPS1;
2093 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2094 ADD_FM<0, 0x22>, ISA_MIPS1;
2096 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2098 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2100 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2101 ADD_FM<0, 0x24>, ISA_MIPS1;
2102 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2103 ADD_FM<0, 0x25>, ISA_MIPS1;
2104 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2105 ADD_FM<0, 0x26>, ISA_MIPS1;
2106 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2110 let AdditionalPredicates = [NotInMicroMips] in {
2111 /// Shift Instructions
2112 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2113 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2114 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2115 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2116 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2117 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2118 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2119 SRLV_FM<4, 0>, ISA_MIPS1;
2120 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2121 SRLV_FM<6, 0>, ISA_MIPS1;
2122 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2123 SRLV_FM<7, 0>, ISA_MIPS1;
2125 // Rotate Instructions
2126 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2128 SRA_FM<2, 1>, ISA_MIPS32R2;
2129 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2130 SRLV_FM<6, 1>, ISA_MIPS32R2;
2133 /// Load and Store Instructions
2135 let AdditionalPredicates = [NotInMicroMips] in {
2136 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2137 LW_FM<0x20>, ISA_MIPS1;
2138 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2139 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2140 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2141 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2142 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2143 MMRel, LW_FM<0x25>, ISA_MIPS1;
2144 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2145 LW_FM<0x23>, ISA_MIPS1;
2146 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2147 LW_FM<0x28>, ISA_MIPS1;
2148 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2150 def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>, ISA_MIPS1;
2153 /// load/store left/right
2154 let AdditionalPredicates = [NotInMicroMips] in {
2155 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2156 ISA_MIPS1_NOT_32R6_64R6;
2157 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2158 ISA_MIPS1_NOT_32R6_64R6;
2159 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2160 ISA_MIPS1_NOT_32R6_64R6;
2161 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2162 ISA_MIPS1_NOT_32R6_64R6;
2164 // COP2 Memory Instructions
2165 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2166 ISA_MIPS1_NOT_32R6_64R6;
2167 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2168 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2169 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2170 ISA_MIPS2_NOT_32R6_64R6;
2171 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2172 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2174 // COP3 Memory Instructions
2175 let DecoderNamespace = "COP3_" in {
2176 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2177 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2178 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2179 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2180 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2181 ISA_MIPS2, NOT_ASE_CNMIPS;
2182 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2183 ISA_MIPS2, NOT_ASE_CNMIPS;
2186 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2187 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2191 let AdditionalPredicates = [NotInMicroMips] in {
2192 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2194 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2196 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2198 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2200 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2202 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2205 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2206 ISA_MIPS2_NOT_32R6_64R6;
2207 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2208 ISA_MIPS2_NOT_32R6_64R6;
2209 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2210 ISA_MIPS2_NOT_32R6_64R6;
2211 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2212 ISA_MIPS2_NOT_32R6_64R6;
2213 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2214 ISA_MIPS2_NOT_32R6_64R6;
2215 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2216 ISA_MIPS2_NOT_32R6_64R6;
2219 let AdditionalPredicates = [NotInMicroMips] in {
2220 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2221 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2223 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2224 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2225 ISA_MIPS32_NOT_32R6_64R6;
2227 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2228 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2230 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2232 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2234 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2237 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2240 let AdditionalPredicates = [NotInMicroMips] in {
2241 /// Load-linked, Store-conditional
2242 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2243 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2245 /// Jump and Branch Instructions
2246 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2247 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2248 IsBranch, ISA_MIPS1;
2250 let AdditionalPredicates = [NotInMicroMips] in {
2251 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
2252 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2254 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2255 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2256 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2258 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2259 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2260 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2261 BGEZ_FM<1, 1>, ISA_MIPS1;
2262 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2263 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2264 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2265 BGEZ_FM<7, 0>, ISA_MIPS1;
2266 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2267 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2268 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2269 BGEZ_FM<6, 0>, ISA_MIPS1;
2270 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2271 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2272 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2273 BGEZ_FM<1, 0>, ISA_MIPS1;
2274 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2275 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2276 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2278 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2282 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2283 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2284 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2287 let AdditionalPredicates = [NotInMicroMips] in {
2288 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2289 ISA_MIPS32_NOT_32R6_64R6;
2290 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2291 ISA_MIPS1_NOT_32R6_64R6;
2292 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2293 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2294 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2295 ISA_MIPS1_NOT_32R6_64R6;
2296 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2297 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2298 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2300 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2301 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2303 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2304 NoIndirectJumpGuards] in
2305 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2307 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2308 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2309 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2310 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2311 II_IndirectBranchPseudo>,
2312 PseudoInstExpansion<(JumpInst RO:$rs)> {
2315 let hasDelaySlot = 1;
2317 let isIndirectBranch = 1;
2321 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2322 NoIndirectJumpGuards] in
2323 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2324 ISA_MIPS1_NOT_32R6_64R6;
2326 // Return instructions are matched as a RetRA instruction, then are expanded
2327 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2328 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2330 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2331 [], II_ReturnPseudo> {
2332 let isTerminator = 1;
2334 let hasDelaySlot = 1;
2336 let isCodeGenOnly = 1;
2338 let hasExtraSrcRegAllocReq = 1;
2342 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2344 // Exception handling related node and instructions.
2345 // The conversion sequence is:
2346 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2347 // MIPSeh_return -> (stack change + indirect branch)
2349 // MIPSeh_return takes the place of regular return instruction
2350 // but takes two arguments (V1, V0) which are used for storing
2351 // the offset and return address respectively.
2352 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2354 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2355 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2357 let Uses = [V0, V1], isTerminator = 1, isReturn = 1,
2358 isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
2359 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2360 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2361 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
2362 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2365 /// Multiply and Divide Instructions.
2366 let AdditionalPredicates = [NotInMicroMips] in {
2367 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2368 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2369 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2370 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2371 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2372 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2373 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2374 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2375 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2376 ISA_MIPS1_NOT_32R6_64R6;
2377 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2378 ISA_MIPS1_NOT_32R6_64R6;
2379 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2380 ISA_MIPS1_NOT_32R6_64R6;
2381 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2382 ISA_MIPS1_NOT_32R6_64R6;
2384 /// Sign Ext In Register Instructions.
2385 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2386 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2387 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2388 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2391 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2392 ISA_MIPS32_NOT_32R6_64R6;
2393 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2394 ISA_MIPS32_NOT_32R6_64R6;
2396 /// Word Swap Bytes Within Halfwords
2397 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2401 def NOP : PseudoSE<(outs), (ins), []>,
2402 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2404 // FrameIndexes are legalized when they are operands from load/store
2405 // instructions. The same not happens for stack address copies, so an
2406 // add op with mem ComplexPattern is used and the stack address copy
2407 // can be matched. It's similar to Sparc LEA_ADDRi
2408 let AdditionalPredicates = [NotInMicroMips] in
2409 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>, ISA_MIPS1;
2412 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2413 ISA_MIPS32_NOT_32R6_64R6;
2414 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2415 ISA_MIPS32_NOT_32R6_64R6;
2416 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2417 ISA_MIPS32_NOT_32R6_64R6;
2418 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2419 ISA_MIPS32_NOT_32R6_64R6;
2422 let AdditionalPredicates = [NotDSP] in {
2423 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2424 ISA_MIPS1_NOT_32R6_64R6;
2425 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2426 ISA_MIPS1_NOT_32R6_64R6;
2427 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2428 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2429 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2430 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2431 ISA_MIPS32_NOT_32R6_64R6;
2432 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2433 ISA_MIPS32_NOT_32R6_64R6;
2434 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2435 ISA_MIPS32_NOT_32R6_64R6;
2436 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2437 ISA_MIPS32_NOT_32R6_64R6;
2440 let AdditionalPredicates = [NotInMicroMips] in {
2441 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2442 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2443 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2444 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2445 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2446 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2447 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2448 immZExt5, immZExt5Plus1, MipsExt>,
2449 EXT_FM<0>, ISA_MIPS32R2;
2450 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2451 uimm5_inssize_plus1, immZExt5,
2453 EXT_FM<4>, ISA_MIPS32R2;
2455 /// Move Control Registers From/To CPU Registers
2456 let AdditionalPredicates = [NotInMicroMips] in {
2457 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2458 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2459 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2460 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2461 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2462 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2463 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2464 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2467 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2468 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2469 let AdditionalPredicates = [NotInMicroMips] in {
2470 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2472 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2475 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2479 // JR_HB and JALR_HB are defined here using the new style naming
2480 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2481 // and because of that it doesn't follow the naming convention of the
2482 // rest of the file. To avoid a mixture of old vs new style, the new
2483 // style was chosen.
2484 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2485 dag OutOperandList = (outs);
2486 dag InOperandList = (ins GPROpnd:$rs);
2487 string AsmString = !strconcat(instr_asm, "\t$rs");
2488 list<dag> Pattern = [];
2491 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2492 dag OutOperandList = (outs GPROpnd:$rd);
2493 dag InOperandList = (ins GPROpnd:$rs);
2494 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2495 list<dag> Pattern = [];
2498 class JR_HB_DESC<RegisterOperand RO> :
2499 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2501 let isIndirectBranch=1;
2508 class JALR_HB_DESC<RegisterOperand RO> :
2509 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2511 let isIndirectBranch=1;
2516 class JR_HB_ENC : JR_HB_FM<8>;
2517 class JALR_HB_ENC : JALR_HB_FM<9>;
2519 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2520 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2522 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2523 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2526 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2527 UseIndirectJumpsHazard] in {
2528 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2529 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2530 ISA_MIPS32R2_NOT_32R6_64R6;
2533 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2534 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2535 let AdditionalPredicates = [NotInMicroMips] in {
2536 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2537 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2538 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2539 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2541 class CacheOp<string instr_asm, Operand MemOpnd,
2542 InstrItinClass itin = NoItinerary> :
2543 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2544 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2546 let DecoderMethod = "DecodeCacheOp";
2549 let AdditionalPredicates = [NotInMicroMips] in {
2550 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2551 INSN_MIPS3_32_NOT_32R6_64R6;
2552 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2553 INSN_MIPS3_32_NOT_32R6_64R6;
2555 // FIXME: We are missing the prefx instruction.
2556 def ROL : MipsAsmPseudoInst<(outs),
2557 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2558 "rol\t$rs, $rt, $rd">;
2559 def ROLImm : MipsAsmPseudoInst<(outs),
2560 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2561 "rol\t$rs, $rt, $imm">;
2562 def : MipsInstAlias<"rol $rd, $rs",
2563 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2564 def : MipsInstAlias<"rol $rd, $imm",
2565 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2567 def ROR : MipsAsmPseudoInst<(outs),
2568 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2569 "ror\t$rs, $rt, $rd">;
2570 def RORImm : MipsAsmPseudoInst<(outs),
2571 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2572 "ror\t$rs, $rt, $imm">;
2573 def : MipsInstAlias<"ror $rd, $rs",
2574 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2575 def : MipsInstAlias<"ror $rd, $imm",
2576 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2578 def DROL : MipsAsmPseudoInst<(outs),
2579 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2580 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2581 def DROLImm : MipsAsmPseudoInst<(outs),
2582 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2583 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2584 def : MipsInstAlias<"drol $rd, $rs",
2585 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2586 def : MipsInstAlias<"drol $rd, $imm",
2587 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2589 def DROR : MipsAsmPseudoInst<(outs),
2590 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2591 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2592 def DRORImm : MipsAsmPseudoInst<(outs),
2593 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2594 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2595 def : MipsInstAlias<"dror $rd, $rs",
2596 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2597 def : MipsInstAlias<"dror $rd, $imm",
2598 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2600 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2603 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2604 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2605 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2607 def : MipsInstAlias<"seq $rd, $rs",
2608 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2611 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2612 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2613 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2615 def : MipsInstAlias<"seq $rd, $imm",
2616 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2619 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2620 simm32_relaxed:$imm),
2621 "mul\t$rd, $rs, $imm">,
2622 ISA_MIPS1_NOT_32R6_64R6;
2623 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2625 "mulo\t$rd, $rs, $rt">,
2626 ISA_MIPS1_NOT_32R6_64R6;
2627 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2629 "mulou\t$rd, $rs, $rt">,
2630 ISA_MIPS1_NOT_32R6_64R6;
2632 // Virtualization ASE
2633 class HYPCALL_FT<string opstr> :
2634 InstSE<(outs), (ins uimm10:$code_),
2635 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2636 let BaseOpcode = opstr;
2639 let AdditionalPredicates = [NotInMicroMips] in {
2640 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2641 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2642 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2643 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2644 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2645 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2646 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2647 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2648 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2649 ISA_MIPS32R5, ASE_VIRT;
2650 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2651 ISA_MIPS32R5, ASE_VIRT;
2652 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2653 ISA_MIPS32R5, ASE_VIRT;
2654 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2655 ISA_MIPS32R5, ASE_VIRT;
2656 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2657 ISA_MIPS32R5, ASE_VIRT;
2658 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2659 ISA_MIPS32R5, ASE_VIRT;
2660 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2661 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2664 //===----------------------------------------------------------------------===//
2665 // Instruction aliases
2666 //===----------------------------------------------------------------------===//
2668 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2670 RegisterOperand RO = GPR32Opnd,
2671 Operand Imm = simm32_relaxed> {
2672 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2676 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2682 let AdditionalPredicates = [NotInMicroMips] in {
2683 def : MipsInstAlias<"move $dst, $src",
2684 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2686 def : MipsInstAlias<"move $dst, $src",
2687 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2690 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2691 ISA_MIPS1_NOT_32R6_64R6;
2693 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2695 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2697 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2700 def : MipsInstAlias<"neg $rt, $rs",
2701 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2702 def : MipsInstAlias<"neg $rt",
2703 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2704 def : MipsInstAlias<"negu $rt, $rs",
2705 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2706 def : MipsInstAlias<"negu $rt",
2707 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2709 def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2710 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2711 "sge\t$rd, $rs, $rt">, ISA_MIPS1;
2712 def : MipsInstAlias<"sge $rs, $rt",
2713 (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2715 def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2716 (ins GPR32Opnd:$rs, simm32:$imm),
2717 "sge\t$rd, $rs, $imm">, GPR_32;
2718 def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
2723 def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2724 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2725 "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
2726 def : MipsInstAlias<"sgeu $rs, $rt",
2727 (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2729 def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2730 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2731 "sgeu\t$rd, $rs, $imm">, GPR_32;
2732 def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
2734 uimm32_coerced:$imm), 0>,
2737 def : MipsInstAlias<
2738 "sgt $rd, $rs, $rt",
2739 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2740 def : MipsInstAlias<
2742 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2744 def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2745 (ins GPR32Opnd:$rs, simm32:$imm),
2746 "sgt\t$rd, $rs, $imm">, GPR_32;
2747 def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
2751 def : MipsInstAlias<
2752 "sgtu $rd, $rs, $rt",
2753 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2754 def : MipsInstAlias<
2756 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2758 def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2759 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2760 "sgtu\t$rd, $rs, $imm">, GPR_32;
2761 def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
2763 uimm32_coerced:$imm), 0>,
2766 def : MipsInstAlias<
2768 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2769 def : MipsInstAlias<
2771 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2773 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2775 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2777 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2779 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2781 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2783 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2785 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2787 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2789 def : MipsInstAlias<"mfgc0 $rt, $rd",
2790 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2791 ISA_MIPS32R5, ASE_VIRT;
2792 def : MipsInstAlias<"mtgc0 $rt, $rd",
2793 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2794 ISA_MIPS32R5, ASE_VIRT;
2795 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2796 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2797 ISA_MIPS32R5, ASE_VIRT;
2798 def : MipsInstAlias<"mthgc0 $rt, $rd",
2799 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2800 ISA_MIPS32R5, ASE_VIRT;
2801 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2803 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2805 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2807 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2810 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2813 def : MipsInstAlias<"bnez $rs,$offset",
2814 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2816 def : MipsInstAlias<"bnezl $rs, $offset",
2817 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2819 def : MipsInstAlias<"beqz $rs,$offset",
2820 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2822 def : MipsInstAlias<"beqzl $rs, $offset",
2823 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2826 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2828 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2829 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2830 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2831 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2833 def : MipsInstAlias<"teq $rs, $rt",
2834 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2835 def : MipsInstAlias<"tge $rs, $rt",
2836 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2837 def : MipsInstAlias<"tgeu $rs, $rt",
2838 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2839 def : MipsInstAlias<"tlt $rs, $rt",
2840 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2841 def : MipsInstAlias<"tltu $rs, $rt",
2842 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2843 def : MipsInstAlias<"tne $rs, $rt",
2844 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2845 def : MipsInstAlias<"rdhwr $rt, $rs",
2846 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2849 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2850 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2851 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2852 def : MipsInstAlias<"sub $rs, $imm",
2853 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2854 0>, ISA_MIPS1_NOT_32R6_64R6;
2855 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2856 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2857 InvertedImOperand:$imm), 0>;
2858 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2859 InvertedImOperand:$imm), 0>;
2860 let AdditionalPredicates = [NotInMicroMips] in {
2861 def : MipsInstAlias<"sll $rd, $rt, $rs",
2862 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2863 def : MipsInstAlias<"sra $rd, $rt, $rs",
2864 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2865 def : MipsInstAlias<"srl $rd, $rt, $rs",
2866 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2867 def : MipsInstAlias<"sll $rd, $rt",
2868 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2869 def : MipsInstAlias<"sra $rd, $rt",
2870 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2871 def : MipsInstAlias<"srl $rd, $rt",
2872 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2873 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2875 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2878 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2879 let AdditionalPredicates = [NotInMicroMips] in
2880 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2882 def : MipsInstAlias<"mulo $rs, $rt",
2883 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2884 ISA_MIPS1_NOT_32R6_64R6;
2885 def : MipsInstAlias<"mulou $rs, $rt",
2886 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2887 ISA_MIPS1_NOT_32R6_64R6;
2889 let AdditionalPredicates = [NotInMicroMips] in
2890 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2892 //===----------------------------------------------------------------------===//
2893 // Assembler Pseudo Instructions
2894 //===----------------------------------------------------------------------===//
2896 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2898 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2899 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2900 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2901 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2903 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2904 RegisterOperand RO> :
2905 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2906 !strconcat(instr_asm, "\t$rt, $addr")> ;
2907 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2909 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2910 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2911 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2912 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2914 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2916 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2919 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2920 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2921 "nor\t$rs, $rt, $imm">;
2922 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2923 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2924 simm32_relaxed:$imm)>, GPR_32;
2926 let hasDelaySlot = 1, isCTI = 1 in {
2927 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2928 (ins imm64:$imm64, brtarget:$offset),
2929 "bne\t$rt, $imm64, $offset">;
2930 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2931 (ins imm64:$imm64, brtarget:$offset),
2932 "beq\t$rt, $imm64, $offset">;
2934 class CondBranchPseudo<string instr_asm> :
2935 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2937 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2940 def BLT : CondBranchPseudo<"blt">;
2941 def BLE : CondBranchPseudo<"ble">;
2942 def BGE : CondBranchPseudo<"bge">;
2943 def BGT : CondBranchPseudo<"bgt">;
2944 def BLTU : CondBranchPseudo<"bltu">;
2945 def BLEU : CondBranchPseudo<"bleu">;
2946 def BGEU : CondBranchPseudo<"bgeu">;
2947 def BGTU : CondBranchPseudo<"bgtu">;
2948 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2949 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2950 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2951 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2952 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2953 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2954 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2955 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2958 class CondBranchImmPseudo<string instr_asm> :
2959 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2960 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2962 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2963 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2965 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2966 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2967 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2968 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2969 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2970 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2971 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2972 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2973 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2974 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2975 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2976 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2977 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2978 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2979 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2980 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2982 // FIXME: Predicates are removed because instructions are matched regardless of
2983 // predicates, because PredicateControl was not in the hierarchy. This was
2984 // done to emit more precise error message from expansion function.
2985 // Once the tablegen-erated errors are made better, this needs to be fixed and
2986 // predicates needs to be restored.
2988 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2989 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2990 "div\t$rd, $rs, $rt">,
2991 ISA_MIPS1_NOT_32R6_64R6;
2992 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2993 (ins GPR32Opnd:$rs, simm32:$imm),
2994 "div\t$rd, $rs, $imm">,
2995 ISA_MIPS1_NOT_32R6_64R6;
2996 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2997 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2998 "divu\t$rd, $rs, $rt">,
2999 ISA_MIPS1_NOT_32R6_64R6;
3000 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3001 (ins GPR32Opnd:$rs, simm32:$imm),
3002 "divu\t$rd, $rs, $imm">,
3003 ISA_MIPS1_NOT_32R6_64R6;
3006 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
3008 ISA_MIPS1_NOT_32R6_64R6;
3009 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
3010 GPR32NonZeroOpnd:$rs,
3012 ISA_MIPS1_NOT_32R6_64R6;
3013 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3015 ISA_MIPS1_NOT_32R6_64R6;
3017 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
3019 ISA_MIPS1_NOT_32R6_64R6;
3020 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
3021 GPR32NonZeroOpnd:$rt,
3023 ISA_MIPS1_NOT_32R6_64R6;
3025 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3027 ISA_MIPS1_NOT_32R6_64R6;
3029 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3030 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3031 "rem\t$rd, $rs, $rt">,
3032 ISA_MIPS1_NOT_32R6_64R6;
3033 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3034 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3035 "rem\t$rd, $rs, $imm">,
3036 ISA_MIPS1_NOT_32R6_64R6;
3037 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3038 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3039 "remu\t$rd, $rs, $rt">,
3040 ISA_MIPS1_NOT_32R6_64R6;
3041 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3042 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3043 "remu\t$rd, $rs, $imm">,
3044 ISA_MIPS1_NOT_32R6_64R6;
3046 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3048 ISA_MIPS1_NOT_32R6_64R6;
3049 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3050 simm32_relaxed:$imm), 0>,
3051 ISA_MIPS1_NOT_32R6_64R6;
3052 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3054 ISA_MIPS1_NOT_32R6_64R6;
3055 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3056 simm32_relaxed:$imm), 0>,
3057 ISA_MIPS1_NOT_32R6_64R6;
3059 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3060 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3062 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3063 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3065 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3066 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3068 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3069 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3071 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3072 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3074 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3075 (ins mem_simm16:$addr), "ld $rt, $addr">,
3076 ISA_MIPS1_NOT_MIPS3;
3077 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3078 (ins mem_simm16:$addr), "sd $rt, $addr">,
3079 ISA_MIPS1_NOT_MIPS3;
3080 //===----------------------------------------------------------------------===//
3081 // Arbitrary patterns that map to one or more instructions
3082 //===----------------------------------------------------------------------===//
3084 // Load/store pattern templates.
3085 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3086 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3088 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3089 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3091 // Materialize constants.
3092 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3093 Instruction ADDiuOp, Instruction LUiOp,
3094 Instruction ORiOp> {
3096 // Constant synthesis previously relied on the ordering of the patterns below.
3097 // By making the predicates they use non-overlapping, the patterns were
3098 // reordered so that the effect of the newly introduced predicates can be
3101 // Arbitrary immediates
3102 def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3104 // Bits 32-16 set, sign/zero extended.
3105 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3108 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3109 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3112 let AdditionalPredicates = [NotInMicroMips] in
3113 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3115 // Carry MipsPatterns
3116 let AdditionalPredicates = [NotInMicroMips] in {
3117 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3118 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3120 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3121 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3122 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3123 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3125 // Support multiplication for pre-Mips32 targets that don't have
3126 // the MUL instruction.
3127 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3128 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3129 ISA_MIPS1_NOT_32R6_64R6;
3132 def : MipsPat<(MipsSync (i32 immz)),
3133 (SYNC 0)>, ISA_MIPS2;
3136 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3137 (JAL texternalsym:$dst)>, ISA_MIPS1;
3138 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3139 // (JALR GPR32:$dst)>;
3142 let AdditionalPredicates = [NotInMicroMips] in {
3143 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3144 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3145 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3146 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3149 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3150 Register ZeroReg, RegisterOperand GPROpnd> {
3151 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3152 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3153 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3154 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3155 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3157 def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
3158 def : MipsPat<(MipsLo tblockaddress:$in),
3159 (Addiu ZeroReg, tblockaddress:$in)>;
3160 def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
3161 def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
3162 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3163 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3164 def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
3166 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3167 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3168 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3169 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3170 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3171 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3172 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3173 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3174 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3175 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3179 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3180 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3182 let AdditionalPredicates = [NotInMicroMips] in {
3183 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3185 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3186 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3189 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3193 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3194 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3195 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3196 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3198 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3199 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3200 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3201 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3202 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3203 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3205 // Mips does not have "not", so we expand our way
3206 def : MipsPat<(not GPR32:$in),
3207 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3211 let AdditionalPredicates = [NotInMicroMips] in {
3212 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3213 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3214 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3217 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3221 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3222 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3223 Instruction SLTiOp, Instruction SLTiuOp,
3225 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3226 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3227 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3228 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3230 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3231 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3232 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3233 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3234 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3235 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3236 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3237 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3238 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3239 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3240 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3241 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3243 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3244 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3245 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3246 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3248 def : MipsPat<(brcond RC:$cond, bb:$dst),
3249 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3251 let AdditionalPredicates = [NotInMicroMips] in {
3252 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3254 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3255 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3256 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3257 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3261 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3262 Instruction SLTuOp, Register ZEROReg> {
3263 def : MipsPat<(seteq RC:$lhs, 0),
3264 (SLTiuOp RC:$lhs, 1)>;
3265 def : MipsPat<(setne RC:$lhs, 0),
3266 (SLTuOp ZEROReg, RC:$lhs)>;
3267 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3268 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3269 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3270 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3273 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3274 Instruction SLTuOp> {
3275 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3276 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3277 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3278 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3281 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3282 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3283 (SLTOp RC:$rhs, RC:$lhs)>;
3284 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3285 (SLTuOp RC:$rhs, RC:$lhs)>;
3288 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3289 Instruction SLTuOp> {
3290 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3291 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3292 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3293 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3296 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3297 Instruction SLTiOp, Instruction SLTiuOp> {
3298 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3299 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3300 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3301 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3304 let AdditionalPredicates = [NotInMicroMips] in {
3305 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3306 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3307 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3308 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3309 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3312 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3315 // Load halfword/word patterns.
3316 let AdditionalPredicates = [NotInMicroMips] in {
3317 let AddedComplexity = 40 in {
3318 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3319 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3320 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3321 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3322 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3325 // Atomic load patterns.
3326 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3327 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3328 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3330 // Atomic store patterns.
3331 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3333 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3335 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3339 //===----------------------------------------------------------------------===//
3340 // Floating Point Support
3341 //===----------------------------------------------------------------------===//
3343 include "MipsInstrFPU.td"
3344 include "Mips64InstrInfo.td"
3345 include "MipsCondMov.td"
3347 include "Mips32r6InstrInfo.td"
3348 include "Mips64r6InstrInfo.td"
3353 include "Mips16InstrFormats.td"
3354 include "Mips16InstrInfo.td"
3357 include "MipsDSPInstrFormats.td"
3358 include "MipsDSPInstrInfo.td"
3361 include "MipsMSAInstrFormats.td"
3362 include "MipsMSAInstrInfo.td"
3365 include "MipsEVAInstrFormats.td"
3366 include "MipsEVAInstrInfo.td"
3369 include "MipsMTInstrFormats.td"
3370 include "MipsMTInstrInfo.td"
3373 include "MicroMipsInstrFormats.td"
3374 include "MicroMipsInstrInfo.td"
3375 include "MicroMipsInstrFPU.td"
3378 include "MicroMips32r6InstrFormats.td"
3379 include "MicroMips32r6InstrInfo.td"
3382 include "MicroMipsDSPInstrFormats.td"
3383 include "MicroMipsDSPInstrInfo.td"