1 //===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the Mips implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Mips profiles and nodes
16 //===----------------------------------------------------------------------===//
18 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
19 def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
23 def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
24 def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
25 def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
26 def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
27 SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
28 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
30 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
31 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
32 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
33 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
35 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
37 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
39 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
40 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
41 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
42 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
45 def SDTMipsLoadLR : SDTypeProfile<1, 2,
46 [SDTCisInt<0>, SDTCisPtrTy<1>,
50 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
51 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
55 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
56 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
58 // Hi and Lo nodes are used to handle global addresses. Used on
59 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
60 // static model. (nothing to do with Mips Registers Hi and Lo)
62 // Hi is the odd node out, on MIPS64 it can expand to either daddiu when
63 // using static relocations with 64 bit symbols, or lui when using 32 bit
65 def MipsHigher : SDNode<"MipsISD::Higher", SDTIntUnaryOp>;
66 def MipsHighest : SDNode<"MipsISD::Highest", SDTIntUnaryOp>;
67 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
68 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
70 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
72 // Hi node for accessing the GOT.
73 def MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>;
75 // Hi node for handling TLS offsets
76 def MipsTlsHi : SDNode<"MipsISD::TlsHi", SDTIntUnaryOp>;
79 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
82 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
83 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
85 def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
86 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
88 // These are target-independent nodes, but have target-specific formats.
89 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
90 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
91 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
92 [SDNPHasChain, SDNPSideEffect,
93 SDNPOptInGlue, SDNPOutGlue]>;
95 // Nodes used to extract LO/HI registers.
96 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
97 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
99 // Node used to insert 32-bit integers to LOHI register pair.
100 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
103 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
104 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
107 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
108 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
109 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
110 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
113 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
114 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
115 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
117 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
120 // Target constant nodes that are not part of any isel patterns and remain
121 // unchanged can cause instructions with illegal operands to be emitted.
122 // Wrapper node patterns give the instruction selector a chance to replace
123 // target constant nodes that would otherwise remain unchanged with ADDiu
124 // nodes. Without these wrapper node patterns, the following conditional move
125 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
127 // movn %got(d)($gp), %got(c)($gp), $4
128 // This instruction is illegal since movn can take only register operands.
130 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
132 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
134 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
135 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
136 def MipsCIns : SDNode<"MipsISD::CIns", SDT_Ext>;
138 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
139 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
140 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
141 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
143 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
144 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
145 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
147 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
148 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
149 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
150 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
151 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
152 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
153 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
155 //===----------------------------------------------------------------------===//
156 // Mips Instruction Predicate Definitions.
157 //===----------------------------------------------------------------------===//
158 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
159 AssemblerPredicate<"FeatureMips2">;
160 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
161 AssemblerPredicate<"FeatureMips3_32">;
162 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
163 AssemblerPredicate<"FeatureMips3_32r2">;
164 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
165 AssemblerPredicate<"FeatureMips3">;
166 def NotMips3 : Predicate<"!Subtarget->hasMips3()">,
167 AssemblerPredicate<"!FeatureMips3">;
168 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
169 AssemblerPredicate<"FeatureMips4_32">;
170 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
171 AssemblerPredicate<"!FeatureMips4_32">;
172 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
173 AssemblerPredicate<"FeatureMips4_32r2">;
174 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
175 AssemblerPredicate<"FeatureMips5_32r2">;
176 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
177 AssemblerPredicate<"FeatureMips32">;
178 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
179 AssemblerPredicate<"FeatureMips32r2">;
180 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
181 AssemblerPredicate<"FeatureMips32r5">;
182 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
183 AssemblerPredicate<"FeatureMips32r6">;
184 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
185 AssemblerPredicate<"!FeatureMips32r6">;
186 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
187 AssemblerPredicate<"FeatureGP64Bit">;
188 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
189 AssemblerPredicate<"!FeatureGP64Bit">;
190 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
191 AssemblerPredicate<"FeaturePTR64Bit">;
192 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
193 AssemblerPredicate<"!FeaturePTR64Bit">;
194 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
195 AssemblerPredicate<"FeatureMips64">;
196 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
197 AssemblerPredicate<"!FeatureMips64">;
198 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
199 AssemblerPredicate<"FeatureMips64r2">;
200 def HasMips64r5 : Predicate<"Subtarget->hasMips64r5()">,
201 AssemblerPredicate<"FeatureMips64r5">;
202 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
203 AssemblerPredicate<"FeatureMips64r6">;
204 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
205 AssemblerPredicate<"!FeatureMips64r6">;
206 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
207 AssemblerPredicate<"FeatureMips16">;
208 def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
209 AssemblerPredicate<"!FeatureMips16">;
210 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
211 AssemblerPredicate<"FeatureCnMips">;
212 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
213 AssemblerPredicate<"!FeatureCnMips">;
214 def IsSym32 : Predicate<"Subtarget->HasSym32()">,
215 AssemblerPredicate<"FeatureSym32">;
216 def IsSym64 : Predicate<"!Subtarget->HasSym32()">,
217 AssemblerPredicate<"!FeatureSym32">;
218 def IsN64 : Predicate<"Subtarget->isABI_N64()">;
219 def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">;
220 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
221 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
222 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
223 def UseAbs : Predicate<"Subtarget->inAbs2008Mode() ||"
224 "TM.Options.NoNaNsFPMath">;
225 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
226 AssemblerPredicate<"!FeatureMips16">;
227 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
228 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
229 AssemblerPredicate<"FeatureMicroMips">;
230 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
231 AssemblerPredicate<"!FeatureMicroMips">;
232 def IsLE : Predicate<"Subtarget->isLittle()">;
233 def IsBE : Predicate<"!Subtarget->isLittle()">;
234 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
235 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
236 def HasEVA : Predicate<"Subtarget->hasEVA()">,
237 AssemblerPredicate<"FeatureEVA">;
238 def HasMSA : Predicate<"Subtarget->hasMSA()">,
239 AssemblerPredicate<"FeatureMSA">;
240 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
241 AssemblerPredicate<"!FeatureMadd4">;
242 def HasMT : Predicate<"Subtarget->hasMT()">,
243 AssemblerPredicate<"FeatureMT">;
244 def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
245 AssemblerPredicate<"FeatureUseIndirectJumpsHazard">;
246 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
247 AssemblerPredicate<"!FeatureUseIndirectJumpsHazard">;
248 def HasCRC : Predicate<"Subtarget->hasCRC()">,
249 AssemblerPredicate<"FeatureCRC">;
250 def HasVirt : Predicate<"Subtarget->hasVirt()">,
251 AssemblerPredicate<"FeatureVirt">;
252 def HasGINV : Predicate<"Subtarget->hasGINV()">,
253 AssemblerPredicate<"FeatureGINV">;
254 // TODO: Add support for FPOpFusion::Standard
255 def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
256 " FPOpFusion::Fast">;
257 //===----------------------------------------------------------------------===//
258 // Mips GPR size adjectives.
259 // They are mutually exclusive.
260 //===----------------------------------------------------------------------===//
262 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
263 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
265 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
266 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
268 //===----------------------------------------------------------------------===//
269 // Mips Symbol size adjectives.
270 // They are mutally exculsive.
271 //===----------------------------------------------------------------------===//
273 class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
274 class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
276 //===----------------------------------------------------------------------===//
277 // Mips ISA/ASE membership and instruction group membership adjectives.
278 // They are mutually exclusive.
279 //===----------------------------------------------------------------------===//
281 // FIXME: I'd prefer to use additive predicates to build the instruction sets
282 // but we are short on assembler feature bits at the moment. Using a
283 // subtractive predicate will hopefully keep us under the 32 predicate
284 // limit long enough to develop an alternative way to handle P1||P2
287 list<Predicate> EncodingPredicates = [HasStdEnc];
289 class ISA_MIPS1_NOT_MIPS3 {
290 list<Predicate> InsnPredicates = [NotMips3];
291 list<Predicate> EncodingPredicates = [HasStdEnc];
293 class ISA_MIPS1_NOT_4_32 {
294 list<Predicate> InsnPredicates = [NotMips4_32];
295 list<Predicate> EncodingPredicates = [HasStdEnc];
297 class ISA_MIPS1_NOT_32R6_64R6 {
298 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
299 list<Predicate> EncodingPredicates = [HasStdEnc];
302 list<Predicate> InsnPredicates = [HasMips2];
303 list<Predicate> EncodingPredicates = [HasStdEnc];
305 class ISA_MIPS2_NOT_32R6_64R6 {
306 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
307 list<Predicate> EncodingPredicates = [HasStdEnc];
310 list<Predicate> InsnPredicates = [HasMips3];
311 list<Predicate> EncodingPredicates = [HasStdEnc];
313 class ISA_MIPS3_NOT_32R6_64R6 {
314 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
315 list<Predicate> EncodingPredicates = [HasStdEnc];
318 list<Predicate> InsnPredicates = [HasMips32];
319 list<Predicate> EncodingPredicates = [HasStdEnc];
321 class ISA_MIPS32_NOT_32R6_64R6 {
322 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
323 list<Predicate> EncodingPredicates = [HasStdEnc];
326 list<Predicate> InsnPredicates = [HasMips32r2];
327 list<Predicate> EncodingPredicates = [HasStdEnc];
329 class ISA_MIPS32R2_NOT_32R6_64R6 {
330 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
331 list<Predicate> EncodingPredicates = [HasStdEnc];
334 list<Predicate> InsnPredicates = [HasMips32r5];
335 list<Predicate> EncodingPredicates = [HasStdEnc];
338 list<Predicate> InsnPredicates = [HasMips64];
339 list<Predicate> EncodingPredicates = [HasStdEnc];
341 class ISA_MIPS64_NOT_64R6 {
342 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
343 list<Predicate> EncodingPredicates = [HasStdEnc];
346 list<Predicate> InsnPredicates = [HasMips64r2];
347 list<Predicate> EncodingPredicates = [HasStdEnc];
350 list<Predicate> InsnPredicates = [HasMips64r5];
351 list<Predicate> EncodingPredicates = [HasStdEnc];
354 list<Predicate> InsnPredicates = [HasMips32r6];
355 list<Predicate> EncodingPredicates = [HasStdEnc];
358 list<Predicate> InsnPredicates = [HasMips64r6];
359 list<Predicate> EncodingPredicates = [HasStdEnc];
361 class ISA_MICROMIPS {
362 list<Predicate> EncodingPredicates = [InMicroMips];
364 class ISA_MICROMIPS32R5 {
365 list<Predicate> InsnPredicates = [HasMips32r5];
366 list<Predicate> EncodingPredicates = [InMicroMips];
368 class ISA_MICROMIPS32R6 {
369 list<Predicate> InsnPredicates = [HasMips32r6];
370 list<Predicate> EncodingPredicates = [InMicroMips];
372 class ISA_MICROMIPS64R6 {
373 list<Predicate> InsnPredicates = [HasMips64r6];
374 list<Predicate> EncodingPredicates = [InMicroMips];
376 class ISA_MICROMIPS32_NOT_MIPS32R6 {
377 list<Predicate> InsnPredicates = [NotMips32r6];
378 list<Predicate> EncodingPredicates = [InMicroMips];
380 class ASE_EVA { list<Predicate> ASEPredicate = [HasEVA]; }
382 // The portions of MIPS-III that were also added to MIPS32
383 class INSN_MIPS3_32 {
384 list<Predicate> InsnPredicates = [HasMips3_32];
385 list<Predicate> EncodingPredicates = [HasStdEnc];
388 // The portions of MIPS-III that were also added to MIPS32 but were removed in
389 // MIPS32r6 and MIPS64r6.
390 class INSN_MIPS3_32_NOT_32R6_64R6 {
391 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
392 list<Predicate> EncodingPredicates = [HasStdEnc];
395 // The portions of MIPS-III that were also added to MIPS32
396 class INSN_MIPS3_32R2 {
397 list<Predicate> InsnPredicates = [HasMips3_32r2];
398 list<Predicate> EncodingPredicates = [HasStdEnc];
401 // The portions of MIPS-IV that were also added to MIPS32.
402 class INSN_MIPS4_32 {
403 list <Predicate> InsnPredicates = [HasMips4_32];
404 list<Predicate> EncodingPredicates = [HasStdEnc];
407 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
408 // MIPS32r6 and MIPS64r6.
409 class INSN_MIPS4_32_NOT_32R6_64R6 {
410 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
411 list<Predicate> EncodingPredicates = [HasStdEnc];
414 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
415 // MIPS32r6 and MIPS64r6.
416 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
417 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
418 list<Predicate> EncodingPredicates = [HasStdEnc];
421 // The portions of MIPS-IV that were also added to MIPS32r2.
422 class INSN_MIPS4_32R2 {
423 list<Predicate> InsnPredicates = [HasMips4_32r2];
424 list<Predicate> EncodingPredicates = [HasStdEnc];
427 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
428 // MIPS32r6 and MIPS64r6.
429 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
430 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
431 list<Predicate> EncodingPredicates = [HasStdEnc];
435 list<Predicate> ASEPredicate = [HasCnMips];
438 class NOT_ASE_CNMIPS {
439 list<Predicate> ASEPredicate = [NotCnMips];
442 class ASE_MIPS64_CNMIPS {
443 list<Predicate> ASEPredicate = [HasMips64, HasCnMips];
447 list<Predicate> ASEPredicate = [HasMSA];
450 class ASE_MSA_NOT_MSA64 {
451 list<Predicate> ASEPredicate = [HasMSA, NotMips64];
455 list<Predicate> ASEPredicate = [HasMSA, HasMips64];
459 list <Predicate> ASEPredicate = [HasMT];
463 list <Predicate> ASEPredicate = [HasCRC];
467 list <Predicate> ASEPredicate = [HasVirt];
471 list <Predicate> ASEPredicate = [HasGINV];
474 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
475 // It can be used only on instructions that doesn't inherit PredicateControl.
476 class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
477 let InsnPredicates = [NotMips32r6];
478 let EncodingPredicates = [InMicroMips];
482 list<Predicate> ASEPredicate = [NotDSP];
486 list<Predicate> AdditionalPredicates = [HasMadd4];
489 // Classses used for separating expansions that differ based on the ABI in
492 list<Predicate> AdditionalPredicates = [IsN64];
496 list<Predicate> AdditionalPredicates = [IsNotN64];
499 class FPOP_FUSION_FAST {
500 list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
503 //===----------------------------------------------------------------------===//
505 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl;
507 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
508 InstAlias<Asm, Result, Emit>, PredicateControl;
511 bit isCommutable = 1;
531 bit isTerminator = 1;
534 bit hasExtraSrcRegAllocReq = 1;
535 bit isCodeGenOnly = 1;
539 class IsAsCheapAsAMove {
540 bit isAsCheapAsAMove = 1;
543 class NeverHasSideEffects {
544 bit hasSideEffects = 0;
547 //===----------------------------------------------------------------------===//
548 // Instruction format superclass
549 //===----------------------------------------------------------------------===//
551 include "MipsInstrFormats.td"
553 //===----------------------------------------------------------------------===//
554 // Mips Operand, Complex Patterns and Transformations Definitions.
555 //===----------------------------------------------------------------------===//
557 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
558 int Offset = 0> : AsmOperandClass {
559 let Name = "ConstantSImm" # Bits # "_" # Offset;
560 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
561 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
562 let SuperClasses = Supers;
563 let DiagnosticType = "SImm" # Bits # "_" # Offset;
566 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
567 int Shift = 0> : AsmOperandClass {
568 let Name = "Simm" # Bits # "_Lsl" # Shift;
569 let RenderMethod = "addImmOperands";
570 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
571 let SuperClasses = Supers;
572 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
575 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
576 int Offset = 0> : AsmOperandClass {
577 let Name = "ConstantUImm" # Bits # "_" # Offset;
578 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
579 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
580 let SuperClasses = Supers;
581 let DiagnosticType = "UImm" # Bits # "_" # Offset;
584 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
585 list<AsmOperandClass> Supers = []>
587 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
588 let RenderMethod = "addImmOperands";
589 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
590 let SuperClasses = Supers;
591 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
594 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
596 let Name = "SImm" # Bits;
597 let RenderMethod = "addSImmOperands<" # Bits # ">";
598 let PredicateMethod = "isSImm<" # Bits # ">";
599 let SuperClasses = Supers;
600 let DiagnosticType = "SImm" # Bits;
603 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
605 let Name = "UImm" # Bits;
606 let RenderMethod = "addUImmOperands<" # Bits # ">";
607 let PredicateMethod = "isUImm<" # Bits # ">";
608 let SuperClasses = Supers;
609 let DiagnosticType = "UImm" # Bits;
612 // Generic case - only to support certain assembly pseudo instructions.
613 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
616 let RenderMethod = "addConstantUImmOperands<32>";
617 let PredicateMethod = "isSImm<" # Bits # ">";
618 let SuperClasses = Supers;
619 let DiagnosticType = "ImmAny";
622 // AsmOperandClasses require a strict ordering which is difficult to manage
623 // as a hierarchy. Instead, we use a linear ordering and impose an order that
624 // is in some places arbitrary.
626 // Here the rules that are in use:
627 // * Wider immediates are a superset of narrower immediates:
628 // uimm4 < uimm5 < uimm6
629 // * For the same bit-width, unsigned immediates are a superset of signed
631 // simm4 < uimm4 < simm5 < uimm5
632 // * For the same upper-bound, signed immediates are a superset of unsigned
634 // uimm3 < simm4 < uimm4 < simm4
635 // * Modified immediates are a superset of ordinary immediates:
636 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
637 // The term 'superset' starts to break down here since the uimm5_plus* classes
638 // are not true supersets of uimm5 (but they are still subsets of uimm6).
639 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
640 // uimm16 < uimm16_relaxed
641 // * The codeGen pattern type is arbitrarily ordered.
642 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
643 // This is entirely arbitrary. We need an ordering and what we pick is
644 // unimportant since only one is possible for a given mnemonic.
646 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
647 let Name = "UImm32_Coerced";
648 let DiagnosticType = "UImm32_Coerced";
650 def SImm32RelaxedAsmOperandClass
651 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
652 let Name = "SImm32_Relaxed";
653 let PredicateMethod = "isAnyImm<33>";
654 let DiagnosticType = "SImm32_Relaxed";
656 def SImm32AsmOperandClass
657 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
658 def ConstantUImm26AsmOperandClass
659 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
660 def ConstantUImm20AsmOperandClass
661 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
662 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
663 let Name = "SImm19Lsl2";
664 let RenderMethod = "addImmOperands";
665 let PredicateMethod = "isScaledSImm<19, 2>";
666 let SuperClasses = [ConstantUImm20AsmOperandClass];
667 let DiagnosticType = "SImm19_Lsl2";
669 def UImm16RelaxedAsmOperandClass
670 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
671 let Name = "UImm16_Relaxed";
672 let PredicateMethod = "isAnyImm<16>";
673 let DiagnosticType = "UImm16_Relaxed";
675 // Similar to the relaxed classes which take an SImm and render it as
676 // an UImm, this takes a UImm and renders it as an SImm.
677 def UImm16AltRelaxedAsmOperandClass
678 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
679 let Name = "UImm16_AltRelaxed";
680 let PredicateMethod = "isUImm<16>";
681 let DiagnosticType = "UImm16_AltRelaxed";
683 // FIXME: One of these should probably have UImm16AsmOperandClass as the
684 // superclass instead of UImm16RelaxedasmOPerandClass.
685 def UImm16AsmOperandClass
686 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
687 def SImm16RelaxedAsmOperandClass
688 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
689 let Name = "SImm16_Relaxed";
690 let PredicateMethod = "isAnyImm<16>";
691 let DiagnosticType = "SImm16_Relaxed";
693 def SImm16AsmOperandClass
694 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
695 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
696 let Name = "SImm10Lsl3";
697 let RenderMethod = "addImmOperands";
698 let PredicateMethod = "isScaledSImm<10, 3>";
699 let SuperClasses = [SImm16AsmOperandClass];
700 let DiagnosticType = "SImm10_Lsl3";
702 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
703 let Name = "SImm10Lsl2";
704 let RenderMethod = "addImmOperands";
705 let PredicateMethod = "isScaledSImm<10, 2>";
706 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
707 let DiagnosticType = "SImm10_Lsl2";
709 def ConstantSImm11AsmOperandClass
710 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
711 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
712 let Name = "SImm10Lsl1";
713 let RenderMethod = "addImmOperands";
714 let PredicateMethod = "isScaledSImm<10, 1>";
715 let SuperClasses = [ConstantSImm11AsmOperandClass];
716 let DiagnosticType = "SImm10_Lsl1";
718 def ConstantUImm10AsmOperandClass
719 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
720 def ConstantSImm10AsmOperandClass
721 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
722 def ConstantSImm9AsmOperandClass
723 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
724 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
725 let Name = "SImm7Lsl2";
726 let RenderMethod = "addImmOperands";
727 let PredicateMethod = "isScaledSImm<7, 2>";
728 let SuperClasses = [ConstantSImm9AsmOperandClass];
729 let DiagnosticType = "SImm7_Lsl2";
731 def ConstantUImm8AsmOperandClass
732 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
733 def ConstantUImm7Sub1AsmOperandClass
734 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
735 // Specify the names since the -1 offset causes invalid identifiers otherwise.
736 let Name = "UImm7_N1";
737 let DiagnosticType = "UImm7_N1";
739 def ConstantUImm7AsmOperandClass
740 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
741 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
742 let Name = "UImm6Lsl2";
743 let RenderMethod = "addImmOperands";
744 let PredicateMethod = "isScaledUImm<6, 2>";
745 let SuperClasses = [ConstantUImm7AsmOperandClass];
746 let DiagnosticType = "UImm6_Lsl2";
748 def ConstantUImm6AsmOperandClass
749 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
750 def ConstantSImm6AsmOperandClass
751 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
752 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
753 let Name = "UImm5Lsl2";
754 let RenderMethod = "addImmOperands";
755 let PredicateMethod = "isScaledUImm<5, 2>";
756 let SuperClasses = [ConstantSImm6AsmOperandClass];
757 let DiagnosticType = "UImm5_Lsl2";
759 def ConstantUImm5_Range2_64AsmOperandClass
760 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
761 def ConstantUImm5Plus33AsmOperandClass
762 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
764 def ConstantUImm5ReportUImm6AsmOperandClass
765 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
766 let Name = "ConstantUImm5_0_Report_UImm6";
767 let DiagnosticType = "UImm5_0_Report_UImm6";
769 def ConstantUImm5Plus32AsmOperandClass
770 : ConstantUImmAsmOperandClass<
771 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
772 def ConstantUImm5Plus32NormalizeAsmOperandClass
773 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
774 let Name = "ConstantUImm5_32_Norm";
775 // We must also subtract 32 when we render the operand.
776 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
778 def ConstantUImm5Plus1ReportUImm6AsmOperandClass
779 : ConstantUImmAsmOperandClass<
780 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
781 let Name = "ConstantUImm5_Plus1_Report_UImm6";
783 def ConstantUImm5Plus1AsmOperandClass
784 : ConstantUImmAsmOperandClass<
785 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
786 def ConstantUImm5AsmOperandClass
787 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
788 def ConstantSImm5AsmOperandClass
789 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
790 def ConstantUImm4AsmOperandClass
791 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
792 def ConstantSImm4AsmOperandClass
793 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
794 def ConstantUImm3AsmOperandClass
795 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
796 def ConstantUImm2Plus1AsmOperandClass
797 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
798 def ConstantUImm2AsmOperandClass
799 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
800 def ConstantUImm1AsmOperandClass
801 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
802 def ConstantImmzAsmOperandClass : AsmOperandClass {
803 let Name = "ConstantImmz";
804 let RenderMethod = "addConstantUImmOperands<1>";
805 let PredicateMethod = "isConstantImmz";
806 let SuperClasses = [ConstantUImm1AsmOperandClass];
807 let DiagnosticType = "Immz";
810 def Simm19Lsl2AsmOperand
811 : SimmLslAsmOperandClass<19, [], 2>;
813 def MipsJumpTargetAsmOperand : AsmOperandClass {
814 let Name = "JumpTarget";
815 let ParserMethod = "parseJumpTarget";
816 let PredicateMethod = "isImm";
817 let RenderMethod = "addImmOperands";
820 // Instruction operand types
821 def jmptarget : Operand<OtherVT> {
822 let EncoderMethod = "getJumpTargetOpValue";
823 let ParserMatchClass = MipsJumpTargetAsmOperand;
825 def brtarget : Operand<OtherVT> {
826 let EncoderMethod = "getBranchTargetOpValue";
827 let OperandType = "OPERAND_PCREL";
828 let DecoderMethod = "DecodeBranchTarget";
829 let ParserMatchClass = MipsJumpTargetAsmOperand;
831 def brtarget1SImm16 : Operand<OtherVT> {
832 let EncoderMethod = "getBranchTargetOpValue1SImm16";
833 let OperandType = "OPERAND_PCREL";
834 let DecoderMethod = "DecodeBranchTarget1SImm16";
835 let ParserMatchClass = MipsJumpTargetAsmOperand;
837 def calltarget : Operand<iPTR> {
838 let EncoderMethod = "getJumpTargetOpValue";
839 let ParserMatchClass = MipsJumpTargetAsmOperand;
842 def imm64: Operand<i64>;
844 def simm19_lsl2 : Operand<i32> {
845 let EncoderMethod = "getSimm19Lsl2Encoding";
846 let DecoderMethod = "DecodeSimm19Lsl2";
847 let ParserMatchClass = Simm19Lsl2AsmOperand;
850 def simm18_lsl3 : Operand<i32> {
851 let EncoderMethod = "getSimm18Lsl3Encoding";
852 let DecoderMethod = "DecodeSimm18Lsl3";
853 let ParserMatchClass = MipsJumpTargetAsmOperand;
857 def uimmz : Operand<i32> {
858 let PrintMethod = "printUImm<0>";
859 let ParserMatchClass = ConstantImmzAsmOperandClass;
862 // size operand of ins instruction
863 def uimm_range_2_64 : Operand<i32> {
864 let PrintMethod = "printUImm<6, 2>";
865 let EncoderMethod = "getSizeInsEncoding";
866 let DecoderMethod = "DecodeInsSize";
867 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
871 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
872 def uimm # I : Operand<i32> {
873 let PrintMethod = "printUImm<" # I # ">";
874 let ParserMatchClass =
875 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
878 def uimm2_plus1 : Operand<i32> {
879 let PrintMethod = "printUImm<2, 1>";
880 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
881 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
882 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
885 def uimm5_plus1 : Operand<i32> {
886 let PrintMethod = "printUImm<5, 1>";
887 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
888 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
889 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
892 def uimm5_plus1_report_uimm6 : Operand<i32> {
893 let PrintMethod = "printUImm<6, 1>";
894 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
895 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
896 let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
899 def uimm5_plus32 : Operand<i32> {
900 let PrintMethod = "printUImm<5, 32>";
901 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
904 def uimm5_plus33 : Operand<i32> {
905 let PrintMethod = "printUImm<5, 33>";
906 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
907 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
908 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
911 def uimm5_inssize_plus1 : Operand<i32> {
912 let PrintMethod = "printUImm<6>";
913 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
914 let EncoderMethod = "getSizeInsEncoding";
915 let DecoderMethod = "DecodeInsSize";
918 def uimm5_plus32_normalize : Operand<i32> {
919 let PrintMethod = "printUImm<5>";
920 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
923 def uimm5_lsl2 : Operand<OtherVT> {
924 let EncoderMethod = "getUImm5Lsl2Encoding";
925 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
926 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
929 def uimm5_plus32_normalize_64 : Operand<i64> {
930 let PrintMethod = "printUImm<5>";
931 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
934 def uimm6_lsl2 : Operand<OtherVT> {
935 let EncoderMethod = "getUImm6Lsl2Encoding";
936 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
937 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
941 def uimm # I : Operand<i32> {
942 let PrintMethod = "printUImm<" # I # ">";
943 let ParserMatchClass =
944 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
947 // Like uimm16_64 but coerces simm16 to uimm16.
948 def uimm16_relaxed : Operand<i32> {
949 let PrintMethod = "printUImm<16>";
950 let ParserMatchClass =
951 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
955 def uimm # I # _64 : Operand<i64> {
956 let PrintMethod = "printUImm<" # I # ">";
957 let ParserMatchClass =
958 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
962 def uimm # I # _64 : Operand<i64> {
963 let PrintMethod = "printUImm<" # I # ">";
964 let ParserMatchClass =
965 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
968 // Like uimm16_64 but coerces simm16 to uimm16.
969 def uimm16_64_relaxed : Operand<i64> {
970 let PrintMethod = "printUImm<16>";
971 let ParserMatchClass =
972 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
975 def uimm16_altrelaxed : Operand<i32> {
976 let PrintMethod = "printUImm<16>";
977 let ParserMatchClass =
978 !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
980 // Like uimm5 but reports a less confusing error for 32-63 when
981 // an instruction alias permits that.
982 def uimm5_report_uimm6 : Operand<i32> {
983 let PrintMethod = "printUImm<6>";
984 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
987 // Like uimm5_64 but reports a less confusing error for 32-63 when
988 // an instruction alias permits that.
989 def uimm5_64_report_uimm6 : Operand<i64> {
990 let PrintMethod = "printUImm<5>";
991 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
994 foreach I = {1, 2, 3, 4} in
995 def uimm # I # _ptr : Operand<iPTR> {
996 let PrintMethod = "printUImm<" # I # ">";
997 let ParserMatchClass =
998 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1001 foreach I = {1, 2, 3, 4, 5, 6, 8} in
1002 def vsplat_uimm # I : Operand<vAny> {
1003 let PrintMethod = "printUImm<" # I # ">";
1004 let ParserMatchClass =
1005 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
1009 foreach I = {4, 5, 6, 9, 10, 11} in
1010 def simm # I : Operand<i32> {
1011 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1012 let ParserMatchClass =
1013 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1016 foreach I = {1, 2, 3} in
1017 def simm10_lsl # I : Operand<i32> {
1018 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
1019 let ParserMatchClass =
1020 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
1024 def simm # I # _64 : Operand<i64> {
1025 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1026 let ParserMatchClass =
1027 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1030 foreach I = {5, 10} in
1031 def vsplat_simm # I : Operand<vAny> {
1032 let ParserMatchClass =
1033 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
1036 def simm7_lsl2 : Operand<OtherVT> {
1037 let EncoderMethod = "getSImm7Lsl2Encoding";
1038 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
1039 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
1042 foreach I = {16, 32} in
1043 def simm # I : Operand<i32> {
1044 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
1045 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
1048 // Like simm16 but coerces uimm16 to simm16.
1049 def simm16_relaxed : Operand<i32> {
1050 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1051 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
1054 def simm16_64 : Operand<i64> {
1055 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
1056 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
1059 // like simm32 but coerces simm32 to uimm32.
1060 def uimm32_coerced : Operand<i32> {
1061 let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
1063 // Like simm32 but coerces uimm32 to simm32.
1064 def simm32_relaxed : Operand<i32> {
1065 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
1066 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
1069 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
1070 def li16_imm : Operand<i32> {
1071 let DecoderMethod = "DecodeLi16Imm";
1072 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
1075 def MipsMemAsmOperand : AsmOperandClass {
1077 let ParserMethod = "parseMemOperand";
1080 def MipsMemSimm9AsmOperand : AsmOperandClass {
1081 let Name = "MemOffsetSimm9";
1082 let SuperClasses = [MipsMemAsmOperand];
1083 let RenderMethod = "addMemOperands";
1084 let ParserMethod = "parseMemOperand";
1085 let PredicateMethod = "isMemWithSimmOffset<9>";
1086 let DiagnosticType = "MemSImm9";
1089 def MipsMemSimm10AsmOperand : AsmOperandClass {
1090 let Name = "MemOffsetSimm10";
1091 let SuperClasses = [MipsMemAsmOperand];
1092 let RenderMethod = "addMemOperands";
1093 let ParserMethod = "parseMemOperand";
1094 let PredicateMethod = "isMemWithSimmOffset<10>";
1095 let DiagnosticType = "MemSImm10";
1098 def MipsMemSimm12AsmOperand : AsmOperandClass {
1099 let Name = "MemOffsetSimm12";
1100 let SuperClasses = [MipsMemAsmOperand];
1101 let RenderMethod = "addMemOperands";
1102 let ParserMethod = "parseMemOperand";
1103 let PredicateMethod = "isMemWithSimmOffset<12>";
1104 let DiagnosticType = "MemSImm12";
1107 foreach I = {1, 2, 3} in
1108 def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
1109 let Name = "MemOffsetSimm10_" # I;
1110 let SuperClasses = [MipsMemAsmOperand];
1111 let RenderMethod = "addMemOperands";
1112 let ParserMethod = "parseMemOperand";
1113 let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
1114 let DiagnosticType = "MemSImm10Lsl" # I;
1117 def MipsMemSimm11AsmOperand : AsmOperandClass {
1118 let Name = "MemOffsetSimm11";
1119 let SuperClasses = [MipsMemAsmOperand];
1120 let RenderMethod = "addMemOperands";
1121 let ParserMethod = "parseMemOperand";
1122 let PredicateMethod = "isMemWithSimmOffset<11>";
1123 let DiagnosticType = "MemSImm11";
1126 def MipsMemSimm16AsmOperand : AsmOperandClass {
1127 let Name = "MemOffsetSimm16";
1128 let SuperClasses = [MipsMemAsmOperand];
1129 let RenderMethod = "addMemOperands";
1130 let ParserMethod = "parseMemOperand";
1131 let PredicateMethod = "isMemWithSimmOffset<16>";
1132 let DiagnosticType = "MemSImm16";
1135 def MipsMemSimmPtrAsmOperand : AsmOperandClass {
1136 let Name = "MemOffsetSimmPtr";
1137 let SuperClasses = [MipsMemAsmOperand];
1138 let RenderMethod = "addMemOperands";
1139 let ParserMethod = "parseMemOperand";
1140 let PredicateMethod = "isMemWithPtrSizeOffset";
1141 let DiagnosticType = "MemSImmPtr";
1144 def MipsInvertedImmoperand : AsmOperandClass {
1145 let Name = "InvNum";
1146 let RenderMethod = "addImmOperands";
1147 let ParserMethod = "parseInvNum";
1150 def InvertedImOperand : Operand<i32> {
1151 let ParserMatchClass = MipsInvertedImmoperand;
1154 def InvertedImOperand64 : Operand<i64> {
1155 let ParserMatchClass = MipsInvertedImmoperand;
1158 class mem_generic : Operand<iPTR> {
1159 let PrintMethod = "printMemOperand";
1160 let MIOperandInfo = (ops ptr_rc, simm16);
1161 let EncoderMethod = "getMemEncoding";
1162 let ParserMatchClass = MipsMemAsmOperand;
1163 let OperandType = "OPERAND_MEMORY";
1167 def mem : mem_generic;
1169 // MSA specific address operand
1170 def mem_msa : mem_generic {
1171 let MIOperandInfo = (ops ptr_rc, simm10);
1172 let EncoderMethod = "getMSAMemEncoding";
1175 def simm12 : Operand<i32> {
1176 let DecoderMethod = "DecodeSimm12";
1179 def mem_simm9 : mem_generic {
1180 let MIOperandInfo = (ops ptr_rc, simm9);
1181 let EncoderMethod = "getMemEncoding";
1182 let ParserMatchClass = MipsMemSimm9AsmOperand;
1185 def mem_simm10 : mem_generic {
1186 let MIOperandInfo = (ops ptr_rc, simm10);
1187 let EncoderMethod = "getMemEncoding";
1188 let ParserMatchClass = MipsMemSimm10AsmOperand;
1191 foreach I = {1, 2, 3} in
1192 def mem_simm10_lsl # I : mem_generic {
1193 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1194 let EncoderMethod = "getMemEncoding<" # I # ">";
1195 let ParserMatchClass =
1196 !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
1199 def mem_simm11 : mem_generic {
1200 let MIOperandInfo = (ops ptr_rc, simm11);
1201 let EncoderMethod = "getMemEncoding";
1202 let ParserMatchClass = MipsMemSimm11AsmOperand;
1205 def mem_simm12 : mem_generic {
1206 let MIOperandInfo = (ops ptr_rc, simm12);
1207 let EncoderMethod = "getMemEncoding";
1208 let ParserMatchClass = MipsMemSimm12AsmOperand;
1211 def mem_simm16 : mem_generic {
1212 let MIOperandInfo = (ops ptr_rc, simm16);
1213 let EncoderMethod = "getMemEncoding";
1214 let ParserMatchClass = MipsMemSimm16AsmOperand;
1217 def mem_simmptr : mem_generic {
1218 let ParserMatchClass = MipsMemSimmPtrAsmOperand;
1221 def mem_ea : Operand<iPTR> {
1222 let PrintMethod = "printMemOperandEA";
1223 let MIOperandInfo = (ops ptr_rc, simm16);
1224 let EncoderMethod = "getMemEncoding";
1225 let OperandType = "OPERAND_MEMORY";
1228 def PtrRC : Operand<iPTR> {
1229 let MIOperandInfo = (ops ptr_rc);
1230 let DecoderMethod = "DecodePtrRegisterClass";
1231 let ParserMatchClass = GPR32AsmOperand;
1234 // size operand of ins instruction
1235 def size_ins : Operand<i32> {
1236 let EncoderMethod = "getSizeInsEncoding";
1237 let DecoderMethod = "DecodeInsSize";
1240 // Transformation Function - get the lower 16 bits.
1241 def LO16 : SDNodeXForm<imm, [{
1242 return getImm(N, N->getZExtValue() & 0xFFFF);
1245 // Transformation Function - get the higher 16 bits.
1246 def HI16 : SDNodeXForm<imm, [{
1247 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1251 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1253 // Node immediate is zero (e.g. insve.d)
1254 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1256 // Node immediate fits as 16-bit sign extended on target immediate.
1258 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1260 // Node immediate fits as 16-bit sign extended on target immediate.
1262 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1264 // Node immediate fits as 7-bit zero extended on target immediate.
1265 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1267 // Node immediate fits as 16-bit zero extended on target immediate.
1268 // The LO16 param means that only the lower 16 bits of the node
1269 // immediate are caught.
1270 // e.g. addiu, sltiu
1271 def immZExt16 : PatLeaf<(imm), [{
1272 if (N->getValueType(0) == MVT::i32)
1273 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1275 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1278 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1279 def immSExt32Low16Zero : PatLeaf<(imm), [{
1280 int64_t Val = N->getSExtValue();
1281 return isInt<32>(Val) && !(Val & 0xffff);
1284 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1285 def immZExt32Low16Zero : PatLeaf<(imm), [{
1286 uint64_t Val = N->getZExtValue();
1287 return isUInt<32>(Val) && !(Val & 0xffff);
1290 // Note immediate fits as a 32 bit signed extended on target immediate.
1291 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1293 // Note immediate fits as a 32 bit zero extended on target immediate.
1294 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1296 // shamt field must fit in 5 bits.
1297 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1299 def immZExt5Plus1 : PatLeaf<(imm), [{
1300 return isUInt<5>(N->getZExtValue() - 1);
1302 def immZExt5Plus32 : PatLeaf<(imm), [{
1303 return isUInt<5>(N->getZExtValue() - 32);
1305 def immZExt5Plus33 : PatLeaf<(imm), [{
1306 return isUInt<5>(N->getZExtValue() - 33);
1309 def immZExt5To31 : SDNodeXForm<imm, [{
1310 return getImm(N, 31 - N->getZExtValue());
1313 // True if (N + 1) fits in 16-bit field.
1314 def immSExt16Plus1 : PatLeaf<(imm), [{
1315 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1318 def immZExtRange2To64 : PatLeaf<(imm), [{
1319 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1320 (N->getZExtValue() <= 64);
1323 def ORiPred : PatLeaf<(imm), [{
1324 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1327 def LUiPred : PatLeaf<(imm), [{
1328 int64_t Val = N->getSExtValue();
1329 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1332 def LUiORiPred : PatLeaf<(imm), [{
1333 int64_t SVal = N->getSExtValue();
1334 return isInt<32>(SVal) && (SVal & 0xffff);
1337 // Mips Address Mode! SDNode frameindex could possibily be a match
1338 // since load and store instructions from stack used it.
1340 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1343 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1346 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1348 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1349 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1351 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1353 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1356 //===----------------------------------------------------------------------===//
1357 // Instructions specific format
1358 //===----------------------------------------------------------------------===//
1360 // Arithmetic and logical instructions with 3 register operands.
1361 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1362 InstrItinClass Itin = NoItinerary,
1363 SDPatternOperator OpNode = null_frag>:
1364 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1365 !strconcat(opstr, "\t$rd, $rs, $rt"),
1366 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1367 let isCommutable = isComm;
1368 let isReMaterializable = 1;
1369 let TwoOperandAliasConstraint = "$rd = $rs";
1372 // Arithmetic and logical instructions with 2 register operands.
1373 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1374 InstrItinClass Itin = NoItinerary,
1375 SDPatternOperator imm_type = null_frag,
1376 SDPatternOperator OpNode = null_frag> :
1377 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1378 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1379 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1380 Itin, FrmI, opstr> {
1381 let isReMaterializable = 1;
1382 let TwoOperandAliasConstraint = "$rs = $rt";
1385 // Arithmetic Multiply ADD/SUB
1386 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1387 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1388 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1389 let Defs = [HI0, LO0];
1390 let Uses = [HI0, LO0];
1391 let isCommutable = isComm;
1395 class LogicNOR<string opstr, RegisterOperand RO>:
1396 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1397 !strconcat(opstr, "\t$rd, $rs, $rt"),
1398 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1399 let isCommutable = 1;
1403 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1404 RegisterOperand RO, InstrItinClass itin,
1405 SDPatternOperator OpNode = null_frag,
1406 SDPatternOperator PF = null_frag> :
1407 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1408 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1409 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1410 let TwoOperandAliasConstraint = "$rt = $rd";
1413 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1414 SDPatternOperator OpNode = null_frag>:
1415 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1416 !strconcat(opstr, "\t$rd, $rt, $rs"),
1417 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1420 // Load Upper Immediate
1421 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1422 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1423 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1424 let hasSideEffects = 0;
1425 let isReMaterializable = 1;
1428 // Memory Load/Store
1429 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1430 SDPatternOperator OpNode = null_frag,
1431 InstrItinClass Itin = NoItinerary,
1432 ComplexPattern Addr = addr> :
1433 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1434 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1435 let DecoderMethod = "DecodeMem";
1436 let canFoldAsLoad = 1;
1437 string BaseOpcode = opstr;
1441 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1442 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1443 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1445 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1446 SDPatternOperator OpNode = null_frag,
1447 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1448 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1449 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1450 let DecoderMethod = "DecodeMem";
1451 string BaseOpcode = opstr;
1455 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1456 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1457 DAGOperand MO = mem> :
1458 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1460 // Load/Store Left/Right
1461 let canFoldAsLoad = 1 in
1462 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1463 InstrItinClass Itin> :
1464 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1465 !strconcat(opstr, "\t$rt, $addr"),
1466 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1467 let DecoderMethod = "DecodeMem";
1468 string Constraints = "$src = $rt";
1469 let BaseOpcode = opstr;
1472 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1473 InstrItinClass Itin> :
1474 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1475 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1476 let DecoderMethod = "DecodeMem";
1477 let BaseOpcode = opstr;
1481 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1482 SDPatternOperator OpNode= null_frag> :
1483 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1484 !strconcat(opstr, "\t$rt, $addr"),
1485 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1486 let DecoderMethod = "DecodeFMem2";
1490 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1491 SDPatternOperator OpNode= null_frag> :
1492 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1493 !strconcat(opstr, "\t$rt, $addr"),
1494 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1495 let DecoderMethod = "DecodeFMem2";
1500 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1501 SDPatternOperator OpNode= null_frag> :
1502 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1503 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1504 let DecoderMethod = "DecodeFMem3";
1508 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1509 SDPatternOperator OpNode= null_frag> :
1510 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1511 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1512 let DecoderMethod = "DecodeFMem3";
1516 // Conditional Branch
1517 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1518 RegisterOperand RO> :
1519 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1520 !strconcat(opstr, "\t$rs, $rt, $offset"),
1521 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1524 let isTerminator = 1;
1525 let hasDelaySlot = 1;
1530 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1531 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1532 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1534 let isTerminator = 1;
1535 let hasDelaySlot = 1;
1540 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1541 RegisterOperand RO> :
1542 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1543 !strconcat(opstr, "\t$rs, $offset"),
1544 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1547 let isTerminator = 1;
1548 let hasDelaySlot = 1;
1553 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1554 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1555 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1557 let isTerminator = 1;
1558 let hasDelaySlot = 1;
1564 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1565 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1566 !strconcat(opstr, "\t$rd, $rs, $rt"),
1567 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1568 II_SLT_SLTU, FrmR, opstr>;
1570 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1571 RegisterOperand RO>:
1572 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1573 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1574 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1575 II_SLTI_SLTIU, FrmI, opstr>;
1578 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1579 SDPatternOperator targetoperator, string bopstr> :
1580 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1581 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1584 let hasDelaySlot = 1;
1585 let DecoderMethod = "DecodeJumpTarget";
1590 // Unconditional branch
1591 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1592 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1593 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1595 let isTerminator = 1;
1597 let hasDelaySlot = 1;
1598 let AdditionalPredicates = [RelocPIC];
1603 // Base class for indirect branch and return instruction classes.
1604 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1605 class JumpFR<string opstr, RegisterOperand RO,
1606 SDPatternOperator operator = null_frag>:
1607 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1611 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1613 let isIndirectBranch = 1;
1616 // Jump and Link (Call)
1617 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1618 class JumpLink<string opstr, DAGOperand opnd> :
1619 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1620 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1621 let DecoderMethod = "DecodeJumpTarget";
1624 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1625 Register RetReg, RegisterOperand ResRO = RO>:
1626 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1627 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1628 let hasPostISelHook = 1;
1631 class JumpLinkReg<string opstr, RegisterOperand RO>:
1632 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1633 [], II_JALR, FrmR, opstr> {
1634 let hasPostISelHook = 1;
1637 class BGEZAL_FT<string opstr, DAGOperand opnd,
1638 RegisterOperand RO> :
1639 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1640 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1641 let hasDelaySlot = 1;
1646 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1647 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1648 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1649 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1650 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1652 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1653 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1654 PseudoInstExpansion<(JumpInst RO:$rs)> {
1655 let hasPostISelHook = 1;
1659 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1660 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1661 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1663 let isTerminator = 1;
1665 let hasDelaySlot = 1;
1672 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1673 InstSE<(outs), (ins ImmOp:$code_),
1674 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1676 class BRK_FT<string opstr> :
1677 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1678 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1682 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1683 InstSE<(outs), (ins),
1684 opstr, [], itin, FrmOther, opstr>;
1687 class WAIT_FT<string opstr> :
1688 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1692 class DEI_FT<string opstr, RegisterOperand RO,
1693 InstrItinClass itin = NoItinerary> :
1694 InstSE<(outs RO:$rt), (ins),
1695 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1698 let hasSideEffects = 1 in
1699 class SYNC_FT<string opstr> :
1700 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1701 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1703 class SYNCI_FT<string opstr, DAGOperand MO> :
1704 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1705 II_SYNCI, FrmOther, opstr> {
1706 let hasSideEffects = 1;
1707 let DecoderMethod = "DecodeSyncI";
1710 let hasSideEffects = 1, isCTI = 1 in {
1711 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1712 InstrItinClass itin = NoItinerary> :
1713 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1714 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1716 class TEQI_FT<string opstr, RegisterOperand RO,
1717 InstrItinClass itin = NoItinerary> :
1718 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1719 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1723 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1724 list<Register> DefRegs> :
1725 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1726 itin, FrmR, opstr> {
1727 let isCommutable = 1;
1729 let hasSideEffects = 0;
1732 // Pseudo multiply/divide instruction with explicit accumulator register
1734 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1735 SDPatternOperator OpNode, InstrItinClass Itin,
1736 bit IsComm = 1, bit HasSideEffects = 0,
1737 bit UsesCustomInserter = 0> :
1738 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1739 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1740 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1741 let isCommutable = IsComm;
1742 let hasSideEffects = HasSideEffects;
1743 let usesCustomInserter = UsesCustomInserter;
1746 // Pseudo multiply add/sub instruction with explicit accumulator register
1748 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1749 InstrItinClass itin>
1750 : PseudoSE<(outs ACC64:$ac),
1751 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1753 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1755 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1756 string Constraints = "$acin = $ac";
1759 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1760 list<Register> DefRegs> :
1761 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1762 [], itin, FrmR, opstr> {
1767 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1768 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1769 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1771 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1772 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1774 let Uses = [UseReg];
1775 let hasSideEffects = 0;
1779 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1780 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1781 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1784 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1785 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1788 let hasSideEffects = 0;
1792 class EffectiveAddress<string opstr, RegisterOperand RO> :
1793 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1794 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1795 !strconcat(opstr, "_lea")> {
1796 let isCodeGenOnly = 1;
1797 let hasNoSchedulingInfo = 1;
1798 let DecoderMethod = "DecodeMem";
1801 // Count Leading Ones/Zeros in Word
1802 class CountLeading0<string opstr, RegisterOperand RO,
1803 InstrItinClass itin = NoItinerary>:
1804 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1805 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1807 class CountLeading1<string opstr, RegisterOperand RO,
1808 InstrItinClass itin = NoItinerary>:
1809 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1810 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1812 // Sign Extend in Register.
1813 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1814 InstrItinClass itin> :
1815 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1816 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1819 class SubwordSwap<string opstr, RegisterOperand RO,
1820 InstrItinClass itin = NoItinerary>:
1821 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1823 let hasSideEffects = 0;
1827 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1828 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1829 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1832 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1833 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1834 SDPatternOperator Op = null_frag> :
1835 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1836 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1837 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1840 // 'ins' and its' 64 bit variants are matched by C++ code.
1841 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1842 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1843 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1844 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1845 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1847 II_INS, FrmR, opstr> {
1848 let Constraints = "$src = $rt";
1851 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1852 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1853 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1854 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1856 class Atomic2OpsPostRA<RegisterClass RC> :
1857 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1862 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1863 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1864 RC:$shiftamnt), []>;
1866 // Atomic Compare & Swap.
1867 // Atomic compare and swap is lowered into two stages. The first stage happens
1868 // during ISelLowering, which produces the PostRA version of this instruction.
1869 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1870 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1871 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1873 class AtomicCmpSwapPostRA<RegisterClass RC> :
1874 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1879 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1880 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1881 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1887 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1888 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1889 [], II_LL, FrmI, opstr> {
1890 let DecoderMethod = "DecodeMem";
1894 class SCBase<string opstr, RegisterOperand RO> :
1895 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1896 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1897 let DecoderMethod = "DecodeMem";
1899 let Constraints = "$rt = $dst";
1902 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1903 InstrItinClass itin> :
1904 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1905 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1906 let BaseOpcode = asmstr;
1909 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1910 InstrItinClass itin> :
1911 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1912 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1913 let BaseOpcode = asmstr;
1916 class TrapBase<Instruction RealInst>
1917 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1918 PseudoInstExpansion<(RealInst 0, 0)> {
1920 let isTerminator = 1;
1921 let isCodeGenOnly = 1;
1925 //===----------------------------------------------------------------------===//
1926 // Pseudo instructions
1927 //===----------------------------------------------------------------------===//
1930 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1931 let hasDelaySlot=1 in
1932 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1934 let hasSideEffects=1 in
1935 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1938 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1939 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1940 [(callseq_start timm:$amt1, timm:$amt2)]>;
1941 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1942 [(callseq_end timm:$amt1, timm:$amt2)]>;
1945 let usesCustomInserter = 1 in {
1946 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1947 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1948 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1949 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1950 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1951 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1952 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1953 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1954 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1955 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1956 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1957 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1958 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1959 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1960 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1961 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1962 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1963 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1965 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1966 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1967 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1969 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1970 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1971 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1975 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1976 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1977 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1978 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1979 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1980 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1981 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1982 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1983 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1984 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1985 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1986 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1987 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1988 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1989 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1990 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1991 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1992 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1994 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1995 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1996 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1998 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
1999 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2000 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
2002 /// Pseudo instructions for loading and storing accumulator registers.
2003 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
2004 def LOAD_ACC64 : Load<"", ACC64>;
2005 def STORE_ACC64 : Store<"", ACC64>;
2008 // We need these two pseudo instructions to avoid offset calculation for long
2009 // branches. See the comment in file MipsLongBranch.cpp for detailed
2012 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
2013 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
2014 (ins brtarget:$tgt, brtarget:$baltgt), []>;
2015 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
2016 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2017 (ins brtarget:$tgt), []>;
2019 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2020 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2021 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
2022 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2023 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2024 (ins GPR32Opnd:$src, brtarget:$tgt), []>;
2026 //===----------------------------------------------------------------------===//
2027 // Instruction definition
2028 //===----------------------------------------------------------------------===//
2029 //===----------------------------------------------------------------------===//
2030 // MipsI Instructions
2031 //===----------------------------------------------------------------------===//
2033 /// Arithmetic Instructions (ALU Immediate)
2034 let AdditionalPredicates = [NotInMicroMips] in {
2035 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2036 II_ADDIU, immSExt16, add>,
2037 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2039 def ANDi : MMRel, StdMMR6Rel,
2040 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
2041 ADDI_FM<0xc>, ISA_MIPS1;
2042 def ORi : MMRel, StdMMR6Rel,
2043 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
2044 ADDI_FM<0xd>, ISA_MIPS1;
2045 def XORi : MMRel, StdMMR6Rel,
2046 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
2047 ADDI_FM<0xe>, ISA_MIPS1;
2048 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2049 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2050 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2051 SLTI_FM<0xa>, ISA_MIPS1;
2052 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2053 SLTI_FM<0xb>, ISA_MIPS1;
2055 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2058 /// Arithmetic Instructions (3-Operand, R-Type)
2059 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2060 ADD_FM<0, 0x21>, ISA_MIPS1;
2061 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2062 ADD_FM<0, 0x23>, ISA_MIPS1;
2064 let Defs = [HI0, LO0] in
2065 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2066 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2068 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2069 ADD_FM<0, 0x20>, ISA_MIPS1;
2070 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2071 ADD_FM<0, 0x22>, ISA_MIPS1;
2073 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2075 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2077 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2078 ADD_FM<0, 0x24>, ISA_MIPS1;
2079 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2080 ADD_FM<0, 0x25>, ISA_MIPS1;
2081 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2082 ADD_FM<0, 0x26>, ISA_MIPS1;
2083 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2087 let AdditionalPredicates = [NotInMicroMips] in {
2088 /// Shift Instructions
2089 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2090 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2091 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2092 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2093 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2094 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2095 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2096 SRLV_FM<4, 0>, ISA_MIPS1;
2097 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2098 SRLV_FM<6, 0>, ISA_MIPS1;
2099 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2100 SRLV_FM<7, 0>, ISA_MIPS1;
2102 // Rotate Instructions
2103 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2105 SRA_FM<2, 1>, ISA_MIPS32R2;
2106 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2107 SRLV_FM<6, 1>, ISA_MIPS32R2;
2110 /// Load and Store Instructions
2112 let AdditionalPredicates = [NotInMicroMips] in {
2113 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2114 LW_FM<0x20>, ISA_MIPS1;
2115 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2116 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2117 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2118 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2119 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2120 MMRel, LW_FM<0x25>, ISA_MIPS1;
2121 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2122 LW_FM<0x23>, ISA_MIPS1;
2123 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2124 LW_FM<0x28>, ISA_MIPS1;
2125 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2127 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>, ISA_MIPS1;
2130 /// load/store left/right
2131 let AdditionalPredicates = [NotInMicroMips] in {
2132 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2133 ISA_MIPS1_NOT_32R6_64R6;
2134 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2135 ISA_MIPS1_NOT_32R6_64R6;
2136 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2137 ISA_MIPS1_NOT_32R6_64R6;
2138 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2139 ISA_MIPS1_NOT_32R6_64R6;
2141 // COP2 Memory Instructions
2142 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2143 ISA_MIPS1_NOT_32R6_64R6;
2144 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2145 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2146 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2147 ISA_MIPS2_NOT_32R6_64R6;
2148 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2149 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2151 // COP3 Memory Instructions
2152 let DecoderNamespace = "COP3_" in {
2153 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2154 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2155 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2156 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2157 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2158 ISA_MIPS2, NOT_ASE_CNMIPS;
2159 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2160 ISA_MIPS2, NOT_ASE_CNMIPS;
2163 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2164 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2168 let AdditionalPredicates = [NotInMicroMips] in {
2169 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2171 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2173 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2175 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2177 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2179 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2182 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2183 ISA_MIPS2_NOT_32R6_64R6;
2184 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2185 ISA_MIPS2_NOT_32R6_64R6;
2186 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2187 ISA_MIPS2_NOT_32R6_64R6;
2188 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2189 ISA_MIPS2_NOT_32R6_64R6;
2190 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2191 ISA_MIPS2_NOT_32R6_64R6;
2192 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2193 ISA_MIPS2_NOT_32R6_64R6;
2196 let AdditionalPredicates = [NotInMicroMips] in {
2197 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2198 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2200 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2201 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2202 ISA_MIPS32_NOT_32R6_64R6;
2204 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2205 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2207 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2209 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2211 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2214 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2217 let AdditionalPredicates = [NotInMicroMips] in {
2218 /// Load-linked, Store-conditional
2219 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2220 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2222 /// Jump and Branch Instructions
2223 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2224 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2225 IsBranch, ISA_MIPS1;
2227 let AdditionalPredicates = [NotInMicroMips] in {
2228 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
2229 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2231 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2232 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2233 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2235 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2236 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2237 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2238 BGEZ_FM<1, 1>, ISA_MIPS1;
2239 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2240 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2241 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2242 BGEZ_FM<7, 0>, ISA_MIPS1;
2243 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2244 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2245 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2246 BGEZ_FM<6, 0>, ISA_MIPS1;
2247 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2248 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2249 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2250 BGEZ_FM<1, 0>, ISA_MIPS1;
2251 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2252 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2253 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2255 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2259 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2260 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2261 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2264 let AdditionalPredicates = [NotInMicroMips] in {
2265 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2266 ISA_MIPS32_NOT_32R6_64R6;
2267 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2268 ISA_MIPS1_NOT_32R6_64R6;
2269 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2270 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2271 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2272 ISA_MIPS1_NOT_32R6_64R6;
2273 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2274 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2275 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2277 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2278 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2280 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2281 NoIndirectJumpGuards] in
2282 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2284 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2285 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2286 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2287 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2288 II_IndirectBranchPseudo>,
2289 PseudoInstExpansion<(JumpInst RO:$rs)> {
2292 let hasDelaySlot = 1;
2294 let isIndirectBranch = 1;
2298 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2299 NoIndirectJumpGuards] in
2300 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2301 ISA_MIPS1_NOT_32R6_64R6;
2303 // Return instructions are matched as a RetRA instruction, then are expanded
2304 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2305 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2307 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2308 [], II_ReturnPseudo> {
2309 let isTerminator = 1;
2311 let hasDelaySlot = 1;
2313 let isCodeGenOnly = 1;
2315 let hasExtraSrcRegAllocReq = 1;
2319 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2321 // Exception handling related node and instructions.
2322 // The conversion sequence is:
2323 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2324 // MIPSeh_return -> (stack change + indirect branch)
2326 // MIPSeh_return takes the place of regular return instruction
2327 // but takes two arguments (V1, V0) which are used for storing
2328 // the offset and return address respectively.
2329 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2331 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2332 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2334 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in {
2335 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2336 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2337 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
2339 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2342 /// Multiply and Divide Instructions.
2343 let AdditionalPredicates = [NotInMicroMips] in {
2344 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2345 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2346 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2347 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2348 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2349 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2350 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2351 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2352 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2353 ISA_MIPS1_NOT_32R6_64R6;
2354 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2355 ISA_MIPS1_NOT_32R6_64R6;
2356 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2357 ISA_MIPS1_NOT_32R6_64R6;
2358 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2359 ISA_MIPS1_NOT_32R6_64R6;
2361 /// Sign Ext In Register Instructions.
2362 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2363 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2364 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2365 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2368 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2369 ISA_MIPS32_NOT_32R6_64R6;
2370 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2371 ISA_MIPS32_NOT_32R6_64R6;
2373 /// Word Swap Bytes Within Halfwords
2374 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2378 def NOP : PseudoSE<(outs), (ins), []>,
2379 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2381 // FrameIndexes are legalized when they are operands from load/store
2382 // instructions. The same not happens for stack address copies, so an
2383 // add op with mem ComplexPattern is used and the stack address copy
2384 // can be matched. It's similar to Sparc LEA_ADDRi
2385 let AdditionalPredicates = [NotInMicroMips] in
2386 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>, ISA_MIPS1;
2389 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2390 ISA_MIPS32_NOT_32R6_64R6;
2391 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2392 ISA_MIPS32_NOT_32R6_64R6;
2393 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2394 ISA_MIPS32_NOT_32R6_64R6;
2395 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2396 ISA_MIPS32_NOT_32R6_64R6;
2399 let AdditionalPredicates = [NotDSP] in {
2400 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2401 ISA_MIPS1_NOT_32R6_64R6;
2402 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2403 ISA_MIPS1_NOT_32R6_64R6;
2404 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2405 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2406 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2407 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2408 ISA_MIPS32_NOT_32R6_64R6;
2409 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2410 ISA_MIPS32_NOT_32R6_64R6;
2411 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2412 ISA_MIPS32_NOT_32R6_64R6;
2413 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2414 ISA_MIPS32_NOT_32R6_64R6;
2417 let AdditionalPredicates = [NotInMicroMips] in {
2418 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2419 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2420 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2421 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2422 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2423 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2424 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2425 immZExt5, immZExt5Plus1, MipsExt>,
2426 EXT_FM<0>, ISA_MIPS32R2;
2427 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2428 uimm5_inssize_plus1, immZExt5,
2430 EXT_FM<4>, ISA_MIPS32R2;
2432 /// Move Control Registers From/To CPU Registers
2433 let AdditionalPredicates = [NotInMicroMips] in {
2434 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2435 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2436 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2437 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2438 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2439 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2440 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2441 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2444 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2445 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2446 let AdditionalPredicates = [NotInMicroMips] in {
2447 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2449 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2452 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2456 // JR_HB and JALR_HB are defined here using the new style naming
2457 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2458 // and because of that it doesn't follow the naming convention of the
2459 // rest of the file. To avoid a mixture of old vs new style, the new
2460 // style was chosen.
2461 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2462 dag OutOperandList = (outs);
2463 dag InOperandList = (ins GPROpnd:$rs);
2464 string AsmString = !strconcat(instr_asm, "\t$rs");
2465 list<dag> Pattern = [];
2468 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2469 dag OutOperandList = (outs GPROpnd:$rd);
2470 dag InOperandList = (ins GPROpnd:$rs);
2471 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2472 list<dag> Pattern = [];
2475 class JR_HB_DESC<RegisterOperand RO> :
2476 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2478 let isIndirectBranch=1;
2485 class JALR_HB_DESC<RegisterOperand RO> :
2486 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2488 let isIndirectBranch=1;
2493 class JR_HB_ENC : JR_HB_FM<8>;
2494 class JALR_HB_ENC : JALR_HB_FM<9>;
2496 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2497 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2499 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2500 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2503 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2504 UseIndirectJumpsHazard] in {
2505 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2506 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2507 ISA_MIPS32R2_NOT_32R6_64R6;
2510 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2511 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2512 let AdditionalPredicates = [NotInMicroMips] in {
2513 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2514 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2515 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2516 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2518 class CacheOp<string instr_asm, Operand MemOpnd,
2519 InstrItinClass itin = NoItinerary> :
2520 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2521 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2523 let DecoderMethod = "DecodeCacheOp";
2526 let AdditionalPredicates = [NotInMicroMips] in {
2527 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2528 INSN_MIPS3_32_NOT_32R6_64R6;
2529 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2530 INSN_MIPS3_32_NOT_32R6_64R6;
2532 // FIXME: We are missing the prefx instruction.
2533 def ROL : MipsAsmPseudoInst<(outs),
2534 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2535 "rol\t$rs, $rt, $rd">;
2536 def ROLImm : MipsAsmPseudoInst<(outs),
2537 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2538 "rol\t$rs, $rt, $imm">;
2539 def : MipsInstAlias<"rol $rd, $rs",
2540 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2541 def : MipsInstAlias<"rol $rd, $imm",
2542 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2544 def ROR : MipsAsmPseudoInst<(outs),
2545 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2546 "ror\t$rs, $rt, $rd">;
2547 def RORImm : MipsAsmPseudoInst<(outs),
2548 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2549 "ror\t$rs, $rt, $imm">;
2550 def : MipsInstAlias<"ror $rd, $rs",
2551 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2552 def : MipsInstAlias<"ror $rd, $imm",
2553 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2555 def DROL : MipsAsmPseudoInst<(outs),
2556 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2557 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2558 def DROLImm : MipsAsmPseudoInst<(outs),
2559 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2560 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2561 def : MipsInstAlias<"drol $rd, $rs",
2562 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2563 def : MipsInstAlias<"drol $rd, $imm",
2564 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2566 def DROR : MipsAsmPseudoInst<(outs),
2567 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2568 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2569 def DRORImm : MipsAsmPseudoInst<(outs),
2570 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2571 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2572 def : MipsInstAlias<"dror $rd, $rs",
2573 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2574 def : MipsInstAlias<"dror $rd, $imm",
2575 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2577 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2580 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2581 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2582 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2584 def : MipsInstAlias<"seq $rd, $rs",
2585 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2588 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2589 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2590 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2592 def : MipsInstAlias<"seq $rd, $imm",
2593 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2596 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2597 simm32_relaxed:$imm),
2598 "mul\t$rd, $rs, $imm">,
2599 ISA_MIPS1_NOT_32R6_64R6;
2600 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2602 "mulo\t$rd, $rs, $rt">,
2603 ISA_MIPS1_NOT_32R6_64R6;
2604 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2606 "mulou\t$rd, $rs, $rt">,
2607 ISA_MIPS1_NOT_32R6_64R6;
2609 // Virtualization ASE
2610 class HYPCALL_FT<string opstr> :
2611 InstSE<(outs), (ins uimm10:$code_),
2612 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2613 let BaseOpcode = opstr;
2616 let AdditionalPredicates = [NotInMicroMips] in {
2617 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2618 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2619 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2620 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2621 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2622 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2623 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2624 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2625 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2626 ISA_MIPS32R5, ASE_VIRT;
2627 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2628 ISA_MIPS32R5, ASE_VIRT;
2629 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2630 ISA_MIPS32R5, ASE_VIRT;
2631 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2632 ISA_MIPS32R5, ASE_VIRT;
2633 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2634 ISA_MIPS32R5, ASE_VIRT;
2635 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2636 ISA_MIPS32R5, ASE_VIRT;
2637 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2638 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2641 //===----------------------------------------------------------------------===//
2642 // Instruction aliases
2643 //===----------------------------------------------------------------------===//
2645 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2647 RegisterOperand RO = GPR32Opnd,
2648 Operand Imm = simm32_relaxed> {
2649 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2653 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2659 let AdditionalPredicates = [NotInMicroMips] in {
2660 def : MipsInstAlias<"move $dst, $src",
2661 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2663 def : MipsInstAlias<"move $dst, $src",
2664 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2667 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2668 ISA_MIPS1_NOT_32R6_64R6;
2670 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2672 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2674 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2677 def : MipsInstAlias<"neg $rt, $rs",
2678 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2679 def : MipsInstAlias<"neg $rt",
2680 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2681 def : MipsInstAlias<"negu $rt, $rs",
2682 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2683 def : MipsInstAlias<"negu $rt",
2684 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2685 def : MipsInstAlias<
2686 "sgt $rd, $rs, $rt",
2687 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2688 def : MipsInstAlias<
2690 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2691 def : MipsInstAlias<
2692 "sgtu $rd, $rs, $rt",
2693 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2694 def : MipsInstAlias<
2696 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2697 def : MipsInstAlias<
2699 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2700 def : MipsInstAlias<
2702 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2704 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2706 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2708 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2710 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2712 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2714 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2716 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2718 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2720 def : MipsInstAlias<"mfgc0 $rt, $rd",
2721 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2722 ISA_MIPS32R5, ASE_VIRT;
2723 def : MipsInstAlias<"mtgc0 $rt, $rd",
2724 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2725 ISA_MIPS32R5, ASE_VIRT;
2726 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2727 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2728 ISA_MIPS32R5, ASE_VIRT;
2729 def : MipsInstAlias<"mthgc0 $rt, $rd",
2730 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2731 ISA_MIPS32R5, ASE_VIRT;
2732 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2734 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2736 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2738 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2741 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2744 def : MipsInstAlias<"bnez $rs,$offset",
2745 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2747 def : MipsInstAlias<"bnezl $rs,$offset",
2748 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2750 def : MipsInstAlias<"beqz $rs,$offset",
2751 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2753 def : MipsInstAlias<"beqzl $rs,$offset",
2754 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2757 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2759 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2760 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2761 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2762 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2764 def : MipsInstAlias<"teq $rs, $rt",
2765 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2766 def : MipsInstAlias<"tge $rs, $rt",
2767 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2768 def : MipsInstAlias<"tgeu $rs, $rt",
2769 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2770 def : MipsInstAlias<"tlt $rs, $rt",
2771 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2772 def : MipsInstAlias<"tltu $rs, $rt",
2773 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2774 def : MipsInstAlias<"tne $rs, $rt",
2775 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2776 def : MipsInstAlias<"rdhwr $rt, $rs",
2777 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2780 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2781 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2782 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2783 def : MipsInstAlias<"sub $rs, $imm",
2784 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2785 0>, ISA_MIPS1_NOT_32R6_64R6;
2786 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2787 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2788 InvertedImOperand:$imm), 0>;
2789 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2790 InvertedImOperand:$imm), 0>;
2791 let AdditionalPredicates = [NotInMicroMips] in {
2792 def : MipsInstAlias<"sll $rd, $rt, $rs",
2793 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2794 def : MipsInstAlias<"sra $rd, $rt, $rs",
2795 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2796 def : MipsInstAlias<"srl $rd, $rt, $rs",
2797 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2798 def : MipsInstAlias<"sll $rd, $rt",
2799 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2800 def : MipsInstAlias<"sra $rd, $rt",
2801 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2802 def : MipsInstAlias<"srl $rd, $rt",
2803 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2804 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2806 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2809 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2810 let AdditionalPredicates = [NotInMicroMips] in
2811 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2813 def : MipsInstAlias<"mulo $rs, $rt",
2814 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2815 ISA_MIPS1_NOT_32R6_64R6;
2816 def : MipsInstAlias<"mulou $rs, $rt",
2817 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2818 ISA_MIPS1_NOT_32R6_64R6;
2820 let AdditionalPredicates = [NotInMicroMips] in
2821 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2823 //===----------------------------------------------------------------------===//
2824 // Assembler Pseudo Instructions
2825 //===----------------------------------------------------------------------===//
2827 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2829 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2830 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2831 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2832 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2834 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2835 RegisterOperand RO> :
2836 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2837 !strconcat(instr_asm, "\t$rt, $addr")> ;
2838 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2840 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2841 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2842 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2843 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2845 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2847 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2850 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2851 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2852 "nor\t$rs, $rt, $imm">;
2853 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2854 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2855 simm32_relaxed:$imm)>, GPR_32;
2857 let hasDelaySlot = 1, isCTI = 1 in {
2858 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2859 (ins imm64:$imm64, brtarget:$offset),
2860 "bne\t$rt, $imm64, $offset">;
2861 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2862 (ins imm64:$imm64, brtarget:$offset),
2863 "beq\t$rt, $imm64, $offset">;
2865 class CondBranchPseudo<string instr_asm> :
2866 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2868 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2871 def BLT : CondBranchPseudo<"blt">;
2872 def BLE : CondBranchPseudo<"ble">;
2873 def BGE : CondBranchPseudo<"bge">;
2874 def BGT : CondBranchPseudo<"bgt">;
2875 def BLTU : CondBranchPseudo<"bltu">;
2876 def BLEU : CondBranchPseudo<"bleu">;
2877 def BGEU : CondBranchPseudo<"bgeu">;
2878 def BGTU : CondBranchPseudo<"bgtu">;
2879 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2880 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2881 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2882 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2883 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2884 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2885 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2886 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2889 class CondBranchImmPseudo<string instr_asm> :
2890 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2891 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2893 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2894 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2896 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2897 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2898 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2899 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2900 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2901 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2902 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2903 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2904 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2905 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2906 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2907 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2908 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2909 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2910 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2911 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2913 // FIXME: Predicates are removed because instructions are matched regardless of
2914 // predicates, because PredicateControl was not in the hierarchy. This was
2915 // done to emit more precise error message from expansion function.
2916 // Once the tablegen-erated errors are made better, this needs to be fixed and
2917 // predicates needs to be restored.
2919 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2920 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2921 "div\t$rd, $rs, $rt">,
2922 ISA_MIPS1_NOT_32R6_64R6;
2923 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2924 (ins GPR32Opnd:$rs, simm32:$imm),
2925 "div\t$rd, $rs, $imm">,
2926 ISA_MIPS1_NOT_32R6_64R6;
2927 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2928 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2929 "divu\t$rd, $rs, $rt">,
2930 ISA_MIPS1_NOT_32R6_64R6;
2931 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2932 (ins GPR32Opnd:$rs, simm32:$imm),
2933 "divu\t$rd, $rs, $imm">,
2934 ISA_MIPS1_NOT_32R6_64R6;
2937 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2939 ISA_MIPS1_NOT_32R6_64R6;
2940 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
2941 GPR32NonZeroOpnd:$rs,
2943 ISA_MIPS1_NOT_32R6_64R6;
2944 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2946 ISA_MIPS1_NOT_32R6_64R6;
2948 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
2950 ISA_MIPS1_NOT_32R6_64R6;
2951 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
2952 GPR32NonZeroOpnd:$rt,
2954 ISA_MIPS1_NOT_32R6_64R6;
2956 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2958 ISA_MIPS1_NOT_32R6_64R6;
2960 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2961 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2962 "rem\t$rd, $rs, $rt">,
2963 ISA_MIPS1_NOT_32R6_64R6;
2964 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2965 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2966 "rem\t$rd, $rs, $imm">,
2967 ISA_MIPS1_NOT_32R6_64R6;
2968 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2969 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2970 "remu\t$rd, $rs, $rt">,
2971 ISA_MIPS1_NOT_32R6_64R6;
2972 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2973 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2974 "remu\t$rd, $rs, $imm">,
2975 ISA_MIPS1_NOT_32R6_64R6;
2977 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2979 ISA_MIPS1_NOT_32R6_64R6;
2980 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2981 simm32_relaxed:$imm), 0>,
2982 ISA_MIPS1_NOT_32R6_64R6;
2983 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2985 ISA_MIPS1_NOT_32R6_64R6;
2986 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2987 simm32_relaxed:$imm), 0>,
2988 ISA_MIPS1_NOT_32R6_64R6;
2990 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2991 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2993 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2994 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2996 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2997 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2999 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3000 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3002 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3003 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3005 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3006 (ins mem_simm16:$addr), "ld $rt, $addr">,
3007 ISA_MIPS1_NOT_MIPS3;
3008 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3009 (ins mem_simm16:$addr), "sd $rt, $addr">,
3010 ISA_MIPS1_NOT_MIPS3;
3011 //===----------------------------------------------------------------------===//
3012 // Arbitrary patterns that map to one or more instructions
3013 //===----------------------------------------------------------------------===//
3015 // Load/store pattern templates.
3016 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3017 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3019 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3020 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3022 // Materialize constants.
3023 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3024 Instruction ADDiuOp, Instruction LUiOp,
3025 Instruction ORiOp> {
3027 // Constant synthesis previously relied on the ordering of the patterns below.
3028 // By making the predicates they use non-overlapping, the patterns were
3029 // reordered so that the effect of the newly introduced predicates can be
3032 // Arbitrary immediates
3033 def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3035 // Bits 32-16 set, sign/zero extended.
3036 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3039 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3040 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3043 let AdditionalPredicates = [NotInMicroMips] in
3044 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3046 // Carry MipsPatterns
3047 let AdditionalPredicates = [NotInMicroMips] in {
3048 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3049 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3051 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3052 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3053 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3054 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3056 // Support multiplication for pre-Mips32 targets that don't have
3057 // the MUL instruction.
3058 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3059 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3060 ISA_MIPS1_NOT_32R6_64R6;
3063 def : MipsPat<(MipsSync (i32 immz)),
3064 (SYNC 0)>, ISA_MIPS2;
3067 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3068 (JAL texternalsym:$dst)>, ISA_MIPS1;
3069 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3070 // (JALR GPR32:$dst)>;
3073 let AdditionalPredicates = [NotInMicroMips] in {
3074 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3075 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3076 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3077 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3080 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3081 Register ZeroReg, RegisterOperand GPROpnd> {
3082 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3083 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3084 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3085 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3086 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3088 def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
3089 def : MipsPat<(MipsLo tblockaddress:$in),
3090 (Addiu ZeroReg, tblockaddress:$in)>;
3091 def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
3092 def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
3093 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3094 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3095 def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
3097 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3098 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3099 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3100 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3101 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3102 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3103 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3104 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3105 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3106 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3110 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3111 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3113 let AdditionalPredicates = [NotInMicroMips] in {
3114 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3116 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3117 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3120 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3124 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3125 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3126 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3127 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3129 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3130 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3131 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3132 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3133 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3134 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3136 // Mips does not have "not", so we expand our way
3137 def : MipsPat<(not GPR32:$in),
3138 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3142 let AdditionalPredicates = [NotInMicroMips] in {
3143 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3144 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3145 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3148 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3152 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3153 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3154 Instruction SLTiOp, Instruction SLTiuOp,
3156 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3157 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3158 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3159 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3161 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3162 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3163 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3164 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3165 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3166 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3167 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3168 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3169 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3170 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3171 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3172 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3174 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3175 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3176 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3177 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3179 def : MipsPat<(brcond RC:$cond, bb:$dst),
3180 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3182 let AdditionalPredicates = [NotInMicroMips] in {
3183 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3185 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3186 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3187 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3188 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3192 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3193 Instruction SLTuOp, Register ZEROReg> {
3194 def : MipsPat<(seteq RC:$lhs, 0),
3195 (SLTiuOp RC:$lhs, 1)>;
3196 def : MipsPat<(setne RC:$lhs, 0),
3197 (SLTuOp ZEROReg, RC:$lhs)>;
3198 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3199 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3200 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3201 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3204 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3205 Instruction SLTuOp> {
3206 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3207 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3208 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3209 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3212 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3213 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3214 (SLTOp RC:$rhs, RC:$lhs)>;
3215 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3216 (SLTuOp RC:$rhs, RC:$lhs)>;
3219 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3220 Instruction SLTuOp> {
3221 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3222 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3223 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3224 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3227 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3228 Instruction SLTiOp, Instruction SLTiuOp> {
3229 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3230 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3231 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3232 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3235 let AdditionalPredicates = [NotInMicroMips] in {
3236 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3237 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3238 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3239 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3240 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3243 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3246 // Load halfword/word patterns.
3247 let AdditionalPredicates = [NotInMicroMips] in {
3248 let AddedComplexity = 40 in {
3249 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3250 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3251 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3252 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3253 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3256 // Atomic load patterns.
3257 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3258 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3259 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3261 // Atomic store patterns.
3262 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3264 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3266 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3270 //===----------------------------------------------------------------------===//
3271 // Floating Point Support
3272 //===----------------------------------------------------------------------===//
3274 include "MipsInstrFPU.td"
3275 include "Mips64InstrInfo.td"
3276 include "MipsCondMov.td"
3278 include "Mips32r6InstrInfo.td"
3279 include "Mips64r6InstrInfo.td"
3284 include "Mips16InstrFormats.td"
3285 include "Mips16InstrInfo.td"
3288 include "MipsDSPInstrFormats.td"
3289 include "MipsDSPInstrInfo.td"
3292 include "MipsMSAInstrFormats.td"
3293 include "MipsMSAInstrInfo.td"
3296 include "MipsEVAInstrFormats.td"
3297 include "MipsEVAInstrInfo.td"
3300 include "MipsMTInstrFormats.td"
3301 include "MipsMTInstrInfo.td"
3304 include "MicroMipsInstrFormats.td"
3305 include "MicroMipsInstrInfo.td"
3306 include "MicroMipsInstrFPU.td"
3309 include "MicroMips32r6InstrFormats.td"
3310 include "MicroMips32r6InstrInfo.td"
3313 include "MicroMipsDSPInstrFormats.td"
3314 include "MicroMipsDSPInstrInfo.td"