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<(all_of FeatureMips2)>;
160 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
161 AssemblerPredicate<(all_of FeatureMips3_32)>;
162 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
163 AssemblerPredicate<(all_of FeatureMips3_32r2)>;
164 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
165 AssemblerPredicate<(all_of FeatureMips3)>;
166 def NotMips3 : Predicate<"!Subtarget->hasMips3()">,
167 AssemblerPredicate<(all_of (not FeatureMips3))>;
168 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
169 AssemblerPredicate<(all_of FeatureMips4_32)>;
170 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
171 AssemblerPredicate<(all_of (not FeatureMips4_32))>;
172 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
173 AssemblerPredicate<(all_of FeatureMips4_32r2)>;
174 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
175 AssemblerPredicate<(all_of FeatureMips5_32r2)>;
176 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
177 AssemblerPredicate<(all_of FeatureMips32)>;
178 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
179 AssemblerPredicate<(all_of FeatureMips32r2)>;
180 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
181 AssemblerPredicate<(all_of FeatureMips32r5)>;
182 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
183 AssemblerPredicate<(all_of FeatureMips32r6)>;
184 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
185 AssemblerPredicate<(all_of (not FeatureMips32r6))>;
186 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
187 AssemblerPredicate<(all_of FeatureGP64Bit)>;
188 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
189 AssemblerPredicate<(all_of (not FeatureGP64Bit))>;
190 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
191 AssemblerPredicate<(all_of FeaturePTR64Bit)>;
192 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
193 AssemblerPredicate<(all_of (not FeaturePTR64Bit))>;
194 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
195 AssemblerPredicate<(all_of FeatureMips64)>;
196 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
197 AssemblerPredicate<(all_of (not FeatureMips64))>;
198 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
199 AssemblerPredicate<(all_of FeatureMips64r2)>;
200 def HasMips64r5 : Predicate<"Subtarget->hasMips64r5()">,
201 AssemblerPredicate<(all_of FeatureMips64r5)>;
202 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
203 AssemblerPredicate<(all_of FeatureMips64r6)>;
204 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
205 AssemblerPredicate<(all_of (not FeatureMips64r6))>;
206 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
207 AssemblerPredicate<(all_of FeatureMips16)>;
208 def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
209 AssemblerPredicate<(all_of (not FeatureMips16))>;
210 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
211 AssemblerPredicate<(all_of FeatureCnMips)>;
212 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
213 AssemblerPredicate<(all_of (not FeatureCnMips))>;
214 def HasCnMipsP : Predicate<"Subtarget->hasCnMipsP()">,
215 AssemblerPredicate<(all_of FeatureCnMipsP)>;
216 def NotCnMipsP : Predicate<"!Subtarget->hasCnMipsP()">,
217 AssemblerPredicate<(all_of (not FeatureCnMipsP))>;
218 def IsSym32 : Predicate<"Subtarget->hasSym32()">,
219 AssemblerPredicate<(all_of FeatureSym32)>;
220 def IsSym64 : Predicate<"!Subtarget->hasSym32()">,
221 AssemblerPredicate<(all_of (not 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<(all_of (not FeatureMips16))>;
231 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
232 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
233 AssemblerPredicate<(all_of FeatureMicroMips)>;
234 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
235 AssemblerPredicate<(all_of (not FeatureMicroMips))>;
236 def IsLE : Predicate<"Subtarget->isLittle()">;
237 def IsBE : Predicate<"!Subtarget->isLittle()">;
238 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
239 def UseTCCInDIV : AssemblerPredicate<(all_of FeatureUseTCCInDIV)>;
240 def HasEVA : Predicate<"Subtarget->hasEVA()">,
241 AssemblerPredicate<(all_of FeatureEVA)>;
242 def HasMSA : Predicate<"Subtarget->hasMSA()">,
243 AssemblerPredicate<(all_of FeatureMSA)>;
244 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
245 AssemblerPredicate<(all_of (not FeatureNoMadd4))>;
246 def HasMT : Predicate<"Subtarget->hasMT()">,
247 AssemblerPredicate<(all_of FeatureMT)>;
248 def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
249 AssemblerPredicate<(all_of FeatureUseIndirectJumpsHazard)>;
250 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
251 AssemblerPredicate<(all_of (not FeatureUseIndirectJumpsHazard))>;
252 def HasCRC : Predicate<"Subtarget->hasCRC()">,
253 AssemblerPredicate<(all_of FeatureCRC)>;
254 def HasVirt : Predicate<"Subtarget->hasVirt()">,
255 AssemblerPredicate<(all_of FeatureVirt)>;
256 def HasGINV : Predicate<"Subtarget->hasGINV()">,
257 AssemblerPredicate<(all_of 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 // Classes used for separating expansions that differ based on the ABI in
504 list<Predicate> AdditionalPredicates = [IsN64];
508 list<Predicate> AdditionalPredicates = [IsNotN64];
511 class FPOP_FUSION_FAST {
512 list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
515 //===----------------------------------------------------------------------===//
517 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl;
519 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
520 InstAlias<Asm, Result, Emit>, PredicateControl;
523 bit isCommutable = 1;
543 bit isTerminator = 1;
546 bit hasExtraSrcRegAllocReq = 1;
547 bit isCodeGenOnly = 1;
551 class IsAsCheapAsAMove {
552 bit isAsCheapAsAMove = 1;
555 class NeverHasSideEffects {
556 bit hasSideEffects = 0;
559 //===----------------------------------------------------------------------===//
560 // Instruction format superclass
561 //===----------------------------------------------------------------------===//
563 include "MipsInstrFormats.td"
565 //===----------------------------------------------------------------------===//
566 // Mips Operand, Complex Patterns and Transformations Definitions.
567 //===----------------------------------------------------------------------===//
569 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
570 int Offset = 0> : AsmOperandClass {
571 let Name = "ConstantSImm" # Bits # "_" # Offset;
572 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
573 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
574 let SuperClasses = Supers;
575 let DiagnosticType = "SImm" # Bits # "_" # Offset;
578 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
579 int Shift = 0> : AsmOperandClass {
580 let Name = "Simm" # Bits # "_Lsl" # Shift;
581 let RenderMethod = "addImmOperands";
582 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
583 let SuperClasses = Supers;
584 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
587 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
588 int Offset = 0> : AsmOperandClass {
589 let Name = "ConstantUImm" # Bits # "_" # Offset;
590 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
591 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
592 let SuperClasses = Supers;
593 let DiagnosticType = "UImm" # Bits # "_" # Offset;
596 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
597 list<AsmOperandClass> Supers = []>
599 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
600 let RenderMethod = "addImmOperands";
601 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
602 let SuperClasses = Supers;
603 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
606 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
608 let Name = "SImm" # Bits;
609 let RenderMethod = "addSImmOperands<" # Bits # ">";
610 let PredicateMethod = "isSImm<" # Bits # ">";
611 let SuperClasses = Supers;
612 let DiagnosticType = "SImm" # Bits;
615 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
617 let Name = "UImm" # Bits;
618 let RenderMethod = "addUImmOperands<" # Bits # ">";
619 let PredicateMethod = "isUImm<" # Bits # ">";
620 let SuperClasses = Supers;
621 let DiagnosticType = "UImm" # Bits;
624 // Generic case - only to support certain assembly pseudo instructions.
625 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
628 let RenderMethod = "addConstantUImmOperands<32>";
629 let PredicateMethod = "isSImm<" # Bits # ">";
630 let SuperClasses = Supers;
631 let DiagnosticType = "ImmAny";
634 // AsmOperandClasses require a strict ordering which is difficult to manage
635 // as a hierarchy. Instead, we use a linear ordering and impose an order that
636 // is in some places arbitrary.
638 // Here the rules that are in use:
639 // * Wider immediates are a superset of narrower immediates:
640 // uimm4 < uimm5 < uimm6
641 // * For the same bit-width, unsigned immediates are a superset of signed
643 // simm4 < uimm4 < simm5 < uimm5
644 // * For the same upper-bound, signed immediates are a superset of unsigned
646 // uimm3 < simm4 < uimm4 < simm4
647 // * Modified immediates are a superset of ordinary immediates:
648 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
649 // The term 'superset' starts to break down here since the uimm5_plus* classes
650 // are not true supersets of uimm5 (but they are still subsets of uimm6).
651 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
652 // uimm16 < uimm16_relaxed
653 // * The codeGen pattern type is arbitrarily ordered.
654 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
655 // This is entirely arbitrary. We need an ordering and what we pick is
656 // unimportant since only one is possible for a given mnemonic.
658 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
659 let Name = "UImm32_Coerced";
660 let DiagnosticType = "UImm32_Coerced";
662 def SImm32RelaxedAsmOperandClass
663 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
664 let Name = "SImm32_Relaxed";
665 let PredicateMethod = "isAnyImm<33>";
666 let DiagnosticType = "SImm32_Relaxed";
668 def SImm32AsmOperandClass
669 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
670 def ConstantUImm26AsmOperandClass
671 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
672 def ConstantUImm20AsmOperandClass
673 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
674 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
675 let Name = "SImm19Lsl2";
676 let RenderMethod = "addImmOperands";
677 let PredicateMethod = "isScaledSImm<19, 2>";
678 let SuperClasses = [ConstantUImm20AsmOperandClass];
679 let DiagnosticType = "SImm19_Lsl2";
681 def UImm16RelaxedAsmOperandClass
682 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
683 let Name = "UImm16_Relaxed";
684 let PredicateMethod = "isAnyImm<16>";
685 let DiagnosticType = "UImm16_Relaxed";
687 // Similar to the relaxed classes which take an SImm and render it as
688 // an UImm, this takes a UImm and renders it as an SImm.
689 def UImm16AltRelaxedAsmOperandClass
690 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
691 let Name = "UImm16_AltRelaxed";
692 let PredicateMethod = "isUImm<16>";
693 let DiagnosticType = "UImm16_AltRelaxed";
695 // FIXME: One of these should probably have UImm16AsmOperandClass as the
696 // superclass instead of UImm16RelaxedasmOPerandClass.
697 def UImm16AsmOperandClass
698 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
699 def SImm16RelaxedAsmOperandClass
700 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
701 let Name = "SImm16_Relaxed";
702 let PredicateMethod = "isAnyImm<16>";
703 let DiagnosticType = "SImm16_Relaxed";
705 def SImm16AsmOperandClass
706 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
707 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
708 let Name = "SImm10Lsl3";
709 let RenderMethod = "addImmOperands";
710 let PredicateMethod = "isScaledSImm<10, 3>";
711 let SuperClasses = [SImm16AsmOperandClass];
712 let DiagnosticType = "SImm10_Lsl3";
714 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
715 let Name = "SImm10Lsl2";
716 let RenderMethod = "addImmOperands";
717 let PredicateMethod = "isScaledSImm<10, 2>";
718 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
719 let DiagnosticType = "SImm10_Lsl2";
721 def ConstantSImm11AsmOperandClass
722 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
723 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
724 let Name = "SImm10Lsl1";
725 let RenderMethod = "addImmOperands";
726 let PredicateMethod = "isScaledSImm<10, 1>";
727 let SuperClasses = [ConstantSImm11AsmOperandClass];
728 let DiagnosticType = "SImm10_Lsl1";
730 def ConstantUImm10AsmOperandClass
731 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
732 def ConstantSImm10AsmOperandClass
733 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
734 def ConstantSImm9AsmOperandClass
735 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
736 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
737 let Name = "SImm7Lsl2";
738 let RenderMethod = "addImmOperands";
739 let PredicateMethod = "isScaledSImm<7, 2>";
740 let SuperClasses = [ConstantSImm9AsmOperandClass];
741 let DiagnosticType = "SImm7_Lsl2";
743 def ConstantUImm8AsmOperandClass
744 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
745 def ConstantUImm7Sub1AsmOperandClass
746 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
747 // Specify the names since the -1 offset causes invalid identifiers otherwise.
748 let Name = "UImm7_N1";
749 let DiagnosticType = "UImm7_N1";
751 def ConstantUImm7AsmOperandClass
752 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
753 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
754 let Name = "UImm6Lsl2";
755 let RenderMethod = "addImmOperands";
756 let PredicateMethod = "isScaledUImm<6, 2>";
757 let SuperClasses = [ConstantUImm7AsmOperandClass];
758 let DiagnosticType = "UImm6_Lsl2";
760 def ConstantUImm6AsmOperandClass
761 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
762 def ConstantSImm6AsmOperandClass
763 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
764 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
765 let Name = "UImm5Lsl2";
766 let RenderMethod = "addImmOperands";
767 let PredicateMethod = "isScaledUImm<5, 2>";
768 let SuperClasses = [ConstantSImm6AsmOperandClass];
769 let DiagnosticType = "UImm5_Lsl2";
771 def ConstantUImm5_Range2_64AsmOperandClass
772 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
773 def ConstantUImm5Plus33AsmOperandClass
774 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
776 def ConstantUImm5ReportUImm6AsmOperandClass
777 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
778 let Name = "ConstantUImm5_0_Report_UImm6";
779 let DiagnosticType = "UImm5_0_Report_UImm6";
781 def ConstantUImm5Plus32AsmOperandClass
782 : ConstantUImmAsmOperandClass<
783 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
784 def ConstantUImm5Plus32NormalizeAsmOperandClass
785 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
786 let Name = "ConstantUImm5_32_Norm";
787 // We must also subtract 32 when we render the operand.
788 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
790 def ConstantUImm5Plus1ReportUImm6AsmOperandClass
791 : ConstantUImmAsmOperandClass<
792 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
793 let Name = "ConstantUImm5_Plus1_Report_UImm6";
795 def ConstantUImm5Plus1AsmOperandClass
796 : ConstantUImmAsmOperandClass<
797 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
798 def ConstantUImm5AsmOperandClass
799 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
800 def ConstantSImm5AsmOperandClass
801 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
802 def ConstantUImm4AsmOperandClass
803 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
804 def ConstantSImm4AsmOperandClass
805 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
806 def ConstantUImm3AsmOperandClass
807 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
808 def ConstantUImm2Plus1AsmOperandClass
809 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
810 def ConstantUImm2AsmOperandClass
811 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
812 def ConstantUImm1AsmOperandClass
813 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
814 def ConstantImmzAsmOperandClass : AsmOperandClass {
815 let Name = "ConstantImmz";
816 let RenderMethod = "addConstantUImmOperands<1>";
817 let PredicateMethod = "isConstantImmz";
818 let SuperClasses = [ConstantUImm1AsmOperandClass];
819 let DiagnosticType = "Immz";
822 def Simm19Lsl2AsmOperand
823 : SimmLslAsmOperandClass<19, [], 2>;
825 def MipsJumpTargetAsmOperand : AsmOperandClass {
826 let Name = "JumpTarget";
827 let ParserMethod = "parseJumpTarget";
828 let PredicateMethod = "isImm";
829 let RenderMethod = "addImmOperands";
832 // Instruction operand types
833 def jmptarget : Operand<OtherVT> {
834 let EncoderMethod = "getJumpTargetOpValue";
835 let ParserMatchClass = MipsJumpTargetAsmOperand;
837 def brtarget : Operand<OtherVT> {
838 let EncoderMethod = "getBranchTargetOpValue";
839 let OperandType = "OPERAND_PCREL";
840 let DecoderMethod = "DecodeBranchTarget";
841 let ParserMatchClass = MipsJumpTargetAsmOperand;
843 def brtarget1SImm16 : Operand<OtherVT> {
844 let EncoderMethod = "getBranchTargetOpValue1SImm16";
845 let OperandType = "OPERAND_PCREL";
846 let DecoderMethod = "DecodeBranchTarget1SImm16";
847 let ParserMatchClass = MipsJumpTargetAsmOperand;
849 def calltarget : Operand<iPTR> {
850 let EncoderMethod = "getJumpTargetOpValue";
851 let ParserMatchClass = MipsJumpTargetAsmOperand;
854 def imm64: Operand<i64>;
856 def simm19_lsl2 : Operand<i32> {
857 let EncoderMethod = "getSimm19Lsl2Encoding";
858 let DecoderMethod = "DecodeSimm19Lsl2";
859 let ParserMatchClass = Simm19Lsl2AsmOperand;
862 def simm18_lsl3 : Operand<i32> {
863 let EncoderMethod = "getSimm18Lsl3Encoding";
864 let DecoderMethod = "DecodeSimm18Lsl3";
865 let ParserMatchClass = MipsJumpTargetAsmOperand;
869 def uimmz : Operand<i32> {
870 let PrintMethod = "printUImm<0>";
871 let ParserMatchClass = ConstantImmzAsmOperandClass;
874 // size operand of ins instruction
875 def uimm_range_2_64 : Operand<i32> {
876 let PrintMethod = "printUImm<6, 2>";
877 let EncoderMethod = "getSizeInsEncoding";
878 let DecoderMethod = "DecodeInsSize";
879 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
883 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
884 def uimm # I : Operand<i32> {
885 let PrintMethod = "printUImm<" # I # ">";
886 let ParserMatchClass =
887 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
890 def uimm2_plus1 : Operand<i32> {
891 let PrintMethod = "printUImm<2, 1>";
892 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
893 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
894 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
897 def uimm5_plus1 : Operand<i32> {
898 let PrintMethod = "printUImm<5, 1>";
899 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
900 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
901 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
904 def uimm5_plus1_report_uimm6 : Operand<i32> {
905 let PrintMethod = "printUImm<6, 1>";
906 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
907 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
908 let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
911 def uimm5_plus32 : Operand<i32> {
912 let PrintMethod = "printUImm<5, 32>";
913 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
916 def uimm5_plus33 : Operand<i32> {
917 let PrintMethod = "printUImm<5, 33>";
918 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
919 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
920 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
923 def uimm5_inssize_plus1 : Operand<i32> {
924 let PrintMethod = "printUImm<6>";
925 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
926 let EncoderMethod = "getSizeInsEncoding";
927 let DecoderMethod = "DecodeInsSize";
930 def uimm5_plus32_normalize : Operand<i32> {
931 let PrintMethod = "printUImm<5>";
932 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
935 def uimm5_lsl2 : Operand<OtherVT> {
936 let EncoderMethod = "getUImm5Lsl2Encoding";
937 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
938 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
941 def uimm5_plus32_normalize_64 : Operand<i64> {
942 let PrintMethod = "printUImm<5>";
943 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
946 def uimm6_lsl2 : Operand<OtherVT> {
947 let EncoderMethod = "getUImm6Lsl2Encoding";
948 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
949 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
953 def uimm # I : Operand<i32> {
954 let PrintMethod = "printUImm<" # I # ">";
955 let ParserMatchClass =
956 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
959 // Like uimm16_64 but coerces simm16 to uimm16.
960 def uimm16_relaxed : Operand<i32> {
961 let PrintMethod = "printUImm<16>";
962 let ParserMatchClass = UImm16RelaxedAsmOperandClass;
966 def uimm # I # _64 : Operand<i64> {
967 let PrintMethod = "printUImm<" # I # ">";
968 let ParserMatchClass =
969 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
973 def uimm # I # _64 : Operand<i64> {
974 let PrintMethod = "printUImm<" # I # ">";
975 let ParserMatchClass =
976 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
979 // Like uimm16_64 but coerces simm16 to uimm16.
980 def uimm16_64_relaxed : Operand<i64> {
981 let PrintMethod = "printUImm<16>";
982 let ParserMatchClass = UImm16RelaxedAsmOperandClass;
985 def uimm16_altrelaxed : Operand<i32> {
986 let PrintMethod = "printUImm<16>";
987 let ParserMatchClass = UImm16AltRelaxedAsmOperandClass;
989 // Like uimm5 but reports a less confusing error for 32-63 when
990 // an instruction alias permits that.
991 def uimm5_report_uimm6 : Operand<i32> {
992 let PrintMethod = "printUImm<6>";
993 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
996 // Like uimm5_64 but reports a less confusing error for 32-63 when
997 // an instruction alias permits that.
998 def uimm5_64_report_uimm6 : Operand<i64> {
999 let PrintMethod = "printUImm<5>";
1000 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
1003 foreach I = {1, 2, 3, 4} in
1004 def uimm # I # _ptr : Operand<iPTR> {
1005 let PrintMethod = "printUImm<" # I # ">";
1006 let ParserMatchClass =
1007 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1010 foreach I = {1, 2, 3, 4, 5, 6, 8} in
1011 def vsplat_uimm # I : Operand<vAny> {
1012 let PrintMethod = "printUImm<" # I # ">";
1013 let ParserMatchClass =
1014 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1018 foreach I = {4, 5, 6, 9, 10, 11} in
1019 def simm # I : Operand<i32> {
1020 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1021 let ParserMatchClass =
1022 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1025 foreach I = {1, 2, 3} in
1026 def simm10_lsl # I : Operand<i32> {
1027 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
1028 let ParserMatchClass =
1029 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
1033 def simm # I # _64 : Operand<i64> {
1034 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1035 let ParserMatchClass =
1036 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1039 foreach I = {5, 10} in
1040 def vsplat_simm # I : Operand<vAny> {
1041 let ParserMatchClass =
1042 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1045 def simm7_lsl2 : Operand<OtherVT> {
1046 let EncoderMethod = "getSImm7Lsl2Encoding";
1047 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
1048 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
1051 foreach I = {16, 32} in
1052 def simm # I : Operand<i32> {
1053 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1054 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
1057 // Like simm16 but coerces uimm16 to simm16.
1058 def simm16_relaxed : Operand<i32> {
1059 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1060 let ParserMatchClass = SImm16RelaxedAsmOperandClass;
1063 def simm16_64 : Operand<i64> {
1064 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1065 let ParserMatchClass = SImm16AsmOperandClass;
1068 // like simm32 but coerces simm32 to uimm32.
1069 def uimm32_coerced : Operand<i32> {
1070 let ParserMatchClass = UImm32CoercedAsmOperandClass;
1072 // Like simm32 but coerces uimm32 to simm32.
1073 def simm32_relaxed : Operand<i32> {
1074 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1075 let ParserMatchClass = SImm32RelaxedAsmOperandClass;
1078 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
1079 def li16_imm : Operand<i32> {
1080 let DecoderMethod = "DecodeLi16Imm";
1081 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
1084 def MipsMemAsmOperand : AsmOperandClass {
1086 let ParserMethod = "parseMemOperand";
1089 class MipsMemSimmAsmOperand<int Width, int Shift = 0> : AsmOperandClass {
1090 let Name = "MemOffsetSimm" # Width # "_" # Shift;
1091 let SuperClasses = [MipsMemAsmOperand];
1092 let RenderMethod = "addMemOperands";
1093 let ParserMethod = "parseMemOperand";
1094 let PredicateMethod = "isMemWithSimmOffset<" # Width # ", " # Shift # ">";
1095 let DiagnosticType = !if(!eq(Shift, 0), "MemSImm" # Width,
1096 "MemSImm" # Width # "Lsl" # Shift);
1099 def MipsMemSimmPtrAsmOperand : AsmOperandClass {
1100 let Name = "MemOffsetSimmPtr";
1101 let SuperClasses = [MipsMemAsmOperand];
1102 let RenderMethod = "addMemOperands";
1103 let ParserMethod = "parseMemOperand";
1104 let PredicateMethod = "isMemWithPtrSizeOffset";
1105 let DiagnosticType = "MemSImmPtr";
1108 def MipsInvertedImmoperand : AsmOperandClass {
1109 let Name = "InvNum";
1110 let RenderMethod = "addImmOperands";
1111 let ParserMethod = "parseInvNum";
1114 def InvertedImOperand : Operand<i32> {
1115 let ParserMatchClass = MipsInvertedImmoperand;
1118 def InvertedImOperand64 : Operand<i64> {
1119 let ParserMatchClass = MipsInvertedImmoperand;
1122 class mem_generic : Operand<iPTR> {
1123 let PrintMethod = "printMemOperand";
1124 let MIOperandInfo = (ops ptr_rc, simm16);
1125 let EncoderMethod = "getMemEncoding";
1126 let ParserMatchClass = MipsMemAsmOperand;
1127 let OperandType = "OPERAND_MEMORY";
1131 def mem : mem_generic;
1133 // MSA specific address operand
1134 def mem_msa : mem_generic {
1135 let MIOperandInfo = (ops ptr_rc, simm10);
1136 let EncoderMethod = "getMSAMemEncoding";
1139 def simm12 : Operand<i32> {
1140 let DecoderMethod = "DecodeSimm12";
1143 def mem_simm9_exp : mem_generic {
1144 let MIOperandInfo = (ops ptr_rc, simm9);
1145 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1146 let OperandNamespace = "MipsII";
1147 let OperandType = "OPERAND_MEM_SIMM9";
1150 foreach I = {9, 10, 11, 12, 16} in
1151 def mem_simm # I : mem_generic {
1152 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm" # I));
1153 let ParserMatchClass = MipsMemSimmAsmOperand<I>;
1156 foreach I = {1, 2, 3} in
1157 def mem_simm10_lsl # I : mem_generic {
1158 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1159 let EncoderMethod = "getMemEncoding<" # I # ">";
1160 let ParserMatchClass = MipsMemSimmAsmOperand<10, I>;
1163 def mem_simmptr : mem_generic {
1164 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1167 def mem_ea : Operand<iPTR> {
1168 let PrintMethod = "printMemOperandEA";
1169 let MIOperandInfo = (ops ptr_rc, simm16);
1170 let EncoderMethod = "getMemEncoding";
1171 let OperandType = "OPERAND_MEMORY";
1174 def PtrRC : Operand<iPTR> {
1175 let MIOperandInfo = (ops ptr_rc);
1176 let DecoderMethod = "DecodePtrRegisterClass";
1177 let ParserMatchClass = GPR32AsmOperand;
1180 // size operand of ins instruction
1181 def size_ins : Operand<i32> {
1182 let EncoderMethod = "getSizeInsEncoding";
1183 let DecoderMethod = "DecodeInsSize";
1186 // Transformation Function - get the lower 16 bits.
1187 def LO16 : SDNodeXForm<imm, [{
1188 return getImm(N, N->getZExtValue() & 0xFFFF);
1191 // Transformation Function - get the higher 16 bits.
1192 def HI16 : SDNodeXForm<imm, [{
1193 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1197 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1199 // Node immediate is zero (e.g. insve.d)
1200 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1202 // Node immediate fits as 16-bit sign extended on target immediate.
1204 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1206 // Node immediate fits as 16-bit sign extended on target immediate.
1208 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1209 def imm32SExt16 : IntImmLeaf<i32, [{ return isInt<16>(Imm.getSExtValue()); }]>;
1211 // Node immediate fits as 7-bit zero extended on target immediate.
1212 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1213 def timmZExt7 : PatLeaf<(timm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1215 // Node immediate fits as 16-bit zero extended on target immediate.
1216 // The LO16 param means that only the lower 16 bits of the node
1217 // immediate are caught.
1218 // e.g. addiu, sltiu
1219 def immZExt16 : PatLeaf<(imm), [{
1220 if (N->getValueType(0) == MVT::i32)
1221 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1223 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1225 def imm32ZExt16 : IntImmLeaf<i32, [{
1226 return (uint32_t)Imm.getZExtValue() == (unsigned short)Imm.getZExtValue();
1229 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1230 def immSExt32Low16Zero : PatLeaf<(imm), [{
1231 int64_t Val = N->getSExtValue();
1232 return isInt<32>(Val) && !(Val & 0xffff);
1235 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1236 def immZExt32Low16Zero : PatLeaf<(imm), [{
1237 uint64_t Val = N->getZExtValue();
1238 return isUInt<32>(Val) && !(Val & 0xffff);
1241 // Note immediate fits as a 32 bit signed extended on target immediate.
1242 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1244 // Note immediate fits as a 32 bit zero extended on target immediate.
1245 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1247 // shamt field must fit in 5 bits.
1248 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1249 def timmZExt5 : TImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1251 def immZExt5Plus1 : PatLeaf<(imm), [{
1252 return isUInt<5>(N->getZExtValue() - 1);
1254 def immZExt5Plus32 : PatLeaf<(imm), [{
1255 return isUInt<5>(N->getZExtValue() - 32);
1257 def immZExt5Plus33 : PatLeaf<(imm), [{
1258 return isUInt<5>(N->getZExtValue() - 33);
1261 def immZExt5To31 : SDNodeXForm<imm, [{
1262 return getImm(N, 31 - N->getZExtValue());
1265 // True if (N + 1) fits in 16-bit field.
1266 def immSExt16Plus1 : PatLeaf<(imm), [{
1267 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1270 def immZExtRange2To64 : PatLeaf<(imm), [{
1271 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1272 (N->getZExtValue() <= 64);
1275 def ORiPred : PatLeaf<(imm), [{
1276 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1279 def LUiPred : PatLeaf<(imm), [{
1280 int64_t Val = N->getSExtValue();
1281 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1284 def LUiORiPred : PatLeaf<(imm), [{
1285 int64_t SVal = N->getSExtValue();
1286 return isInt<32>(SVal) && (SVal & 0xffff);
1289 // Mips Address Mode! SDNode frameindex could possibly be a match
1290 // since load and store instructions from stack used it.
1292 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1295 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1298 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1300 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1301 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1303 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1305 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1308 //===----------------------------------------------------------------------===//
1309 // Instructions specific format
1310 //===----------------------------------------------------------------------===//
1312 // Arithmetic and logical instructions with 3 register operands.
1313 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1314 InstrItinClass Itin = NoItinerary,
1315 SDPatternOperator OpNode = null_frag>:
1316 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1317 !strconcat(opstr, "\t$rd, $rs, $rt"),
1318 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1319 let isCommutable = isComm;
1320 let isReMaterializable = 1;
1321 let TwoOperandAliasConstraint = "$rd = $rs";
1324 // Arithmetic and logical instructions with 2 register operands.
1325 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1326 InstrItinClass Itin = NoItinerary,
1327 SDPatternOperator imm_type = null_frag,
1328 SDPatternOperator OpNode = null_frag> :
1329 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1330 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1331 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1332 Itin, FrmI, opstr> {
1333 let isReMaterializable = 1;
1334 let TwoOperandAliasConstraint = "$rs = $rt";
1337 // Arithmetic Multiply ADD/SUB
1338 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1339 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1340 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1341 let Defs = [HI0, LO0];
1342 let Uses = [HI0, LO0];
1343 let isCommutable = isComm;
1347 class LogicNOR<string opstr, RegisterOperand RO>:
1348 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1349 !strconcat(opstr, "\t$rd, $rs, $rt"),
1350 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1351 let isCommutable = 1;
1355 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1356 RegisterOperand RO, InstrItinClass itin,
1357 SDPatternOperator OpNode = null_frag,
1358 SDPatternOperator PF = null_frag> :
1359 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1360 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1361 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1362 let TwoOperandAliasConstraint = "$rt = $rd";
1365 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1366 SDPatternOperator OpNode = null_frag>:
1367 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1368 !strconcat(opstr, "\t$rd, $rt, $rs"),
1369 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1372 // Load Upper Immediate
1373 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1374 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1375 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1376 let hasSideEffects = 0;
1377 let isReMaterializable = 1;
1380 // Memory Load/Store
1381 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1382 SDPatternOperator OpNode = null_frag,
1383 InstrItinClass Itin = NoItinerary,
1384 ComplexPattern Addr = addr> :
1385 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1386 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1387 let DecoderMethod = "DecodeMem";
1388 let canFoldAsLoad = 1;
1389 string BaseOpcode = opstr;
1393 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1394 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1395 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1397 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1398 SDPatternOperator OpNode = null_frag,
1399 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1400 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1401 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1402 let DecoderMethod = "DecodeMem";
1403 string BaseOpcode = opstr;
1407 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1408 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1409 DAGOperand MO = mem> :
1410 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1412 // Load/Store Left/Right
1413 let canFoldAsLoad = 1 in
1414 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1415 InstrItinClass Itin> :
1416 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1417 !strconcat(opstr, "\t$rt, $addr"),
1418 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1419 let DecoderMethod = "DecodeMem";
1420 string Constraints = "$src = $rt";
1421 let BaseOpcode = opstr;
1424 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1425 InstrItinClass Itin> :
1426 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1427 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1428 let DecoderMethod = "DecodeMem";
1429 let BaseOpcode = opstr;
1433 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1434 SDPatternOperator OpNode= null_frag> :
1435 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1436 !strconcat(opstr, "\t$rt, $addr"),
1437 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1438 let DecoderMethod = "DecodeFMem2";
1442 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1443 SDPatternOperator OpNode= null_frag> :
1444 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1445 !strconcat(opstr, "\t$rt, $addr"),
1446 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1447 let DecoderMethod = "DecodeFMem2";
1452 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1453 SDPatternOperator OpNode= null_frag> :
1454 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1455 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1456 let DecoderMethod = "DecodeFMem3";
1460 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1461 SDPatternOperator OpNode= null_frag> :
1462 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1463 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1464 let DecoderMethod = "DecodeFMem3";
1468 // Conditional Branch
1469 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1470 RegisterOperand RO> :
1471 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1472 !strconcat(opstr, "\t$rs, $rt, $offset"),
1473 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1476 let isTerminator = 1;
1477 let hasDelaySlot = 1;
1482 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1483 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1484 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1486 let isTerminator = 1;
1487 let hasDelaySlot = 1;
1492 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1493 RegisterOperand RO> :
1494 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1495 !strconcat(opstr, "\t$rs, $offset"),
1496 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1499 let isTerminator = 1;
1500 let hasDelaySlot = 1;
1505 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1506 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1507 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1509 let isTerminator = 1;
1510 let hasDelaySlot = 1;
1516 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1517 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1518 !strconcat(opstr, "\t$rd, $rs, $rt"),
1519 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1520 II_SLT_SLTU, FrmR, opstr>;
1522 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1523 RegisterOperand RO>:
1524 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1525 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1526 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1527 II_SLTI_SLTIU, FrmI, opstr>;
1530 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1531 SDPatternOperator targetoperator, string bopstr> :
1532 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1533 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1536 let hasDelaySlot = 1;
1537 let DecoderMethod = "DecodeJumpTarget";
1542 // Unconditional branch
1543 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1544 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1545 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1547 let isTerminator = 1;
1549 let hasDelaySlot = 1;
1550 let AdditionalPredicates = [RelocPIC];
1555 // Base class for indirect branch and return instruction classes.
1556 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1557 class JumpFR<string opstr, RegisterOperand RO,
1558 SDPatternOperator operator = null_frag>:
1559 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1563 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1565 let isIndirectBranch = 1;
1568 // Jump and Link (Call)
1569 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1570 class JumpLink<string opstr, DAGOperand opnd> :
1571 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1572 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1573 let DecoderMethod = "DecodeJumpTarget";
1576 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1577 Register RetReg, RegisterOperand ResRO = RO>:
1578 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1579 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1580 let hasPostISelHook = 1;
1583 class JumpLinkReg<string opstr, RegisterOperand RO>:
1584 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1585 [], II_JALR, FrmR, opstr> {
1586 let hasPostISelHook = 1;
1589 class BGEZAL_FT<string opstr, DAGOperand opnd,
1590 RegisterOperand RO> :
1591 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1592 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1593 let hasDelaySlot = 1;
1598 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1599 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1600 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1601 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1602 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1604 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1605 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1606 PseudoInstExpansion<(JumpInst RO:$rs)> {
1607 let hasPostISelHook = 1;
1611 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1612 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1613 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1615 let isTerminator = 1;
1617 let hasDelaySlot = 1;
1624 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1625 InstSE<(outs), (ins ImmOp:$code_),
1626 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1628 class BRK_FT<string opstr> :
1629 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1630 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1634 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1635 InstSE<(outs), (ins),
1636 opstr, [], itin, FrmOther, opstr>;
1639 class WAIT_FT<string opstr> :
1640 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1644 class DEI_FT<string opstr, RegisterOperand RO,
1645 InstrItinClass itin = NoItinerary> :
1646 InstSE<(outs RO:$rt), (ins),
1647 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1650 let hasSideEffects = 1 in
1651 class SYNC_FT<string opstr> :
1652 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1653 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1655 class SYNCI_FT<string opstr, DAGOperand MO> :
1656 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1657 II_SYNCI, FrmOther, opstr> {
1658 let hasSideEffects = 1;
1659 let DecoderMethod = "DecodeSyncI";
1662 let hasSideEffects = 1, isCTI = 1 in {
1663 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1664 InstrItinClass itin = NoItinerary> :
1665 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1666 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1668 class TEQI_FT<string opstr, RegisterOperand RO,
1669 InstrItinClass itin = NoItinerary> :
1670 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1671 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1675 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1676 list<Register> DefRegs> :
1677 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1678 itin, FrmR, opstr> {
1679 let isCommutable = 1;
1681 let hasSideEffects = 0;
1684 // Pseudo multiply/divide instruction with explicit accumulator register
1686 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1687 SDPatternOperator OpNode, InstrItinClass Itin,
1688 bit IsComm = 1, bit HasSideEffects = 0,
1689 bit UsesCustomInserter = 0> :
1690 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1691 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1692 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1693 let isCommutable = IsComm;
1694 let hasSideEffects = HasSideEffects;
1695 let usesCustomInserter = UsesCustomInserter;
1698 // Pseudo multiply add/sub instruction with explicit accumulator register
1700 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1701 InstrItinClass itin>
1702 : PseudoSE<(outs ACC64:$ac),
1703 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1705 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1707 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1708 string Constraints = "$acin = $ac";
1711 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1712 list<Register> DefRegs> :
1713 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1714 [], itin, FrmR, opstr> {
1719 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1720 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1721 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1723 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1724 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1726 let Uses = [UseReg];
1727 let hasSideEffects = 0;
1731 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1732 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1733 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1736 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1737 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1740 let hasSideEffects = 0;
1744 class EffectiveAddress<string opstr, RegisterOperand RO> :
1745 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1746 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1747 !strconcat(opstr, "_lea")> {
1748 let isCodeGenOnly = 1;
1749 let hasNoSchedulingInfo = 1;
1750 let DecoderMethod = "DecodeMem";
1753 // Count Leading Ones/Zeros in Word
1754 class CountLeading0<string opstr, RegisterOperand RO,
1755 InstrItinClass itin = NoItinerary>:
1756 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1757 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1759 class CountLeading1<string opstr, RegisterOperand RO,
1760 InstrItinClass itin = NoItinerary>:
1761 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1762 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1764 // Sign Extend in Register.
1765 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1766 InstrItinClass itin> :
1767 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1768 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1771 class SubwordSwap<string opstr, RegisterOperand RO,
1772 InstrItinClass itin = NoItinerary>:
1773 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1775 let hasSideEffects = 0;
1779 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1780 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1781 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1784 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1785 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1786 SDPatternOperator Op = null_frag> :
1787 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1788 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1789 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1792 // 'ins' and its' 64 bit variants are matched by C++ code.
1793 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1794 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1795 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1796 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1797 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1799 II_INS, FrmR, opstr> {
1800 let Constraints = "$src = $rt";
1803 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1804 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1805 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1806 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
1807 let hasNoSchedulingInfo = 1;
1810 class Atomic2OpsPostRA<RegisterClass RC> :
1811 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1816 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1817 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1818 RC:$shiftamnt), []>;
1820 // Atomic Compare & Swap.
1821 // Atomic compare and swap is lowered into two stages. The first stage happens
1822 // during ISelLowering, which produces the PostRA version of this instruction.
1823 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1824 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1825 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
1826 let hasNoSchedulingInfo = 1;
1829 class AtomicCmpSwapPostRA<RegisterClass RC> :
1830 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1835 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1836 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1837 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1842 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1843 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1844 [], II_LL, FrmI, opstr> {
1845 let DecoderMethod = "DecodeMem";
1849 class SCBase<string opstr, RegisterOperand RO> :
1850 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1851 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1852 let DecoderMethod = "DecodeMem";
1854 let Constraints = "$rt = $dst";
1857 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1858 InstrItinClass itin> :
1859 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1860 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1861 let BaseOpcode = asmstr;
1864 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1865 InstrItinClass itin> :
1866 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1867 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1868 let BaseOpcode = asmstr;
1871 class TrapBase<Instruction RealInst>
1872 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1873 PseudoInstExpansion<(RealInst 0, 0)> {
1876 let hasSideEffects = 1;
1878 let isCodeGenOnly = 1;
1881 //===----------------------------------------------------------------------===//
1882 // Pseudo instructions
1883 //===----------------------------------------------------------------------===//
1886 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1887 let hasDelaySlot=1 in
1888 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1890 let hasSideEffects=1 in
1891 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1894 let Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
1895 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1896 [(callseq_start timm:$amt1, timm:$amt2)]>;
1897 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1898 [(callseq_end timm:$amt1, timm:$amt2)]>;
1901 let usesCustomInserter = 1 in {
1902 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1903 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1904 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1905 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1906 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1907 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1908 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1909 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1910 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1911 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1912 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1913 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1914 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1915 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1916 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1917 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1918 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1919 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1921 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1922 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1923 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1925 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1926 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1927 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1929 def ATOMIC_LOAD_MIN_I8 : Atomic2Ops<atomic_load_min_8, GPR32>;
1930 def ATOMIC_LOAD_MIN_I16 : Atomic2Ops<atomic_load_min_16, GPR32>;
1931 def ATOMIC_LOAD_MIN_I32 : Atomic2Ops<atomic_load_min_32, GPR32>;
1932 def ATOMIC_LOAD_MAX_I8 : Atomic2Ops<atomic_load_max_8, GPR32>;
1933 def ATOMIC_LOAD_MAX_I16 : Atomic2Ops<atomic_load_max_16, GPR32>;
1934 def ATOMIC_LOAD_MAX_I32 : Atomic2Ops<atomic_load_max_32, GPR32>;
1935 def ATOMIC_LOAD_UMIN_I8 : Atomic2Ops<atomic_load_umin_8, GPR32>;
1936 def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops<atomic_load_umin_16, GPR32>;
1937 def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops<atomic_load_umin_32, GPR32>;
1938 def ATOMIC_LOAD_UMAX_I8 : Atomic2Ops<atomic_load_umax_8, GPR32>;
1939 def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops<atomic_load_umax_16, GPR32>;
1940 def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops<atomic_load_umax_32, GPR32>;
1943 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1944 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1945 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1946 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1947 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1948 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1949 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1950 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1951 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1952 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1953 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1954 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1955 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1956 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1957 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1958 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1959 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1960 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1962 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1963 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1964 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1966 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1967 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1968 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
1970 def ATOMIC_LOAD_MIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1971 def ATOMIC_LOAD_MIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1972 def ATOMIC_LOAD_MIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1973 def ATOMIC_LOAD_MAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1974 def ATOMIC_LOAD_MAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1975 def ATOMIC_LOAD_MAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1976 def ATOMIC_LOAD_UMIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1977 def ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1978 def ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1979 def ATOMIC_LOAD_UMAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1980 def ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1981 def ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1983 /// Pseudo instructions for loading and storing accumulator registers.
1984 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1985 def LOAD_ACC64 : Load<"", ACC64>;
1986 def STORE_ACC64 : Store<"", ACC64>;
1989 // We need these two pseudo instructions to avoid offset calculation for long
1990 // branches. See the comment in file MipsLongBranch.cpp for detailed
1993 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
1994 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1995 (ins brtarget:$tgt, brtarget:$baltgt), []> {
1996 bit hasNoSchedulingInfo = 1;
1998 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
1999 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2000 (ins brtarget:$tgt), []> {
2001 bit hasNoSchedulingInfo = 1;
2004 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2005 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2006 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
2007 bit hasNoSchedulingInfo = 1;
2009 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2010 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2011 (ins GPR32Opnd:$src, brtarget:$tgt), []> {
2012 bit hasNoSchedulingInfo = 1;
2015 //===----------------------------------------------------------------------===//
2016 // Instruction definition
2017 //===----------------------------------------------------------------------===//
2018 //===----------------------------------------------------------------------===//
2019 // MipsI Instructions
2020 //===----------------------------------------------------------------------===//
2022 /// Arithmetic Instructions (ALU Immediate)
2023 let AdditionalPredicates = [NotInMicroMips] in {
2024 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2025 II_ADDIU, imm32SExt16, add>,
2026 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2028 def ANDi : MMRel, StdMMR6Rel,
2029 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, imm32ZExt16, and>,
2030 ADDI_FM<0xc>, ISA_MIPS1;
2031 def ORi : MMRel, StdMMR6Rel,
2032 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, imm32ZExt16, or>,
2033 ADDI_FM<0xd>, ISA_MIPS1;
2034 def XORi : MMRel, StdMMR6Rel,
2035 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, imm32ZExt16, xor>,
2036 ADDI_FM<0xe>, ISA_MIPS1;
2037 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2038 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2039 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2040 SLTI_FM<0xa>, ISA_MIPS1;
2041 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2042 SLTI_FM<0xb>, ISA_MIPS1;
2044 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2047 /// Arithmetic Instructions (3-Operand, R-Type)
2048 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2049 ADD_FM<0, 0x21>, ISA_MIPS1;
2050 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2051 ADD_FM<0, 0x23>, ISA_MIPS1;
2053 let Defs = [HI0, LO0] in
2054 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2055 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2057 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2058 ADD_FM<0, 0x20>, ISA_MIPS1;
2059 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2060 ADD_FM<0, 0x22>, ISA_MIPS1;
2062 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2064 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2066 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2067 ADD_FM<0, 0x24>, ISA_MIPS1;
2068 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2069 ADD_FM<0, 0x25>, ISA_MIPS1;
2070 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2071 ADD_FM<0, 0x26>, ISA_MIPS1;
2072 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2076 let AdditionalPredicates = [NotInMicroMips] in {
2077 /// Shift Instructions
2078 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2079 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2080 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2081 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2082 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2083 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2084 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2085 SRLV_FM<4, 0>, ISA_MIPS1;
2086 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2087 SRLV_FM<6, 0>, ISA_MIPS1;
2088 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2089 SRLV_FM<7, 0>, ISA_MIPS1;
2091 // Rotate Instructions
2092 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2094 SRA_FM<2, 1>, ISA_MIPS32R2;
2095 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2096 SRLV_FM<6, 1>, ISA_MIPS32R2;
2099 /// Load and Store Instructions
2101 let AdditionalPredicates = [NotInMicroMips] in {
2102 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2103 LW_FM<0x20>, ISA_MIPS1;
2104 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2105 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2106 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2107 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2108 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2109 MMRel, LW_FM<0x25>, ISA_MIPS1;
2110 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2111 LW_FM<0x23>, ISA_MIPS1;
2112 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2113 LW_FM<0x28>, ISA_MIPS1;
2114 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2116 def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>,
2117 MMRel, LW_FM<0x2b>, ISA_MIPS1;
2120 /// load/store left/right
2121 let AdditionalPredicates = [NotInMicroMips] in {
2122 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2123 ISA_MIPS1_NOT_32R6_64R6;
2124 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2125 ISA_MIPS1_NOT_32R6_64R6;
2126 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2127 ISA_MIPS1_NOT_32R6_64R6;
2128 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2129 ISA_MIPS1_NOT_32R6_64R6;
2131 // COP2 Memory Instructions
2132 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2133 ISA_MIPS1_NOT_32R6_64R6;
2134 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2135 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2136 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2137 ISA_MIPS2_NOT_32R6_64R6;
2138 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2139 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2141 // COP3 Memory Instructions
2142 let DecoderNamespace = "COP3_" in {
2143 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2144 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2145 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2146 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2147 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2148 ISA_MIPS2, NOT_ASE_CNMIPS;
2149 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2150 ISA_MIPS2, NOT_ASE_CNMIPS;
2153 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2154 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2158 let AdditionalPredicates = [NotInMicroMips] in {
2159 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2161 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2163 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2165 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2167 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2169 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2172 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2173 ISA_MIPS2_NOT_32R6_64R6;
2174 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2175 ISA_MIPS2_NOT_32R6_64R6;
2176 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2177 ISA_MIPS2_NOT_32R6_64R6;
2178 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2179 ISA_MIPS2_NOT_32R6_64R6;
2180 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2181 ISA_MIPS2_NOT_32R6_64R6;
2182 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2183 ISA_MIPS2_NOT_32R6_64R6;
2186 let AdditionalPredicates = [NotInMicroMips] in {
2187 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2188 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2190 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2191 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2192 ISA_MIPS32_NOT_32R6_64R6;
2194 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2195 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2197 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2199 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2201 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2204 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2207 let AdditionalPredicates = [NotInMicroMips] in {
2208 /// Load-linked, Store-conditional
2209 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2210 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2212 /// Jump and Branch Instructions
2213 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2214 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2215 IsBranch, ISA_MIPS1;
2217 let AdditionalPredicates = [NotInMicroMips] in {
2218 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>,
2219 ISA_MIPS1_NOT_32R6_64R6;
2220 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2222 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2223 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2224 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2226 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2227 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2228 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2229 BGEZ_FM<1, 1>, ISA_MIPS1;
2230 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2231 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2232 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2233 BGEZ_FM<7, 0>, ISA_MIPS1;
2234 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2235 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2236 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2237 BGEZ_FM<6, 0>, ISA_MIPS1;
2238 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2239 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2240 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2241 BGEZ_FM<1, 0>, ISA_MIPS1;
2242 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2243 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2244 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2246 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2250 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2251 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2252 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2255 let AdditionalPredicates = [NotInMicroMips] in {
2256 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2257 ISA_MIPS32_NOT_32R6_64R6;
2258 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2259 ISA_MIPS1_NOT_32R6_64R6;
2260 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2261 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2262 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2263 ISA_MIPS1_NOT_32R6_64R6;
2264 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2265 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2266 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2268 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2269 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2271 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2272 NoIndirectJumpGuards] in
2273 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2275 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2276 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2277 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2278 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2279 II_IndirectBranchPseudo>,
2280 PseudoInstExpansion<(JumpInst RO:$rs)> {
2283 let hasDelaySlot = 1;
2285 let isIndirectBranch = 1;
2289 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2290 NoIndirectJumpGuards] in
2291 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2292 ISA_MIPS1_NOT_32R6_64R6;
2294 // Return instructions are matched as a RetRA instruction, then are expanded
2295 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2296 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2298 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2299 [], II_ReturnPseudo> {
2300 let isTerminator = 1;
2302 let hasDelaySlot = 1;
2304 let isCodeGenOnly = 1;
2306 let hasExtraSrcRegAllocReq = 1;
2310 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2312 // Exception handling related node and instructions.
2313 // The conversion sequence is:
2314 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2315 // MIPSeh_return -> (stack change + indirect branch)
2317 // MIPSeh_return takes the place of regular return instruction
2318 // but takes two arguments (V1, V0) which are used for storing
2319 // the offset and return address respectively.
2320 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2322 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2323 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2325 let Uses = [V0, V1], isTerminator = 1, isReturn = 1,
2326 isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
2327 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2328 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2329 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
2330 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2333 /// Multiply and Divide Instructions.
2334 let AdditionalPredicates = [NotInMicroMips] in {
2335 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2336 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2337 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2338 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2339 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2340 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2341 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2342 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2343 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2344 ISA_MIPS1_NOT_32R6_64R6;
2345 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2346 ISA_MIPS1_NOT_32R6_64R6;
2347 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2348 ISA_MIPS1_NOT_32R6_64R6;
2349 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2350 ISA_MIPS1_NOT_32R6_64R6;
2352 /// Sign Ext In Register Instructions.
2353 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2354 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2355 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2356 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2359 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2360 ISA_MIPS32_NOT_32R6_64R6;
2361 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2362 ISA_MIPS32_NOT_32R6_64R6;
2364 /// Word Swap Bytes Within Halfwords
2365 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2369 def NOP : PseudoSE<(outs), (ins), []>,
2370 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2372 // FrameIndexes are legalized when they are operands from load/store
2373 // instructions. The same not happens for stack address copies, so an
2374 // add op with mem ComplexPattern is used and the stack address copy
2375 // can be matched. It's similar to Sparc LEA_ADDRi
2376 let AdditionalPredicates = [NotInMicroMips] in
2377 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>,
2381 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2382 ISA_MIPS32_NOT_32R6_64R6;
2383 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2384 ISA_MIPS32_NOT_32R6_64R6;
2385 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2386 ISA_MIPS32_NOT_32R6_64R6;
2387 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2388 ISA_MIPS32_NOT_32R6_64R6;
2391 let AdditionalPredicates = [NotDSP] in {
2392 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2393 ISA_MIPS1_NOT_32R6_64R6;
2394 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2395 ISA_MIPS1_NOT_32R6_64R6;
2396 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2397 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2398 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2399 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2400 ISA_MIPS32_NOT_32R6_64R6;
2401 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2402 ISA_MIPS32_NOT_32R6_64R6;
2403 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2404 ISA_MIPS32_NOT_32R6_64R6;
2405 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2406 ISA_MIPS32_NOT_32R6_64R6;
2409 let AdditionalPredicates = [NotInMicroMips] in {
2410 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2411 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2412 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2413 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2414 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2415 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2416 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2417 immZExt5, immZExt5Plus1, MipsExt>,
2418 EXT_FM<0>, ISA_MIPS32R2;
2419 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2420 uimm5_inssize_plus1, immZExt5,
2422 EXT_FM<4>, ISA_MIPS32R2;
2424 /// Move Control Registers From/To CPU Registers
2425 let AdditionalPredicates = [NotInMicroMips] in {
2426 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2427 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2428 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2429 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2430 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2431 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2432 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2433 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2436 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2437 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2438 let AdditionalPredicates = [NotInMicroMips] in {
2439 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2441 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2444 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2448 // JR_HB and JALR_HB are defined here using the new style naming
2449 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2450 // and because of that it doesn't follow the naming convention of the
2451 // rest of the file. To avoid a mixture of old vs new style, the new
2452 // style was chosen.
2453 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2454 dag OutOperandList = (outs);
2455 dag InOperandList = (ins GPROpnd:$rs);
2456 string AsmString = !strconcat(instr_asm, "\t$rs");
2457 list<dag> Pattern = [];
2460 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2461 dag OutOperandList = (outs GPROpnd:$rd);
2462 dag InOperandList = (ins GPROpnd:$rs);
2463 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2464 list<dag> Pattern = [];
2467 class JR_HB_DESC<RegisterOperand RO> :
2468 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2470 let isIndirectBranch=1;
2477 class JALR_HB_DESC<RegisterOperand RO> :
2478 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2480 let isIndirectBranch=1;
2485 class JR_HB_ENC : JR_HB_FM<8>;
2486 class JALR_HB_ENC : JALR_HB_FM<9>;
2488 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2489 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2491 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2492 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2495 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2496 UseIndirectJumpsHazard] in {
2497 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2498 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2499 ISA_MIPS32R2_NOT_32R6_64R6;
2502 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2503 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2504 let AdditionalPredicates = [NotInMicroMips] in {
2505 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2506 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2507 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2508 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2510 class CacheOp<string instr_asm, Operand MemOpnd,
2511 InstrItinClass itin = NoItinerary> :
2512 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2513 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2515 let DecoderMethod = "DecodeCacheOp";
2518 let AdditionalPredicates = [NotInMicroMips] in {
2519 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2520 INSN_MIPS3_32_NOT_32R6_64R6;
2521 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2522 INSN_MIPS3_32_NOT_32R6_64R6;
2524 // FIXME: We are missing the prefx instruction.
2525 def ROL : MipsAsmPseudoInst<(outs),
2526 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2527 "rol\t$rs, $rt, $rd">;
2528 def ROLImm : MipsAsmPseudoInst<(outs),
2529 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2530 "rol\t$rs, $rt, $imm">;
2531 def : MipsInstAlias<"rol $rd, $rs",
2532 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2533 def : MipsInstAlias<"rol $rd, $imm",
2534 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2536 def ROR : MipsAsmPseudoInst<(outs),
2537 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2538 "ror\t$rs, $rt, $rd">;
2539 def RORImm : MipsAsmPseudoInst<(outs),
2540 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2541 "ror\t$rs, $rt, $imm">;
2542 def : MipsInstAlias<"ror $rd, $rs",
2543 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2544 def : MipsInstAlias<"ror $rd, $imm",
2545 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2547 def DROL : MipsAsmPseudoInst<(outs),
2548 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2549 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2550 def DROLImm : MipsAsmPseudoInst<(outs),
2551 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2552 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2553 def : MipsInstAlias<"drol $rd, $rs",
2554 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2556 def : MipsInstAlias<"drol $rd, $imm",
2557 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2560 def DROR : MipsAsmPseudoInst<(outs),
2561 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2562 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2563 def DRORImm : MipsAsmPseudoInst<(outs),
2564 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2565 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2566 def : MipsInstAlias<"dror $rd, $rs",
2567 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2569 def : MipsInstAlias<"dror $rd, $imm",
2570 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
2573 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2576 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2577 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2578 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2580 def : MipsInstAlias<"seq $rd, $rs",
2581 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2584 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2585 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2586 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2588 def : MipsInstAlias<"seq $rd, $imm",
2589 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2592 def SNEMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2593 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2594 "sne $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2596 def : MipsInstAlias<"sne $rd, $rs",
2597 (SNEMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2600 def SNEIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2601 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2602 "sne $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2604 def : MipsInstAlias<"sne $rd, $imm",
2605 (SNEIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2608 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2609 simm32_relaxed:$imm),
2610 "mul\t$rd, $rs, $imm">,
2611 ISA_MIPS1_NOT_32R6_64R6;
2612 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2614 "mulo\t$rd, $rs, $rt">,
2615 ISA_MIPS1_NOT_32R6_64R6;
2616 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2618 "mulou\t$rd, $rs, $rt">,
2619 ISA_MIPS1_NOT_32R6_64R6;
2621 // Virtualization ASE
2622 class HYPCALL_FT<string opstr> :
2623 InstSE<(outs), (ins uimm10:$code_),
2624 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2625 let BaseOpcode = opstr;
2628 let AdditionalPredicates = [NotInMicroMips] in {
2629 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2630 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2631 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2632 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2633 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2634 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2635 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2636 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2637 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2638 ISA_MIPS32R5, ASE_VIRT;
2639 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2640 ISA_MIPS32R5, ASE_VIRT;
2641 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2642 ISA_MIPS32R5, ASE_VIRT;
2643 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2644 ISA_MIPS32R5, ASE_VIRT;
2645 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2646 ISA_MIPS32R5, ASE_VIRT;
2647 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2648 ISA_MIPS32R5, ASE_VIRT;
2649 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2650 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2653 //===----------------------------------------------------------------------===//
2654 // Instruction aliases
2655 //===----------------------------------------------------------------------===//
2657 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2659 RegisterOperand RO = GPR32Opnd,
2660 Operand Imm = simm32_relaxed> {
2661 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2665 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2671 let AdditionalPredicates = [NotInMicroMips] in {
2672 def : MipsInstAlias<"move $dst, $src",
2673 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2675 def : MipsInstAlias<"move $dst, $src",
2676 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2679 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2680 ISA_MIPS1_NOT_32R6_64R6;
2682 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2684 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2686 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2689 def : MipsInstAlias<"neg $rt, $rs",
2690 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2691 def : MipsInstAlias<"neg $rt",
2692 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2693 def : MipsInstAlias<"negu $rt, $rs",
2694 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2695 def : MipsInstAlias<"negu $rt",
2696 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2698 def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2699 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2700 "sge\t$rd, $rs, $rt">, ISA_MIPS1;
2701 def : MipsInstAlias<"sge $rs, $rt",
2702 (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2704 def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2705 (ins GPR32Opnd:$rs, simm32:$imm),
2706 "sge\t$rd, $rs, $imm">, GPR_32;
2707 def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
2712 def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2713 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2714 "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
2715 def : MipsInstAlias<"sgeu $rs, $rt",
2716 (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2718 def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2719 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2720 "sgeu\t$rd, $rs, $imm">, GPR_32;
2721 def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
2723 uimm32_coerced:$imm), 0>,
2726 def : MipsInstAlias<
2727 "sgt $rd, $rs, $rt",
2728 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2729 def : MipsInstAlias<
2731 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2733 def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2734 (ins GPR32Opnd:$rs, simm32:$imm),
2735 "sgt\t$rd, $rs, $imm">, GPR_32;
2736 def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
2740 def : MipsInstAlias<
2741 "sgtu $rd, $rs, $rt",
2742 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2743 def : MipsInstAlias<
2745 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2747 def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2748 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2749 "sgtu\t$rd, $rs, $imm">, GPR_32;
2750 def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
2752 uimm32_coerced:$imm), 0>,
2755 def SLE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2756 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2757 "sle\t$rd, $rs, $rt">, ISA_MIPS1;
2758 def : MipsInstAlias<"sle $rs, $rt",
2759 (SLE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2761 def SLEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2762 (ins GPR32Opnd:$rs, simm32:$imm),
2763 "sle\t$rd, $rs, $imm">, GPR_32;
2764 def : MipsInstAlias<"sle $rs, $imm", (SLEImm GPR32Opnd:$rs,
2769 def SLEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2770 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2771 "sleu\t$rd, $rs, $rt">, ISA_MIPS1;
2772 def : MipsInstAlias<"sleu $rs, $rt",
2773 (SLEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2775 def SLEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2776 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2777 "sleu\t$rd, $rs, $imm">, GPR_32;
2778 def : MipsInstAlias<"sleu $rs, $imm", (SLEUImm GPR32Opnd:$rs,
2780 uimm32_coerced:$imm), 0>,
2783 def : MipsInstAlias<
2785 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2786 def : MipsInstAlias<
2788 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2790 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2792 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>,
2793 ISA_MIPS1_NOT_32R6_64R6;
2795 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2797 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2799 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2801 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2803 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2805 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2807 def : MipsInstAlias<"mfgc0 $rt, $rd",
2808 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2809 ISA_MIPS32R5, ASE_VIRT;
2810 def : MipsInstAlias<"mtgc0 $rt, $rd",
2811 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2812 ISA_MIPS32R5, ASE_VIRT;
2813 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2814 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2815 ISA_MIPS32R5, ASE_VIRT;
2816 def : MipsInstAlias<"mthgc0 $rt, $rd",
2817 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2818 ISA_MIPS32R5, ASE_VIRT;
2819 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2821 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2823 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2825 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2828 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2831 def : MipsInstAlias<"bnez $rs,$offset",
2832 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2834 def : MipsInstAlias<"bnezl $rs, $offset",
2835 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2837 def : MipsInstAlias<"beqz $rs,$offset",
2838 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2840 def : MipsInstAlias<"beqzl $rs, $offset",
2841 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2844 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2846 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2847 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2848 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2849 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2851 def : MipsInstAlias<"teq $rs, $rt",
2852 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2853 def : MipsInstAlias<"tge $rs, $rt",
2854 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2855 def : MipsInstAlias<"tgeu $rs, $rt",
2856 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2857 def : MipsInstAlias<"tlt $rs, $rt",
2858 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2859 def : MipsInstAlias<"tltu $rs, $rt",
2860 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2861 def : MipsInstAlias<"tne $rs, $rt",
2862 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2863 def : MipsInstAlias<"rdhwr $rt, $rs",
2864 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2867 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2868 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2869 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2870 def : MipsInstAlias<"sub $rs, $imm",
2871 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2872 0>, ISA_MIPS1_NOT_32R6_64R6;
2873 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2874 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2875 InvertedImOperand:$imm), 0>;
2876 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2877 InvertedImOperand:$imm), 0>;
2878 let AdditionalPredicates = [NotInMicroMips] in {
2879 def : MipsInstAlias<"sll $rd, $rt, $rs",
2880 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2881 def : MipsInstAlias<"sra $rd, $rt, $rs",
2882 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2883 def : MipsInstAlias<"srl $rd, $rt, $rs",
2884 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2885 def : MipsInstAlias<"sll $rd, $rt",
2886 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2887 def : MipsInstAlias<"sra $rd, $rt",
2888 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2889 def : MipsInstAlias<"srl $rd, $rt",
2890 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2891 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2893 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2896 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2897 let AdditionalPredicates = [NotInMicroMips] in
2898 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2900 def : MipsInstAlias<"mulo $rs, $rt",
2901 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2902 ISA_MIPS1_NOT_32R6_64R6;
2903 def : MipsInstAlias<"mulou $rs, $rt",
2904 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2905 ISA_MIPS1_NOT_32R6_64R6;
2907 let AdditionalPredicates = [NotInMicroMips] in
2908 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2910 //===----------------------------------------------------------------------===//
2911 // Assembler Pseudo Instructions
2912 //===----------------------------------------------------------------------===//
2914 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2916 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2917 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2918 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2919 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2921 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2922 RegisterOperand RO> :
2923 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2924 !strconcat(instr_asm, "\t$rt, $addr")> ;
2925 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2927 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2928 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2929 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2930 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2932 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2934 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2937 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2938 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2939 "nor\t$rs, $rt, $imm">;
2940 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2941 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2942 simm32_relaxed:$imm)>, GPR_32;
2944 let hasDelaySlot = 1, isCTI = 1 in {
2945 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2946 (ins imm64:$imm64, brtarget:$offset),
2947 "bne\t$rt, $imm64, $offset">;
2948 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2949 (ins imm64:$imm64, brtarget:$offset),
2950 "beq\t$rt, $imm64, $offset">;
2952 class CondBranchPseudo<string instr_asm> :
2953 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2955 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2958 def BLT : CondBranchPseudo<"blt">;
2959 def BLE : CondBranchPseudo<"ble">;
2960 def BGE : CondBranchPseudo<"bge">;
2961 def BGT : CondBranchPseudo<"bgt">;
2962 def BLTU : CondBranchPseudo<"bltu">;
2963 def BLEU : CondBranchPseudo<"bleu">;
2964 def BGEU : CondBranchPseudo<"bgeu">;
2965 def BGTU : CondBranchPseudo<"bgtu">;
2966 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2967 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2968 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2969 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2970 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2971 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2972 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2973 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2976 class CondBranchImmPseudo<string instr_asm> :
2977 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2978 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2980 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2981 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2983 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2984 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2985 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2986 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2987 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2988 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2989 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2990 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2991 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2992 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2993 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2994 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2995 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2996 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2997 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2998 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
3000 // FIXME: Predicates are removed because instructions are matched regardless of
3001 // predicates, because PredicateControl was not in the hierarchy. This was
3002 // done to emit more precise error message from expansion function.
3003 // Once the tablegen-erated errors are made better, this needs to be fixed and
3004 // predicates needs to be restored.
3006 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
3007 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3008 "div\t$rd, $rs, $rt">,
3009 ISA_MIPS1_NOT_32R6_64R6;
3010 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3011 (ins GPR32Opnd:$rs, simm32:$imm),
3012 "div\t$rd, $rs, $imm">,
3013 ISA_MIPS1_NOT_32R6_64R6;
3014 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3015 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3016 "divu\t$rd, $rs, $rt">,
3017 ISA_MIPS1_NOT_32R6_64R6;
3018 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3019 (ins GPR32Opnd:$rs, simm32:$imm),
3020 "divu\t$rd, $rs, $imm">,
3021 ISA_MIPS1_NOT_32R6_64R6;
3024 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
3026 ISA_MIPS1_NOT_32R6_64R6;
3027 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
3028 GPR32NonZeroOpnd:$rs,
3030 ISA_MIPS1_NOT_32R6_64R6;
3031 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3033 ISA_MIPS1_NOT_32R6_64R6;
3035 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
3037 ISA_MIPS1_NOT_32R6_64R6;
3038 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
3039 GPR32NonZeroOpnd:$rt,
3041 ISA_MIPS1_NOT_32R6_64R6;
3043 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3045 ISA_MIPS1_NOT_32R6_64R6;
3047 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3048 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3049 "rem\t$rd, $rs, $rt">,
3050 ISA_MIPS1_NOT_32R6_64R6;
3051 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3052 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3053 "rem\t$rd, $rs, $imm">,
3054 ISA_MIPS1_NOT_32R6_64R6;
3055 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3056 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3057 "remu\t$rd, $rs, $rt">,
3058 ISA_MIPS1_NOT_32R6_64R6;
3059 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3060 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3061 "remu\t$rd, $rs, $imm">,
3062 ISA_MIPS1_NOT_32R6_64R6;
3064 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3066 ISA_MIPS1_NOT_32R6_64R6;
3067 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3068 simm32_relaxed:$imm), 0>,
3069 ISA_MIPS1_NOT_32R6_64R6;
3070 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3072 ISA_MIPS1_NOT_32R6_64R6;
3073 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3074 simm32_relaxed:$imm), 0>,
3075 ISA_MIPS1_NOT_32R6_64R6;
3077 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3078 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3080 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3081 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3083 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3084 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3086 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3087 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3089 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3090 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3092 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3093 (ins mem_simm16:$addr), "ld $rt, $addr">,
3094 ISA_MIPS1_NOT_MIPS3;
3095 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3096 (ins mem_simm16:$addr), "sd $rt, $addr">,
3097 ISA_MIPS1_NOT_MIPS3;
3098 //===----------------------------------------------------------------------===//
3099 // Arbitrary patterns that map to one or more instructions
3100 //===----------------------------------------------------------------------===//
3102 // Load/store pattern templates.
3103 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3104 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3106 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3107 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3109 // Materialize constants.
3110 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3111 Instruction ADDiuOp, Instruction LUiOp,
3112 Instruction ORiOp> {
3114 // Constant synthesis previously relied on the ordering of the patterns below.
3115 // By making the predicates they use non-overlapping, the patterns were
3116 // reordered so that the effect of the newly introduced predicates can be
3119 // Arbitrary immediates
3120 def : MipsPat<(VT LUiORiPred:$imm),
3121 (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3123 // Bits 32-16 set, sign/zero extended.
3124 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3127 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3128 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3131 let AdditionalPredicates = [NotInMicroMips] in
3132 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3134 // Carry MipsPatterns
3135 let AdditionalPredicates = [NotInMicroMips] in {
3136 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3137 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3139 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3140 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3141 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3142 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3144 // Support multiplication for pre-Mips32 targets that don't have
3145 // the MUL instruction.
3146 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3147 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3148 ISA_MIPS1_NOT_32R6_64R6;
3151 def : MipsPat<(MipsSync (i32 immz)),
3152 (SYNC 0)>, ISA_MIPS2;
3155 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3156 (JAL texternalsym:$dst)>, ISA_MIPS1;
3157 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3158 // (JALR GPR32:$dst)>;
3161 let AdditionalPredicates = [NotInMicroMips] in {
3162 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3163 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3164 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3165 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3168 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3169 Register ZeroReg, RegisterOperand GPROpnd> {
3170 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3171 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3172 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3173 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3174 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3176 def : MipsPat<(MipsLo tglobaladdr:$in),
3177 (Addiu ZeroReg, tglobaladdr:$in)>;
3178 def : MipsPat<(MipsLo tblockaddress:$in),
3179 (Addiu ZeroReg, tblockaddress:$in)>;
3180 def : MipsPat<(MipsLo tjumptable:$in),
3181 (Addiu ZeroReg, tjumptable:$in)>;
3182 def : MipsPat<(MipsLo tconstpool:$in),
3183 (Addiu ZeroReg, tconstpool:$in)>;
3184 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3185 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3186 def : MipsPat<(MipsLo texternalsym:$in),
3187 (Addiu ZeroReg, texternalsym:$in)>;
3189 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3190 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3191 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3192 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3193 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3194 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3195 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3196 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3197 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3198 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3199 def : MipsPat<(add GPROpnd:$hi, (MipsLo texternalsym:$lo)),
3200 (Addiu GPROpnd:$hi, texternalsym:$lo)>;
3204 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3205 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3207 let AdditionalPredicates = [NotInMicroMips] in {
3208 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3210 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3211 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3214 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3218 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3219 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3220 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3221 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3223 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3224 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3225 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3226 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3227 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3228 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3230 // Mips does not have "not", so we expand our way
3231 def : MipsPat<(not GPR32:$in),
3232 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3236 let AdditionalPredicates = [NotInMicroMips] in {
3237 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3238 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3239 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3242 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3246 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3247 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3248 Instruction SLTiOp, Instruction SLTiuOp,
3250 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3251 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3252 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3253 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3255 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3256 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3257 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3258 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3259 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3260 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3261 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3262 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3263 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3264 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3265 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3266 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3268 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3269 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3270 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3271 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3273 def : MipsPat<(brcond RC:$cond, bb:$dst),
3274 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3276 let AdditionalPredicates = [NotInMicroMips] in {
3277 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3279 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3280 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3281 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3282 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3286 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3287 Instruction SLTuOp, Register ZEROReg> {
3288 def : MipsPat<(seteq RC:$lhs, 0),
3289 (SLTiuOp RC:$lhs, 1)>;
3290 def : MipsPat<(setne RC:$lhs, 0),
3291 (SLTuOp ZEROReg, RC:$lhs)>;
3292 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3293 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3294 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3295 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3298 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3299 Instruction SLTuOp> {
3300 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3301 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3302 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3303 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3306 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3307 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3308 (SLTOp RC:$rhs, RC:$lhs)>;
3309 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3310 (SLTuOp RC:$rhs, RC:$lhs)>;
3313 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3314 Instruction SLTuOp> {
3315 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3316 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3317 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3318 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3321 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3322 Instruction SLTiOp, Instruction SLTiuOp> {
3323 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3324 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3325 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3326 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3329 let AdditionalPredicates = [NotInMicroMips] in {
3330 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3331 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3332 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3333 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3334 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3337 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3340 // Load halfword/word patterns.
3341 let AdditionalPredicates = [NotInMicroMips] in {
3342 let AddedComplexity = 40 in {
3343 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3344 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3345 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3346 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3347 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3350 // Atomic load patterns.
3351 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3352 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3353 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3355 // Atomic store patterns.
3356 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3358 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3360 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3364 //===----------------------------------------------------------------------===//
3365 // Floating Point Support
3366 //===----------------------------------------------------------------------===//
3368 include "MipsInstrFPU.td"
3369 include "Mips64InstrInfo.td"
3370 include "MipsCondMov.td"
3372 include "Mips32r6InstrInfo.td"
3373 include "Mips64r6InstrInfo.td"
3378 include "Mips16InstrFormats.td"
3379 include "Mips16InstrInfo.td"
3382 include "MipsDSPInstrFormats.td"
3383 include "MipsDSPInstrInfo.td"
3386 include "MipsMSAInstrFormats.td"
3387 include "MipsMSAInstrInfo.td"
3390 include "MipsEVAInstrFormats.td"
3391 include "MipsEVAInstrInfo.td"
3394 include "MipsMTInstrFormats.td"
3395 include "MipsMTInstrInfo.td"
3398 include "MicroMipsInstrFormats.td"
3399 include "MicroMipsInstrInfo.td"
3400 include "MicroMipsInstrFPU.td"
3403 include "MicroMips32r6InstrFormats.td"
3404 include "MicroMips32r6InstrInfo.td"
3407 include "MicroMipsDSPInstrFormats.td"
3408 include "MicroMipsDSPInstrInfo.td"